svn commit: r241283 - head/sys/boot/zfs

Andriy Gapon avg at FreeBSD.org
Sat Oct 6 19:27:04 UTC 2012


Author: avg
Date: Sat Oct  6 19:27:04 2012
New Revision: 241283
URL: http://svn.freebsd.org/changeset/base/241283

Log:
  zfs boot: add code for listing child datasets of a given dataset
  
  - only filesystem datasets are supported
  - children names are printed to stdout
  
  To do: allow to iterate over the list and fetch names programatically
  
  MFC after:	17 days

Modified:
  head/sys/boot/zfs/libzfs.h
  head/sys/boot/zfs/zfs.c
  head/sys/boot/zfs/zfsimpl.c

Modified: head/sys/boot/zfs/libzfs.h
==============================================================================
--- head/sys/boot/zfs/libzfs.h	Sat Oct  6 19:25:40 2012	(r241282)
+++ head/sys/boot/zfs/libzfs.h	Sat Oct  6 19:27:04 2012	(r241283)
@@ -59,6 +59,7 @@ int	zfs_parsedev(struct zfs_devdesc *dev
 		     const char **path);
 char	*zfs_fmtdev(void *vdev);
 int	zfs_probe_dev(const char *devname, uint64_t *pool_guid);
+int	zfs_list(const char *name);
 
 extern struct devsw zfs_dev;
 extern struct fs_ops zfs_fsops;

Modified: head/sys/boot/zfs/zfs.c
==============================================================================
--- head/sys/boot/zfs/zfs.c	Sat Oct  6 19:25:40 2012	(r241282)
+++ head/sys/boot/zfs/zfs.c	Sat Oct  6 19:27:04 2012	(r241283)
@@ -658,3 +658,38 @@ zfs_fmtdev(void *vdev)
 		    rootname);
 	return (buf);
 }
+
+int
+zfs_list(const char *name)
+{
+	static char	poolname[ZFS_MAXNAMELEN];
+	uint64_t	objid;
+	spa_t		*spa;
+	const char	*dsname;
+	int		len;
+	int		rv;
+
+	len = strlen(name);
+	dsname = strchr(name, '/');
+	if (dsname != NULL) {
+		len = dsname - name;
+		dsname++;
+	}
+	memcpy(poolname, name, len);
+	poolname[len] = '\0';
+
+	spa = spa_find_by_name(poolname);
+	if (!spa)
+		return (ENXIO);
+	rv = zfs_spa_init(spa);
+	if (rv != 0)
+		return (rv);
+	if (dsname != NULL)
+		rv = zfs_lookup_dataset(spa, dsname, &objid);
+	else
+		rv = zfs_get_root(spa, &objid);
+	if (rv != 0)
+		return (rv);
+	rv = zfs_list_dataset(spa, objid);
+	return (0);
+}

Modified: head/sys/boot/zfs/zfsimpl.c
==============================================================================
--- head/sys/boot/zfs/zfsimpl.c	Sat Oct  6 19:25:40 2012	(r241282)
+++ head/sys/boot/zfs/zfsimpl.c	Sat Oct  6 19:27:04 2012	(r241283)
@@ -1387,8 +1387,6 @@ zap_lookup(const spa_t *spa, const dnode
 	return (EIO);
 }
 
-#ifdef BOOT2
-
 /*
  * List a microzap directory. Assumes that the zap scratch buffer contains
  * the directory contents.
@@ -1513,8 +1511,6 @@ zap_list(const spa_t *spa, const dnode_p
 		return fzap_list(spa, dnode);
 }
 
-#endif
-
 static int
 objset_get_dnode(const spa_t *spa, const objset_phys_t *os, uint64_t objnum, dnode_phys_t *dnode)
 {
@@ -1751,6 +1747,38 @@ zfs_lookup_dataset(const spa_t *spa, con
 	return (0);
 }
 
+#ifndef BOOT2
+static int
+zfs_list_dataset(const spa_t *spa, uint64_t objnum/*, int pos, char *entry*/)
+{
+	uint64_t dir_obj, child_dir_zapobj;
+	dnode_phys_t child_dir_zap, dir, dataset;
+	dsl_dataset_phys_t *ds;
+	dsl_dir_phys_t *dd;
+
+	if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+		printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+		return (EIO);
+	}
+	ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+	dir_obj = ds->ds_dir_obj;
+
+	if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir)) {
+		printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
+		return (EIO);
+	}
+	dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+	child_dir_zapobj = dd->dd_child_dir_zapobj;
+	if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) {
+		printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
+		return (EIO);
+	}
+
+	return (zap_list(spa, &child_dir_zap) != 0);
+}
+#endif
+
 /*
  * Find the object set given the object number of its dataset object
  * and return its details in *objset


More information about the svn-src-all mailing list