1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Iterate over all children of the current object. This includes the normal 28 * dataset hierarchy, but also arbitrary hierarchies due to clones. We want to 29 * walk all datasets in the pool, and construct a directed graph of the form: 30 * 31 * home 32 * | 33 * +----+----+ 34 * | | 35 * v v ws 36 * bar baz | 37 * | | 38 * v v 39 * @yesterday ----> foo 40 * 41 * In order to construct this graph, we have to walk every dataset in the pool, 42 * because the clone parent is stored as a property of the child, not the 43 * parent. The parent only keeps track of the number of clones. 44 * 45 * In the normal case (without clones) this would be rather expensive. To avoid 46 * unnecessary computation, we first try a walk of the subtree hierarchy 47 * starting from the initial node. At each dataset, we construct a node in the 48 * graph and an edge leading from its parent. If we don't see any snapshots 49 * with a non-zero clone count, then we are finished. 50 * 51 * If we do find a cloned snapshot, then we finish the walk of the current 52 * subtree, but indicate that we need to do a complete walk. We then perform a 53 * global walk of all datasets, avoiding the subtree we already processed. 54 * 55 * At the end of this, we'll end up with a directed graph of all relevant (and 56 * possible some irrelevant) datasets in the system. We need to both find our 57 * limiting subgraph and determine a safe ordering in which to destroy the 58 * datasets. We do a topological ordering of our graph starting at our target 59 * dataset, and then walk the results in reverse. 60 * 61 * It's possible for the graph to have cycles if, for example, the user renames 62 * a clone to be the parent of its origin snapshot. The user can request to 63 * generate an error in this case, or ignore the cycle and continue. 64 * 65 * When removing datasets, we want to destroy the snapshots in chronological 66 * order (because this is the most efficient method). In order to accomplish 67 * this, we store the creation transaction group with each vertex and keep each 68 * vertex's edges sorted according to this value. The topological sort will 69 * automatically walk the snapshots in the correct order. 70 */ 71 72 #include <assert.h> 73 #include <libintl.h> 74 #include <stdio.h> 75 #include <stdlib.h> 76 #include <string.h> 77 #include <strings.h> 78 #include <unistd.h> 79 80 #include <libzfs.h> 81 82 #include "libzfs_impl.h" 83 #include "zfs_namecheck.h" 84 85 #define MIN_EDGECOUNT 4 86 87 /* 88 * Vertex structure. Indexed by dataset name, this structure maintains a list 89 * of edges to other vertices. 90 */ 91 struct zfs_edge; 92 typedef struct zfs_vertex { 93 char zv_dataset[ZFS_MAXNAMELEN]; 94 struct zfs_vertex *zv_next; 95 int zv_visited; 96 uint64_t zv_txg; 97 struct zfs_edge **zv_edges; 98 int zv_edgecount; 99 int zv_edgealloc; 100 } zfs_vertex_t; 101 102 enum { 103 VISIT_SEEN = 1, 104 VISIT_SORT_PRE, 105 VISIT_SORT_POST 106 }; 107 108 /* 109 * Edge structure. Simply maintains a pointer to the destination vertex. There 110 * is no need to store the source vertex, since we only use edges in the context 111 * of the source vertex. 112 */ 113 typedef struct zfs_edge { 114 zfs_vertex_t *ze_dest; 115 struct zfs_edge *ze_next; 116 } zfs_edge_t; 117 118 #define ZFS_GRAPH_SIZE 1027 /* this could be dynamic some day */ 119 120 /* 121 * Graph structure. Vertices are maintained in a hash indexed by dataset name. 122 */ 123 typedef struct zfs_graph { 124 zfs_vertex_t **zg_hash; 125 size_t zg_size; 126 size_t zg_nvertex; 127 const char *zg_root; 128 int zg_clone_count; 129 } zfs_graph_t; 130 131 /* 132 * Allocate a new edge pointing to the target vertex. 133 */ 134 static zfs_edge_t * 135 zfs_edge_create(libzfs_handle_t *hdl, zfs_vertex_t *dest) 136 { 137 zfs_edge_t *zep = zfs_alloc(hdl, sizeof (zfs_edge_t)); 138 139 if (zep == NULL) 140 return (NULL); 141 142 zep->ze_dest = dest; 143 144 return (zep); 145 } 146 147 /* 148 * Destroy an edge. 149 */ 150 static void 151 zfs_edge_destroy(zfs_edge_t *zep) 152 { 153 free(zep); 154 } 155 156 /* 157 * Allocate a new vertex with the given name. 158 */ 159 static zfs_vertex_t * 160 zfs_vertex_create(libzfs_handle_t *hdl, const char *dataset) 161 { 162 zfs_vertex_t *zvp = zfs_alloc(hdl, sizeof (zfs_vertex_t)); 163 164 if (zvp == NULL) 165 return (NULL); 166 167 assert(strlen(dataset) < ZFS_MAXNAMELEN); 168 169 (void) strlcpy(zvp->zv_dataset, dataset, sizeof (zvp->zv_dataset)); 170 171 if ((zvp->zv_edges = zfs_alloc(hdl, 172 MIN_EDGECOUNT * sizeof (void *))) == NULL) { 173 free(zvp); 174 return (NULL); 175 } 176 177 zvp->zv_edgealloc = MIN_EDGECOUNT; 178 179 return (zvp); 180 } 181 182 /* 183 * Destroy a vertex. Frees up any associated edges. 184 */ 185 static void 186 zfs_vertex_destroy(zfs_vertex_t *zvp) 187 { 188 int i; 189 190 for (i = 0; i < zvp->zv_edgecount; i++) 191 zfs_edge_destroy(zvp->zv_edges[i]); 192 193 free(zvp->zv_edges); 194 free(zvp); 195 } 196 197 /* 198 * Given a vertex, add an edge to the destination vertex. 199 */ 200 static int 201 zfs_vertex_add_edge(libzfs_handle_t *hdl, zfs_vertex_t *zvp, 202 zfs_vertex_t *dest) 203 { 204 zfs_edge_t *zep = zfs_edge_create(hdl, dest); 205 206 if (zep == NULL) 207 return (-1); 208 209 if (zvp->zv_edgecount == zvp->zv_edgealloc) { 210 void *ptr; 211 212 if ((ptr = zfs_realloc(hdl, zvp->zv_edges, 213 zvp->zv_edgealloc * sizeof (void *), 214 zvp->zv_edgealloc * 2 * sizeof (void *))) == NULL) 215 return (-1); 216 217 zvp->zv_edges = ptr; 218 zvp->zv_edgealloc *= 2; 219 } 220 221 zvp->zv_edges[zvp->zv_edgecount++] = zep; 222 223 return (0); 224 } 225 226 static int 227 zfs_edge_compare(const void *a, const void *b) 228 { 229 const zfs_edge_t *ea = *((zfs_edge_t **)a); 230 const zfs_edge_t *eb = *((zfs_edge_t **)b); 231 232 if (ea->ze_dest->zv_txg < eb->ze_dest->zv_txg) 233 return (-1); 234 if (ea->ze_dest->zv_txg > eb->ze_dest->zv_txg) 235 return (1); 236 return (0); 237 } 238 239 /* 240 * Sort the given vertex edges according to the creation txg of each vertex. 241 */ 242 static void 243 zfs_vertex_sort_edges(zfs_vertex_t *zvp) 244 { 245 if (zvp->zv_edgecount == 0) 246 return; 247 248 qsort(zvp->zv_edges, zvp->zv_edgecount, sizeof (void *), 249 zfs_edge_compare); 250 } 251 252 /* 253 * Construct a new graph object. We allow the size to be specified as a 254 * parameter so in the future we can size the hash according to the number of 255 * datasets in the pool. 256 */ 257 static zfs_graph_t * 258 zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size) 259 { 260 zfs_graph_t *zgp = zfs_alloc(hdl, sizeof (zfs_graph_t)); 261 262 if (zgp == NULL) 263 return (NULL); 264 265 zgp->zg_size = size; 266 if ((zgp->zg_hash = zfs_alloc(hdl, 267 size * sizeof (zfs_vertex_t *))) == NULL) { 268 free(zgp); 269 return (NULL); 270 } 271 272 zgp->zg_root = dataset; 273 zgp->zg_clone_count = 0; 274 275 return (zgp); 276 } 277 278 /* 279 * Destroy a graph object. We have to iterate over all the hash chains, 280 * destroying each vertex in the process. 281 */ 282 static void 283 zfs_graph_destroy(zfs_graph_t *zgp) 284 { 285 int i; 286 zfs_vertex_t *current, *next; 287 288 for (i = 0; i < zgp->zg_size; i++) { 289 current = zgp->zg_hash[i]; 290 while (current != NULL) { 291 next = current->zv_next; 292 zfs_vertex_destroy(current); 293 current = next; 294 } 295 } 296 297 free(zgp->zg_hash); 298 free(zgp); 299 } 300 301 /* 302 * Graph hash function. Classic bernstein k=33 hash function, taken from 303 * usr/src/cmd/sgs/tools/common/strhash.c 304 */ 305 static size_t 306 zfs_graph_hash(zfs_graph_t *zgp, const char *str) 307 { 308 size_t hash = 5381; 309 int c; 310 311 while ((c = *str++) != 0) 312 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 313 314 return (hash % zgp->zg_size); 315 } 316 317 /* 318 * Given a dataset name, finds the associated vertex, creating it if necessary. 319 */ 320 static zfs_vertex_t * 321 zfs_graph_lookup(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset, 322 uint64_t txg) 323 { 324 size_t idx = zfs_graph_hash(zgp, dataset); 325 zfs_vertex_t *zvp; 326 327 for (zvp = zgp->zg_hash[idx]; zvp != NULL; zvp = zvp->zv_next) { 328 if (strcmp(zvp->zv_dataset, dataset) == 0) { 329 if (zvp->zv_txg == 0) 330 zvp->zv_txg = txg; 331 return (zvp); 332 } 333 } 334 335 if ((zvp = zfs_vertex_create(hdl, dataset)) == NULL) 336 return (NULL); 337 338 zvp->zv_next = zgp->zg_hash[idx]; 339 zvp->zv_txg = txg; 340 zgp->zg_hash[idx] = zvp; 341 zgp->zg_nvertex++; 342 343 return (zvp); 344 } 345 346 /* 347 * Given two dataset names, create an edge between them. For the source vertex, 348 * mark 'zv_visited' to indicate that we have seen this vertex, and not simply 349 * created it as a destination of another edge. If 'dest' is NULL, then this 350 * is an individual vertex (i.e. the starting vertex), so don't add an edge. 351 */ 352 static int 353 zfs_graph_add(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *source, 354 const char *dest, uint64_t txg) 355 { 356 zfs_vertex_t *svp, *dvp; 357 358 if ((svp = zfs_graph_lookup(hdl, zgp, source, 0)) == NULL) 359 return (-1); 360 svp->zv_visited = VISIT_SEEN; 361 if (dest != NULL) { 362 dvp = zfs_graph_lookup(hdl, zgp, dest, txg); 363 if (dvp == NULL) 364 return (-1); 365 if (zfs_vertex_add_edge(hdl, svp, dvp) != 0) 366 return (-1); 367 } 368 369 return (0); 370 } 371 372 /* 373 * Iterate over all children of the given dataset, adding any vertices 374 * as necessary. Returns -1 if there was an error, or 0 otherwise. 375 * This is a simple recursive algorithm - the ZFS namespace typically 376 * is very flat. We manually invoke the necessary ioctl() calls to 377 * avoid the overhead and additional semantics of zfs_open(). 378 */ 379 static int 380 iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset) 381 { 382 zfs_cmd_t zc = { 0 }; 383 zfs_vertex_t *zvp; 384 385 /* 386 * Look up the source vertex, and avoid it if we've seen it before. 387 */ 388 zvp = zfs_graph_lookup(hdl, zgp, dataset, 0); 389 if (zvp == NULL) 390 return (-1); 391 if (zvp->zv_visited == VISIT_SEEN) 392 return (0); 393 394 /* 395 * Iterate over all children 396 */ 397 for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 398 ioctl(hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0; 399 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) { 400 /* 401 * Get statistics for this dataset, to determine the type of the 402 * dataset and clone statistics. If this fails, the dataset has 403 * since been removed, and we're pretty much screwed anyway. 404 */ 405 zc.zc_objset_stats.dds_origin[0] = '\0'; 406 if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) 407 continue; 408 409 if (zc.zc_objset_stats.dds_origin[0] != '\0') { 410 if (zfs_graph_add(hdl, zgp, 411 zc.zc_objset_stats.dds_origin, zc.zc_name, 412 zc.zc_objset_stats.dds_creation_txg) != 0) 413 return (-1); 414 /* 415 * Count origins only if they are contained in the graph 416 */ 417 if (isa_child_of(zc.zc_objset_stats.dds_origin, 418 zgp->zg_root)) 419 zgp->zg_clone_count--; 420 } 421 422 /* 423 * Add an edge between the parent and the child. 424 */ 425 if (zfs_graph_add(hdl, zgp, dataset, zc.zc_name, 426 zc.zc_objset_stats.dds_creation_txg) != 0) 427 return (-1); 428 429 /* 430 * Recursively visit child 431 */ 432 if (iterate_children(hdl, zgp, zc.zc_name)) 433 return (-1); 434 } 435 436 /* 437 * Now iterate over all snapshots. 438 */ 439 bzero(&zc, sizeof (zc)); 440 441 for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 442 ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT, &zc) == 0; 443 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) { 444 445 /* 446 * Get statistics for this dataset, to determine the type of the 447 * dataset and clone statistics. If this fails, the dataset has 448 * since been removed, and we're pretty much screwed anyway. 449 */ 450 if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) 451 continue; 452 453 /* 454 * Add an edge between the parent and the child. 455 */ 456 if (zfs_graph_add(hdl, zgp, dataset, zc.zc_name, 457 zc.zc_objset_stats.dds_creation_txg) != 0) 458 return (-1); 459 460 zgp->zg_clone_count += zc.zc_objset_stats.dds_num_clones; 461 } 462 463 zvp->zv_visited = VISIT_SEEN; 464 465 return (0); 466 } 467 468 /* 469 * Returns false if there are no snapshots with dependent clones in this 470 * subtree or if all of those clones are also in this subtree. Returns 471 * true if there is an error or there are external dependents. 472 */ 473 static boolean_t 474 external_dependents(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset) 475 { 476 zfs_cmd_t zc = { 0 }; 477 478 /* 479 * Check whether this dataset is a clone or has clones since 480 * iterate_children() only checks the children. 481 */ 482 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name)); 483 if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) 484 return (B_TRUE); 485 486 if (zc.zc_objset_stats.dds_origin[0] != '\0') { 487 if (zfs_graph_add(hdl, zgp, 488 zc.zc_objset_stats.dds_origin, zc.zc_name, 489 zc.zc_objset_stats.dds_creation_txg) != 0) 490 return (B_TRUE); 491 if (isa_child_of(zc.zc_objset_stats.dds_origin, dataset)) 492 zgp->zg_clone_count--; 493 } 494 495 if ((zc.zc_objset_stats.dds_num_clones) || 496 iterate_children(hdl, zgp, dataset)) 497 return (B_TRUE); 498 499 return (zgp->zg_clone_count != 0); 500 } 501 502 /* 503 * Construct a complete graph of all necessary vertices. First, iterate over 504 * only our object's children. If no cloned snapshots are found, or all of 505 * the cloned snapshots are in this subtree then return a graph of the subtree. 506 * Otherwise, start at the root of the pool and iterate over all datasets. 507 */ 508 static zfs_graph_t * 509 construct_graph(libzfs_handle_t *hdl, const char *dataset) 510 { 511 zfs_graph_t *zgp = zfs_graph_create(hdl, dataset, ZFS_GRAPH_SIZE); 512 int ret = 0; 513 514 if (zgp == NULL) 515 return (zgp); 516 517 if ((strchr(dataset, '/') == NULL) || 518 (external_dependents(hdl, zgp, dataset))) { 519 /* 520 * Determine pool name and try again. 521 */ 522 int len = strcspn(dataset, "/@") + 1; 523 char *pool = zfs_alloc(hdl, len); 524 525 if (pool == NULL) { 526 zfs_graph_destroy(zgp); 527 return (NULL); 528 } 529 (void) strlcpy(pool, dataset, len); 530 531 if (iterate_children(hdl, zgp, pool) == -1 || 532 zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) { 533 free(pool); 534 zfs_graph_destroy(zgp); 535 return (NULL); 536 } 537 free(pool); 538 } 539 540 if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) { 541 zfs_graph_destroy(zgp); 542 return (NULL); 543 } 544 545 return (zgp); 546 } 547 548 /* 549 * Given a graph, do a recursive topological sort into the given array. This is 550 * really just a depth first search, so that the deepest nodes appear first. 551 * hijack the 'zv_visited' marker to avoid visiting the same vertex twice. 552 */ 553 static int 554 topo_sort(libzfs_handle_t *hdl, boolean_t allowrecursion, char **result, 555 size_t *idx, zfs_vertex_t *zgv) 556 { 557 int i; 558 559 if (zgv->zv_visited == VISIT_SORT_PRE && !allowrecursion) { 560 /* 561 * If we've already seen this vertex as part of our depth-first 562 * search, then we have a cyclic dependency, and we must return 563 * an error. 564 */ 565 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 566 "recursive dependency at '%s'"), 567 zgv->zv_dataset); 568 return (zfs_error(hdl, EZFS_RECURSIVE, 569 dgettext(TEXT_DOMAIN, 570 "cannot determine dependent datasets"))); 571 } else if (zgv->zv_visited >= VISIT_SORT_PRE) { 572 /* 573 * If we've already processed this as part of the topological 574 * sort, then don't bother doing so again. 575 */ 576 return (0); 577 } 578 579 zgv->zv_visited = VISIT_SORT_PRE; 580 581 /* avoid doing a search if we don't have to */ 582 zfs_vertex_sort_edges(zgv); 583 for (i = 0; i < zgv->zv_edgecount; i++) { 584 if (topo_sort(hdl, allowrecursion, result, idx, 585 zgv->zv_edges[i]->ze_dest) != 0) 586 return (-1); 587 } 588 589 /* we may have visited this in the course of the above */ 590 if (zgv->zv_visited == VISIT_SORT_POST) 591 return (0); 592 593 if ((result[*idx] = zfs_alloc(hdl, 594 strlen(zgv->zv_dataset) + 1)) == NULL) 595 return (-1); 596 597 (void) strcpy(result[*idx], zgv->zv_dataset); 598 *idx += 1; 599 zgv->zv_visited = VISIT_SORT_POST; 600 return (0); 601 } 602 603 /* 604 * The only public interface for this file. Do the dirty work of constructing a 605 * child list for the given object. Construct the graph, do the toplogical 606 * sort, and then return the array of strings to the caller. 607 * 608 * The 'allowrecursion' parameter controls behavior when cycles are found. If 609 * it is set, the the cycle is ignored and the results returned as if the cycle 610 * did not exist. If it is not set, then the routine will generate an error if 611 * a cycle is found. 612 */ 613 int 614 get_dependents(libzfs_handle_t *hdl, boolean_t allowrecursion, 615 const char *dataset, char ***result, size_t *count) 616 { 617 zfs_graph_t *zgp; 618 zfs_vertex_t *zvp; 619 620 if ((zgp = construct_graph(hdl, dataset)) == NULL) 621 return (-1); 622 623 if ((*result = zfs_alloc(hdl, 624 zgp->zg_nvertex * sizeof (char *))) == NULL) { 625 zfs_graph_destroy(zgp); 626 return (-1); 627 } 628 629 if ((zvp = zfs_graph_lookup(hdl, zgp, dataset, 0)) == NULL) { 630 free(*result); 631 zfs_graph_destroy(zgp); 632 return (-1); 633 } 634 635 *count = 0; 636 if (topo_sort(hdl, allowrecursion, *result, count, zvp) != 0) { 637 free(*result); 638 zfs_graph_destroy(zgp); 639 return (-1); 640 } 641 642 /* 643 * Get rid of the last entry, which is our starting vertex and not 644 * strictly a dependent. 645 */ 646 assert(*count > 0); 647 free((*result)[*count - 1]); 648 (*count)--; 649 650 zfs_graph_destroy(zgp); 651 652 return (0); 653 } 654