Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Feb 2019 19:13:29 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r344265 - stable/11/stand/zfs
Message-ID:  <201902181913.x1IJDT4f085906@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Mon Feb 18 19:13:28 2019
New Revision: 344265
URL: https://svnweb.freebsd.org/changeset/base/344265

Log:
  MFC r329727-r329728: lualoader ZFS BE Support
  
  r329727:
  stand/zfs: Add all bootenvs to environment
  
  For the benefit of lualoader, add all bootenvs to environment when
  init_zfs_bootenv is invoked. All of the boot environment logic can then be
  implemented in pure lua, rather than going back and forth with C to
  implement paging.
  
  This stores all boot environments in bootenvs[idx] and the final count of
  bootenvs in bootenvs_count.
  
  While here, make a copy of currdev for init_zfs_bootenv since it will be
  modifying it and the caller may not necessarily want that. Some of the logic
  was shifted around so that the 'currdev' pointer remains at the beginning of
  the string and 'beroot' is moved around as needed to modify it or ultimately
  store it in zfs_be_root.
  
  The original zfs_bootenv that this was copied from will be able to go away
  only if/when forth eventually goes away.
  
  r329728:
  stand/zfs: Unbreak build, 'truct' ~= 'struct'

Modified:
  stable/11/stand/zfs/libzfs.h
  stable/11/stand/zfs/zfs.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/stand/zfs/libzfs.h
==============================================================================
--- stable/11/stand/zfs/libzfs.h	Mon Feb 18 19:07:15 2019	(r344264)
+++ stable/11/stand/zfs/libzfs.h	Mon Feb 18 19:13:28 2019	(r344265)
@@ -75,7 +75,7 @@ char	*zfs_fmtdev(void *vdev);
 int	zfs_probe_dev(const char *devname, uint64_t *pool_guid);
 int	zfs_list(const char *name);
 uint64_t ldi_get_size(void *);
-void	init_zfs_bootenv(char *currdev);
+void	init_zfs_bootenv(const char *currdev);
 int	zfs_bootenv(const char *name);
 int	zfs_belist_add(const char *name, uint64_t __unused);
 int	zfs_set_env(void);

Modified: stable/11/stand/zfs/zfs.c
==============================================================================
--- stable/11/stand/zfs/zfs.c	Mon Feb 18 19:07:15 2019	(r344264)
+++ stable/11/stand/zfs/zfs.c	Mon Feb 18 19:13:28 2019	(r344265)
@@ -59,6 +59,8 @@ static off_t	zfs_seek(struct open_file *f, off_t offse
 static int	zfs_stat(struct open_file *f, struct stat *sb);
 static int	zfs_readdir(struct open_file *f, struct dirent *d);
 
+static void	zfs_bootenv_initial(const char *);
+
 struct devsw zfs_dev;
 
 struct fs_ops zfs_fsops = {
@@ -758,27 +760,83 @@ zfs_list(const char *name)
 }
 
 void
-init_zfs_bootenv(char *currdev)
+init_zfs_bootenv(const char *currdev_in)
 {
-	char *beroot;
+	char *beroot, *currdev;
+	int currdev_len;
 
-	if (strlen(currdev) == 0)
+	currdev = NULL;
+	currdev_len = strlen(currdev_in);
+	if (currdev_len == 0)
 		return;
-	if(strncmp(currdev, "zfs:", 4) != 0)
+	if (strncmp(currdev_in, "zfs:", 4) != 0)
 		return;
+	currdev = strdup(currdev_in);
+	if (currdev == NULL)
+		return;
 	/* Remove the trailing : */
-	currdev[strlen(currdev) - 1] = '\0';
+	currdev[currdev_len - 1] = '\0';
 	setenv("zfs_be_active", currdev, 1);
 	setenv("zfs_be_currpage", "1", 1);
-	/* Forward past zfs: */
-	currdev = strchr(currdev, ':');
-	currdev++;
 	/* Remove the last element (current bootenv) */
 	beroot = strrchr(currdev, '/');
 	if (beroot != NULL)
 		beroot[0] = '\0';
-	beroot = currdev;
+	beroot = strchr(currdev, ':') + 1;
 	setenv("zfs_be_root", beroot, 1);
+	zfs_bootenv_initial(beroot);
+	free(currdev);
+}
+
+static void
+zfs_bootenv_initial(const char *name)
+{
+	char		poolname[ZFS_MAXNAMELEN], *dsname;
+	char envname[32], envval[256];
+	uint64_t	objid;
+	spa_t		*spa;
+	int		bootenvs_idx, len, rv;
+
+	SLIST_INIT(&zfs_be_head);
+	zfs_env_count = 0;
+	len = strlen(name);
+	dsname = strchr(name, '/');
+	if (dsname != NULL) {
+		len = dsname - name;
+		dsname++;
+	} else
+		dsname = "";
+	strlcpy(poolname, name, len + 1);
+	spa = spa_find_by_name(poolname);
+	if (spa == NULL)
+		return;
+	rv = zfs_lookup_dataset(spa, dsname, &objid);
+	if (rv != 0)
+		return;
+	rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
+	bootenvs_idx = 0;
+	/* Populate the initial environment variables */
+	SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
+		/* Enumerate all bootenvs for general usage */
+		snprintf(envname, sizeof(envname), "bootenvs[%d]", bootenvs_idx);
+		snprintf(envval, sizeof(envval), "zfs:%s/%s", name, zfs_be->name);
+		rv = setenv(envname, envval, 1);
+		if (rv != 0)
+			break;
+		bootenvs_idx++;
+	}
+	snprintf(envval, sizeof(envval), "%d", bootenvs_idx);
+	setenv("bootenvs_count", envval, 1);
+
+	/* Clean up the SLIST of ZFS BEs */
+	while (!SLIST_EMPTY(&zfs_be_head)) {
+		zfs_be = SLIST_FIRST(&zfs_be_head);
+		SLIST_REMOVE_HEAD(&zfs_be_head, entries);
+		free(zfs_be);
+	}
+
+	return;
+
 }
 
 int



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