Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jul 2018 03:08:11 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r336696 - projects/bectl/lib/libbe
Message-ID:  <201807250308.w6P38Bub063668@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807250308.w6P38Bub063668>