static int fill_opts(void) { static char _device[PATH_MAX]; static char _mount_point[PATH_MAX]; if (device && mount_point) return 0; if (disk_descriptor) { int ret; struct ploop_disk_images_data *di; ret = read_dd(&di, disk_descriptor); if (ret) return ret; ret = ploop_get_dev(di, _device, sizeof(_device)); ploop_free_diskdescriptor(di); if (ret < 0) return SYSEXIT_PARAM; if (ret == 1) { fprintf(stderr, "The image is not mounted\n"); return SYSEXIT_PARAM; } device = _device; } if (!device && mount_point) { if (ploop_get_dev_by_mnt(mount_point, _device, sizeof(_device))) { fprintf(stderr, "Unable to find ploop device by %s\n", mount_point); return SYSEXIT_PARAM; } device = _device; return 0; } if (!mount_point && device) { if (ploop_get_mnt_by_dev(device, _mount_point, sizeof(_mount_point))) { fprintf(stderr, "Unable to find mount point for %s\n", device); return SYSEXIT_PARAM; } mount_point = _mount_point; return 0; } fprintf(stderr, "Error: one of -d, -m or DiskDescriptor.xml argument is required\n"); return 1; }
static int plooptool_umount(int argc, char **argv) { int i, ret; char *mnt = NULL; char device[PATH_MAX]; struct { char * device; } umountopts = { }; const char *component_name = NULL; while ((i = getopt(argc, argv, "d:m:c:")) != EOF) { switch (i) { case 'd': umountopts.device = optarg; break; case 'm': mnt = optarg; break; case 'c': component_name = optarg; break; default: usage_umount(); return SYSEXIT_PARAM; } } argc -= optind; argv += optind; if (argc != 1 && !umountopts.device && !mnt) { usage_umount(); return SYSEXIT_PARAM; } if (umountopts.device != NULL) { int len = strlen(umountopts.device); /* if partition is provided, strip it */ if (strcmp(umountopts.device + len - 2, "p1") == 0 && isdigit(umountopts.device[len - 3])) umountopts.device[len - 2] = '\0'; ret = ploop_umount(umountopts.device, NULL); }else if (mnt != NULL) { if (ploop_get_dev_by_mnt(mnt, device, sizeof(device))) { fprintf(stderr, "Unable to find ploop device by %s\n", mnt); return SYSEXIT_PARAM; } ret = ploop_umount(device, NULL); } else if (is_xml_fname(argv[0])) { struct ploop_disk_images_data *di; ret = ploop_open_dd(&di, argv[0]); if (ret) return ret; if (component_name != NULL) ploop_set_component_name(di, component_name); ret = ploop_umount_image(di); ploop_close_dd(di); } else { if (ploop_find_dev(component_name, argv[0], device, sizeof(device)) != 0) { fprintf(stderr, "Image %s is not mounted\n", argv[0]); return SYSEXIT_PARAM; } ret = ploop_umount(device, NULL); } return ret; }
static int plooptool_replace(int argc, char **argv) { int i; char dev[PATH_MAX]; char *device = NULL; char *mnt = NULL; struct ploop_replace_param param = { .level = -1, }; while ((i = getopt(argc, argv, "d:m:l:i:u:o:")) != EOF) { switch (i) { case 'd': device = optarg; break; case 'm': mnt = optarg; break; case 'l': param.level = atoi(optarg); break; case 'u': param.guid = parse_uuid(optarg); if (!param.guid) return SYSEXIT_PARAM; break; case 'i': param.file = strdup(optarg); break; case 'o': param.cur_file = strdup(optarg); break; default: usage_replace(); return SYSEXIT_PARAM; } } argc -= optind; argv += optind; if (!param.file) { fprintf(stderr, "Error: image file not specified (use -i)\n"); usage_replace(); return SYSEXIT_PARAM; } if ((argc == 1) && is_xml_fname(argv[0])) { int ret; struct ploop_disk_images_data *di; /* only one way of choosing delta to replace */ if ( (!!param.guid) + (param.level != -1) + (!!param.cur_file) != 1) { fprintf(stderr, "Error: either one of uuid (-u), " "level (-l) or current file (-o) " "must be specified\n"); usage_replace(); return SYSEXIT_PARAM; } ret = ploop_open_dd(&di, argv[0]); if (ret) return ret; ret = ploop_replace_image(di, ¶m); ploop_close_dd(di); return ret; } else { int level = param.level; if (argc > 0) { usage_replace(); return SYSEXIT_PARAM; } if ((!!device) + (!!mnt) != 1) { fprintf(stderr, "Error: either device (-d), mount " "point (-m) or DiskDescriptor.xml " "must be specified\n"); usage_replace(); return SYSEXIT_PARAM; } if (mnt) { if (ploop_get_dev_by_mnt(mnt, dev, sizeof(dev))) { fprintf(stderr, "Unable to find ploop device " "by mount point %s\n", mnt); return SYSEXIT_PARAM; } device = dev; } /* Either level or current delta must be specified */ if ((level != -1) + (!!param.cur_file) != 1) { fprintf(stderr, "Error: either one of level (-l) or " "current delta file (-o) must be " "specified\n"); usage_replace(); return SYSEXIT_PARAM; } if (param.cur_file) { int ret; level = find_level_by_delta(device, param.cur_file); if (level < 0) { fprintf(stderr, "Can't find level by " "delta file name %s", param.cur_file); return SYSEXIT_PARAM; } ret = check_deltas_same(param.cur_file, param.file); if (ret) return ret; } return replace_delta(device, level, param.file); } } int main(int argc, char **argv) { char * cmd; int v = 3; /* global options */ while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { case 'v': switch (argv[1][2]) { case '\0': v++; break; case 'v': /* -vvv... */ v += strlen(&argv[1][1]); break; default: /* -vNN */ v = atoi(&argv[1][2]); } break; case '-': /* long option */ /* fall through */ default: fprintf(stderr, "Bad option %s\n", argv[1]); usage_summary(); return SYSEXIT_PARAM; } argc--; argv++; } if (argc < 2) { usage_summary(); return SYSEXIT_PARAM; } cmd = argv[1]; argc--; argv++; ploop_set_verbose_level(v); init_signals(); if (strcmp(cmd, "init") == 0) return plooptool_init(argc, argv); if (strcmp(cmd, "start") == 0) return plooptool_start(argc, argv); if (strcmp(cmd, "stop") == 0) return plooptool_stop(argc, argv); if (strcmp(cmd, "clear") == 0) return plooptool_clear(argc, argv); if (strcmp(cmd, "mount") == 0) return plooptool_mount(argc, argv); if (strcmp(cmd, "umount") == 0) return plooptool_umount(argc, argv); if (strcmp(cmd, "delete") == 0 || strcmp(cmd, "rm") == 0) return plooptool_rm(argc, argv); if (strcmp(cmd, "snapshot") == 0) return plooptool_snapshot(argc, argv); if (strcmp(cmd, "tsnapshot") == 0) return plooptool_tsnapshot(argc, argv); if (strcmp(cmd, "snapshot-switch") == 0) return plooptool_snapshot_switch(argc, argv); if (strcmp(cmd, "snapshot-delete") == 0) return plooptool_snapshot_delete(argc, argv); if (strcmp(cmd, "snapshot-merge") == 0) return plooptool_snapshot_merge(argc, argv); if (strcmp(cmd, "snapshot-list") == 0) return plooptool_snapshot_list(argc, argv); if (strcmp(cmd, "getdev") == 0) return plooptool_getdevice(argc, argv); if (strcmp(cmd, "resize") == 0) return plooptool_resize(argc, argv); if (strcmp(cmd, "convert") == 0) return plooptool_convert(argc, argv); if (strcmp(cmd, "info") == 0) return plooptool_info(argc, argv); if (strcmp(cmd, "list") == 0) return plooptool_list(argc, argv); if (strcmp(cmd, "check") == 0) return plooptool_check(argc, argv); if (strcmp(cmd, "fsck") == 0) { fprintf(stderr, "WARNING: ploop fsck command is obsoleted, " "please use ploop check\n"); return plooptool_check(argc, argv); } if (strcmp(cmd, "grow") == 0) return plooptool_grow(argc, argv); if (strcmp(cmd, "merge") == 0) return plooptool_merge(argc, argv); if (strcmp(cmd, "stat") == 0) return plooptool_stat(argc, argv); if (strcmp(cmd, "copy") == 0) return plooptool_copy(argc, argv); if (strcmp(cmd, "replace") == 0) return plooptool_replace(argc, argv); if (cmd[0] != '-') { char ** nargs; nargs = calloc(argc+1, sizeof(char*)); nargs[0] = malloc(sizeof("ploop-") + strlen(cmd)); sprintf(nargs[0], "ploop-%s", cmd); memcpy(nargs + 1, argv + 1, (argc - 1)*sizeof(char*)); nargs[argc] = NULL; execvp(nargs[0], nargs); } usage_summary(); return SYSEXIT_PARAM; }