前回の続き。ようやく、zfsでブートできた。何が問題だったかというと、
- 最初にrpi4に使っていたUSB-ATAのコントローラーとrpi4の相性が悪かった
- md上にシステムを書き込んで、ディスクにコピーしていた
1に関しては、よくわからないが、rpi4に1台だけつないだ場合は問題ないのだが、2台つなぐと途端に調子が悪くなる。両方ともコントローラーはCypress AT2LP RC7で、
Aug 27 02:58:57 generic kernel: (da2:umass-sim2:2:0:0): READ(10). CDB: 28 00 00 01 97 ff 00 00 01 00 Aug 27 02:58:57 generic kernel: (da2:umass-sim2:2:0:0): CAM status: CCB request completed with an error Aug 27 02:58:57 generic kernel: (da2:umass-sim2:2:0:0): Retrying command, 3 more tries remain Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): WRITE(10). CDB: 2a 00 00 02 35 c0 00 00 08 00 Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): CAM status: CCB request completed with an error Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): Retrying command, 3 more tries remain Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): WRITE(10). CDB: 2a 00 00 02 35 c0 00 00 08 00 Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): CAM status: SCSI Status Error Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): SCSI status: Check Condition Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): SCSI sense: ABORTED COMMAND asc:8,3 (Logical unit communication CRC error (Ultra-DMA/32)) Aug 27 02:59:12 generic kernel: (da0:umass-sim0:0:0:0): Retrying command (per sense data)
のようなカーネルのエラーが出でてくる。ただ、プログラム自体はエラー終了していないので、なんとか書き込みはできているのではと思っていたのだが、途中でこれはやはり良くないだろうと思い、rpi4上での作業は止めて、ラップトップPCに移行した。何が悪くてブートしないのかわからないから、少しでも問題になる可能性を排除した方がいいと思ったのだ。
PCに移行したので、bsdinstallを使う方法もやめて、公式のimgファイルの中身を新しいディスクにコピーすることにした。参考にしたのはこのページ。
2については、物理ディスクにパーティションの追加をすると"gpart destroy -F"を実行しても、追加した時点で以前のパーティションがゾンビのように復活するので、スクリプト一発で一連のコマンドが実行しにくい。それで、まっさらのメモリディスク上で準備してから、ddで物理ディスクに書き込んでいたのだが、これを行うと十中八九zpoolが破損するのだ。これは未だに理由がわからない。これに気づくのに二日ぐらいかかった。
参考にしたページの「zfs set canmount=noauto zpi/ROOT/default」もはまったポイントだった。最初は出来上がったメモリディスクをどうやって確認したらいいのかすらわからなかったが、「zpool import」でできることが分かり、実際にimportしてみると、書き込んだはずのファイルがないのだ。このファイル消失に気づいたときは、何が起きているか全くわからなかった。この理由は「canmount=noauto」にしているから、自動でマウントされない。これでも立ち上がるのかもしれないが、自動でマウントされないと面倒なので変えた。
結局、パーティション作成することろまではメモリディスクで行って、そのイメージを物理ディスクに書き込んでから、作業を継続するようにした。
#!/bin/sh GO=0 ORIG="" NEW="" case $# in 2) GO=1 ORIG=$1 NEW=$2 ;; *) ;; esac if [ ${GO} -eq 0 ]; then echo "create_gpt_zfs.sh <original boot image> <target disk>" exit 1 fi # create dummy md image TMP=/tmp/xxx.img dd if=/dev/zero of=${TMP} bs=1G count=1 # attach image SOURCE=$(mdconfig -a -f ${ORIG}) DEST=$(mdconfig -a -f ${TMP}) # create partitions FAT_SIZE="50m -b 1m" FAT_TYPE="16" gpart destroy -F /dev/${DEST} gpart create -s GPT /dev/${DEST} gpart add -t efi -l efi -a 512k -s ${FAT_SIZE} ${DEST} newfs_msdos -L efi -F ${FAT_TYPE} /dev/${DEST}p1 gpart add -t freebsd-ufs -l rootfs -a 64k /dev/${DEST} newfs -U -L rootfs /dev/${DEST}p2 # deatch image and write it to disk mdconfig -d -u ${DEST} dd if=${TMP} of=/dev/${NEW} bs=16M gpart recover ${NEW} gpart resize -i 2 ${NEW} rm -f ${TMP} # write files DSOURCE=/media/source DDEST=/media/dest CONT=0 mkdir -p ${DSOURCE} mkdir -p ${DDEST} # create dataset zpool destroy zpi || true zpool create -f -O compress=lz4 -O atime=off -o altroot=${DDEST} -m none zpi ${NEW}p2 zfs create -o mountpoint=none zpi/ROOT zfs create -o mountpoint=/ zpi/ROOT/default zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zpi/tmp zfs create -o mountpoint=/usr -o canmount=off zpi/usr zfs create zpi/usr/home zfs create -o setuid=off zpi/usr/ports zfs create zpi/usr/src zfs create -o mountpoint=/var -o canmount=off zpi/var zfs create -o exec=off -o setuid=off zpi/var/audit zfs create -o exec=off -o setuid=off zpi/var/crash zfs create -o exec=off -o setuid=off zpi/var/log zfs create -o atime=on zpi/var/mail zfs create -o setuid=off zpi/var/tmp zfs set mountpoint=/zpi zpi chmod 1777 ${DDEST}/tmp chmod 1777 ${DDESt}/var/tmp zpool set bootfs=zpi/ROOT/default zpi #zfs set canmount=noauto zpi/ROOT/default zfs set canmount=on zpi/ROOT/default # copy files mount /dev/${SOURCE}s2a ${DSOURCE} mkdir -p ${DDEST}/boot mkdir -p ${DDEST}/boot/msdos if [ -d ${DSOURCE}/boot/msdos ]; then mount -t msdos /dev/${SOURCE}s1 ${DSOURCE}/boot/msdos mount -t msdos /dev/${NEW}p1 ${DDEST}/boot/msdos CONT=1 fi if [ ${CONT} -eq 0 ]; then echo "Abort. No FreeBSD loader directory is detected" exit 2 fi tar cf - -C ${DSOURCE} . | tar -xpf - -C ${DDEST} FREEBSD_VER=$(${DDEST}/bin/freebsd-version -u | cut -d "-" -f 1) if [ ${FREEBSD_VER} == "13.1" ]; then (cd ${DDEST}/home; mv -i * ../usr/home; cd ..; rmdir home; ln -sf usr/home home) fi # file modification for zfs and others echo 'kern.geom.label.disk_ident.enable="0"' >> ${DDEST}/boot/loader.conf echo 'kern.geom.label.gptid.enable="0"' >> ${DDEST}/boot/loader.conf echo 'cryptodev_load="YES"' >> ${DDEST}/boot/loader.conf echo 'zfs_load="YES"' >> ${DDEST}/boot/loader.conf echo 'autoboot_delay="3"' >> ${DDEST}/boot/loader.conf sed -i '' '/boot_serial/ s/^/#/' ${DDEST}/boot/loader.conf sed -i '' '/beastie_disable/ s/^/#/' ${DDEST}/boot/loader.conf echo 'zfs_enable="YES"' >> ${DDEST}/etc/rc.conf echo 'ntpdate_enable="YES"' >> ${DDEST}/etc/rc.conf echo 'powerd_enable="YES"' >> ${DDEST}/etc/rc.conf sed -i '' /ufs/d ${DDEST}/etc/fstab sed -i '' /^tmpfs/d ${DDEST}/etc/fstab sed -i '' s/MSDOSBOOT/EFI/ ${DDEST}/etc/fstab # unmount sync umount /dev/${SOURCE}s1 umount /dev/${SOURCE}s2a umount /dev/${NEW}p1 zpool sync zpi zfs unmount -a zpool export zpi # detach mdconfig -d -u ${SOURCE} rmdir ${DSOURCE} rmdir ${DDEST}
今のところケース付属のファンはジャンパーの設定で動かしているが、結構ノイズがあるので、これも何とかした。