Date: Wed, 29 Jun 2011 15:55:13 +0100 From: Matt Burke <mattblists@icritical.com> To: fs@FreeBSD.org Subject: gptzfsboot bug? Message-ID: <4E0B3CD1.7030007@icritical.com>
next in thread | raw e-mail | index | archive | help
When you have a log partition to a non-bootable zfs pool discovered before a bootable zfs pool, the 2nd stage bootloader will break because the check for ZPOOL_CONFIG_IS_LOG will never find it - at least on my system. The problem is that ZFS uses nested nvlist structures, the 'is_log' attribute is held below the root level, and nvlist_find doesn't recurse. Attached is a diff against 8-STABLE as of a few minutes ago. C is not my main language and I've been looking at zfs source for less than a day, so please do check it for correctness although it works here. The xdr_int() call is used to bump p to the beginning of the embedded list. --- zfsimpl.c.orig 2011-06-29 14:29:49.460537991 +0100 +++ zfsimpl.c 2011-06-29 15:16:20.526890896 +0100 @@ -173,10 +173,20 @@ (const unsigned char*) p; return (0); } else { return (EIO); } + } else if (!memcmp(ZPOOL_CONFIG_VDEV_TREE, pairname, namelen) + && pairtype == DATA_TYPE_NVLIST) { + /* + * If we find an nvlist, recurse into it + */ + xdr_int(&p, &elements); + if (0 == nvlist_find(p, name, type, elementsp, valuep)) + return 0; + /* reset position in case find fails mid-way */ + p = pair + encoded_size; } else { /* * Not the pair we are looking for, skip to the next one. */ p = pair + encoded_size; As an aside, is it sensible for zfsboot.c to leave the prompt at /boot/kernel/kernel, or even bother trying it given zfs is usually built as a module and will need /boot/zfsloader to load everything first? Would it be an idea to do something like this? printf("First boot attempt failed.\n"); STAILQ_FOREACH(spa, &zfs_pools, spa_link) { printf("Trying %s:%s\n", spa->spa_name, kname); zfs_mount_pool(spa); load(); printf("Failed.\n"); } Matt. --
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E0B3CD1.7030007>