From owner-freebsd-current@FreeBSD.ORG Tue Jan 21 21:11:24 2014 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id F1AB14BF; Tue, 21 Jan 2014 21:11:23 +0000 (UTC) Received: from mail-vc0-x22d.google.com (mail-vc0-x22d.google.com [IPv6:2607:f8b0:400c:c03::22d]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 9863C1931; Tue, 21 Jan 2014 21:11:23 +0000 (UTC) Received: by mail-vc0-f173.google.com with SMTP id ld13so3798045vcb.4 for ; Tue, 21 Jan 2014 13:11:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=Z09szqQWJEUUUQajQBmGdw4cQDl9yOoRbMmNRnCYlw0=; b=EoqPWy09HOAwaeFXvKg4gqIcIMyTQTf18Lz9P3C/XeopdslVz2Diy8xicX5Rzl5aFA C6WNbTYnd7yh638SKhkrXn4PrWcNGOcy/PJ2reGqaDkEsm3jyMdzfPWihSU9kjjRayNU rKYD93Xi+g0kx6E1zWPfqzrMIfnOe4tg4w10MCPwgKefpj/CfVDkt6aEtwSNrmddzkV7 wecCNrFPNZk5afeGHprkHhrzl4k9v4ERVr/m5sBb1QZJPfxaW4rUaEUL7e1MJ0H11Gnu gmcvEln+b4TzljsPV0hgp9kKaxfRJ4UbuUzemlOVmhtwIP+ov/7dLu9/QsGKbGu9JyHG 5fHQ== MIME-Version: 1.0 X-Received: by 10.58.255.233 with SMTP id at9mr7004460ved.20.1390338682595; Tue, 21 Jan 2014 13:11:22 -0800 (PST) Received: by 10.220.168.135 with HTTP; Tue, 21 Jan 2014 13:11:22 -0800 (PST) In-Reply-To: <52DE9699.5040801@FreeBSD.org> References: <52DE3F6B.6050209@yandex.ru> <52DE4FD0.5030409@FreeBSD.org> <52DE5781.7090600@yandex.ru> <52DE9699.5040801@FreeBSD.org> Date: Tue, 21 Jan 2014 16:11:22 -0500 Message-ID: Subject: Re: Problem updating bootcode on ZFS on root system with MBR From: Thomas Hoffmann To: freebsd-current Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.17 Cc: "Andrey V. Elsukov" , Andriy Gapon X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jan 2014 21:11:24 -0000 On Tue, Jan 21, 2014 at 10:47 AM, Andriy Gapon wrote: > on 21/01/2014 13:18 Andrey V. Elsukov said the following: > > On 21.01.2014 14:45, Andriy Gapon wrote: > >>>> What do I need to do to get the boot2 code written to /dev/ada0s1a? > >>> > >>> This will work only if ada0s1a isn't in use. The debugflags trick works > >>> only for whole disk, i.e. for geoms with rank=1. Another way is > >>> calculate needed offset and write bootcode directly to ada0. > >> > >> > >> And ultimately we should extend our ZFS interface with an ioctl to > write a blob > >> to a boot code area of a specified ZFS leaf vdev. This would the right > way to > >> install zfsboot. > > > > Hi Andriy, > > > > do you have some patches to test? :-) > > > > I don't, but the following patch can serve as a very good example. > It adds an ioctl that serves a slightly different but quite similar > purpose: > > commit 54802d6659ec134fd221c3daaa8fdf9cee985d39 > Author: Andriy Gapon > Date: Fri Sep 14 23:15:43 2012 +0300 > > [wip] zfs: add a new ioctl that allows to place text data into pad2 > area > > The data is placed into Pad2 area of the first vdev label of a given > vdev in a given pool. > > diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h > b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h > index fb30ea9..4a46cc2 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h > +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h > @@ -162,6 +162,8 @@ typedef enum { > > extern int vdev_label_init(vdev_t *vd, uint64_t txg, vdev_labeltype_t > reason); > > +extern int vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t > size); > + > #ifdef __cplusplus > } > #endif > diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c > b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c > index c7dd3ad..55c87d8 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c > +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c > @@ -855,6 +855,44 @@ retry: > return (error); > } > > +int > +vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size) > +{ > + spa_t *spa = vd->vdev_spa; > + zio_t *zio; > + char *pad2; > + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; > + int error; > + > + if (size > VDEV_PAD_SIZE) > + return (EINVAL); > + > + if (!vd->vdev_ops->vdev_op_leaf) > + return (ENODEV); > + if (vdev_is_dead(vd)) > + return (ENXIO); > + > + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); > + > + pad2 = zio_buf_alloc(VDEV_PAD_SIZE); > + bzero(pad2, VDEV_PAD_SIZE); > + memcpy(pad2, buf, size); > + > +retry: > + zio = zio_root(spa, NULL, NULL, flags); > + vdev_label_write(zio, vd, 0, pad2, > + offsetof(vdev_label_t, vl_pad2), > + VDEV_PAD_SIZE, NULL, NULL, flags); > + error = zio_wait(zio); > + if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) { > + flags |= ZIO_FLAG_TRYHARD; > + goto retry; > + } > + > + zio_buf_free(pad2, VDEV_PAD_SIZE); > + return (error); > +} > + > /* > * > ========================================================================== > * uberblock load/sync > diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > index e208ed8..ff90839 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > @@ -3404,6 +3404,53 @@ zfs_ioc_log_history(const char *unused, nvlist_t > *innvl, > nvlist_t *outnvl) > return (error); > } > > +#ifdef __FreeBSD__ > +static int > +zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) > +{ > + char name[MAXNAMELEN]; > + spa_t *spa; > + vdev_t *vd; > + char *command; > + uint64_t pool_guid; > + uint64_t vdev_guid; > + int error; > + > + if (nvlist_lookup_uint64(innvl, > + ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0) > + return (EINVAL); > + if (nvlist_lookup_uint64(innvl, > + ZPOOL_CONFIG_GUID, &vdev_guid) != 0) > + return (EINVAL); > + if (nvlist_lookup_string(innvl, > + "command", &command) != 0) > + return (EINVAL); > + > + mutex_enter(&spa_namespace_lock); > + spa = spa_by_guid(pool_guid, vdev_guid); > + if (spa != NULL) > + strcpy(name, spa_name(spa)); > + mutex_exit(&spa_namespace_lock); > + if (spa == NULL) > + return (ENOENT); > + > + if ((error = spa_open(name, &spa, FTAG)) != 0) > + return (error); > + spa_vdev_state_enter(spa, SCL_ALL); > + vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE); > + if (vd == NULL) { > + (void) spa_vdev_state_exit(spa, NULL, ENXIO); > + spa_close(spa, FTAG); > + return (ENODEV); > + } > + error = vdev_label_write_pad2(vd, command, strlen(command)); > + (void) spa_vdev_state_exit(spa, NULL, 0); > + txg_wait_synced(spa->spa_dsl_pool, 0); > + spa_close(spa, FTAG); > + return (error); > +} > +#endif > + > /* > * The dp_config_rwlock must not be held when calling this, because the > * unmount may need to write out data. > @@ -5605,6 +5652,9 @@ zfs_ioctl_init(void) > zfs_secpolicy_config, POOL_CHECK_NONE); > zfs_ioctl_register_dataset_nolog(ZFS_IOC_UNJAIL, zfs_ioc_unjail, > zfs_secpolicy_config, POOL_CHECK_NONE); > + zfs_ioctl_register("fbsd_nextboot", ZFS_IOC_NEXTBOOT, > + zfs_ioc_nextboot, zfs_secpolicy_config, NO_NAME, > + POOL_CHECK_NONE, B_FALSE, B_FALSE); > #endif > } > > diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h > b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h > index 454c28a..917223dc 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h > +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h > @@ -839,6 +839,7 @@ typedef enum zfs_ioc { > ZFS_IOC_SEND_NEW, > ZFS_IOC_SEND_SPACE, > ZFS_IOC_CLONE, > + ZFS_IOC_NEXTBOOT, > ZFS_IOC_LAST > } zfs_ioc_t; > > > -- > Andriy Gapon > Thanks for the responses. My apologies for going silent, but I had to step away from the problem for a bit. I was able to resolve my problem by doing the following: After upgrading my zpools and after my aborted attempt to update the bootcode as reported above, I copied /boot/zfsboot (or more precisely /bootpool/boot/zfsboot) to a USB thumb drive. I attempted to reboot my system, which failed due to unsupported zfs features. This was expected, but I thought, hey, I might get lucky. I then booted into a Live CD, mounted my USB thumb drive on /tmp/usb and executed: sysctl kern.geom.debugflags=0x10 dd if=/tmp/usb/zfsboot of=/dev/ada0s1 count=1 dd if=/tmp/usb/zfsboot of=/dev/ada0s1d skip=1 seek=1024 Then I rebooted and all is well. All zpools support all features. While this procedure was not tedious, it would still be nice if, as Andriy stated, FreeBSD contained a native way do this zfs bootcode update for MBR schemes that is as simple as for the GPT schemes. Its been a gazillion years since I've done any C programming, but I'll take a look at the patches. Thanks, Andriy and Andrey. - Tom