be.c (73c3d60843efc6116e8dc3bbbf8c32948490d850) | be.c (6d4b1d241d7b3e471c61cae3775d511e6864e3b3) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 601 unchanged lines hidden (view full) --- 610 return (set_error(lbh, BE_ERR_MOUNTED)); 611 612 if (!zfs_dataset_exists(lbh->lzh, full_old, ZFS_TYPE_DATASET)) 613 return (set_error(lbh, BE_ERR_NOENT)); 614 615 if (zfs_dataset_exists(lbh->lzh, full_new, ZFS_TYPE_DATASET)) 616 return (set_error(lbh, BE_ERR_EXISTS)); 617 | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 601 unchanged lines hidden (view full) --- 610 return (set_error(lbh, BE_ERR_MOUNTED)); 611 612 if (!zfs_dataset_exists(lbh->lzh, full_old, ZFS_TYPE_DATASET)) 613 return (set_error(lbh, BE_ERR_NOENT)); 614 615 if (zfs_dataset_exists(lbh->lzh, full_new, ZFS_TYPE_DATASET)) 616 return (set_error(lbh, BE_ERR_EXISTS)); 617 |
618 /* XXX TODO 619 * - What about mounted BEs? 620 * - if mounted error out unless a force flag is set? 621 */ | |
622 if ((zfs_hdl = zfs_open(lbh->lzh, full_old, 623 ZFS_TYPE_FILESYSTEM)) == NULL) 624 return (set_error(lbh, BE_ERR_ZFSOPEN)); 625 | 618 if ((zfs_hdl = zfs_open(lbh->lzh, full_old, 619 ZFS_TYPE_FILESYSTEM)) == NULL) 620 return (set_error(lbh, BE_ERR_ZFSOPEN)); 621 |
622 /* XXX TODO: Allow a force flag */ 623 if (zfs_is_mounted(zfs_hdl, NULL)) { 624 zfs_close(zfs_hdl); 625 return (set_error(lbh, BE_ERR_MOUNTED)); 626 } 627 |
|
626 /* recurse, nounmount, forceunmount */ 627 struct renameflags flags = { 0, 0, 0 }; 628 629 err = zfs_rename(zfs_hdl, NULL, full_new, flags); 630 631 zfs_close(zfs_hdl); 632 633 return (set_error(lbh, err)); --- 4 unchanged lines hidden (view full) --- 638be_export(libbe_handle_t *lbh, const char *bootenv, int fd) 639{ 640 char snap_name[BE_MAXPATHLEN]; 641 char buf[BE_MAXPATHLEN]; 642 zfs_handle_t *zfs; 643 int err; 644 645 if ((err = be_snapshot(lbh, bootenv, NULL, true, snap_name)) != 0) | 628 /* recurse, nounmount, forceunmount */ 629 struct renameflags flags = { 0, 0, 0 }; 630 631 err = zfs_rename(zfs_hdl, NULL, full_new, flags); 632 633 zfs_close(zfs_hdl); 634 635 return (set_error(lbh, err)); --- 4 unchanged lines hidden (view full) --- 640be_export(libbe_handle_t *lbh, const char *bootenv, int fd) 641{ 642 char snap_name[BE_MAXPATHLEN]; 643 char buf[BE_MAXPATHLEN]; 644 zfs_handle_t *zfs; 645 int err; 646 647 if ((err = be_snapshot(lbh, bootenv, NULL, true, snap_name)) != 0) |
646 /* XXX TODO error handle */ 647 return (-1); | 648 /* Use the error set by be_snapshot */ 649 return (err); |
648 649 be_root_concat(lbh, snap_name, buf); 650 651 if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL) 652 return (set_error(lbh, BE_ERR_ZFSOPEN)); 653 654 err = zfs_send_one(zfs, NULL, fd, 0); | 650 651 be_root_concat(lbh, snap_name, buf); 652 653 if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL) 654 return (set_error(lbh, BE_ERR_ZFSOPEN)); 655 656 err = zfs_send_one(zfs, NULL, fd, 0); |
657 zfs_close(zfs); 658 |
|
655 return (err); 656} 657 658 659int 660be_import(libbe_handle_t *lbh, const char *bootenv, int fd) 661{ 662 char buf[BE_MAXPATHLEN]; --- 46 unchanged lines hidden (view full) --- 709 710 be_root_concat(lbh, bootenv, buf); 711 712 err = zfs_clone(zfs, buf, props); 713 zfs_close(zfs); 714 715 nvlist_free(props); 716 | 659 return (err); 660} 661 662 663int 664be_import(libbe_handle_t *lbh, const char *bootenv, int fd) 665{ 666 char buf[BE_MAXPATHLEN]; --- 46 unchanged lines hidden (view full) --- 713 714 be_root_concat(lbh, bootenv, buf); 715 716 err = zfs_clone(zfs, buf, props); 717 zfs_close(zfs); 718 719 nvlist_free(props); 720 |
717 /* XXX TODO: recursively delete nbuf dataset */ 718 return (err); | 721 return (be_destroy(lbh, nbuf, 0)); |
719} 720 721 722int 723be_add_child(libbe_handle_t *lbh, const char *child_path, bool cp_if_exists) 724{ 725 struct stat sb; 726 char active[BE_MAXPATHLEN]; 727 char buf[BE_MAXPATHLEN]; 728 nvlist_t *props; 729 const char *s; 730 zfs_handle_t *zfs; | 722} 723 724 725int 726be_add_child(libbe_handle_t *lbh, const char *child_path, bool cp_if_exists) 727{ 728 struct stat sb; 729 char active[BE_MAXPATHLEN]; 730 char buf[BE_MAXPATHLEN]; 731 nvlist_t *props; 732 const char *s; 733 zfs_handle_t *zfs; |
731 long snap_name; 732 int err, pos; | 734 int err; |
733 734 /* Require absolute paths */ 735 if (*child_path != '/') | 735 736 /* Require absolute paths */ 737 if (*child_path != '/') |
736 /* XXX TODO: create appropriate error */ 737 return (-1); | 738 return (set_error(lbh, BE_ERR_BADPATH)); |
738 | 739 |
739 strncpy(active, be_active_path(lbh), BE_MAXPATHLEN); | 740 strlcpy(active, be_active_path(lbh), BE_MAXPATHLEN); |
740 strcpy(buf, active); 741 742 /* Create non-mountable parent dataset(s) */ 743 s = child_path; 744 for (char *p; (p = strchr(s+1, '/')) != NULL; s = p) { 745 size_t len = p - s; 746 strncat(buf, s, len); 747 748 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP); 749 nvlist_add_string(props, "canmount", "off"); 750 nvlist_add_string(props, "mountpoint", "none"); 751 zfs_create(lbh->lzh, buf, ZFS_TYPE_DATASET, props); 752 nvlist_free(props); 753 } 754 755 /* Path does not exist as a descendent of / yet */ | 741 strcpy(buf, active); 742 743 /* Create non-mountable parent dataset(s) */ 744 s = child_path; 745 for (char *p; (p = strchr(s+1, '/')) != NULL; s = p) { 746 size_t len = p - s; 747 strncat(buf, s, len); 748 749 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP); 750 nvlist_add_string(props, "canmount", "off"); 751 nvlist_add_string(props, "mountpoint", "none"); 752 zfs_create(lbh->lzh, buf, ZFS_TYPE_DATASET, props); 753 nvlist_free(props); 754 } 755 756 /* Path does not exist as a descendent of / yet */ |
756 pos = strlen(active); | 757 if (strlcat(active, child_path, BE_MAXPATHLEN) >= BE_MAXPATHLEN) 758 return (set_error(lbh, BE_ERR_PATHLEN)); |
757 | 759 |
758 /* XXX TODO: Verify that resulting str is less than BE_MAXPATHLEN */ 759 strncpy(&active[pos], child_path, BE_MAXPATHLEN-pos); 760 | |
761 if (stat(child_path, &sb) != 0) { 762 /* Verify that error is ENOENT */ | 760 if (stat(child_path, &sb) != 0) { 761 /* Verify that error is ENOENT */ |
763 if (errno != 2) 764 /* XXX TODO: create appropriate error */ 765 return (-1); | 762 if (errno != ENOENT) 763 return (set_error(lbh, BE_ERR_NOENT)); |
766 767 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP); 768 nvlist_add_string(props, "canmount", "noauto"); 769 nvlist_add_string(props, "mountpoint", child_path); 770 771 /* Create */ 772 if ((err = 773 zfs_create(lbh->lzh, active, ZFS_TYPE_DATASET, props)) != 0) 774 /* XXX TODO handle error */ | 764 765 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP); 766 nvlist_add_string(props, "canmount", "noauto"); 767 nvlist_add_string(props, "mountpoint", child_path); 768 769 /* Create */ 770 if ((err = 771 zfs_create(lbh->lzh, active, ZFS_TYPE_DATASET, props)) != 0) 772 /* XXX TODO handle error */ |
775 return (-1); | 773 return (set_error(lbh, BE_ERR_UNKNOWN)); |
776 nvlist_free(props); 777 778 if ((zfs = 779 zfs_open(lbh->lzh, active, ZFS_TYPE_DATASET)) == NULL) | 774 nvlist_free(props); 775 776 if ((zfs = 777 zfs_open(lbh->lzh, active, ZFS_TYPE_DATASET)) == NULL) |
780 /* XXX TODO handle error */ 781 return (-1); | 778 return (set_error(lbh, BE_ERR_ZFSOPEN)); |
782 783 /* Set props */ 784 if ((err = zfs_prop_set(zfs, "canmount", "noauto")) != 0) 785 /* TODO handle error */ | 779 780 /* Set props */ 781 if ((err = zfs_prop_set(zfs, "canmount", "noauto")) != 0) 782 /* TODO handle error */ |
786 return (-1); | 783 return (set_error(lbh, BE_ERR_UNKNOWN)); |
787 } else if (cp_if_exists) { 788 /* Path is already a descendent of / and should be copied */ 789 790 /* XXX TODO ? */ 791 792 /* 793 * Establish if the existing path is a zfs dataset or just 794 * the subdirectory of one 795 */ | 784 } else if (cp_if_exists) { 785 /* Path is already a descendent of / and should be copied */ 786 787 /* XXX TODO ? */ 788 789 /* 790 * Establish if the existing path is a zfs dataset or just 791 * the subdirectory of one 792 */ |
793 strlcpy(buf, "/tmp/be_snap.XXXXX", sizeof(buf)); 794 if (mktemp(buf) == NULL) 795 return (set_error(lbh, BE_ERR_UNKNOWN)); |
|
796 | 796 |
797 /* XXX TODO: use mktemp */ 798 snap_name = random(); 799 800 snprintf(buf, BE_MAXPATHLEN, "%s@%ld", child_path, snap_name); 801 | |
802 if ((err = zfs_snapshot(lbh->lzh, buf, false, NULL)) != 0) 803 /* XXX TODO correct error */ | 797 if ((err = zfs_snapshot(lbh->lzh, buf, false, NULL)) != 0) 798 /* XXX TODO correct error */ |
804 return (-1); | 799 return (set_error(lbh, BE_ERR_UNKNOWN)); |
805 806 /* Clone */ 807 if ((zfs = 808 zfs_open(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT)) == NULL) | 800 801 /* Clone */ 802 if ((zfs = 803 zfs_open(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT)) == NULL) |
809 /* XXX TODO correct error */ 810 return (-1); | 804 return (BE_ERR_ZFSOPEN); |
811 812 if ((err = zfs_clone(zfs, active, NULL)) != 0) 813 /* XXX TODO correct error */ | 805 806 if ((err = zfs_clone(zfs, active, NULL)) != 0) 807 /* XXX TODO correct error */ |
814 return (-1); | 808 return (set_error(lbh, BE_ERR_UNKNOWN)); |
815 816 /* set props */ | 809 810 /* set props */ |
811 zfs_close(zfs); |
|
817 } else 818 /* TODO: error code for exists, but not cp? */ | 812 } else 813 /* TODO: error code for exists, but not cp? */ |
819 return (-1); | 814 return (set_error(lbh, BE_ERR_EXISTS)); |
820 821 return (BE_ERR_SUCCESS); 822} 823 824static int 825be_set_nextboot(libbe_handle_t *lbh, nvlist_t *config, uint64_t pool_guid, 826 const char *zfsdev) 827{ --- 75 unchanged lines hidden --- | 815 816 return (BE_ERR_SUCCESS); 817} 818 819static int 820be_set_nextboot(libbe_handle_t *lbh, nvlist_t *config, uint64_t pool_guid, 821 const char *zfsdev) 822{ --- 75 unchanged lines hidden --- |