/usr /var /home の引っ越し

ルートパーティションがいっぱいになったので /usr /var /home を移動させることに。
引っ越し前の状況 ↓ /dev/sda4 を使ってません。明らかなOSインストール時のミス

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2             6.8G  6.2G  263M  97% /
tmpfs                 3.8G     0  3.8G   0% /dev/shm
/dev/sda1             310M   54M  240M  19% /boot
tmpfs                 512M  1.9M  511M   1% /tmp
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          41      327680   83  Linux
/dev/sda2              41         941     7222272   83  Linux
/dev/sda3            1034        1702     5373742+  82  Linux swap / Solaris
/dev/sda4            1703       14594   103548533   83  Linux

パーティション拡張に LVM は使わず。使う機会が少なすぎて pvcreatevgscan などのコマンドがなかなか覚えられないのと、今回のサーバではスナップショットや動的リサイズなどの機能は特に不要だと思ったため。

$ sudo fdisk /dev/sda

# 状態確認
Command (m for help): p

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          41      327680   83  Linux
/dev/sda2              41         941     7222272   83  Linux
/dev/sda3            1034        1702     5373742+  82  Linux swap / Solaris
/dev/sda4            1703       14594   103548533   83  Linux

# 怖いのでコマンド確認
Command (m for help): m
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)

# パーティション削除
Command (m for help): d
Partition number (1-4): 4

# 拡張パーティションを作成
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
e
Selected partition 4
First cylinder (941-14593, default 941): 1703
Last cylinder, +cylinders or +size{K,M,G} (1703-14593, default 14593): 14593

# 確認
Command (m for help): p

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          41      327680   83  Linux
/dev/sda2              41         941     7222272   83  Linux
/dev/sda3            1034        1702     5373742+  82  Linux swap / Solaris
/dev/sda4            1703       14593   103546957+   5  Extended

# 新規パーティション作成 /var
Command (m for help): n
First cylinder (1703-14593, default 1703):
Using default value 1703
Last cylinder, +cylinders or +size{K,M,G} (1703-14593, default 14593): +30G

# 新規パーティション作成 /usr
Command (m for help): n
First cylinder (5620-14593, default 5620):
Using default value 5620
Last cylinder, +cylinders or +size{K,M,G} (5620-14593, default 14593): +30G

# 新規パーティション作成 /home
Command (m for help): n
First cylinder (9537-14593, default 9537):
Using default value 9537
Last cylinder, +cylinders or +size{K,M,G} (9537-14593, default 14593): +30G

# 確認
Command (m for help): p

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          41      327680   83  Linux
/dev/sda2              41         941     7222272   83  Linux
/dev/sda3            1034        1702     5373742+  82  Linux swap / Solaris
/dev/sda4            1703       14593   103546957+   5  Extended
/dev/sda5            1703        5619    31463271   83  Linux
/dev/sda6            5620        9536    31463271   83  Linux
/dev/sda7            9537       13453    31463271   83  Linux

# 確定
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

Device or resource busy. と言われたので一旦再起動。

$ sudo shutdown -r now

再起動後、フォーマット

# フォーマット
$ sudo mkfs -t ext4 /dev/sda5
$ sudo mkfs -t ext4 /dev/sda6
$ sudo mkfs -t ext4 /dev/sda7

# UUID を確認
$ sudo blkid
/dev/sda1: UUID="5c9c4ad7-25e6-4fdc-8f0a-074b73828596" TYPE="ext4"
/dev/sda2: UUID="712a7910-1ec3-4cc3-a8ce-49cd82a0e0a4" TYPE="ext4"
/dev/sda3: LABEL="swap" TYPE="swap"
/dev/sda5: UUID="2b55d1af-fe53-4a1f-bed0-80a05b4e51d1" TYPE="ext4"
/dev/sda6: UUID="6d120d95-67c3-40d0-8b4c-b8433a751182" TYPE="ext4"
/dev/sda7: UUID="4fe9b898-64a4-407d-b27d-c97de6500819" TYPE="ext4" 

# マウントポイント作成 → マウント
$ sudo mkdir /mnt/new_home /mnt/new_usr /mnt/new_var
$ sudo mount /dev/sda5 /mnt/new_var
$ sudo mount /dev/sda6 /mnt/new_usr
$ sudo mount /dev/sda7 /mnt/new_home

