{
// use the 'zfs list | grep opath' entry to get the zfsroot
char output[MAXPATHLEN], option[MAXPATHLEN], *p;
+ const char *zfsroot = output;
int ret;
pid_t pid;
- if (!zfs_list_entry(opath, output))
- // default is tank. I'd prefer lxc, but apparently this is
- // tradition.
- sprintf(output, "tank");
-
- if ((p = index(output, ' ')) == NULL)
- return -1;
- *p = '\0';
- if ((p = rindex(output, '/')) == NULL)
- return -1;
- *p = '\0';
+ if (zfs_list_entry(opath, output)) {
+ // zfsroot is output up to ' '
+ if ((p = index(output, ' ')) == NULL)
+ return -1;
+ *p = '\0';
+ if ((p = rindex(output, '/')) == NULL)
+ return -1;
+ *p = '\0';
+ } else
+ zfsroot = default_zfs_root();
ret = snprintf(option, MAXPATHLEN, "-omountpoint=%s/%s/rootfs",
lxcpath, nname);
if (ret < 0 || ret >= MAXPATHLEN)
return -1;
- // zfsroot is output up to ' '
// zfs create -omountpoint=$lxcpath/$lxcname $zfsroot/$nname
if (!snapshot) {
if ((pid = fork()) < 0)
return -1;
if (!pid) {
char dev[MAXPATHLEN];
- ret = snprintf(dev, MAXPATHLEN, "%s/%s", output, nname);
+ ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, nname);
if (ret < 0 || ret >= MAXPATHLEN)
exit(1);
execlp("zfs", "zfs", "create", option, dev, NULL);
// zfs clone zfsroot/oname@nname zfsroot/nname
char path1[MAXPATHLEN], path2[MAXPATHLEN];
- ret = snprintf(path1, MAXPATHLEN, "%s/%s@%s", output,
+ ret = snprintf(path1, MAXPATHLEN, "%s/%s@%s", zfsroot,
oname, nname);
if (ret < 0 || ret >= MAXPATHLEN)
return -1;
- (void) snprintf(path2, MAXPATHLEN, "%s/%s", output, nname);
+ (void) snprintf(path2, MAXPATHLEN, "%s/%s", zfsroot, nname);
// if the snapshot exists, delete it
if ((pid = fork()) < 0)
return -1;
if (strcmp(orig->type, "lvm")) {
+ const char *vg;
+
if (snap) {
ERROR("LVM snapshot from %s backing store is not supported",
orig->type);
return -1;
}
- // Use VG 'lxc' by default
- // We will want to support custom VGs, at least as specified through
- // /etc/lxc/lxc.conf, preferably also over cmdline
- len = strlen("/dev/lxc/") + strlen(cname) + 1;
+ vg = default_lvm_vg();
+ len = strlen("/dev/") + strlen(vg) + strlen(cname) + 2;
if ((new->src = malloc(len)) == NULL)
return -1;
- ret = snprintf(new->src, len, "/dev/lxc/%s", cname);
+ ret = snprintf(new->src, len, "/dev/%s/%s", vg, cname);
if (ret < 0 || ret >= len)
return -1;
} else {
}
char *default_lxcpath;
+#define DEFAULT_VG "lxc"
+char *default_lvmvg;
+#define DEFAULT_ZFSROOT "lxc"
+char *default_zfsroot;
+const char *default_lvm_vg(void)
+{
+ char buf[1024], *p;
+ FILE *fin;
+
+ if (default_lvmvg)
+ return default_lvmvg;
+
+ fin = fopen(LXC_GLOBAL_CONF, "r");
+ if (fin) {
+ while (fgets(buf, 1024, fin)) {
+ if (buf[0] == '#')
+ continue;
+ p = strstr(buf, "lvm_vg");
+ if (!p)
+ continue;
+ p = strchr(p, '=');
+ if (!p)
+ continue;
+ p++;
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+ if (!*p)
+ continue;
+ default_lvmvg = copypath(p);
+ goto out;
+ }
+ }
+ default_lvmvg = DEFAULT_VG;
+
+out:
+ if (fin)
+ fclose(fin);
+ return default_lvmvg;
+}
+
+const char *default_zfs_root(void)
+{
+ char buf[1024], *p;
+ FILE *fin;
+
+ if (default_zfsroot)
+ return default_zfsroot;
+
+ fin = fopen(LXC_GLOBAL_CONF, "r");
+ if (fin) {
+ while (fgets(buf, 1024, fin)) {
+ if (buf[0] == '#')
+ continue;
+ p = strstr(buf, "zfsroot");
+ if (!p)
+ continue;
+ p = strchr(p, '=');
+ if (!p)
+ continue;
+ p++;
+ while (*p && (*p == ' ' || *p == '\t')) p++;
+ if (!*p)
+ continue;
+ default_zfsroot = copypath(p);
+ goto out;
+ }
+ }
+ default_zfsroot = DEFAULT_ZFSROOT;
+
+out:
+ if (fin)
+ fclose(fin);
+ return default_zfsroot;
+}
const char *default_lxc_path(void)
{
char buf[1024], *p;