From owner-freebsd-fs@FreeBSD.ORG Wed Jun 29 15:22:01 2011 Return-Path: Delivered-To: fs@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CF8DA106564A for ; Wed, 29 Jun 2011 15:22:01 +0000 (UTC) (envelope-from mattblists@icritical.com) Received: from mail1.icritical.com (mail1.icritical.com [93.95.13.41]) by mx1.freebsd.org (Postfix) with SMTP id 247F38FC14 for ; Wed, 29 Jun 2011 15:22:00 +0000 (UTC) Received: (qmail 358 invoked from network); 29 Jun 2011 14:55:17 -0000 Received: from localhost (127.0.0.1) by mail1.icritical.com with SMTP; 29 Jun 2011 14:55:17 -0000 Received: (qmail 350 invoked by uid 599); 29 Jun 2011 14:55:17 -0000 Received: from unknown (HELO icritical.com) (212.57.254.146) by mail1.icritical.com (qpsmtpd/0.28) with ESMTP; Wed, 29 Jun 2011 15:55:17 +0100 Message-ID: <4E0B3CD1.7030007@icritical.com> Date: Wed, 29 Jun 2011 15:55:13 +0100 From: Matt Burke User-Agent: Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.2.15) Gecko/20110403 Thunderbird/3.1.9 MIME-Version: 1.0 To: fs@FreeBSD.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 29 Jun 2011 14:55:13.0654 (UTC) FILETIME=[8CFB2960:01CC366C] X-Virus-Scanned: by iCritical at mail1.icritical.com Cc: Subject: gptzfsboot bug? X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jun 2011 15:22:01 -0000 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. --