|
Lines 271-277
be_snapshot(libbe_handle_t *lbh, const char *source, const char *snap_name,
Link Here
|
| 271 |
be_root_concat(lbh, source, buf); |
271 |
be_root_concat(lbh, source, buf); |
| 272 |
|
272 |
|
| 273 |
if ((err = be_exists(lbh, buf)) != 0) |
273 |
if ((err = be_exists(lbh, buf)) != 0) |
| 274 |
return (set_error(lbh, err)); |
274 |
return err; |
| 275 |
|
275 |
|
| 276 |
if (snap_name != NULL) { |
276 |
if (snap_name != NULL) { |
| 277 |
if (strlcat(buf, "@", sizeof(buf)) >= sizeof(buf)) |
277 |
if (strlcat(buf, "@", sizeof(buf)) >= sizeof(buf)) |
|
Lines 325-331
be_create(libbe_handle_t *lbh, const char *name)
Link Here
|
| 325 |
|
325 |
|
| 326 |
err = be_create_from_existing(lbh, name, be_active_path(lbh)); |
326 |
err = be_create_from_existing(lbh, name, be_active_path(lbh)); |
| 327 |
|
327 |
|
| 328 |
return (set_error(lbh, err)); |
328 |
return err; |
| 329 |
} |
329 |
} |
| 330 |
|
330 |
|
| 331 |
|
331 |
|
|
Lines 377-383
be_deep_clone(zfs_handle_t *ds, void *data)
Link Here
|
| 377 |
isdc = (struct libbe_deep_clone *)data; |
377 |
isdc = (struct libbe_deep_clone *)data; |
| 378 |
dspath = zfs_get_name(ds); |
378 |
dspath = zfs_get_name(ds); |
| 379 |
if ((dsname = strrchr(dspath, '/')) == NULL) |
379 |
if ((dsname = strrchr(dspath, '/')) == NULL) |
| 380 |
return (BE_ERR_UNKNOWN); |
380 |
return (set_error(isdc->lbh, BE_ERR_UNKNOWN)); |
| 381 |
dsname++; |
381 |
dsname++; |
| 382 |
|
382 |
|
| 383 |
if (isdc->bename == NULL) |
383 |
if (isdc->bename == NULL) |
|
Lines 439-452
be_create_from_existing_snap(libbe_handle_t *lbh, const char *name,
Link Here
|
| 439 |
struct libbe_deep_clone sdc; |
439 |
struct libbe_deep_clone sdc; |
| 440 |
|
440 |
|
| 441 |
if ((err = be_validate_name(lbh, name)) != 0) |
441 |
if ((err = be_validate_name(lbh, name)) != 0) |
| 442 |
return (set_error(lbh, err)); |
442 |
return err; |
| 443 |
if ((err = be_root_concat(lbh, snap, snap_path)) != 0) |
443 |
if ((err = be_root_concat(lbh, snap, snap_path)) != 0) |
| 444 |
return (set_error(lbh, err)); |
444 |
return err; |
| 445 |
if ((err = be_validate_snap(lbh, snap_path)) != 0) |
445 |
if ((err = be_validate_snap(lbh, snap_path)) != 0) |
| 446 |
return (set_error(lbh, err)); |
446 |
return err; |
| 447 |
|
447 |
|
| 448 |
if ((err = be_root_concat(lbh, name, be_path)) != 0) |
448 |
if ((err = be_root_concat(lbh, name, be_path)) != 0) |
| 449 |
return (set_error(lbh, err)); |
449 |
return err; |
| 450 |
|
450 |
|
| 451 |
if ((bename = strrchr(name, '/')) == NULL) |
451 |
if ((bename = strrchr(name, '/')) == NULL) |
| 452 |
bename = name; |
452 |
bename = name; |
|
Lines 473-479
be_create_from_existing_snap(libbe_handle_t *lbh, const char *name,
Link Here
|
| 473 |
err = be_deep_clone(parent_hdl, &sdc); |
473 |
err = be_deep_clone(parent_hdl, &sdc); |
| 474 |
|
474 |
|
| 475 |
free(parentname); |
475 |
free(parentname); |
| 476 |
return (set_error(lbh, err)); |
476 |
return err; |
| 477 |
} |
477 |
} |
| 478 |
|
478 |
|
| 479 |
|
479 |
|
|
Lines 487-497
be_create_from_existing(libbe_handle_t *lbh, const char *name, const char *old)
Link Here
|
| 487 |
char buf[BE_MAXPATHLEN]; |
487 |
char buf[BE_MAXPATHLEN]; |
| 488 |
|
488 |
|
| 489 |
if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)) != 0) |
489 |
if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)) != 0) |
| 490 |
return (set_error(lbh, err)); |
490 |
return err; |
| 491 |
|
491 |
|
| 492 |
err = be_create_from_existing_snap(lbh, name, (char *)buf); |
492 |
err = be_create_from_existing_snap(lbh, name, (char *)buf); |
| 493 |
|
493 |
|
| 494 |
return (set_error(lbh, err)); |
494 |
return err; |
| 495 |
} |
495 |
} |
| 496 |
|
496 |
|
| 497 |
|
497 |
|
|
Lines 509-530
be_validate_snap(libbe_handle_t *lbh, const char *snap_name)
Link Here
|
| 509 |
int err = BE_ERR_SUCCESS; |
509 |
int err = BE_ERR_SUCCESS; |
| 510 |
|
510 |
|
| 511 |
if (strlen(snap_name) >= BE_MAXPATHLEN) |
511 |
if (strlen(snap_name) >= BE_MAXPATHLEN) |
| 512 |
return (BE_ERR_PATHLEN); |
512 |
return (set_error(lbh, BE_ERR_PATHLEN)); |
| 513 |
|
513 |
|
| 514 |
if (!zfs_dataset_exists(lbh->lzh, snap_name, |
514 |
if (!zfs_dataset_exists(lbh->lzh, snap_name, |
| 515 |
ZFS_TYPE_SNAPSHOT)) |
515 |
ZFS_TYPE_SNAPSHOT)) |
| 516 |
return (BE_ERR_NOENT); |
516 |
return (set_error(lbh, BE_ERR_NOENT)); |
| 517 |
|
517 |
|
| 518 |
strlcpy(buf, snap_name, sizeof(buf)); |
518 |
strlcpy(buf, snap_name, sizeof(buf)); |
| 519 |
|
519 |
|
| 520 |
/* Find the base filesystem of the snapshot */ |
520 |
/* Find the base filesystem of the snapshot */ |
| 521 |
if ((delim_pos = strchr(buf, '@')) == NULL) |
521 |
if ((delim_pos = strchr(buf, '@')) == NULL) |
| 522 |
return (BE_ERR_INVALIDNAME); |
522 |
return (set_error(lbh, BE_ERR_INVALIDNAME)); |
| 523 |
*delim_pos = '\0'; |
523 |
*delim_pos = '\0'; |
| 524 |
|
524 |
|
| 525 |
if ((zfs_hdl = |
525 |
if ((zfs_hdl = |
| 526 |
zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL) |
526 |
zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL) |
| 527 |
return (BE_ERR_NOORIGIN); |
527 |
return (set_error(lbh, BE_ERR_NOORIGIN)); |
| 528 |
|
528 |
|
| 529 |
if ((err = zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, |
529 |
if ((err = zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, buf, |
| 530 |
sizeof(buf), NULL, NULL, 0, 1)) != 0) |
530 |
sizeof(buf), NULL, NULL, 0, 1)) != 0) |
|
Lines 535-541
be_validate_snap(libbe_handle_t *lbh, const char *snap_name)
Link Here
|
| 535 |
|
535 |
|
| 536 |
zfs_close(zfs_hdl); |
536 |
zfs_close(zfs_hdl); |
| 537 |
|
537 |
|
| 538 |
return (err); |
538 |
return (set_error(lbh, err)); |
| 539 |
} |
539 |
} |
| 540 |
|
540 |
|
| 541 |
|
541 |
|
|
Lines 558-577
be_root_concat(libbe_handle_t *lbh, const char *name, char *result)
Link Here
|
| 558 |
/* Act idempotently; return be name if it is already a full path */ |
558 |
/* Act idempotently; return be name if it is already a full path */ |
| 559 |
if (strrchr(name, '/') != NULL) { |
559 |
if (strrchr(name, '/') != NULL) { |
| 560 |
if (strstr(name, lbh->root) != name) |
560 |
if (strstr(name, lbh->root) != name) |
| 561 |
return (BE_ERR_INVALIDNAME); |
561 |
return (set_error(lbh, BE_ERR_INVALIDNAME)); |
| 562 |
|
562 |
|
| 563 |
if (name_len >= BE_MAXPATHLEN) |
563 |
if (name_len >= BE_MAXPATHLEN) |
| 564 |
return (BE_ERR_PATHLEN); |
564 |
return (set_error(lbh, BE_ERR_PATHLEN)); |
| 565 |
|
565 |
|
| 566 |
strlcpy(result, name, BE_MAXPATHLEN); |
566 |
strlcpy(result, name, BE_MAXPATHLEN); |
| 567 |
return (BE_ERR_SUCCESS); |
567 |
return (set_error(lbh, BE_ERR_SUCCESS)); |
| 568 |
} else if (name_len + root_len + 1 < BE_MAXPATHLEN) { |
568 |
} else if (name_len + root_len + 1 < BE_MAXPATHLEN) { |
| 569 |
snprintf(result, BE_MAXPATHLEN, "%s/%s", lbh->root, |
569 |
snprintf(result, BE_MAXPATHLEN, "%s/%s", lbh->root, |
| 570 |
name); |
570 |
name); |
| 571 |
return (BE_ERR_SUCCESS); |
571 |
return (set_error(lbh, BE_ERR_SUCCESS)); |
| 572 |
} |
572 |
} |
| 573 |
|
573 |
|
| 574 |
return (BE_ERR_PATHLEN); |
574 |
return (set_error(lbh, BE_ERR_PATHLEN)); |
| 575 |
} |
575 |
} |
| 576 |
|
576 |
|
| 577 |
|
577 |
|
|
Lines 588-594
be_validate_name(libbe_handle_t *lbh, const char *name)
Link Here
|
| 588 |
char c = *(name++); |
588 |
char c = *(name++); |
| 589 |
if (isalnum(c) || (c == '-') || (c == '_') || (c == '.')) |
589 |
if (isalnum(c) || (c == '-') || (c == '_') || (c == '.')) |
| 590 |
continue; |
590 |
continue; |
| 591 |
return (BE_ERR_INVALIDNAME); |
591 |
return (set_error(lbh, BE_ERR_INVALIDNAME)); |
| 592 |
} |
592 |
} |
| 593 |
|
593 |
|
| 594 |
/* |
594 |
/* |
|
Lines 596-603
be_validate_name(libbe_handle_t *lbh, const char *name)
Link Here
|
| 596 |
* not exceed the maximum length of a dataset, i.e. MAXNAMELEN. |
596 |
* not exceed the maximum length of a dataset, i.e. MAXNAMELEN. |
| 597 |
*/ |
597 |
*/ |
| 598 |
if (strlen(lbh->root) + 1 + strlen(name) > MAXNAMELEN) |
598 |
if (strlen(lbh->root) + 1 + strlen(name) > MAXNAMELEN) |
| 599 |
return (BE_ERR_PATHLEN); |
599 |
return (set_error(lbh, BE_ERR_PATHLEN)); |
| 600 |
return (BE_ERR_SUCCESS); |
600 |
return (set_error(lbh, BE_ERR_SUCCESS)); |
| 601 |
} |
601 |
} |
| 602 |
|
602 |
|
| 603 |
|
603 |
|
|
Lines 617-627
be_rename(libbe_handle_t *lbh, const char *old, const char *new)
Link Here
|
| 617 |
* do so here. |
617 |
* do so here. |
| 618 |
*/ |
618 |
*/ |
| 619 |
if ((err = be_validate_name(lbh, new)) != 0) |
619 |
if ((err = be_validate_name(lbh, new)) != 0) |
| 620 |
return (set_error(lbh, err)); |
620 |
return err; |
| 621 |
if ((err = be_root_concat(lbh, old, full_old)) != 0) |
621 |
if ((err = be_root_concat(lbh, old, full_old)) != 0) |
| 622 |
return (set_error(lbh, err)); |
622 |
return err; |
| 623 |
if ((err = be_root_concat(lbh, new, full_new)) != 0) |
623 |
if ((err = be_root_concat(lbh, new, full_new)) != 0) |
| 624 |
return (set_error(lbh, err)); |
624 |
return err; |
| 625 |
|
625 |
|
| 626 |
if (!zfs_dataset_exists(lbh->lzh, full_old, ZFS_TYPE_DATASET)) |
626 |
if (!zfs_dataset_exists(lbh->lzh, full_old, ZFS_TYPE_DATASET)) |
| 627 |
return (set_error(lbh, BE_ERR_NOENT)); |
627 |
return (set_error(lbh, BE_ERR_NOENT)); |
|
Lines 657-663
be_export(libbe_handle_t *lbh, const char *bootenv, int fd)
Link Here
|
| 657 |
|
657 |
|
| 658 |
if ((err = be_snapshot(lbh, bootenv, NULL, true, snap_name)) != 0) |
658 |
if ((err = be_snapshot(lbh, bootenv, NULL, true, snap_name)) != 0) |
| 659 |
/* Use the error set by be_snapshot */ |
659 |
/* Use the error set by be_snapshot */ |
| 660 |
return (err); |
660 |
return err; |
| 661 |
|
661 |
|
| 662 |
be_root_concat(lbh, snap_name, buf); |
662 |
be_root_concat(lbh, snap_name, buf); |
| 663 |
|
663 |
|
|
Lines 667-673
be_export(libbe_handle_t *lbh, const char *bootenv, int fd)
Link Here
|
| 667 |
err = zfs_send_one(zfs, NULL, fd, 0); |
667 |
err = zfs_send_one(zfs, NULL, fd, 0); |
| 668 |
zfs_close(zfs); |
668 |
zfs_close(zfs); |
| 669 |
|
669 |
|
| 670 |
return (err); |
670 |
return (set_error(lbh, err)); |
| 671 |
} |
671 |
} |
| 672 |
|
672 |
|
| 673 |
|
673 |
|
|
Lines 953-959
be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
Link Here
|
| 953 |
|
953 |
|
| 954 |
/* Note: be_exists fails if mountpoint is not / */ |
954 |
/* Note: be_exists fails if mountpoint is not / */ |
| 955 |
if ((err = be_exists(lbh, be_path)) != 0) |
955 |
if ((err = be_exists(lbh, be_path)) != 0) |
| 956 |
return (set_error(lbh, err)); |
956 |
return err; |
| 957 |
|
957 |
|
| 958 |
if (temporary) { |
958 |
if (temporary) { |
| 959 |
config = zpool_get_config(lbh->active_phandle, NULL); |
959 |
config = zpool_get_config(lbh->active_phandle, NULL); |