ZFS: Kernel not found after upgrade to 8.2

I had used this guide to setup FreeBSD 8.1 in a ZFS mirrored configuration using GPT. The system has been running without any problems till now. After the release of FreeBSD-8.2, I tried to upgrade the system using the procedure described in the handbook (with some changed options for ZFS). Here are the steps that I used:
Code:
# cd /usr/src
# make buildworld
# make buildkernel
# make installkernel
# shutdown -r now
Then booted the system in single-user mode and did the following:
Code:
# adjkerntz -i
# zfs mount -a <-----(Changed from: mount -a -t ufs)
# mergemaster -p
# cd /usr/src
# make installworld
# mergemaster
However, 'mergemaster' (after installworld) complained that it cannot install the files as the file system is read-only. Therefore, I did the following:
Code:
zfs set readonly=off zroot
The 'mergemaster' finished successfully after this and all the required files were installed. Now, when I reboot the system, it complains that "Kernel cannot be found". What did I do wrong? Is there anyway to fix it? Did I destroy the zpool?
 
The detailed configuration is as follows:

Code:
% gpart show
=>        63  1250263665  ad4  MBR  (596G)
          63  1250263665    1  freebsd  [active]  (596G)

=>         0  1250263665  ad4s1  BSD  (596G)
           0     2097152      1  freebsd-ufs  (1.0G)
     2097152     8388608      2  freebsd-swap  (4.0G)
    10485760    10377216      4  freebsd-ufs  (4.9G)
    20862976     1048576      5  freebsd-ufs  (512M)
    21911552  1228352113      6  freebsd-ufs  (586G)

=>        34  1953525101  ad5  GPT  (932G)
          34         128    1  freebsd-boot  (64K)
         162     4194304    2  freebsd-swap  (2.0G)
     4194466  1949330669    3  freebsd-zfs  (930G)

=>        34  1953525101  ad6  GPT  (932G)
          34         128    1  freebsd-boot  (64K)
         162     4194304    2  freebsd-swap  (2.0G)
     4194466  1949330669    3  freebsd-zfs  (930G)
 
Make sure you remount / as read/write before doing anything else in single user mode.

# mount -u /

Edit: err yeah, if it's not booting you'll have to do a recovery with the livefs cd (or the usb memstick) and verify at least these:

- /boot/loader.conf has correct setting for vfs.root.mountfrom

- Your root filesystem has mountpoint property set to "legacy".

- /boot/kernel/kernel is the kernel from "make installkernel" you did earlier.

- Reinstall the zfs boot loader(s).
 
Before rebooting the system I had checked my /boot/loader.conf it had following two entries pertaining to zfs:
Code:
zfs_load="YES"
vfs.root.mountfrom="zfs:zroot"
Before the upgrade the mountpoint for the root was set to legacy. I don't think it should change during the upgrade...but I may be wrong. I am not sure how to check the kernel in an unusable system. I had this line:
Code:
LOADER_ZFS_SUPPORT=YES
in make.conf when I built the system therefore, the loader installed should be zfs aware.
 
Boot into Fixit and import your pool with -f and -R altroot -options (your pool will show under /altroot directory with the exception of root filesystem) and then mount your root filesystem manually into for example /mnt/zroot:

# kldload /mnt2/boot/kernel/opensolaris.ko
# kldload /mnt2/boot/kernel/zfs.ko
# zpool import -f -R altroot zroot
# mkdir /mnt/zroot
# mount -t zfs zroot /mnt/zroot

The last one may need to be # mount -t zfs zroot:zroot /mnt/zroot , I don't have a system to test those commands.
 
Thanks. I managed reboot the system in FIXIT mode through memstick. The kernel modules (opensolaris/zfs) were loaded. The command # zpool import -f -R altroot zroot failed. It says:
cannot import pool 'zroot': bad alternate root altroot
However, the command # zpool import worked and I get the output as:
Code:
  pool: zroot
    id: zzzzzzzzzzzzzzzz
 state: ONLINE
status: The pool is formatted using an older on-disk version.
action: The pool can be imported using its name or numeric identifier, though some features will not be available without an explicit 'zpool upgrade'.
config:
       zroot             ONLINE
          mirror         ONLINE
             gpt/disk0   ONLINE
             gpt/disk1   ONLINE
Looks like the pool has to be upgraded. I have never worked with ZFS until the previous install. How do I proceed further?
 
The version is not significant (yet), you can keep the pool at version 14 until you get your system back up and running and then do the upgrade to version 15.

I think the import command with altroot should read:
# zpool import -f -R /altroot zroot

