Unverified Commit 45d6d89b by Stéphane Graber Committed by GitHub

Merge pull request #3328 from brauner/2020-03-25/fixes

tree-wide: fixes
parents 75688909 65146c97
...@@ -27,11 +27,13 @@ ...@@ -27,11 +27,13 @@
#include "strlcpy.h" #include "strlcpy.h"
#endif #endif
size_t strlcat(char *d, const char *s, size_t n) size_t strlcat(char *src, const char *append, size_t len)
{ {
size_t l = strnlen(d, n); size_t src_len;
if (l == n)
return l + strlen(s);
return l + strlcpy(d + l, s, n - l); src_len = strnlen(src, len);
if (src_len == len)
return src_len + strlen(append);
return src_len + strlcpy(src + src_len, append, len - src_len);
} }
...@@ -24,6 +24,6 @@ ...@@ -24,6 +24,6 @@
#include <stdio.h> #include <stdio.h>
extern size_t strlcat(char *d, const char *s, size_t n); extern size_t strlcat(char *src, const char *append, size_t len);
#endif #endif
...@@ -70,9 +70,6 @@ struct arguments { ...@@ -70,9 +70,6 @@ struct arguments {
int argc; int argc;
}; };
static int arguments_parse(struct arguments *my_args, int argc,
char *const argv[]);
static struct arguments my_args = { static struct arguments my_args = {
.options = long_options, .options = long_options,
.shortopts = short_options .shortopts = short_options
...@@ -90,7 +87,8 @@ static void prevent_forking(void) ...@@ -90,7 +87,8 @@ static void prevent_forking(void)
return; return;
while (getline(&line, &len, f) != -1) { while (getline(&line, &len, f) != -1) {
int fd, ret; __do_close int fd = -EBADF;
int ret;
char *p, *p2; char *p, *p2;
p = strchr(line, ':'); p = strchr(line, ':');
...@@ -121,7 +119,7 @@ static void prevent_forking(void) ...@@ -121,7 +119,7 @@ static void prevent_forking(void)
return; return;
} }
fd = open(path, O_WRONLY); fd = open(path, O_WRONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
if (my_args.quiet) if (my_args.quiet)
fprintf(stderr, "Failed to open \"%s\"\n", path); fprintf(stderr, "Failed to open \"%s\"\n", path);
...@@ -132,7 +130,6 @@ static void prevent_forking(void) ...@@ -132,7 +130,6 @@ static void prevent_forking(void)
if (ret != 1 && !my_args.quiet) if (ret != 1 && !my_args.quiet)
fprintf(stderr, "Failed to write to \"%s\"\n", path); fprintf(stderr, "Failed to write to \"%s\"\n", path);
close(fd);
return; return;
} }
} }
...@@ -191,6 +188,99 @@ static void remove_self(void) ...@@ -191,6 +188,99 @@ static void remove_self(void)
return; return;
} }
__noreturn static void print_usage_exit(const struct option longopts[])
{
fprintf(stderr, "Usage: lxc-init [-n|--name=NAME] [-h|--help] [--usage] [--version]\n\
[-q|--quiet] [-P|--lxcpath=LXCPATH]\n");
exit(EXIT_SUCCESS);
}
__noreturn static void print_version_exit(void)
{
printf("%s\n", LXC_VERSION);
exit(EXIT_SUCCESS);
}
static void print_help(void)
{
fprintf(stderr, "\
Usage: lxc-init --name=NAME -- COMMAND\n\
\n\
lxc-init start a COMMAND as PID 2 inside a container\n\
\n\
Options :\n\
-n, --name=NAME NAME of the container\n\
-q, --quiet Don't produce any output\n\
-P, --lxcpath=PATH Use specified container path\n\
-?, --help Give this help list\n\
--usage Give a short usage message\n\
--version Print the version number\n\
\n\
Mandatory or optional arguments to long options are also mandatory or optional\n\
for any corresponding short options.\n\
\n\
See the lxc-init man page for further information.\n\n");
}
static int arguments_parse(struct arguments *args, int argc,
char *const argv[])
{
for (;;) {
int c;
int index = 0;
c = getopt_long(argc, argv, args->shortopts, args->options, &index);
if (c == -1)
break;
switch (c) {
case 'n':
args->name = optarg;
break;
case 'o':
break;
case 'l':
break;
case 'q':
args->quiet = true;
break;
case 'P':
remove_trailing_slashes(optarg);
args->lxcpath = optarg;
break;
case OPT_USAGE:
print_usage_exit(args->options);
case OPT_VERSION:
print_version_exit();
case '?':
print_help();
exit(EXIT_FAILURE);
case 'h':
print_help();
exit(EXIT_SUCCESS);
}
}
/*
* Reclaim the remaining command arguments
*/
args->argv = &argv[optind];
args->argc = argc - optind;
/* If no lxcpath was given, use default */
if (!args->lxcpath)
args->lxcpath = lxc_global_config_value("lxc.lxcpath");
/* Check the command options */
if (!args->name) {
if (!args->quiet)
fprintf(stderr, "lxc-init: missing container name, use --name option\n");
return -1;
}
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, logfd, ret; int i, logfd, ret;
...@@ -426,96 +516,3 @@ out: ...@@ -426,96 +516,3 @@ out:
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
exit(exit_with); exit(exit_with);
} }
__noreturn static void print_usage_exit(const struct option longopts[])
{
fprintf(stderr, "Usage: lxc-init [-n|--name=NAME] [-h|--help] [--usage] [--version]\n\
[-q|--quiet] [-P|--lxcpath=LXCPATH]\n");
exit(EXIT_SUCCESS);
}
__noreturn static void print_version_exit(void)
{
printf("%s\n", LXC_VERSION);
exit(EXIT_SUCCESS);
}
static void print_help(void)
{
fprintf(stderr, "\
Usage: lxc-init --name=NAME -- COMMAND\n\
\n\
lxc-init start a COMMAND as PID 2 inside a container\n\
\n\
Options :\n\
-n, --name=NAME NAME of the container\n\
-q, --quiet Don't produce any output\n\
-P, --lxcpath=PATH Use specified container path\n\
-?, --help Give this help list\n\
--usage Give a short usage message\n\
--version Print the version number\n\
\n\
Mandatory or optional arguments to long options are also mandatory or optional\n\
for any corresponding short options.\n\
\n\
See the lxc-init man page for further information.\n\n");
}
static int arguments_parse(struct arguments *args, int argc,
char *const argv[])
{
for (;;) {
int c;
int index = 0;
c = getopt_long(argc, argv, args->shortopts, args->options, &index);
if (c == -1)
break;
switch (c) {
case 'n':
args->name = optarg;
break;
case 'o':
break;
case 'l':
break;
case 'q':
args->quiet = true;
break;
case 'P':
remove_trailing_slashes(optarg);
args->lxcpath = optarg;
break;
case OPT_USAGE:
print_usage_exit(args->options);
case OPT_VERSION:
print_version_exit();
case '?':
print_help();
exit(EXIT_FAILURE);
case 'h':
print_help();
exit(EXIT_SUCCESS);
}
}
/*
* Reclaim the remaining command arguments
*/
args->argv = &argv[optind];
args->argc = argc - optind;
/* If no lxcpath was given, use default */
if (!args->lxcpath)
args->lxcpath = lxc_global_config_value("lxc.lxcpath");
/* Check the command options */
if (!args->name) {
if (!args->quiet)
fprintf(stderr, "lxc-init: missing container name, use --name option\n");
return -1;
}
return 0;
}
...@@ -1694,61 +1694,70 @@ static int lxc_setup_console(const struct lxc_rootfs *rootfs, ...@@ -1694,61 +1694,70 @@ static int lxc_setup_console(const struct lxc_rootfs *rootfs,
return lxc_setup_ttydir_console(rootfs, console, ttydir); return lxc_setup_ttydir_console(rootfs, console, ttydir);
} }
static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) static int parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size)
{ {
struct mount_opt *mo; ssize_t ret;
/* If '=' is contained in opt, the option must go into data. */ /* If '=' is contained in opt, the option must go into data. */
if (!strchr(opt, '=')) { if (!strchr(opt, '=')) {
/*
/* If opt is found in mount_opt, set or clear flags. * If opt is found in mount_opt, set or clear flags.
* Otherwise append it to data. */ * Otherwise append it to data.
*/
size_t opt_len = strlen(opt); size_t opt_len = strlen(opt);
for (mo = &mount_opt[0]; mo->name != NULL; mo++) { for (struct mount_opt *mo = &mount_opt[0]; mo->name != NULL; mo++) {
size_t mo_name_len = strlen(mo->name); size_t mo_name_len = strlen(mo->name);
if (opt_len == mo_name_len && strncmp(opt, mo->name, mo_name_len) == 0) { if (opt_len == mo_name_len && strncmp(opt, mo->name, mo_name_len) == 0) {
if (mo->clear) if (mo->clear)
*flags &= ~mo->flag; *flags &= ~mo->flag;
else else
*flags |= mo->flag; *flags |= mo->flag;
return; return 0;
} }
} }
} }
if (strlen(*data)) if (strlen(*data)) {
(void)strlcat(*data, ",", size); ret = strlcat(*data, ",", size);
if (ret < 0)
return log_error_errno(ret, errno, "Failed to append \",\" to %s", *data);
}
ret = strlcat(*data, opt, size);
if (ret < 0)
return log_error_errno(ret, errno, "Failed to append \"%s\" to %s", opt, *data);
(void)strlcat(*data, opt, size); return 0;
} }
int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata)
{ {
__do_free char *data = NULL, *s = NULL; __do_free char *mntopts_new = NULL, *mntopts_dup = NULL;
char *p; char *mntopt_cur = NULL;
size_t size; size_t size;
*mntdata = NULL; if (*mntdata || *mntflags)
*mntflags = 0L; return ret_errno(EINVAL);
if (!mntopts) if (!mntopts)
return 0; return 0;
s = strdup(mntopts); mntopts_dup = strdup(mntopts);
if (!s) if (!mntopts_dup)
return -1; return ret_errno(ENOMEM);
size = strlen(s) + 1; size = strlen(mntopts_dup) + 1;
data = malloc(size); mntopts_new = zalloc(size);
if (!data) if (!mntopts_new)
return -1; return ret_errno(ENOMEM);
*data = 0;
lxc_iterate_parts(p, s, ",") lxc_iterate_parts(mntopt_cur, mntopts_dup, ",")
parse_mntopt(p, mntflags, &data, size); if (parse_mntopt(mntopt_cur, mntflags, &mntopts_new, size) < 0)
return ret_errno(EINVAL);
if (*data) if (*mntopts_new)
*mntdata = move_ptr(data); *mntdata = move_ptr(mntopts_new);
return 0; return 0;
} }
...@@ -2001,11 +2010,10 @@ static inline int mount_entry_on_generic(struct mntent *mntent, ...@@ -2001,11 +2010,10 @@ static inline int mount_entry_on_generic(struct mntent *mntent,
const char *lxc_path) const char *lxc_path)
{ {
__do_free char *mntdata = NULL; __do_free char *mntdata = NULL;
unsigned long mntflags = 0, pflags = 0;
char *rootfs_path = NULL;
int ret; int ret;
unsigned long mntflags;
bool dev, optional, relative; bool dev, optional, relative;
unsigned long pflags = 0;
char *rootfs_path = NULL;
optional = hasmntopt(mntent, "optional") != NULL; optional = hasmntopt(mntent, "optional") != NULL;
dev = hasmntopt(mntent, "dev") != NULL; dev = hasmntopt(mntent, "dev") != NULL;
...@@ -2030,7 +2038,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, ...@@ -2030,7 +2038,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent,
ret = parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata); ret = parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata);
if (ret < 0) if (ret < 0)
return -1; return ret;
ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags,
pflags, mntdata, optional, dev, relative, rootfs_path); pflags, mntdata, optional, dev, relative, rootfs_path);
......
...@@ -2572,9 +2572,9 @@ static int set_config_rootfs_mount(const char *key, const char *value, ...@@ -2572,9 +2572,9 @@ static int set_config_rootfs_mount(const char *key, const char *value,
static int set_config_rootfs_options(const char *key, const char *value, static int set_config_rootfs_options(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
int ret;
unsigned long mflags = 0, pflags = 0; unsigned long mflags = 0, pflags = 0;
char *mdata = NULL, *opts = NULL; char *mdata = NULL, *opts = NULL;
int ret;
struct lxc_rootfs *rootfs = &lxc_conf->rootfs; struct lxc_rootfs *rootfs = &lxc_conf->rootfs;
ret = parse_mntopts(value, &mflags, &mdata); ret = parse_mntopts(value, &mflags, &mdata);
......
...@@ -367,9 +367,9 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, ...@@ -367,9 +367,9 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
goto err; goto err;
while (getmntent_r(mnts, &mntent, buf, sizeof(buf))) { while (getmntent_r(mnts, &mntent, buf, sizeof(buf))) {
char *mntdata; unsigned long flags = 0;
char *mntdata = NULL;
char arg[2 * PATH_MAX + 2]; char arg[2 * PATH_MAX + 2];
unsigned long flags;
if (parse_mntopts(mntent.mnt_opts, &flags, &mntdata) < 0) if (parse_mntopts(mntent.mnt_opts, &flags, &mntdata) < 0)
goto err; goto err;
......
...@@ -192,8 +192,8 @@ bool btrfs_detect(const char *path) ...@@ -192,8 +192,8 @@ bool btrfs_detect(const char *path)
int btrfs_mount(struct lxc_storage *bdev) int btrfs_mount(struct lxc_storage *bdev)
{ {
unsigned long mntflags; unsigned long mntflags = 0;
char *mntdata; char *mntdata = NULL;
const char *src; const char *src;
int ret; int ret;
......
...@@ -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;
...@@ -138,9 +126,9 @@ bool dir_detect(const char *path) ...@@ -138,9 +126,9 @@ bool dir_detect(const char *path)
int dir_mount(struct lxc_storage *bdev) int dir_mount(struct lxc_storage *bdev)
{ {
int ret; __do_free char *mntdata = NULL;
unsigned long mflags = 0, mntflags = 0, pflags = 0; unsigned long mflags = 0, mntflags = 0, pflags = 0;
char *mntdata; int ret;
const char *src; const char *src;
if (strcmp(bdev->type, "dir")) if (strcmp(bdev->type, "dir"))
...@@ -150,47 +138,42 @@ int dir_mount(struct lxc_storage *bdev) ...@@ -150,47 +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);
free(mntdata);
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);
free(mntdata);
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);
free(mntdata); return 0;
return -1;
}
TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest);
free(mntdata);
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);
} }
...@@ -342,13 +342,12 @@ bool ovl_detect(const char *path) ...@@ -342,13 +342,12 @@ bool ovl_detect(const char *path)
int ovl_mount(struct lxc_storage *bdev) int ovl_mount(struct lxc_storage *bdev)
{ {
__do_free char *options = NULL, __do_free char *options = NULL, *options_work = NULL;
*options_work = NULL; unsigned long mntflags = 0;
char *mntdata = NULL;
char *tmp, *dup, *lower, *upper; char *tmp, *dup, *lower, *upper;
char *work, *lastslash; char *work, *lastslash;
size_t len, len2; size_t len, len2;
unsigned long mntflags;
char *mntdata;
int ret, ret2; int ret, ret2;
if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs")) if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
......
...@@ -315,9 +315,8 @@ int find_fstype_cb(char *buffer, void *data) ...@@ -315,9 +315,8 @@ int find_fstype_cb(char *buffer, void *data)
const char *target; const char *target;
const char *options; const char *options;
} *cbarg = data; } *cbarg = data;
unsigned long mntflags = 0;
unsigned long mntflags; char *mntdata = NULL;
char *mntdata;
char *fstype; char *fstype;
/* we don't try 'nodev' entries */ /* we don't try 'nodev' entries */
......
...@@ -159,11 +159,12 @@ bool zfs_detect(const char *path) ...@@ -159,11 +159,12 @@ bool zfs_detect(const char *path)
int zfs_mount(struct lxc_storage *bdev) int zfs_mount(struct lxc_storage *bdev)
{ {
unsigned long mntflags = 0;
char *mntdata = NULL;
int ret; int ret;
size_t oldlen, newlen, totallen; size_t oldlen, newlen, totallen;
char *mntdata, *tmp; char *tmp;
const char *src; const char *src;
unsigned long mntflags;
char cmd_output[PATH_MAX] = {0}; char cmd_output[PATH_MAX] = {0};
if (strcmp(bdev->type, "zfs")) if (strcmp(bdev->type, "zfs"))
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include "initutils.h" #include "initutils.h"
#include "macro.h" #include "macro.h"
#ifndef HAVE_STRLCAT
#include "include/strlcat.h"
#endif
/* convert variadic argument lists to arrays (for execl type argument lists) */ /* convert variadic argument lists to arrays (for execl type argument lists) */
extern char **lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup); extern char **lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup);
extern const char **lxc_va_arg_list_to_argv_const(va_list ap, size_t skip); extern const char **lxc_va_arg_list_to_argv_const(va_list ap, size_t skip);
...@@ -103,4 +107,15 @@ static inline bool is_empty_string(const char *s) ...@@ -103,4 +107,15 @@ static inline bool is_empty_string(const char *s)
return !s || strcmp(s, "") == 0; return !s || strcmp(s, "") == 0;
} }
static inline ssize_t safe_strlcat(char *src, const char *append, size_t len)
{
size_t new_len;
new_len = strlcat(src, append, len);
if (new_len >= len)
return ret_errno(EINVAL);
return (ssize_t)new_len;
}
#endif /* __LXC_STRING_UTILS_H */ #endif /* __LXC_STRING_UTILS_H */
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