be.c (fc13fc1c3a746fcece4bc17d4ff49d8d29d3e454) be.c (16ac0705815ba661a3c1a693ff3a7562e932fb47)
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

--- 635 unchanged lines hidden (view full) ---

644 return (err);
645}
646
647
648int
649be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
650{
651 char buf[BE_MAXPATHLEN];
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

--- 635 unchanged lines hidden (view full) ---

644 return (err);
645}
646
647
648int
649be_import(libbe_handle_t *lbh, const char *bootenv, int fd)
650{
651 char buf[BE_MAXPATHLEN];
652 time_t rawtime;
653 nvlist_t *props;
654 zfs_handle_t *zfs;
652 nvlist_t *props;
653 zfs_handle_t *zfs;
655 int err, len;
656 char nbuf[24];
654 recvflags_t flags = { .nomount = 1 };
655 int err;
657
656
658 /*
659 * We don't need this to be incredibly random, just unique enough that
660 * it won't conflict with an existing dataset name. Chopping time
661 * down to 32 bits is probably good enough for this.
662 */
663 snprintf(nbuf, 24, "tmp%u",
664 (uint32_t)(time(NULL) & 0xFFFFFFFF));
665 if ((err = be_root_concat(lbh, nbuf, buf)) != 0)
666 /*
667 * Technically this is our problem, but we try to use short
668 * enough names that we won't run into problems except in
669 * worst-case BE root approaching MAXPATHLEN.
670 */
671 return (set_error(lbh, BE_ERR_PATHLEN));
657 be_root_concat(lbh, bootenv, buf);
672
658
673 time(&rawtime);
674 len = strlen(buf);
675 strftime(buf + len, sizeof(buf) - len, "@%F-%T", localtime(&rawtime));
676
677 if ((err = lzc_receive(buf, NULL, NULL, false, fd)) != 0) {
659 if ((err = zfs_receive(lbh->lzh, buf, NULL, &flags, fd, NULL)) != 0) {
678 switch (err) {
679 case EINVAL:
680 return (set_error(lbh, BE_ERR_NOORIGIN));
681 case ENOENT:
682 return (set_error(lbh, BE_ERR_NOENT));
683 case EIO:
684 return (set_error(lbh, BE_ERR_IO));
685 default:
686 return (set_error(lbh, BE_ERR_UNKNOWN));
687 }
688 }
689
660 switch (err) {
661 case EINVAL:
662 return (set_error(lbh, BE_ERR_NOORIGIN));
663 case ENOENT:
664 return (set_error(lbh, BE_ERR_NOENT));
665 case EIO:
666 return (set_error(lbh, BE_ERR_IO));
667 default:
668 return (set_error(lbh, BE_ERR_UNKNOWN));
669 }
670 }
671
690 if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_SNAPSHOT)) == NULL)
672 if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_FILESYSTEM)) == NULL)
691 return (set_error(lbh, BE_ERR_ZFSOPEN));
692
693 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
694 nvlist_add_string(props, "canmount", "noauto");
695 nvlist_add_string(props, "mountpoint", "/");
696
673 return (set_error(lbh, BE_ERR_ZFSOPEN));
674
675 nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
676 nvlist_add_string(props, "canmount", "noauto");
677 nvlist_add_string(props, "mountpoint", "/");
678
697 be_root_concat(lbh, bootenv, buf);
698
699 err = zfs_clone(zfs, buf, props);
700 zfs_close(zfs);
679 err = zfs_prop_set_list(zfs, props);
701 nvlist_free(props);
702
680 nvlist_free(props);
681
703 if (err != 0)
704 return (set_error(lbh, BE_ERR_UNKNOWN));
705
706 /*
707 * Finally, we open up the dataset we just cloned the snapshot so that
708 * we may promote it. This is necessary in order to clean up the ghost
709 * snapshot that doesn't need to be seen after the operation is
710 * complete.
711 */
712 if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL)
713 return (set_error(lbh, BE_ERR_ZFSOPEN));
714
715 err = zfs_promote(zfs);
716 zfs_close(zfs);
717
718 if (err != 0)
719 return (set_error(lbh, BE_ERR_UNKNOWN));
720
682 zfs_close(zfs);
683
684 if (err != 0)
685 return (set_error(lbh, BE_ERR_UNKNOWN));
686
721 /* Clean up the temporary snapshot */
722 return (be_destroy(lbh, nbuf, 0));
687 return (0);
723}
724
725#if SOON
726static int
727be_create_child_noent(libbe_handle_t *lbh, const char *active,
728 const char *child_path)
729{
730 nvlist_t *props;

--- 254 unchanged lines hidden ---
688}
689
690#if SOON
691static int
692be_create_child_noent(libbe_handle_t *lbh, const char *active,
693 const char *child_path)
694{
695 nvlist_t *props;

--- 254 unchanged lines hidden ---