Commit 055af165 by Sidnei da Silva Committed by Serge Hallyn

Assume a default thin pool named 'lxc'.

Will fallback to no thinpool if not present or if thin pool provided on the command line does not exist. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent 07520b2a
......@@ -145,7 +145,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
rather than the default, <filename>lxc</filename>.
<replaceable>--thinpool thinpool1</replaceable> will create the
LV as a thin-provisioned volume in the pool named
<filename>thinpool1</filename>.
<filename>thinpool1</filename> rather than the
default, <filename>lxc</filename>.
<replaceable>--fstype FSTYPE</replaceable> will create an FSTYPE
filesystem on the LV, rather than the default, which is ext4.
<replaceable>--fssize SIZE</replaceable> will create a LV (and
......
......@@ -811,54 +811,7 @@ static int lvm_umount(struct bdev *bdev)
return umount(bdev->dest);
}
/*
* 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.
*/
static int do_lvm_create(const char *path, unsigned long size, const char *thinpool)
{
int ret, pid;
char sz[24], *pathdup, *vg, *lv;
if ((pid = fork()) < 0) {
SYSERROR("failed fork");
return -1;
}
if (pid > 0)
return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
// lvcreate default size is in M, not bytes.
ret = snprintf(sz, 24, "%lu", size/1000000);
if (ret < 0 || ret >= 24)
exit(1);
pathdup = strdup(path);
if (!pathdup)
exit(1);
lv = strrchr(pathdup, '/');
if (!lv) {
free(pathdup);
exit(1);
}
*lv = '\0';
lv++;
vg = strrchr(pathdup, '/');
if (!vg)
exit(1);
vg++;
if (!thinpool) {
execlp("lvcreate", "lvcreate", "-L", sz, vg, "-n", lv, (char *)NULL);
} else {
execlp("lvcreate", "lvcreate", "--thinpool", thinpool, "-V", sz, vg, "-n", lv, (char *)NULL);
}
free(pathdup);
exit(1);
}
static int lvm_is_thin_volume(const char *path)
{
static int lvm_compare_lv_attr(const char *path, int pos, const char expected) {
FILE *f;
int ret, len, start=0;
char *cmd, output[12];
......@@ -899,12 +852,93 @@ static int lvm_is_thin_volume(const char *path)
len = strlen(output);
while(start < len && output[start] == ' ') start++;
if (start + 6 < len && output[start + 6] == 't')
if (start + pos < len && output[start + pos] == expected)
return 1;
return 0;
}
static int lvm_is_thin_volume(const char *path)
{
return lvm_compare_lv_attr(path, 6, 't');
}
static int lvm_is_thin_pool(const char *path)
{
return lvm_compare_lv_attr(path, 0, 't');
}
/*
* 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, unsigned long size, const char *thinpool)
{
int ret, pid, len;
char sz[24], *pathdup, *vg, *lv, *tp;
if ((pid = fork()) < 0) {
SYSERROR("failed fork");
return -1;
}
if (pid > 0)
return wait_for_pid(pid);
process_unlock(); // we're no longer sharing
// lvcreate default size is in M, not bytes.
ret = snprintf(sz, 24, "%lu", size/1000000);
if (ret < 0 || ret >= 24)
exit(1);
pathdup = strdup(path);
if (!pathdup)
exit(1);
lv = strrchr(pathdup, '/');
if (!lv) {
free(pathdup);
exit(1);
}
*lv = '\0';
lv++;
vg = strrchr(pathdup, '/');
if (!vg)
exit(1);
vg++;
if (thinpool) {
len = strlen(pathdup) + strlen(thinpool) + 2;
tp = alloca(len);
INFO("checking for thin pool at path: %s", tp);
ret = snprintf(tp, len, "%s/%s", pathdup, thinpool);
if (ret < 0 || ret >= len)
return -1;
ret = lvm_is_thin_pool(tp);
INFO("got %d for thin pool at path: %s", ret, tp);
if (ret < 0)
return ret;
if (!ret)
thinpool = NULL;
}
if (!thinpool) {
execlp("lvcreate", "lvcreate", "-L", sz, vg, "-n", lv, (char *)NULL);
} else {
execlp("lvcreate", "lvcreate", "--thinpool", thinpool, "-V", sz, vg, "-n", lv, (char *)NULL);
}
free(pathdup);
exit(1);
}
static int lvm_snapshot(const char *orig, const char *path, unsigned long size)
{
int ret, pid;
......@@ -1028,7 +1062,7 @@ static int lvm_clonepaths(struct bdev *orig, struct bdev *new, const char *oldna
return -1;
}
} else {
if (do_lvm_create(new->src, size, NULL) < 0) {
if (do_lvm_create(new->src, size, default_lvm_thin_pool()) < 0) {
ERROR("Error creating new lvm blockdev");
return -1;
}
......@@ -1073,6 +1107,8 @@ static int lvm_create(struct bdev *bdev, const char *dest, const char *n,
vg = default_lvm_vg();
thinpool = specs->u.lvm.thinpool;
if (!thinpool)
thinpool = default_lvm_thin_pool();
/* /dev/$vg/$lv */
if (specs->u.lvm.lv)
......@@ -1091,7 +1127,6 @@ static int lvm_create(struct bdev *bdev, const char *dest, const char *n,
if (!sz)
sz = DEFAULT_FS_SIZE;
INFO("Error creating new lvm blockdev %s size %lu", bdev->src, sz);
if (do_lvm_create(bdev->src, sz, thinpool) < 0) {
ERROR("Error creating new lvm blockdev %s size %lu", bdev->src, sz);
return -1;
......
......@@ -132,7 +132,7 @@ Options :\n\
--vgname=VG Use LVM vg called VG\n\
(Default: lxc))\n\
--thinpool=TP Use LVM thin pool called TP\n\
(Default: none))\n\
(Default: lxc))\n\
--fstype=TYPE Create fstype TYPE\n\
(Default: ext3))\n\
--fssize=SIZE Create filesystem of size SIZE\n\
......
......@@ -237,13 +237,14 @@ static char *copy_global_config_value(char *p)
}
#define DEFAULT_VG "lxc"
#define DEFAULT_THIN_POOL "lxc"
#define DEFAULT_ZFSROOT "lxc"
const char *lxc_global_config_value(const char *option_name)
{
static const char *options[][2] = {
{ "lvm_vg", DEFAULT_VG },
{ "lvm_thin_pool", NULL },
{ "lvm_thin_pool", DEFAULT_THIN_POOL },
{ "zfsroot", DEFAULT_ZFSROOT },
{ "lxcpath", LXCPATH },
{ "cgroup.pattern", DEFAULT_CGROUP_PATTERN },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment