Esempio n. 1
0
File: lvm.c Progetto: terceiro/lxc
int lvm_snapshot(const char *orig, const char *path, uint64_t size)
{
	int ret;
	char *pathdup, *lv;
	char sz[24];
	char cmd_output[MAXPATHLEN];
	struct lvcreate_args cmd_args = {0};

	ret = snprintf(sz, 24, "%" PRIu64 "b", size);
	if (ret < 0 || ret >= 24) {
		ERROR("Failed to create string");
		return -1;
	}

	pathdup = strdup(path);
	if (!pathdup) {
		ERROR("Failed to duplicate string \"%s\"", path);
		return -1;
	}

	lv = strrchr(pathdup, '/');
	if (!lv) {
		ERROR("Failed to detect \"/\" in string \"%s\"", pathdup);
		free(pathdup);
		return -1;
	}
	*lv = '\0';
	lv++;
	TRACE("Parsed logical volume \"%s\"", lv);

	/* Check if the original logical volume is backed by a thinpool, in
	 * which case we cannot specify a size that's different from the
	 * original size.
	 */
	ret = lvm_is_thin_volume(orig);
	if (ret < 0) {
		free(pathdup);
		return -1;
	} else if (ret) {
		cmd_args.thinpool = orig;
	}

	cmd_args.lv = lv;
	cmd_args.source_lv = orig;
	cmd_args.size = sz;
	TRACE("Creating new lvm snapshot \"%s\" of \"%s\" with size \"%s\"", lv,
	      orig, sz);
	ret = run_command(cmd_output, sizeof(cmd_output),
			  lvm_snapshot_exec_wrapper, (void *)&cmd_args);
	if (ret < 0) {
		ERROR("Failed to create logical volume \"%s\": %s", orig,
		      cmd_output);
		free(pathdup);
		return -1;
	}

	free(pathdup);
	return 0;
}
Esempio n. 2
0
File: lxclvm.c Progetto: 4b42/lxc
int lvm_snapshot(const char *orig, const char *path, uint64_t size)
{
	int ret, pid;
	char sz[24], *pathdup, *lv;

	if ((pid = fork()) < 0) {
		SYSERROR("failed fork");
		return -1;
	}
	if (pid > 0)
		return wait_for_pid(pid);

	// specify bytes to lvcreate
	ret = snprintf(sz, 24, "%"PRIu64"b", size);
	if (ret < 0 || ret >= 24)
		exit(EXIT_FAILURE);

	pathdup = strdup(path);
	if (!pathdup)
		exit(EXIT_FAILURE);
	lv = strrchr(pathdup, '/');
	if (!lv) {
		free(pathdup);
		exit(EXIT_FAILURE);
	}
	*lv = '\0';
	lv++;

	// check if the original lv is backed by a thin pool, in which case we
	// cannot specify a size that's different from the original size.
	ret = lvm_is_thin_volume(orig);
	if (ret == -1) {
		free(pathdup);
		return -1;
	}

	if (!ret) {
		ret = execlp("lvcreate", "lvcreate", "-s", "-L", sz, "-n", lv, orig, (char *)NULL);
	} else {
		ret = execlp("lvcreate", "lvcreate", "-s", "-n", lv, orig, (char *)NULL);
	}

	free(pathdup);
	exit(EXIT_FAILURE);
}