新しいマシンを入手したのでGentooをインストールしました

新しいマシンを入手しました。スペックはこんな感じ

 # cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 42
model name      : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
stepping        : 7
microcode       : 0x14
cpu MHz         : 1600.000
cache size      : 8192 KB
physical id     : 0
siblings        : 8
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
bogomips        : 7004.34
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
...
# free -m
             total       used       free     shared    buffers     cached
Mem:         32018       4900      27118          0       1440        780
-/+ buffers/cache:       2679      29339
Swap:            0          0          0
# fdisk -l|grep /dev/sd
Disk /dev/sdb: 160.0 GB, 160041885696 bytes
/dev/sdb1              63      144584       72261   83  Linux
/dev/sdb2          144585     2265164     1060290   83  Linux
/dev/sdb3         2265165   312576704   155155770   8e  Linux LVM
Disk /dev/sda: 1000.2 GB, 1000203804160 bytes
Disk /dev/sdd: 120.0 GB, 120034123776 bytes
Disk /dev/sde: 80.0 GB, 80026361856 bytes
/dev/sde1               1   156301487    78150743+  ee  GPT
/dev/sde2   *          34      524321      262144   a5  FreeBSD
Disk /dev/sdc: 320.1 GB, 320072933376 bytes
/dev/sdc1            2048   625142447   312570200   83  Linux

ディスク構成は

  • sda: 1TB HDD 一本まるごとbtrfs
  • sdb: 160GB HDD 旧マシンのHDD LVMでVMのディスクプール
  • sdc: 320GB HDD 旧マシンのHDD LVMでVMのディスクプール
  • sdd: 120GB SSD まだ用途を決めかねている
  • sde: 80GB HDD 一本まるごとGentoo/DragonFlyのデータ

で、結局いまのところmountしてるのはこんな感じ

