dir: improve dir backend

parent 0f2e3566
...@@ -4,16 +4,20 @@ ...@@ -4,16 +4,20 @@
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "macro.h"
#include "memory_utils.h"
#include "storage.h" #include "storage.h"
#include "utils.h" #include "utils.h"
lxc_log_define(dir, lxc); lxc_log_define(dir, lxc);
/* For a simple directory bind mount, we substitute the old container name and /*
* For a simple directory bind mount, we substitute the old container name and
* paths for the new. * paths for the new.
*/ */
int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
...@@ -25,33 +29,26 @@ int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, ...@@ -25,33 +29,26 @@ int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
int ret; int ret;
size_t len; size_t len;
if (snap) { if (snap)
ERROR("Directories cannot be snapshotted"); return log_error_errno(-EINVAL, EINVAL, "Directories cannot be snapshotted");
return -1;
}
if (!orig->dest || !orig->src) if (!orig->dest || !orig->src)
return -1; return ret_errno(EINVAL);
len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 4 + 3; len = STRLITERALLEN("dir:") + strlen(lxcpath) + STRLITERALLEN("/") +
strlen(cname) + STRLITERALLEN("/rootfs") + 1;
new->src = malloc(len); new->src = malloc(len);
if (!new->src) { if (!new->src)
ERROR("Failed to allocate memory"); return ret_errno(ENOMEM);
return -1;
}
ret = snprintf(new->src, len, "dir:%s/%s/rootfs", lxcpath, cname); ret = snprintf(new->src, len, "dir:%s/%s/rootfs", lxcpath, cname);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0 || (size_t)ret >= len)
ERROR("Failed to create string"); return ret_errno(EIO);
return -1;
}
src_no_prefix = lxc_storage_get_path(new->src, new->type); src_no_prefix = lxc_storage_get_path(new->src, new->type);
new->dest = strdup(src_no_prefix); new->dest = strdup(src_no_prefix);
if (!new->dest) { if (!new->dest)
ERROR("Failed to duplicate string \"%s\"", new->src); return log_error_errno(-ENOMEM, ENOMEM, "Failed to duplicate string \"%s\"", new->src);
return -1;
}
TRACE("Created new path \"%s\" for dir storage driver", new->dest); TRACE("Created new path \"%s\" for dir storage driver", new->dest);
return 0; return 0;
...@@ -60,42 +57,37 @@ int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, ...@@ -60,42 +57,37 @@ int dir_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
int dir_create(struct lxc_storage *bdev, const char *dest, const char *n, int dir_create(struct lxc_storage *bdev, const char *dest, const char *n,
struct bdev_specs *specs, const struct lxc_conf *conf) struct bdev_specs *specs, const struct lxc_conf *conf)
{ {
__do_free char *bdev_src = NULL, *bdev_dest = NULL;
int ret; int ret;
const char *src; const char *src;
size_t len; size_t len;
/* strlen("dir:") */ len = STRLITERALLEN("dir:");
len = 4;
if (specs && specs->dir) if (specs && specs->dir)
src = specs->dir; src = specs->dir;
else else
src = dest; src = dest;
len += strlen(src) + 1; len += strlen(src) + 1;
bdev->src = malloc(len); bdev_src = malloc(len);
if (!bdev->src) { if (!bdev_src)
ERROR("Failed to allocate memory"); return ret_errno(ENOMEM);
return -1;
}
ret = snprintf(bdev->src, len, "dir:%s", src); ret = snprintf(bdev_src, len, "dir:%s", src);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0 || (size_t)ret >= len)
ERROR("Failed to create string"); return ret_errno(EIO);
return -1;
}
bdev->dest = strdup(dest); bdev_dest = strdup(dest);
if (!bdev->dest) { if (!bdev_dest)
ERROR("Failed to duplicate string \"%s\"", dest); return ret_errno(ENOMEM);
return -1;
}
ret = mkdir_p(dest, 0755); ret = mkdir_p(dest, 0755);
if (ret < 0) { if (ret < 0)
ERROR("Failed to create directory \"%s\"", dest); return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", dest);
return -1;
}
TRACE("Created directory \"%s\"", dest); TRACE("Created directory \"%s\"", dest);
bdev->src = move_ptr(bdev_src);
bdev->dest = move_ptr(bdev_dest);
return 0; return 0;
} }
...@@ -108,10 +100,8 @@ int dir_destroy(struct lxc_storage *orig) ...@@ -108,10 +100,8 @@ int dir_destroy(struct lxc_storage *orig)
src = lxc_storage_get_path(orig->src, orig->src); src = lxc_storage_get_path(orig->src, orig->src);
ret = lxc_rmdir_onedev(src, NULL); ret = lxc_rmdir_onedev(src, NULL);
if (ret < 0) { if (ret < 0)
ERROR("Failed to delete \"%s\"", src); return log_error_errno(ret, errno, "Failed to delete \"%s\"", src);
return -1;
}
return 0; return 0;
} }
...@@ -125,10 +115,8 @@ bool dir_detect(const char *path) ...@@ -125,10 +115,8 @@ bool dir_detect(const char *path)
return true; return true;
ret = stat(path, &statbuf); ret = stat(path, &statbuf);
if (ret == -1 && errno == EPERM) { if (ret == -1 && errno == EPERM)
SYSERROR("dir_detect: failed to look at \"%s\"", path); return log_error_errno(false, errno, "dir_detect: failed to look at \"%s\"", path);
return false;
}
if (ret == 0 && S_ISDIR(statbuf.st_mode)) if (ret == 0 && S_ISDIR(statbuf.st_mode))
return true; return true;
...@@ -150,43 +138,42 @@ int dir_mount(struct lxc_storage *bdev) ...@@ -150,43 +138,42 @@ int dir_mount(struct lxc_storage *bdev)
return -22; return -22;
ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
if (ret < 0) { if (ret < 0)
ERROR("Failed to parse mount options \"%s\"", bdev->mntopts); return log_error_errno(ret, errno, "Failed to parse mount options \"%s\"", bdev->mntopts);
return -EINVAL;
}
ret = parse_propagationopts(bdev->mntopts, &pflags); ret = parse_propagationopts(bdev->mntopts, &pflags);
if (ret < 0) { if (ret < 0)
ERROR("Failed to parse propagation options \"%s\"", bdev->mntopts); return log_error_errno(-EINVAL, EINVAL, "Failed to parse mount propagation options \"%s\"", bdev->mntopts);
return -EINVAL;
}
src = lxc_storage_get_path(bdev->src, bdev->type); src = lxc_storage_get_path(bdev->src, bdev->type);
ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata); ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata);
if ((0 == ret) && (mntflags & MS_RDONLY)) { if (ret < 0)
DEBUG("Remounting \"%s\" on \"%s\" readonly", return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest);
src ? src : "(none)", bdev->dest ? bdev->dest : "(none)");
if (ret == 0 && (mntflags & MS_RDONLY)) {
mflags = add_required_remount_flags(src, bdev->dest, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); mflags = add_required_remount_flags(src, bdev->dest, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT);
ret = mount(src, bdev->dest, "bind", mflags, mntdata); ret = mount(src, bdev->dest, "bind", mflags, mntdata);
if (ret < 0)
return log_error_errno(-errno, errno, "Failed to remount \"%s\" on \"%s\" read-only with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"",
src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags);
else
DEBUG("Remounted \"%s\" on \"%s\" read-only with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"",
src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags);
} }
if (ret < 0) { TRACE("Mounted \"%s\" on \"%s\" with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"",
SYSERROR("Failed to mount \"%s\" on \"%s\"", src, bdev->dest); src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags);
return -1; return 0;
}
TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest);
return ret;
} }
int dir_umount(struct lxc_storage *bdev) int dir_umount(struct lxc_storage *bdev)
{ {
if (strcmp(bdev->type, "dir")) if (strcmp(bdev->type, "dir"))
return -22; return ret_errno(EINVAL);
if (!bdev->src || !bdev->dest) if (!bdev->src || !bdev->dest)
return -22; return ret_errno(EINVAL);
return umount(bdev->dest); return umount2(bdev->dest, MNT_DETACH);
} }
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