From owner-svn-src-projects@freebsd.org Wed Jul 25 03:08:12 2018 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9DAB5103BF17 for ; Wed, 25 Jul 2018 03:08:12 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 441348BF35; Wed, 25 Jul 2018 03:08:12 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 20135148DA; Wed, 25 Jul 2018 03:08:12 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6P38BPE063671; Wed, 25 Jul 2018 03:08:11 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6P38Bub063668; Wed, 25 Jul 2018 03:08:11 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201807250308.w6P38Bub063668@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Wed, 25 Jul 2018 03:08:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r336696 - projects/bectl/lib/libbe X-SVN-Group: projects X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: projects/bectl/lib/libbe X-SVN-Commit-Revision: 336696 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Jul 2018 03:08:12 -0000 Author: kevans Date: Wed Jul 25 03:08:11 2018 New Revision: 336696 URL: https://svnweb.freebsd.org/changeset/base/336696 Log: libbe(3): Disambiguate 'active' a little bit, add 'bootfs' - Rename 'active' to 'rootfs', which is used in other places to describe the currently booted (or about to be booted) BE. - Add 'bootfs', which indicates the next boot environment to be booted. This is pulled from the BOOTFS zpool property. - Go ahead and keep an open handle to the active zpool. We might need to enumerate datasets, get properties, and set properties (e.g. bootfs) throughout other libbe bits, and a single handle isn't overly expensive. Modified: projects/bectl/lib/libbe/be.c projects/bectl/lib/libbe/be_impl.h projects/bectl/lib/libbe/be_info.c Modified: projects/bectl/lib/libbe/be.c ============================================================================== --- projects/bectl/lib/libbe/be.c Wed Jul 25 02:36:55 2018 (r336695) +++ projects/bectl/lib/libbe/be.c Wed Jul 25 03:08:11 2018 (r336696) @@ -52,63 +52,82 @@ libbe_init(void) struct stat sb; dev_t root_dev, boot_dev; libbe_handle_t *lbh; - char *pos; + char *poolname, *pos; + int pnamelen; - // TODO: use errno here?? - + lbh = NULL; + poolname = pos = NULL; + pnamelen = 0; /* Verify that /boot and / are mounted on the same filesystem */ - if (stat("/", &sb) != 0) { - return (NULL); - } + /* TODO: use errno here?? */ + if (stat("/", &sb) != 0) + goto err; root_dev = sb.st_dev; - if (stat("/boot", &sb) != 0) { - return (NULL); - } + if (stat("/boot", &sb) != 0) + goto err; boot_dev = sb.st_dev; if (root_dev != boot_dev) { fprintf(stderr, "/ and /boot not on same device, quitting\n"); - return (NULL); + goto err; } - if ((lbh = calloc(1, sizeof(libbe_handle_t))) == NULL) { - return (NULL); - } + if ((lbh = calloc(1, sizeof(libbe_handle_t))) == NULL) + goto err; - if ((lbh->lzh = libzfs_init()) == NULL) { - free(lbh); - return (NULL); - } + if ((lbh->lzh = libzfs_init()) == NULL) + goto err; - /* Obtain path to active boot environment */ - if ((kenv(KENV_GET, "zfs_be_active", lbh->active, - BE_MAXPATHLEN)) == -1) { - libzfs_fini(lbh->lzh); - free(lbh); - return (NULL); - } + /* Obtain path to boot environment root */ + if ((kenv(KENV_GET, "zfs_be_root", lbh->root, BE_MAXPATHLEN)) == -1) + goto err; /* Remove leading 'zfs:' if present, otherwise use value as-is */ - if ((pos = strrchr(lbh->active, ':')) != NULL) { - strncpy(lbh->active, pos + sizeof(char), BE_MAXPATHLEN); - } + if (strcmp(lbh->root, "zfs:") == 0) + strncpy(lbh->root, strchr(lbh->root, ':') + sizeof(char), + BE_MAXPATHLEN); - /* Obtain path to boot environment root */ - if ((kenv(KENV_GET, "zfs_be_root", lbh->root, BE_MAXPATHLEN)) == -1) { - libzfs_fini(lbh->lzh); - free(lbh); - return (NULL); - } + if ((pos = strchr(lbh->root, '/')) == NULL) + goto err; + pnamelen = pos - lbh->root; + poolname = malloc(pnamelen + 1); + if (poolname == NULL) + goto err; + + strncpy(poolname, lbh->root, pnamelen); + poolname[pnamelen] = '\0'; + if ((lbh->active_phandle = zpool_open(lbh->lzh, poolname)) == NULL) + goto err; + + if (zpool_get_prop(lbh->active_phandle, ZPOOL_PROP_BOOTFS, lbh->bootfs, + BE_MAXPATHLEN, NULL, true) != 0) + goto err; + + /* Obtain path to boot environment rootfs (currently booted) */ + /* XXX Get dataset mounted at / by kenv/GUID from mountroot? */ + if ((kenv(KENV_GET, "zfs_be_active", lbh->rootfs, BE_MAXPATHLEN)) == -1) + goto err; + /* Remove leading 'zfs:' if present, otherwise use value as-is */ - if ((pos = strrchr(lbh->root, ':')) != NULL) { - strncpy(lbh->root, pos + sizeof(char), BE_MAXPATHLEN); - } + if (strcmp(lbh->rootfs, "zfs:") == 0) + strncpy(lbh->rootfs, strchr(lbh->rootfs, ':') + sizeof(char), + BE_MAXPATHLEN); return (lbh); +err: + if (lbh != NULL) { + if (lbh->active_phandle != NULL) + zpool_close(lbh->active_phandle); + if (lbh->lzh != NULL) + libzfs_fini(lbh->lzh); + free(lbh); + } + free(poolname); + return (NULL); } @@ -118,6 +137,8 @@ libbe_init(void) void libbe_close(libbe_handle_t *lbh) { + if (lbh->active_phandle != NULL) + zpool_close(lbh->active_phandle); libzfs_fini(lbh->lzh); free(lbh); } @@ -148,7 +169,7 @@ be_destroy(libbe_handle_t *lbh, char *name, int option return (set_error(lbh, BE_ERR_NOENT)); } - if (strcmp(path, lbh->active) == 0) { + if (strcmp(path, lbh->rootfs) == 0) { return (set_error(lbh, BE_ERR_DESTROYACT)); } @@ -802,7 +823,6 @@ be_activate(libbe_handle_t *lbh, char *bootenv, bool t { char be_path[BE_MAXPATHLEN]; char buf[BE_MAXPATHLEN]; - zpool_handle_t *zph; uint64_t pool_guid; uint64_t vdev_guid; int zfs_fd; @@ -852,17 +872,7 @@ be_activate(libbe_handle_t *lbh, char *bootenv, bool t return (BE_ERR_SUCCESS); } else { /* Obtain bootenv zpool */ - strncpy(buf, be_path, BE_MAXPATHLEN); - *(strchr(buf, '/')) = '\0'; - - if ((zph = zpool_open(lbh->lzh, buf)) == NULL) { - // TODO: create error for this - return (-1); - } - printf("asdf\n"); - - err = zpool_set_prop(zph, "bootfs", be_path); - zpool_close(zph); + err = zpool_set_prop(lbh->active_phandle, "bootfs", be_path); switch (err) { case 0: Modified: projects/bectl/lib/libbe/be_impl.h ============================================================================== --- projects/bectl/lib/libbe/be_impl.h Wed Jul 25 02:36:55 2018 (r336695) +++ projects/bectl/lib/libbe/be_impl.h Wed Jul 25 03:08:11 2018 (r336696) @@ -36,8 +36,10 @@ struct libbe_handle { libzfs_handle_t *lzh; + zpool_handle_t *active_phandle; char root[BE_MAXPATHLEN]; - char active[BE_MAXPATHLEN]; + char rootfs[BE_MAXPATHLEN]; + char bootfs[BE_MAXPATHLEN]; be_error_t error; bool print_on_err; }; Modified: projects/bectl/lib/libbe/be_info.c ============================================================================== --- projects/bectl/lib/libbe/be_info.c Wed Jul 25 02:36:55 2018 (r336695) +++ projects/bectl/lib/libbe/be_info.c Wed Jul 25 03:08:11 2018 (r336696) @@ -43,7 +43,7 @@ static int prop_list_builder(prop_data_t *); const char * be_active_name(libbe_handle_t *lbh) { - return (strrchr(lbh->active, '/') + sizeof(char)); + return (strrchr(lbh->rootfs, '/') + sizeof(char)); } @@ -53,7 +53,7 @@ be_active_name(libbe_handle_t *lbh) const char * be_active_path(libbe_handle_t *lbh) { - return (lbh->active); + return (lbh->rootfs); }