static int cmd_add_dev(int argc, char **argv) { char *mntpnt; int i, fdmnt, ret=0, e; DIR *dirstream = NULL; int discard = 1; int force = 0; while (1) { int c; static const struct option long_options[] = { { "nodiscard", optional_argument, NULL, 'K'}, { "force", no_argument, NULL, 'f'}, { NULL, 0, NULL, 0} }; c = getopt_long(argc, argv, "Kf", long_options, NULL); if (c < 0) break; switch (c) { case 'K': discard = 0; break; case 'f': force = 1; break; default: usage(cmd_add_dev_usage); } } argc = argc - optind; if (check_argc_min(argc, 2)) usage(cmd_add_dev_usage); mntpnt = argv[optind + argc - 1]; fdmnt = open_file_or_dir(mntpnt, &dirstream); if (fdmnt < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", mntpnt); return 1; } for (i = optind; i < optind + argc - 1; i++){ struct btrfs_ioctl_vol_args ioctl_args; int devfd, res; u64 dev_block_count = 0; int mixed = 0; char *path; res = test_dev_for_mkfs(argv[i], force); if (res) { ret++; continue; } devfd = open(argv[i], O_RDWR); if (devfd < 0) { fprintf(stderr, "ERROR: Unable to open device '%s'\n", argv[i]); ret++; continue; } res = btrfs_prepare_device(devfd, argv[i], 1, &dev_block_count, 0, &mixed, discard); close(devfd); if (res) { ret++; goto error_out; } path = canonicalize_path(argv[i]); if (!path) { fprintf(stderr, "ERROR: Could not canonicalize pathname '%s': %s\n", argv[i], strerror(errno)); ret++; goto error_out; } memset(&ioctl_args, 0, sizeof(ioctl_args)); strncpy_null(ioctl_args.name, path); res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV, &ioctl_args); e = errno; if (res < 0) { fprintf(stderr, "ERROR: error adding the device '%s' - %s\n", path, strerror(e)); ret++; } free(path); } error_out: close_file_or_dir(fdmnt, dirstream); return !!ret; }
static int process_snapshot(const char *path, const u8 *uuid, u64 ctransid, const u8 *parent_uuid, u64 parent_ctransid, void *user) { int ret; struct btrfs_receive *r = user; char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; struct btrfs_ioctl_vol_args_v2 args_v2; struct subvol_info *parent_subvol = NULL; ret = finish_subvol(r); if (ret < 0) goto out; r->cur_subvol = calloc(1, sizeof(*r->cur_subvol)); if (strlen(r->dest_dir_path) == 0) r->cur_subvol->path = strdup(path); else r->cur_subvol->path = path_cat(r->dest_dir_path, path); free(r->full_subvol_path); r->full_subvol_path = path_cat3(r->root_path, r->dest_dir_path, path); fprintf(stdout, "At snapshot %s\n", path); memcpy(r->cur_subvol->received_uuid, uuid, BTRFS_UUID_SIZE); r->cur_subvol->stransid = ctransid; if (g_verbose) { uuid_unparse((u8*)r->cur_subvol->received_uuid, uuid_str); fprintf(stderr, "receiving snapshot %s uuid=%s, " "ctransid=%llu ", path, uuid_str, r->cur_subvol->stransid); uuid_unparse(parent_uuid, uuid_str); fprintf(stderr, "parent_uuid=%s, parent_ctransid=%llu\n", uuid_str, parent_ctransid); } memset(&args_v2, 0, sizeof(args_v2)); strncpy_null(args_v2.name, path); parent_subvol = subvol_uuid_search(&r->sus, 0, parent_uuid, parent_ctransid, NULL, subvol_search_by_received_uuid); if (!parent_subvol) { parent_subvol = subvol_uuid_search(&r->sus, 0, parent_uuid, parent_ctransid, NULL, subvol_search_by_uuid); } if (!parent_subvol) { ret = -ENOENT; fprintf(stderr, "ERROR: could not find parent subvolume\n"); goto out; } /*if (rs_args.ctransid > rs_args.rtransid) { if (!r->force) { ret = -EINVAL; fprintf(stderr, "ERROR: subvolume %s was modified after it was received.\n", r->subvol_parent_name); goto out; } else { fprintf(stderr, "WARNING: subvolume %s was modified after it was received.\n", r->subvol_parent_name); } }*/ args_v2.fd = openat(r->mnt_fd, parent_subvol->path, O_RDONLY | O_NOATIME); if (args_v2.fd < 0) { ret = -errno; if (errno != ENOENT) fprintf(stderr, "ERROR: open %s failed. %s\n", parent_subvol->path, strerror(-ret)); else fprintf(stderr, "It seems that you have changed your default " "subvolume or you specify other subvolume to\n" "mount btrfs, try to remount this btrfs filesystem " "with fs tree, and run btrfs receive again!\n"); goto out; } ret = ioctl(r->dest_dir_fd, BTRFS_IOC_SNAP_CREATE_V2, &args_v2); close(args_v2.fd); if (ret < 0) { ret = -errno; fprintf(stderr, "ERROR: creating snapshot %s -> %s " "failed. %s\n", parent_subvol->path, path, strerror(-ret)); goto out; } out: if (parent_subvol) { free(parent_subvol->path); free(parent_subvol); } return ret; }