/* * Construct a complete graph of all necessary vertices. First, we iterate over * only our object's children. If we don't find any cloned snapshots, then we * simple return that. Otherwise, we have to start at the pool root and iterate * over all datasets. */ static zfs_graph_t * construct_graph(libzfs_handle_t *hdl, const char *dataset) { zfs_graph_t *zgp = zfs_graph_create(hdl, ZFS_GRAPH_SIZE); zfs_cmd_t zc = { 0 }; int ret = 0; if (zgp == NULL) return (zgp); /* * We need to explicitly check whether this dataset has clones or not, * since iterate_children() only checks the children. */ (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); (void) ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc); if (zc.zc_objset_stats.dds_num_clones != 0 || (ret = iterate_children(hdl, zgp, dataset)) != 0) { /* * Determine pool name and try again. */ char *pool, *slash; if ((slash = strchr(dataset, '/')) != NULL || (slash = strchr(dataset, '@')) != NULL) { pool = zfs_alloc(hdl, slash - dataset + 1); if (pool == NULL) { zfs_graph_destroy(zgp); return (NULL); } (void) strncpy(pool, dataset, slash - dataset); pool[slash - dataset] = '\0'; if (iterate_children(hdl, zgp, pool) == -1 || zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) { free(pool); zfs_graph_destroy(zgp); return (NULL); } free(pool); } } if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) { zfs_graph_destroy(zgp); return (NULL); } return (zgp); }
/* * Construct a complete graph of all necessary vertices. First, iterate over * only our object's children. If no cloned snapshots are found, or all of * the cloned snapshots are in this subtree then return a graph of the subtree. * Otherwise, start at the root of the pool and iterate over all datasets. */ static zfs_graph_t * construct_graph(libzfs_handle_t *hdl, const char *dataset) { zfs_graph_t *zgp = zfs_graph_create(hdl, dataset, ZFS_GRAPH_SIZE); int ret = 0; if (zgp == NULL) return (zgp); if ((strchr(dataset, '/') == NULL) || (external_dependents(hdl, zgp, dataset))) { /* * Determine pool name and try again. */ int len = strcspn(dataset, "/@") + 1; char *pool = zfs_alloc(hdl, len); if (pool == NULL) { zfs_graph_destroy(zgp); return (NULL); } (void) strlcpy(pool, dataset, len); if (iterate_children(hdl, zgp, pool) == -1 || zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) { free(pool); zfs_graph_destroy(zgp); return (NULL); } free(pool); } if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) { zfs_graph_destroy(zgp); return (NULL); } return (zgp); }