Revert "loop: rework loop storage driver"

This reverts commit 85914b67. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent c476a797
...@@ -22,15 +22,12 @@ ...@@ -22,15 +22,12 @@
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#define __STDC_FORMAT_MACROS
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <inttypes.h>
#include <linux/loop.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <linux/loop.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -52,13 +49,13 @@ int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -52,13 +49,13 @@ int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
const char *cname, const char *oldpath, const char *lxcpath, const char *cname, const char *oldpath, const char *lxcpath,
int snap, uint64_t newsize, struct lxc_conf *conf) int snap, uint64_t newsize, struct lxc_conf *conf)
{ {
char fstype[100];
uint64_t size = newsize; uint64_t size = newsize;
int len, ret; int len, ret;
char *srcdev; char *srcdev;
char fstype[100] = "ext4";
if (snap) { if (snap) {
ERROR("The loop storage driver does not support snapshots"); ERROR("loop devices cannot be snapshotted.");
return -1; return -1;
} }
...@@ -68,65 +65,43 @@ int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -68,65 +65,43 @@ int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
len = strlen(lxcpath) + strlen(cname) + strlen("rootdev") + 3; len = strlen(lxcpath) + strlen(cname) + strlen("rootdev") + 3;
srcdev = alloca(len); srcdev = alloca(len);
ret = snprintf(srcdev, len, "%s/%s/rootdev", lxcpath, cname); ret = snprintf(srcdev, len, "%s/%s/rootdev", lxcpath, cname);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len)
ERROR("Failed to create string");
return -1; return -1;
}
new->src = malloc(len + 5); new->src = malloc(len + 5);
if (!new->src) { if (!new->src)
ERROR("Failed to allocate memory");
return -1; return -1;
} ret = snprintf(new->src, len + 5, "loop:%s", srcdev);
if (ret < 0 || ret >= len + 5)
ret = snprintf(new->src, (len + 5), "loop:%s", srcdev);
if (ret < 0 || ret >= (len + 5)) {
ERROR("Failed to create string");
return -1; return -1;
}
new->dest = malloc(len); new->dest = malloc(len);
if (!new->dest) { if (!new->dest)
ERROR("Failed to allocate memory");
return -1; return -1;
}
ret = snprintf(new->dest, len, "%s/%s/rootfs", lxcpath, cname); ret = snprintf(new->dest, len, "%s/%s/rootfs", lxcpath, cname);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len)
ERROR("Failed to create string");
return -1; return -1;
}
/* It's tempting to say: if orig->src == loopback and !newsize, then // it's tempting to say: if orig->src == loopback and !newsize, then
* copy the loopback file. However, we'd have to make sure to correctly // copy the loopback file. However, we'd have to make sure to
* keep holes! So punt for now. // correctly keep holes! So punt for now.
*/
if (is_blktype(orig)) { if (is_blktype(orig)) {
/* detect size */
if (!newsize && blk_getsize(orig, &size) < 0) { if (!newsize && blk_getsize(orig, &size) < 0) {
ERROR("Failed to detect size of loop file \"%s\"", ERROR("Error getting size of %s", orig->src);
orig->src);
return -1; return -1;
} }
/* detect filesystem */
if (detect_fs(orig, fstype, 100) < 0) { if (detect_fs(orig, fstype, 100) < 0) {
INFO("Failed to detect filesystem type for \"%s\"", orig->src); INFO("could not find fstype for %s, using %s", orig->src,
DEFAULT_FSTYPE);
return -1; return -1;
} }
} else if (!newsize) { } else {
sprintf(fstype, "%s", DEFAULT_FSTYPE);
if (!newsize)
size = DEFAULT_FS_SIZE; size = DEFAULT_FS_SIZE;
} }
return do_loop_create(srcdev, size, fstype);
ret = do_loop_create(srcdev, size, fstype);
if (ret < 0) {
ERROR("Failed to create loop storage volume \"%s\" with "
"filesystem \"%s\" and size \"%" PRIu64 "\"",
srcdev, fstype, size);
return -1;
}
return 0;
} }
int loop_create(struct bdev *bdev, const char *dest, const char *n, int loop_create(struct bdev *bdev, const char *dest, const char *n,
...@@ -140,35 +115,23 @@ int loop_create(struct bdev *bdev, const char *dest, const char *n, ...@@ -140,35 +115,23 @@ int loop_create(struct bdev *bdev, const char *dest, const char *n,
if (!specs) if (!specs)
return -1; return -1;
/* <dest> is passed in as <lxcpath>/<lxcname>/rootfs, <srcdev> will // dest is passed in as $lxcpath / $lxcname / rootfs
* be <lxcpath>/<lxcname>/rootdev, and <src> will be "loop:<srcdev>". // srcdev will be: $lxcpath / $lxcname / rootdev
*/ // src will be 'loop:$srcdev'
len = strlen(dest) + 2; len = strlen(dest) + 2;
srcdev = alloca(len); srcdev = alloca(len);
ret = snprintf(srcdev, len, "%s", dest); ret = snprintf(srcdev, len, "%s", dest);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len)
ERROR("Failed to create string");
return -1;
}
ret = sprintf(srcdev + len - 4, "dev");
if (ret < 0) {
ERROR("Failed to create string");
return -1; return -1;
} sprintf(srcdev + len - 4, "dev");
bdev->src = malloc(len + 5); bdev->src = malloc(len + 5);
if (!bdev->src) { if (!bdev->src)
ERROR("Failed to allocate memory");
return -1; return -1;
}
ret = snprintf(bdev->src, len + 5, "loop:%s", srcdev); ret = snprintf(bdev->src, len + 5, "loop:%s", srcdev);
if (ret < 0 || ret >= len + 5) { if (ret < 0 || ret >= len + 5)
ERROR("Failed to create string");
return -1; return -1;
}
sz = specs->fssize; sz = specs->fssize;
if (!sz) if (!sz)
...@@ -178,31 +141,19 @@ int loop_create(struct bdev *bdev, const char *dest, const char *n, ...@@ -178,31 +141,19 @@ int loop_create(struct bdev *bdev, const char *dest, const char *n,
if (!fstype) if (!fstype)
fstype = DEFAULT_FSTYPE; fstype = DEFAULT_FSTYPE;
bdev->dest = strdup(dest); if (!(bdev->dest = strdup(dest)))
if (!bdev->dest) {
ERROR("Failed to duplicate string \"%s\"", dest);
return -1; return -1;
}
ret = mkdir_p(bdev->dest, 0755); if (mkdir_p(bdev->dest, 0755) < 0) {
if (ret < 0) { ERROR("Error creating %s", bdev->dest);
ERROR("Failed creating directory \"%s\"", bdev->dest);
return -1; return -1;
} }
return do_loop_create(srcdev, sz, fstype);
ret = do_loop_create(srcdev, sz, fstype);
if (ret < 0) {
ERROR("Failed to create loop storage volume \"%s\" with "
"filesystem \"%s\" and size \"%" PRIu64 "\"",
srcdev, fstype, sz);
return -1;
}
return 0;
} }
int loop_destroy(struct bdev *orig) { int loop_destroy(struct bdev *orig)
{
return unlink(orig->src + 5); return unlink(orig->src + 5);
} }
...@@ -228,7 +179,7 @@ int loop_mount(struct bdev *bdev) ...@@ -228,7 +179,7 @@ int loop_mount(struct bdev *bdev)
{ {
int ret, loopfd; int ret, loopfd;
char loname[MAXPATHLEN]; char loname[MAXPATHLEN];
char *src; char *src = bdev->src;
if (strcmp(bdev->type, "loop")) if (strcmp(bdev->type, "loop"))
return -22; return -22;
...@@ -237,98 +188,73 @@ int loop_mount(struct bdev *bdev) ...@@ -237,98 +188,73 @@ int loop_mount(struct bdev *bdev)
return -22; return -22;
/* skip prefix */ /* skip prefix */
src = lxc_storage_get_path(bdev->src, bdev->type); if (!strncmp(bdev->src, "loop:", 5))
src += 5;
loopfd = lxc_prepare_loop_dev(src, loname, LO_FLAGS_AUTOCLEAR); loopfd = lxc_prepare_loop_dev(src, loname, LO_FLAGS_AUTOCLEAR);
if (loopfd < 0) { if (loopfd < 0) {
ERROR("Failed to prepare loop device for loop file \"%s\"", src); ERROR("failed to prepare loop device for loop file \"%s\"", src);
return -1; return -1;
} }
DEBUG("Prepared loop device \"%s\"", loname); DEBUG("prepared loop device \"%s\"", loname);
ret = mount_unknown_fs(loname, bdev->dest, bdev->mntopts); ret = mount_unknown_fs(loname, bdev->dest, bdev->mntopts);
if (ret < 0) { if (ret < 0)
ERROR("Failed to mount rootfs \"%s\" on \"%s\" via loop device \"%s\"", ERROR("failed to mount rootfs \"%s\" onto \"%s\" via loop device \"%s\"", bdev->src, bdev->dest, loname);
bdev->src, bdev->dest, loname); else
close(loopfd);
return -1;
}
bdev->lofd = loopfd; bdev->lofd = loopfd;
DEBUG("Mounted rootfs \"%s\" on \"%s\" via loop device \"%s\"", DEBUG("mounted rootfs \"%s\" onto \"%s\" via loop device \"%s\"", bdev->src, bdev->dest, loname);
bdev->src, bdev->dest, loname);
return 0; return ret;
} }
int loop_umount(struct bdev *bdev) int loop_umount(struct bdev *bdev)
{ {
int ret, saved_errno; int ret;
if (strcmp(bdev->type, "loop")) if (strcmp(bdev->type, "loop"))
return -22; return -22;
if (!bdev->src || !bdev->dest) if (!bdev->src || !bdev->dest)
return -22; return -22;
ret = umount(bdev->dest); ret = umount(bdev->dest);
saved_errno = errno;
if (bdev->lofd >= 0) { if (bdev->lofd >= 0) {
close(bdev->lofd); close(bdev->lofd);
bdev->lofd = -1; bdev->lofd = -1;
} }
errno = saved_errno; return ret;
if (ret < 0) {
SYSERROR("Failed to umount \"%s\"", bdev->dest);
return -1;
}
return 0;
} }
static int do_loop_create(const char *path, uint64_t size, const char *fstype) static int do_loop_create(const char *path, uint64_t size, const char *fstype)
{ {
int fd, ret; int fd, ret;
char cmd_output[MAXPATHLEN];
const char *cmd_args[2] = {fstype, path}; const char *cmd_args[2] = {fstype, path};
char cmd_output[MAXPATHLEN];
/* create the new loopback file */ // create the new loopback file.
fd = creat(path, S_IRUSR | S_IWUSR); fd = creat(path, S_IRUSR|S_IWUSR);
if (fd < 0) { if (fd < 0)
SYSERROR("Failed to create new loop file \"%s\"", path);
return -1; return -1;
} if (lseek(fd, size, SEEK_SET) < 0) {
SYSERROR("Error seeking to set new loop file size");
ret = lseek(fd, size, SEEK_SET);
if (ret < 0) {
SYSERROR("Failed to seek to set new loop file size for loop "
"file \"%s\"", path);
close(fd); close(fd);
return -1; return -1;
} }
if (write(fd, "1", 1) != 1) {
ret = write(fd, "1", 1); SYSERROR("Error creating new loop file");
if (ret != 1) {
SYSERROR("Failed creating new loop file \"%s\"", path);
close(fd); close(fd);
return -1; return -1;
} }
ret = close(fd); ret = close(fd);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to create new loop file \"%s\"", path); SYSERROR("Error closing new loop file");
return -1; return -1;
} }
// create an fs in the loopback file // create an fs in the loopback file
ret = run_command(cmd_output, sizeof(cmd_output), do_mkfs_exec_wrapper, ret = run_command(cmd_output, sizeof(cmd_output), do_mkfs_exec_wrapper,
(void *)cmd_args); (void *)cmd_args);
if (ret < 0) { if (ret < 0)
ERROR("Failed to create new filesystem \"%s\" for loop file "
"\"%s\": %s", fstype, path, cmd_output);
return -1; return -1;
}
return 0; return 0;
} }
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