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
This commit is contained in:
Andriy Gapon 2012-10-06 19:27:04 +00:00
parent 84b339ac4c
commit 74b3e265c7
3 changed files with 68 additions and 4 deletions

View File

@ -59,6 +59,7 @@ int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
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;

View File

@ -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);
}

View File

@ -1387,8 +1387,6 @@ zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64
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_phys_t *dnode)
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, const char *name, uint64_t *objnum)
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