示例#1
0
文件: lxclvm.c 项目: 4b42/lxc
    /*
     * path must be '/dev/$vg/$lv', $vg must be an existing VG, and $lv must not
     * yet exist.  This function will attempt to create /dev/$vg/$lv of size
     * $size. If thinpool is specified, we'll check for it's existence and if
     * it's
     * a valid thin pool, and if so, we'll create the requested lv from that
     * thin
     * pool.
     */
    static int do_lvm_create(const char *path, uint64_t size,
			     const char *thinpool)
{
	int ret, pid, len;
	char sz[24], *pathdup, *vg, *lv, *tp = NULL;

	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)
		exit(EXIT_FAILURE);

	*lv = '\0';
	lv++;

	vg = strrchr(pathdup, '/');
	if (!vg)
		exit(EXIT_FAILURE);
	vg++;

	if (thinpool) {
		len = strlen(pathdup) + strlen(thinpool) + 2;
		tp = alloca(len);

		ret = snprintf(tp, len, "%s/%s", pathdup, thinpool);
		if (ret < 0 || ret >= len)
			exit(EXIT_FAILURE);

		ret = lvm_is_thin_pool(tp);
		INFO("got %d for thin pool at path: %s", ret, tp);
		if (ret < 0)
			exit(EXIT_FAILURE);

		if (!ret)
			tp = NULL;
	}

	if (!tp)
	    execlp("lvcreate", "lvcreate", "-L", sz, vg, "-n", lv, (char *)NULL);
	else
	    execlp("lvcreate", "lvcreate", "--thinpool", tp, "-V", sz, vg, "-n", lv, (char *)NULL);

	SYSERROR("execlp");
	exit(EXIT_FAILURE);
}
示例#2
0
文件: lvm.c 项目: terceiro/lxc
/* The path must be "/dev/<vg>/<lv>". The volume group <vg> must be an existing
 * volume group, and the logical volume <lv> must not yet exist.
 * This function will attempt to create "/dev/<vg>/<lv> of size <size>. If
 * thinpool is specified, we'll check for it's existence and if it's a valid
 * thin pool, and if so, we'll create the requested logical volume from that
 * thin pool.
 */
static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
{
	int len, ret;
	char *pathdup, *vg, *lv;
	char cmd_output[MAXPATHLEN];
	char sz[24];
	char *tp = NULL;
	struct lvcreate_args cmd_args = {0};

	ret = snprintf(sz, 24, "%" PRIu64 "b", size);
	if (ret < 0 || ret >= 24) {
		ERROR("Failed to create string: %d", ret);
		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);

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

	if (thinpool) {
		len = strlen(pathdup) + strlen(thinpool) + 2;
		tp = alloca(len);

		ret = snprintf(tp, len, "%s/%s", pathdup, thinpool);
		if (ret < 0 || ret >= len) {
			ERROR("Failed to create string: %d", ret);
			free(pathdup);
			return -1;
		}

		ret = lvm_is_thin_pool(tp);
		TRACE("got %d for thin pool at path: %s", ret, tp);
		if (ret < 0) {
			ERROR("Failed to detect whether \"%s\" is a thinpool", tp);
			free(pathdup);
			return -1;
		} else if (!ret) {
			TRACE("Detected that \"%s\" is not a thinpool", tp);
			tp = NULL;
		} else {
			TRACE("Detected \"%s\" is a thinpool", tp);
		}
	}

	cmd_args.thinpool = tp;
	cmd_args.vg = vg;
	cmd_args.lv = lv;
	cmd_args.size = sz;
	TRACE("Creating new lvm storage volume \"%s\" on volume group \"%s\" "
	      "of size \"%s\"", lv, vg, sz);
	ret = run_command(cmd_output, sizeof(cmd_output),
			  lvm_create_exec_wrapper, (void *)&cmd_args);
	if (ret < 0) {
		ERROR("Failed to create logical volume \"%s\": %s", lv,
		      cmd_output);
		free(pathdup);
		return -1;
	}
	TRACE("Created new lvm storage volume \"%s\" on volume group \"%s\" "
	      "of size \"%s\"", lv, vg, sz);

	free(pathdup);
	return ret;
}