# ディレクトリ内容コピー
$ sudo cp -a /home/* /mnt/new_home/
$ cd /usr
$ sudo tar cpvf - . | sudo tar xpvf - -C /mnt/new_usr
$ cd /var 
$ sudo tar cpvf - . | sudo tar xpvf - -C /mnt/new_var

# fstab 修正
$ sudo cp /etc/fstab /etc/fstab.bak
$ sudo vim /etc/fstab

追加したパーティションのUUIDとマウントポイントを追記。discard,noatimeSSD用。

--- /etc/fstab.bak  2013-06-28 22:42:48.768179715 +0900
+++ /etc/fstab    2013-06-28 22:45:49.486342373 +0900
@@ -7,10 +7,13 @@
+UUID=2b55d1af-fe53-4a1f-bed0-80a05b4e51d1 /var    ext4    defaults,discard,noatime        1 2
+UUID=6d120d95-67c3-40d0-8b4c-b8433a751182 /usr    ext4    defaults,discard,noatime        1 2
+UUID=4fe9b898-64a4-407d-b27d-c97de6500819 /home   ext4    defaults,discard,noatime        1 2

もういちど再起動。起動失敗すると面倒なので失敗しないよう祈る。

$ sudo shutdown -r now

コンソールにエラーなし、 /var/log/messages にもエラーなしだったので、引っ越しは完了(多分)
一応 New Relic から届く disk full のアラートを消したいので、古い /home を削除する。

$ sudo mount /dev/sda2 /mnt/root
$ sudo rm -rf /mnt/root/home
$ sudo umount /mnt/root

同僚に fdisk とか危なすぎて使わない方がいいって言った矢先に使ってしまいました。許してください。

参考
http://krakenbeal.blogspot.jp/2010/06/ubuntuhomeusrvar.html

Jetty9 WebSocketとChromeのバグ

サンプル を参考に実装してみたけど、いくつかメッセージを送受信するとエラーがずらっと。

Oct 22 23:58:29 [qtp1685059636-58] WARN org.eclipse.jetty.websocket.core.extensions.compress.DeflateCompressionMethod$InflaterProcess:
...
org.eclipse.jetty.websocket.core.api.BadPayloadException: java.util.zip.DataFormatException: invalid distance too far back
Caused by: java.util.zip.DataFormatException: invalid distance too far back

接続してたクライアントは Chrome 安定版(M22)だったんだけど、これに関連する Issue が、最近更新されていて、内容が Java の deflate 実装では BFINAL 1 の方で圧縮データを作成してるけど、Chrome の実装では BFINAL 0 にしか対応していなかったというもの(WebSocket の draft では BFINAL 0, 1 の両方をサポートしてる)。M24 に Fix コードが取り込まれるようだけど、そもそも deflate-frame extensionpermessage-compress extension に移行されるはずなので、WebkitDeflateFrameExtension をオフにしても問題ないと判断して、このあたり を参考に拡張を登録解除して対処した。

import org.eclipse.jetty.server._
import org.eclipse.jetty.websocket.core.api._
import org.eclipse.jetty.websocket.server._
import org.slf4j._

class MyWebSocketHandler extends WebSocketListener {

  val logger = LoggerFactory.getLogger(classOf[MyWebSocketHandler])

  def onWebSocketBinary(payload: Array[Byte], offset: Int, len: Int) {
    logger.info("WebSocket.onBinaryMessage: {}", len)
  }

  def onWebSocketClose(statusCode: Int, reason: String) {
    logger.info("onWebSocketClose: {}: {}", statusCode, reason)
  }

  def onWebSocketConnect(connection: WebSocketConnection) {
    logger.info("WebSocket.onOpen")
  }

  def onWebSocketException(error: WebSocketException) {
    error.printStackTrace
  }

  def onWebSocketText(message: String) {
    logger.info("WebSocket.onTextMessage: {}", message)
  }
}

object WebSocketServer {

  def main(args: Array[String]) {

    val server = new Server
    val connector = new ServerConnector(server)

    connector.setPort(9090)
    server.addConnector(connector)

    val handler = new WebSocketHandler() {

      override def configurePolicy(policy: WebSocketPolicy) {
        policy.setBufferSize(1024)
        policy.setIdleTimeout(30000)
        policy.setMaxTextMessageSize(1024)
        policy.setMaxBinaryMessageSize(1024)
      }

      override def configure(factory: WebSocketServerFactory) {
        factory.getExtensionRegistry.unregister("x-webkit-deflate-frame")

        factory.setCreator(new WebSocketCreator() {
          def createWebSocket(req: UpgradeRequest, resp: UpgradeResponse): Object = {
            new MyWebSocketHandler
          }
        })
      }
    }

    server.setHandler(handler)
    server.start
    server.join
  }
}

WebSocket Extension がまともに実装されてる WebSocket ライブラリはじめて見た。
permessage-compress もバッチリ実装されてる。
 
それはそうと、この拡張問題は安定版の Chrome に混入しちゃってる問題なので、今後 WebSocket の拡張に対応したサーバー(恐らく普通に対応することになるはず)を書くときは、古いバージョンの Chrome で接続されることを考慮した場合、x-webkit-deflate-frame のサポートに関して少し注意しないといけない。