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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to