/dev/root on / type btrfs (rw,noatime,compress=lzo,space_cache,autodefrag,inode_cach
/dev/sda on /btrfs type btrfs (rw,noatime,autodefrag,space_cache,inode_cache,compress=lzo)
/dev/sda on /home type btrfs (rw,noatime,autodefrag,space_cache,inode_cache,compress=lzo,subvol=home)
/dev/sda on /usr/portage type btrfs (rw,noatime,autodefrag,space_cache,inode_cache,compress=lzo,subvol=portage)

マシンの目的としてはGentoo/*BSDVMとか、テスト用のdistroとかのVMを動かすため。なのでインストールされてるパッケージはこんな感じ

# cat /var/lib/portage/world
app-admin/metalog
app-admin/sudo
app-editors/vim
app-emulation/libvirt
app-portage/eix
app-portage/flaggie
app-portage/gentwoo
app-portage/layman
app-portage/portage-utils
dev-util/ccache
mail-mta/ssmtp
net-misc/chrony
net-misc/dhcpcd
sys-apps/kexec-tools
sys-apps/portage
sys-auth/nss-mdns
sys-boot/grub
sys-boot/grub:2
sys-devel/autogen
sys-devel/distcc
sys-devel/gdb
sys-kernel/dracut
sys-kernel/gentoo-sources
sys-power/acpid
sys-power/hibernate-script
sys-power/pm-utils
sys-power/powertop
sys-process/fcron
sys-process/iotop

インストールの思い出

/をbtrfsにしてGRUBもそこから読ませたかったので、SystemRescueCDで起動した。

さっそうと mkfs.btrfs しようとしたんだけれどエラーが出る。 CDのSquashFSイメージをloopbackでmountしているんだけれど、そのファイルが見つからないから、btrfs-progsがエラーになる(mkfsで指定されたものがすでにmountされているものと一致しないかどうか調べてるコードがあってそれのせい)のだった。手元のマシンでそのコードを修正してENOENTは無視するようにして解決。

btrfsはsubvolumeごとにsnapshotがとれるようになっているので、mountしてトップディレクトリにとりあえずこんな感じでsubvolumeを切る。

# btrfs subv cre rootfs
# btrfs subv cre portage
# btrfs subv cre home

/etc/fstabはこんな感じ

/dev/sda                /btrfs          btrfs           noatime,autodefrag,space_cache,inode_cache,compress=lzo 0 1

/dev/sda                /               btrfs           noatime,autodefrag,space_cache,inode_cache,compress=lzo,subvol=rootfs 0 1
/dev/sda                /home           btrfs           noatime,autodefrag,space_cache,inode_cache,compress=lzo,subvol=home 0 1
/dev/sda                /usr/portage            btrfs           noatime,autodefrag,space_cache,inode_cache,compress=lzo,subvol=portage 0 1

/dev/cdrom              /mnt/cdrom      auto            noauto,ro       0 0

stage3とportage treeを展開キメたら make.confにCFLAGSとかを設定する。マシンに最適にしたいよね? gccの助けを借りよう。

# gcc -v -xc -march=native /dev/null 2>&1|grep cc1
 /usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.3/cc1 -quiet -v /dev/null -D_FORTIFY_SOURCE=2 -march=core2 -mcx16 -msahf -maes -mpclmul -mpopcnt -mavx --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -quiet -dumpbase null -auxbase null -version -o /tmp/cc1szasn.s
 /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/as -V -Qy --64 -o /tmp/ccp3QWH3.o /tmp/cc1szasn.s

これの"-march=core2 -mcx16 -msahf -maes -mpclmul -mpopcnt -mavx --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic"をぱりっとコピペしてmake.confに書きつける。ところで make.conf を書く時に vi がない!!ムキー!!ってなっている人もいるみたいだけれど vi が好きで好きでたまらないなら とりあえず busybox vi を使うのも手だと思うな。

次にUSEフラグいじるのを楽にするためにemerge flaggie。そして、さっそくそのflaggieを使う。

flaggie portage +python3

portageをpython3で動くようにする。これでちょっと速くなるらしいよ!やったね! あとは gccにltoをつけて、-flto が動くようにする。 link time optimization ってやつだね。

emerge -uDNavt worldでUSEフラグを吟味……

みんながたいそう苦労しているカーネルGRUBで動かない…><とかrootがーーーとかみんなたいていここでハマってる。 make localyesconfigを使おう。いま読みこんでるモジュールの機能をカーネル組み込みに設定してくれる。あとはmake nconfigでぽちぽちいらんのを外していこう。 M になってるのは外していいってことさ。

あとは lspci -k を活用しよう。 使用しているカーネルモジュールの名前が出てくるから。

 # lspci -k|grep Kernel
        Kernel driver in use: agpgart-intel
        Kernel driver in use: i915
        Kernel driver in use: ehci_hcd
        Kernel driver in use: ehci_hcd
        Kernel driver in use: ahci
        Kernel driver in use: xhci_hcd
        Kernel driver in use: r8169

これで make nconfig -> F8 とかやって i915 とか入力すればどこにその設定項目があるのか、どの設定項目に依存しているのかが一目でわかるようになっている。便利。

設定できたらカーネルのビルド

# make -j -l14 && make modules_install && make install
  • j でjobを上限なしでいくつでも増やさせる。ただし、-l14を設定してload avgが14を超えていたらそれ以上は増やさない。

最初 initrdを入れようかと思って dracutを使おうかと思ってたのだけれど結局やめた。 ちなみにdracutはFedoraさんあたりが作っている、distro-neutralなinitm作成ツールでいろんなプラグイン(モジュールと呼ばれてるけど)で拡張できて便利なツール。 dracutってたたくだけでinitrdを作ってくれていい感じ。

さて、btrfsからカーネル読みこみたい…ってことはGRUB2になります。しかも、compress=lzoしてるのでGRUB2のheadじゃないと動かないです。まあ、Gentooなんでこわくないですね。

# emerge =grub-9999 --autounmask-write
# dispatch-conf
# emerge =grub-9999

ところがインストール失敗。 python3がデフォだとビルドこけるみたいなんで eselect python set 1 します。ようやく通った……と思ったらどこかでgrub2-installがSEGVしてます。 grub2-install /dev/sda --debugしてやると、どうも/sbin/grub2-bios-setup --verbose --directory=/boot/grub/i386-pc --device-map=/boot/grub/device.map がSEGVしているみたいなんでdebugに入ります。

まずはデバッグ情報つけてビルドしましょう。

# CFLAGS='-O0 -ggdb' FEATURES="splitdebug keepwork" USE="debug custom-cflags" emerge =grub-9999

こうすると、debug情報が残るし、ソースも残るのでgdbからコードが見れていい感じです。30秒ぐらいでビルド終わるんで、動かします。

# ulimit -c unlimited
# /sbin/grub2-bios-setup --verbose --directory=/boot/grub/i386-pc --device-map=/boot/grub/device.map /dev/sda

util/grub-setup.cの中で死んでることがわかりました。具体的にはここで

   err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
                               GRUB_EMBED_PCBIOS, &sectors);

dest_partmap == NULL で死んでました。 if(dest_partmap) とかつけくわえてmakeして/sbin にcpしてあげましょう。動きます。

GRUB2の設定は/etc/default/grubでやります。こんな感じ。

GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10

GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""

GRUBFS=btrfs
GRUB_DEVICE=/dev/sda
rootsubvol=rootfs

でもまだ動いてません。残念。多分 grub2-mkconfigで設定ファイル出力するとこがまちがってるのかな。もしくは btrfsの top directoryに /rootfs/boot へのsymlinkが必要なのかも。

GRUB2で手動でbootする時は

linux /rootfs/boot/vmlinuz root=/dev/sda rootflags=subvol=rootfs
boot

という感じで、rootflagsを使ってbtrfsのsubvolumeを指定してあげましょう。

起動してみるとやっぱりrootのパスワード設定を忘れていたのではいれません。 華麗に電源をおとしたら init=/bin/bash をkernel 引数につけて起動して

# mount -o remount,rw /
# passwd
# mount -o remount,ro
# exit

こんな感じでパスワードを設定しましょう。/は最初読みこみ専用になっているので、書きこめるようにremountしてパスワード設定して、ふたたび読みこみ専用にmountしなおして、変更をディスクに書きもどします。ここでexitするとkernel panicしますが、仕様です。

VMホストとして

さて、無事にいろいろ終わったので、VMのホストとして設定します。KVMでやりたいのでlibvirtを使うことにしました。USEフラグはこんな感じ

# grep libvirt /etc/portage/package.use
app-emulation/libvirt lvm virt-network qemu parted

lvmをつけておけばLVMをVMのディスクとして使うことができます。partedで物理デバイスVM用にattachできます。

また、VMのネットワークをbridge接続したいのでbridgeインタフェースを作っておきます。

# cat /etc/conf.d/net
bridge_br0="eth0"
config_br0="dhcp"
config_eth0="null"

libvirtdを起動したらsshごしにvirt-managerから接続できるようになります。GUIでいろいろできて(・∀・)イイネ!

virt-managerを起動したら「ファイル」->「接続の追加」をします。 sshは事前にキーを入れておくと楽です。

接続がうまくできたら、一覧に追加されたホスト名のところを右クリックしてDetailを見ましょう。ストレージタブで、"+"ボタン押すとストレージプール追加するメニューが開くのでLVMを追加しましょう。

この時、virt-managerがかたまったのかと思うほど反応がなくなることがあります。 pstreeで見てみてlibvirtdの下でudevadmが動いていたらvgchange -an で解決するかもしれません。

どうもlibvirtは自分でLVMのvgを立ち上げて udevadm settleでその変更を待っているようです。なので手動でvgに変更をかませるとうまくいくって感じですね。

最後にkexecを設定しておきましょう。再起動でbiosgrubを通らずに、ダイレクトに新しいカーネルを起動するので、速くなります。設定はこんな感じ

# cat /etc/conf.d/kexec 
BOOTPART="/boot"
KNAME="vmlinuz"
ROOTPART="/dev/sda"
KPARAM="rootflags=subvol=rootfs"

まとめ

一通りこんな感じでした。btrfs rootedでsnapshotで楽にbackupとれるし、VMのストレージプールもいっぱいあるし、マシンはやいしで大変便利です。