The reason you should import your pool with altroot option in Fixit is that the pool is otherwise mounted over the running Fixit environment (directories /usr/, /var etc.) and may cause it to stop working.

Have you verified that /boot/loader.conf is intact and the root filesystem has mountpoint property set to "legacy"?
 
Yes. The entries in the /boot/loader.conf are:
Code:
zfs_load="YES"
vfs.root.mountfrom="zfs:zroot"
and the root filesystem mountpoint property is 'legacy'.
 
Is it possible that the disk ad4 is somehow interfering with boot? Can you try booting with that disk disconnected?
 
Same problem.
Code:
definitions not found
forth not found

can't load kernel

Could it be that GPT does not recognize the new ZFS?
 
To me it looks more like required bits of /boot/loader or /boot/zfsloader are missing. I'm not too familiar with the loader(8) I'm afraid so someone who knows more can maybe step in...
 
I tried to rewrite the boot-code onto the GPT disks. Still the system cannot find the kernel. I used the following commands:
[CMD="Fixit #"]gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad5
[/CMD]
[CMD="Fixit #"]gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 ad6
[/CMD]

Could somebody help me to get the system up and running!
 
You have to do it in two commands. First the PMBR:
# gpart bootcode -b /path/to/pmbr diskname
Then you load the GPT boot loader code:
# gpart bootcode -p /path/to/gpt/loader -i 1 diskname

Each of those goes into two different locations, which is why it's done as two separate commands.
 
phoenix said:
You have to do it in two commands. First the PMBR:
# gpart bootcode -b /path/to/pmbr diskname
Then you load the GPT boot loader code:
# gpart bootcode -p /path/to/gpt/loader -i 1 diskname

Each of those goes into two different locations, which is why it's done as two separate commands.

You can do this with 1 command :)
# gpart bootcode -b /path/to/pmbr -p /path/to/gpt/loader -i 1 diskname
 
I tried both the versions of 'gpart' given above. It simply does not work...I mean the initial problem still remains. Anyhow, I managed to boot the system through ad4 (UFS partition) and then was able to import the pool.
# zpool import -f -R /altroot zroot
# mkdir /mnt/zroot
# mount -t zfs zroot /mnt/zroot
Then I upgraded the zpool using
# zpool upgrade
I did not upgrade the zfs. I think it will be easier now to do the troubleshooting...if I know what to do. As a reminder, I am unable to boot from the GPT disk. The boot process terminates with 'kernel not found' followed by the 'OK' (loader) prompt. The output during the boot process scrolls very fast but I was able to read that the system is trying to load 'gptzfsloader Rev 1.1'. Maybe this will help diagnose the problem. Any help in any direction is greatly appreciated.
 
penna said:
I tried both the versions of 'gpart' given above. It simply does not work...I mean the initial problem still remains. Anyhow, I managed to boot the system through ad4 (UFS partition) and then was able to import the pool.
# zpool import -f -R /altroot zroot
# mkdir /mnt/zroot
# mount -t zfs zroot /mnt/zroot
Then I upgraded the zpool using
# zpool upgrade
......

I tried to see the diffs between the boot partitions of the currently working UFS and the failed ZFS version (both use FreeBSD 8.2 release #0) using the following commands:
# cd /mnt/zroot
# diff /boot ./boot | grep differ
Code:
Files /boot/loader and ./boot/loader differ
Files /boot/loader.old and ./boot/loader.old differ
Files /boot/pxeboot and ./boot/pxeboot differ
Files /boot/zfsloader and ./boot/zfsloader differ
Files /boot/zfsloader.old and ./boot/zfsloader.old differ

I do not understand why loader and zfsloader should differ since I am running same release (version FreeBSD 8.2 release #0, build from source) on both. Is this okay or is there a problem?
 
It turned out that the new /boot/zfsloader on ZFS pool was problematic. Here is what I tried:
[CMD="Fixit#"] zpool import -f -R /altroot zroot [/CMD]
[CMD="Fixit#"] mkdir /mnt/zroot [/CMD]
[CMD="Fixit#"] mount -t zfs zroot /mnt/zroot [/CMD]
[CMD="Fixit#"] cd /mnt/zroot/boot [/CMD]
[CMD="Fixit#"] mv zfsloader zfsloader.bad [/CMD]
[CMD="Fixit#"] cp /mnt2/boot/zfsloader ./ [/CMD]
[CMD="Fixit#"] reboot [/CMD]
And voila! System was able to boot from the ZFS partition with everything running normal. Although, I still don't understand how zfsloader build was bad. Thank you everybody for your help.
 
Back
Top