Example #1
0
static int plooptool_resize(int argc, char **argv)
{
	int i, ret;
	off_t new_size = 0; /* in sectors */
	int max_balloon_size = 0; /* make balloon file of max possible size */
	struct ploop_resize_param param = {
		.size		= 0,
		.offline_resize	= 1,
	};
	struct ploop_disk_images_data *di;

	while ((i = getopt(argc, argv, "s:b")) != EOF) {
		switch (i) {
		case 's':
			if (parse_size(optarg, &new_size, "-s")) {
				usage_resize();
				return SYSEXIT_PARAM;
			}
			param.size = new_size;
			break;
		case 'b':
			max_balloon_size = 1;
			break;
		default:
			usage_resize();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1 ||
			(new_size == 0 && !max_balloon_size) ||
			!is_xml_fname(argv[0]))
	{
		usage_resize();
		return SYSEXIT_PARAM;
	}

	ret = ploop_open_dd(&di, argv[0]);
	if (ret)
		return ret;

	ret = ploop_resize_image(di, &param);

	ploop_close_dd(di);

	return ret;
}

static void usage_convert(void)
{
	fprintf(stderr, "Usage: ploop convert {-f FORMAT | -v VERSION} DiskDescriptor.xml\n"
			"       FORMAT := { raw | preallocated }\n"
			"       VERSION := { 1 | 2 }\n"
			);
}
Example #2
0
int ploop_read_disk_descr(struct ploop_disk_images_data **di, const char *file)
{
	int ret;

	ret = ploop_open_dd(di, file);
	if (ret)
		return ret;

	return ploop_read_dd(*di);
}
Example #3
0
static int plooptool_snapshot(int argc, char **argv)
{
	int i, ret;
	char *device = NULL;
	int syncfs = 0;
	struct ploop_snapshot_param param = {};

	while ((i = getopt(argc, argv, "Fd:u:")) != EOF) {
		switch (i) {
		case 'd':
			device = optarg;
			break;
		case 'F':
			syncfs = 1;
			break;
		case 'u':
			param.guid = parse_uuid(optarg);
			if (!param.guid)
				return SYSEXIT_PARAM;
			break;
		default:
			usage_snapshot();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage_snapshot();
		return SYSEXIT_PARAM;
	}

	if (is_xml_fname(argv[0])) {
		struct ploop_disk_images_data *di;
		ret = ploop_open_dd(&di, argv[0]);
		if (ret)
			return ret;

		ret = ploop_create_snapshot(di, &param);

		ploop_close_dd(di);
	} else {
		if (!device) {
			usage_snapshot();
			return SYSEXIT_PARAM;
		}
		ret = create_snapshot(device, argv[0], syncfs);
	}

	return ret;
}
Example #4
0
static int plooptool_convert(int argc, char **argv)
{
	int i, ret;
	struct ploop_disk_images_data *di;
	int mode = -1;
	int version = -1;

	while ((i = getopt(argc, argv, "f:v:")) != EOF) {
		switch (i) {
		case 'f':
			mode = parse_format_opt(optarg);
			break;
		case 'v':
			version = parse_version_opt(optarg);
			if (version < 0) {
				 usage_convert();
				 return SYSEXIT_PARAM;
			}
			break;
		default:
			usage_convert();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0 ||
		(mode == -1 && version == -1) ||
		(mode != -1 && version != -1))
	{
		usage_convert();
		return SYSEXIT_PARAM;
	}

	ret = ploop_open_dd(&di, argv[0]);
	if (ret)
		return ret;
	if (mode != -1)
		ret = ploop_convert_image(di, mode, 0);
	else if (version != -1)
		ret = ploop_change_fmt_version(di, version, 0);

	ploop_close_dd(di);

	return ret;
}
Example #5
0
static int plooptool_snapshot_merge(int argc, char ** argv)
{
	int i, ret;
	struct ploop_merge_param param = {};

	while ((i = getopt(argc, argv, "u:A")) != EOF) {
		switch (i) {
		case 'u':
			param.guid = parse_uuid(optarg);
			if (!param.guid)
				return SYSEXIT_PARAM;
			break;
		case 'A':
			param.merge_all = 1;
			break;
		default:
			usage_snapshot_merge();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (param.guid != NULL && param.merge_all != 0) {
		fprintf(stderr, "Options -u and -A can't be used together\n");
		usage_snapshot_merge();
		return SYSEXIT_PARAM;
	}

	if (argc == 1 && is_xml_fname(argv[0])) {
		struct ploop_disk_images_data *di;
		ret = ploop_open_dd(&di, argv[0]);
		if (ret)
			return ret;

		ret = ploop_merge_snapshot(di, &param);

		ploop_close_dd(di);
	} else {
		usage_snapshot_merge();
		return SYSEXIT_PARAM;
	}

	return ret;
}
Example #6
0
static int plooptool_tsnapshot(int argc, char **argv)
{
	int i, ret;
	struct ploop_disk_images_data *di;
	struct ploop_tsnapshot_param param = {};

	while ((i = getopt(argc, argv, "u:c:m:")) != EOF) {
		switch (i) {
		case 'u':
			param.guid = parse_uuid(optarg);
			if (!param.guid)
				return SYSEXIT_PARAM;
			break;
		case 'c':
			param.component_name = optarg;
			break;
		case 'm':
			param.target = optarg;
			break;
		default:
			usage_snapshot();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1 || !is_xml_fname(argv[0]) ||
			param.guid == NULL ||
			param.component_name == NULL) {
		usage_tsnapshot();
		return SYSEXIT_PARAM;
	}

	ret = ploop_open_dd(&di, argv[0]);
	if (ret)
		return ret;

	ret = ploop_create_temporary_snapshot(di, &param, NULL);

	ploop_close_dd(di);

	return ret;
}
Example #7
0
static int plooptool_snapshot_switch(int argc, char **argv)
{
	int i, ret;
	char *uuid = NULL;
	int flags = 0;
	struct ploop_disk_images_data *di = NULL;

	while ((i = getopt(argc, argv, "u:D")) != EOF) {
		switch (i) {
		case 'u':
			uuid = parse_uuid(optarg);
			if (!uuid)
				return SYSEXIT_PARAM;
			break;
		case 'D':
			/* for test purposes */
			flags = PLOOP_SNAP_SKIP_TOPDELTA_DESTROY;
			break;
		default:
			usage_snapshot_switch();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if ((argc != 1 && !is_xml_fname(argv[0])) || uuid == NULL) {
		usage_snapshot_switch();
		return SYSEXIT_PARAM;
	}

	ret = ploop_open_dd(&di, argv[0]);
	if (ret)
		return ret;

	ret = ploop_switch_snapshot(di, uuid, flags);

	ploop_close_dd(di);

	return ret;
}
Example #8
0
static int plooptool_snapshot_delete(int argc, char **argv)
{
	int i, ret;
	char *uuid = NULL;
	struct ploop_disk_images_data *di = NULL;

	while ((i = getopt(argc, argv, "u:")) != EOF) {
		switch (i) {
		case 'u':
			uuid = parse_uuid(optarg);
			if (!uuid)
				return SYSEXIT_PARAM;
			break;
		default:
			usage_snapshot_delete();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1 || !is_xml_fname(argv[0]) || uuid == NULL) {
		usage_snapshot_delete();
		return SYSEXIT_PARAM;
	}

	ret = ploop_open_dd(&di, argv[0]);
	if (ret)
		return ret;

	ret = ploop_delete_snapshot(di, uuid);

	ploop_close_dd(di);

	return ret;
}
Example #9
0
static
int ploop_get_spec_path(const char *dd_path, struct ploop_spec *spec)
{
	struct ploop_disk_images_data *di;
	int rc;

	if ((rc = ploop_open_dd(&di, dd_path))) {
		rc = putErr(MIG_ERR_PLOOP, "ploop_read_diskdescriptor(%s) : %s [%d]",
				dd_path, ploop_get_last_error(), rc);
		goto cleanup;
	}
	memset((void *)spec, 0, sizeof(*spec));
	if ((rc = ploop_get_spec(di, spec))) {
		rc = putErr(MIG_ERR_PLOOP,
			"ploop_get_spec() : %s [%d]", ploop_get_last_error(), rc);
		goto cleanup;
	}

cleanup:
	if (di != NULL)
		ploop_close_dd(di);

	return rc;
}
Example #10
0
static int plooptool_info(int argc, char **argv)
{
	int ret, i;
	int spec = 0;
	int device = 0;
	struct ploop_info info = {};

	while ((i = getopt(argc, argv, "sd")) != EOF) {
		switch (i) {
		case 's':
			spec = 1;
			break;
		case 'd':
			device = 1;
			break;
		default:
			usage_info();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1 || !is_xml_fname(argv[0])) {
		usage_info();
		return SYSEXIT_PARAM;
	}

	if (spec || device) {
		struct ploop_disk_images_data *di;

		ret = ploop_open_dd(&di, argv[0]);
		if (ret)
			return ret;

		if (spec) {
			struct ploop_spec spec = {};

			ret = ploop_get_spec(di, &spec);
			if (ret)
				goto exit;

			printf("size:\t\t%llu\nblocksize:\t%d\nfmt_version:\t%d\n",
					(unsigned long long)spec.size,
					spec.blocksize,
					spec.fmt_version);
		}

		if (device) {
			char dev[PATH_MAX] = {};

			if (ploop_get_dev(di, dev, sizeof(dev)) == -1) {
				ret = SYSEXIT_SYS;
				goto exit;
			}

			printf("device:\t\t%s\n", dev);
		}

exit:
		ploop_close_dd(di);
	} else {
		ret = ploop_get_info_by_descr(argv[0], &info);
		if (ret == 0)
			print_info(&info);
	}

	return ret;
}
Example #11
0
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;
}
Example #12
0
static int plooptool_mount(int argc, char **argv)
{
	int i, f, ret = 0;
	int raw = 0;
	struct ploop_mount_param mountopts = {};
	const char *component_name = NULL;

	while ((i = getopt(argc, argv, "rFf:d:m:t:u:o:b:c:")) != EOF) {
		switch (i) {
		case 'd':
			strncpy(mountopts.device, optarg, sizeof(mountopts.device)-1);
			break;
		case 'r':
			mountopts.ro = 1;
			break;
		case 'F':
			mountopts.fsck = 1;
			break;
		case 'f':
			f = parse_format_opt(optarg);
			if (f < 0) {
				usage_mount();
				return SYSEXIT_PARAM;
			}
			raw = (f == PLOOP_RAW_MODE);
			break;
		case 'm':
			mountopts.target = strdup(optarg);
			break;
		case 't':
			mountopts.fstype = strdup(optarg);
			break;
		case 'u':
			mountopts.guid = parse_uuid(optarg);
			if (!mountopts.guid)
				return SYSEXIT_PARAM;

			break;
		case 'o':
			mountopts.mount_data = strdup(optarg);
			break;
		case 'b': {
			  char * endptr;

			  mountopts.blocksize = strtoul(optarg, &endptr, 0);
			  if (*endptr != '\0') {
				  usage_mount();
				  return SYSEXIT_PARAM;
			  }
			  break;
		case 'c':
			component_name = optarg;
			break;
		}
		default:
			usage_mount();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1) {
		usage_mount();
		return SYSEXIT_PARAM;
	}

	if (argc == 1 && 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_mount_image(di, &mountopts);

		ploop_close_dd(di);
	}
	else
		ret = ploop_mount(NULL, argv, &mountopts, raw);

	return ret;
}
Example #13
0
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, &param);
		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;
}
Example #14
0
int plooptool_grow(int argc, char **argv)
{
	int i, f;
	off_t new_size = 0; /* in sectors */
	int raw = 0, sparse = 0;
	char *device = NULL;
	static struct option long_opts[] = {
		{ "sparse", no_argument, 0, 'S' },
		{},
	};

	while ((i = getopt_long(argc, argv, "f:d:s:S", long_opts, NULL)) != EOF) {
		switch (i) {
		case 'f':
			f = parse_format_opt(optarg);
			if (f < 0) {
				usage();
				return SYSEXIT_PARAM;
			}
			raw = (f == PLOOP_RAW_MODE);
			break;
		case 'd':
			device = optarg;
			break;
		case 'S':
			sparse = 1;
			break;
		case 's':
			if (parse_size(optarg, &new_size, "-s")) {
				usage();
				return SYSEXIT_PARAM;
			}
			break;
		default:
			usage();
			return SYSEXIT_PARAM;
		}
	}

	argc -= optind;
	argv += optind;

	if (((argc != 0 || !device) && (argc != 1 || device)) ||
	    (raw && device) || (new_size == 0)) {
		usage();
		return SYSEXIT_PARAM;
	}

	if (argc == 1 && is_xml_fname(argv[0]))
	{
		int ret;

		struct ploop_disk_images_data *di;
		ret = ploop_open_dd(&di, argv[0]);
		if (ret)
			return ret;

		ret = ploop_grow_image(di, new_size, sparse);
		ploop_close_dd(di);

		return ret;
	}
	else if (device)
		return ploop_grow_device(device, new_size);
	else if (raw)
		return ploop_grow_raw_delta_offline(argv[0], new_size, sparse);
	else
		return ploop_grow_delta_offline(argv[0], new_size);
}