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