X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2Flxc%2Flxccontainer.c;h=63a66709898897f18910956a613301480e9a73ca;hb=754076f;hp=5f1e7330c849b4276355ad33712f65472562e492;hpb=d1bc8d484caa7b3157aa76da346badabf2a64d12;p=mirror_lxc.git diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 5f1e7330c..63a667098 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define _GNU_SOURCE +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif #include #include #include @@ -41,7 +43,9 @@ #include #include +#include "../include/netns_ifaddrs.h" #include "af_unix.h" +#include "api_extensions.h" #include "attach.h" #include "cgroup.h" #include "commands.h" @@ -61,6 +65,7 @@ #include "namespace.h" #include "network.h" #include "parse.h" +#include "raw_syscalls.h" #include "start.h" #include "state.h" #include "storage.h" @@ -68,6 +73,7 @@ #include "storage/overlay.h" #include "storage_utils.h" #include "sync.h" +#include "syscall_wrappers.h" #include "terminal.h" #include "utils.h" #include "version.h" @@ -77,12 +83,6 @@ #include #endif -#if HAVE_IFADDRS_H -#include -#else -#include <../include/ifaddrs.h> -#endif - #if IS_BIONIC #include <../include/lxcmntent.h> #else @@ -529,7 +529,7 @@ static bool do_lxcapi_freeze(struct lxc_container *c) if (!c) return false; - ret = lxc_freeze(c->name, c->config_path); + ret = lxc_freeze(c->lxc_conf, c->name, c->config_path); if (ret < 0) return false; @@ -545,7 +545,7 @@ static bool do_lxcapi_unfreeze(struct lxc_container *c) if (!c) return false; - ret = lxc_unfreeze(c->name, c->config_path); + ret = lxc_unfreeze(c->lxc_conf, c->name, c->config_path); if (ret < 0) return false; @@ -583,6 +583,9 @@ static int do_lxcapi_console_log(struct lxc_container *c, struct lxc_console_log { int ret; + if (!c) + return -EINVAL; + ret = lxc_cmd_console_log(c->name, do_lxcapi_get_config_path(c), log); if (ret < 0) { if (ret == -ENODATA) @@ -970,10 +973,15 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a /* We don't really care if this doesn't print all the * characters. All that it means is that the proctitle will be * ugly. Similarly, we also don't care if setproctitle() fails. - * */ - (void)snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name); - INFO("Attempting to set proc title to %s", title); - (void)setproctitle(title); + */ + ret = snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name); + if (ret > 0) { + ret = setproctitle(title); + if (ret < 0) + INFO("Failed to set process title to %s", title); + else + INFO("Set process title to %s", title); + } /* We fork() a second time to be reparented to init. Like * POSIX's daemon() function we change to "/" and redirect @@ -1020,24 +1028,22 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ret = setsid(); if (ret < 0) TRACE("Process %d is already process group leader", lxc_raw_getpid()); - } else { - if (!am_single_threaded()) { - ERROR("Cannot start non-daemonized container when threaded"); - free_init_cmd(init_cmd); - lxc_free_handler(handler); - return false; - } + } else if (!am_single_threaded()) { + ERROR("Cannot start non-daemonized container when threaded"); + free_init_cmd(init_cmd); + lxc_free_handler(handler); + return false; } - /* We need to write PID file after daemonize, so we always - * write the right PID. + /* We need to write PID file after daemonize, so we always write the + * right PID. */ if (c->pidfile) { int ret, w; - char pidstr[LXC_NUMSTRLEN64]; + char pidstr[INTTYPE_TO_STRLEN(pid_t)]; - w = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", (int)lxc_raw_getpid()); - if (w < 0 || (size_t)w >= LXC_NUMSTRLEN64) { + w = snprintf(pidstr, sizeof(pidstr), "%d", lxc_raw_getpid()); + if (w < 0 || (size_t)w >= sizeof(pidstr)) { free_init_cmd(init_cmd); lxc_free_handler(handler); @@ -1054,7 +1060,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a free_init_cmd(init_cmd); lxc_free_handler(handler); - SYSERROR("Failed to write '%s'", c->pidfile); + SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); if (c->daemonize) _exit(EXIT_FAILURE); @@ -1069,7 +1075,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a if (conf->monitor_unshare) { ret = unshare(CLONE_NEWNS); if (ret < 0) { - SYSERROR("failed to unshare mount namespace"); + SYSERROR("Failed to unshare mount namespace"); lxc_free_handler(handler); ret = 1; goto on_error; @@ -2320,7 +2326,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) if (pid == 0) { /* child */ int ret = 1, nbytes; - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; + struct netns_ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; /* close the read-end of the pipe */ close(pipefd[0]); @@ -2331,7 +2337,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) } /* Grab the list of interfaces */ - if (getifaddrs(&interfaceArray)) { + if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) { SYSERROR("Failed to get interfaces list"); goto out; } @@ -2350,7 +2356,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) out: if (interfaceArray) - freeifaddrs(interfaceArray); + netns_freeifaddrs(interfaceArray); /* close the write-end of the pipe, thus sending EOF to the reader */ close(pipefd[1]); @@ -2422,7 +2428,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, int ret = 1; char *address = NULL; void *tempAddrPtr = NULL; - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; + struct netns_ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; /* close the read-end of the pipe */ close(pipefd[0]); @@ -2433,7 +2439,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, } /* Grab the list of interfaces */ - if (getifaddrs(&interfaceArray)) { + if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) { SYSERROR("Failed to get interfaces list"); goto out; } @@ -2444,6 +2450,9 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, if (tempIfAddr->ifa_addr == NULL) continue; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + if (tempIfAddr->ifa_addr->sa_family == AF_INET) { if (family && strcmp(family, "inet")) continue; @@ -2459,6 +2468,8 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr; } +#pragma GCC diagnostic pop + if (interface && strcmp(interface, tempIfAddr->ifa_name)) continue; else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0) @@ -2484,7 +2495,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, out: if (interfaceArray) - freeifaddrs(interfaceArray); + netns_freeifaddrs(interfaceArray); /* close the write-end of the pipe, thus sending EOF to the reader */ close(pipefd[1]); @@ -2633,7 +2644,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) return false; fd = open(alt_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd < 0) goto on_error; @@ -2662,8 +2673,8 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc struct stat fbuf; void *buf = NULL; char *del = NULL; - char path[MAXPATHLEN]; - char newpath[MAXPATHLEN]; + char path[PATH_MAX]; + char newpath[PATH_MAX]; int fd, ret, n = 0, v = 0; bool bret = false; size_t len = 0, bytes = 0; @@ -2671,12 +2682,12 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc if (container_disk_lock(c0)) return false; - ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c0->config_path, c0->name); - if (ret < 0 || ret > MAXPATHLEN) + ret = snprintf(path, PATH_MAX, "%s/%s/lxc_snapshots", c0->config_path, c0->name); + if (ret < 0 || ret > PATH_MAX) goto out; - ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name); - if (ret < 0 || ret > MAXPATHLEN) + ret = snprintf(newpath, PATH_MAX, "%s\n%s\n", c->config_path, c->name); + if (ret < 0 || ret > PATH_MAX) goto out; /* If we find an lxc-snapshot file using the old format only listing the @@ -2787,14 +2798,14 @@ out: void mod_all_rdeps(struct lxc_container *c, bool inc) { struct lxc_container *p; - char *lxcpath = NULL, *lxcname = NULL, path[MAXPATHLEN]; + char *lxcpath = NULL, *lxcname = NULL, path[PATH_MAX]; size_t pathlen = 0, namelen = 0; FILE *f; int ret; - ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", + ret = snprintf(path, PATH_MAX, "%s/%s/lxc_rdepends", c->config_path, c->name); - if (ret < 0 || ret >= MAXPATHLEN) { + if (ret < 0 || ret >= PATH_MAX) { ERROR("Path name too long"); return; } @@ -2834,14 +2845,14 @@ out: static bool has_fs_snapshots(struct lxc_container *c) { FILE *f; - char path[MAXPATHLEN]; + char path[PATH_MAX]; int ret, v; struct stat fbuf; bool bret = false; - ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path, + ret = snprintf(path, PATH_MAX, "%s/%s/lxc_snapshots", c->config_path, c->name); - if (ret < 0 || ret > MAXPATHLEN) + if (ret < 0 || ret > PATH_MAX) goto out; /* If the file doesn't exist there are no snapshots. */ @@ -2869,7 +2880,7 @@ out: static bool has_snapshots(struct lxc_container *c) { - char path[MAXPATHLEN]; + char path[PATH_MAX]; struct dirent *direntp; int count=0; DIR *dir; @@ -2981,6 +2992,10 @@ static bool container_destroy(struct lxc_container *c, } } + /* LXC is not managing the storage of the container. */ + if (conf && !conf->rootfs.managed) + goto on_success; + if (conf && conf->rootfs.path && conf->rootfs.mount) { if (!do_destroy_container(conf)) { ERROR("Error destroying rootfs for %s", c->name); @@ -3053,6 +3068,7 @@ static bool container_destroy(struct lxc_container *c, } INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name); +on_success: bret = true; out: @@ -3068,14 +3084,16 @@ static bool do_lxcapi_destroy(struct lxc_container *c) if (!c || !lxcapi_is_defined(c)) return false; - if (has_snapshots(c)) { - ERROR("Container %s has snapshots; not removing", c->name); - return false; - } + if (c->lxc_conf && c->lxc_conf->rootfs.managed) { + if (has_snapshots(c)) { + ERROR("Container %s has snapshots; not removing", c->name); + return false; + } - if (has_fs_snapshots(c)) { - ERROR("container %s has snapshots on its rootfs", c->name); - return false; + if (has_fs_snapshots(c)) { + ERROR("container %s has snapshots on its rootfs", c->name); + return false; + } } return container_destroy(c, NULL); @@ -3260,17 +3278,12 @@ static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsy if (is_stopped(c)) return false; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) return false; - if (container_disk_lock(c)) - return false; - ret = cgroup_ops->set(cgroup_ops, subsys, value, c->name, c->config_path); - container_disk_unlock(c); - cgroup_exit(cgroup_ops); return ret == 0; @@ -3289,18 +3302,13 @@ static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys if (is_stopped(c)) return -1; - cgroup_ops = cgroup_init(NULL); + cgroup_ops = cgroup_init(c->lxc_conf); if (!cgroup_ops) return -1; - if (container_disk_lock(c)) - return -1; - ret = cgroup_ops->get(cgroup_ops, subsys, retv, inlen, c->name, c->config_path); - container_disk_unlock(c); - cgroup_exit(cgroup_ops); return ret; @@ -3400,7 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) lxc_list_for_each(it, &c->lxc_conf->hooks[i]) { char *hookname = it->elem; char *fname = strrchr(hookname, '/'); - char tmppath[MAXPATHLEN]; + char tmppath[PATH_MAX]; if (!fname) /* relative path - we don't support, but maybe we should */ return 0; @@ -3410,9 +3418,9 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) } /* copy the script, and change the entry in confile */ - ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s", + ret = snprintf(tmppath, PATH_MAX, "%s/%s/%s", c->config_path, c->name, fname+1); - if (ret < 0 || ret >= MAXPATHLEN) + if (ret < 0 || ret >= PATH_MAX) return -1; ret = copy_file(it->elem, tmppath); @@ -3442,7 +3450,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) { - char newpath[MAXPATHLEN]; + char newpath[PATH_MAX]; char *oldpath = oldc->lxc_conf->fstab; int ret; @@ -3455,9 +3463,9 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) if (!p) return -1; - ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s", + ret = snprintf(newpath, PATH_MAX, "%s/%s%s", c->config_path, c->name, p); - if (ret < 0 || ret >= MAXPATHLEN) { + if (ret < 0 || ret >= PATH_MAX) { ERROR("error printing new path for %s", oldpath); return -1; } @@ -3490,19 +3498,19 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0) { - char path0[MAXPATHLEN], path1[MAXPATHLEN]; + char path0[PATH_MAX], path1[PATH_MAX]; int ret; - ret = snprintf(path0, MAXPATHLEN, "%s/%s/lxc_rdepends", c0->config_path, + ret = snprintf(path0, PATH_MAX, "%s/%s/lxc_rdepends", c0->config_path, c0->name); - if (ret < 0 || ret >= MAXPATHLEN) { + if (ret < 0 || ret >= PATH_MAX) { WARN("Error copying reverse dependencies"); return; } - ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path, + ret = snprintf(path1, PATH_MAX, "%s/%s/lxc_rdepends", c->config_path, c->name); - if (ret < 0 || ret >= MAXPATHLEN) { + if (ret < 0 || ret >= PATH_MAX) { WARN("Error copying reverse dependencies"); return; } @@ -3516,13 +3524,13 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0) static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) { int ret; - char path[MAXPATHLEN]; + char path[PATH_MAX]; FILE *f; bool bret; - ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path, + ret = snprintf(path, PATH_MAX, "%s/%s/lxc_rdepends", c->config_path, c->name); - if (ret < 0 || ret >= MAXPATHLEN) + if (ret < 0 || ret >= PATH_MAX) return false; f = fopen(path, "a"); @@ -3636,7 +3644,7 @@ static int clone_update_rootfs(struct clone_update_data *data) int flags = data->flags; char **hookargs = data->hookargs; int ret = -1; - char path[MAXPATHLEN]; + char path[PATH_MAX]; struct lxc_storage *bdev; FILE *fout; struct lxc_conf *conf = c->lxc_conf; @@ -3712,10 +3720,10 @@ static int clone_update_rootfs(struct clone_update_data *data) } if (!(flags & LXC_CLONE_KEEPNAME)) { - ret = snprintf(path, MAXPATHLEN, "%s/etc/hostname", bdev->dest); + ret = snprintf(path, PATH_MAX, "%s/etc/hostname", bdev->dest); storage_put(bdev); - if (ret < 0 || ret >= MAXPATHLEN) + if (ret < 0 || ret >= PATH_MAX) return -1; if (!file_exists(path)) @@ -3777,7 +3785,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char const char *bdevtype, const char *bdevdata, uint64_t newsize, char **hookargs) { - char newpath[MAXPATHLEN]; + char newpath[PATH_MAX]; int fd, ret; struct clone_update_data data; size_t saved_unexp_len; @@ -3791,9 +3799,8 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char if (container_mem_lock(c)) return NULL; - - if (!is_stopped(c)) { - ERROR("error: Original container (%s) is running", c->name); + if (!is_stopped(c) && !(flags & LXC_CLONE_ALLOW_RUNNING)) { + ERROR("error: Original container (%s) is running. Use --allowrunning if you want to force a snapshot of the running container.", c->name); goto out; } @@ -3804,8 +3811,8 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char if (!lxcpath) lxcpath = do_lxcapi_get_config_path(c); - ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname); - if (ret < 0 || ret >= MAXPATHLEN) { + ret = snprintf(newpath, PATH_MAX, "%s/%s/config", lxcpath, newname); + if (ret < 0 || ret >= PATH_MAX) { SYSERROR("clone: failed making config pathname"); goto out; } @@ -3828,7 +3835,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char } fd = open(newpath, O_WRONLY | O_CREAT | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd < 0) { SYSERROR("Failed to open \"%s\"", newpath); goto out; @@ -3853,8 +3860,8 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char saved_unexp_conf = NULL; c->lxc_conf->unexpanded_len = saved_unexp_len; - ret = snprintf(newpath, MAXPATHLEN, "%s/%s/rootfs", lxcpath, newname); - if (ret < 0 || ret >= MAXPATHLEN) { + ret = snprintf(newpath, PATH_MAX, "%s/%s/rootfs", lxcpath, newname); + if (ret < 0 || ret >= PATH_MAX) { SYSERROR("clone: failed making rootfs pathname"); goto out; } @@ -4103,13 +4110,13 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath) * If the old style snapshot path exists, use it * /var/lib/lxc -> /var/lib/lxcsnaps */ - ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path); - if (ret < 0 || ret >= MAXPATHLEN) + ret = snprintf(snappath, PATH_MAX, "%ssnaps", c->config_path); + if (ret < 0 || ret >= PATH_MAX) return false; if (dir_exists(snappath)) { - ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name); - if (ret < 0 || ret >= MAXPATHLEN) + ret = snprintf(snappath, PATH_MAX, "%ssnaps/%s", c->config_path, c->name); + if (ret < 0 || ret >= PATH_MAX) return false; return true; @@ -4119,8 +4126,8 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath) * Use the new style path * /var/lib/lxc -> /var/lib/lxc + c->name + /snaps + \0 */ - ret = snprintf(snappath, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name); - if (ret < 0 || ret >= MAXPATHLEN) + ret = snprintf(snappath, PATH_MAX, "%s/%s/snaps", c->config_path, c->name); + if (ret < 0 || ret >= PATH_MAX) return false; return true; @@ -4132,7 +4139,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) time_t timer; struct tm tm_info; struct lxc_container *c2; - char snappath[MAXPATHLEN], newname[20]; + char snappath[PATH_MAX], newname[20]; char buffer[25]; FILE *f; @@ -4252,12 +4259,12 @@ static char *get_snapcomment_path(char* snappath, char *name) static char *get_timestamp(char* snappath, char *name) { - char path[MAXPATHLEN], *s = NULL; + char path[PATH_MAX], *s = NULL; int ret, len; FILE *fin; - ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name); - if (ret < 0 || ret >= MAXPATHLEN) + ret = snprintf(path, PATH_MAX, "%s/%s/ts", snappath, name); + if (ret < 0 || ret >= PATH_MAX) return NULL; fin = fopen(path, "r"); @@ -4285,7 +4292,7 @@ static char *get_timestamp(char* snappath, char *name) static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret_snaps) { - char snappath[MAXPATHLEN], path2[MAXPATHLEN]; + char snappath[PATH_MAX], path2[PATH_MAX]; int count = 0, ret; struct dirent *direntp; struct lxc_snapshot *snaps =NULL, *nsnaps; @@ -4312,8 +4319,8 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot if (!strcmp(direntp->d_name, "..")) continue; - ret = snprintf(path2, MAXPATHLEN, "%s/%s/config", snappath, direntp->d_name); - if (ret < 0 || ret >= MAXPATHLEN) { + ret = snprintf(path2, PATH_MAX, "%s/%s/config", snappath, direntp->d_name); + if (ret < 0 || ret >= PATH_MAX) { ERROR("pathname too long"); goto out_free; } @@ -4370,7 +4377,7 @@ WRAP_API_1(int, lxcapi_snapshot_list, struct lxc_snapshot **) static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snapname, const char *newname) { - char clonelxcpath[MAXPATHLEN]; + char clonelxcpath[PATH_MAX]; int flags = 0; struct lxc_container *snap, *rest; struct lxc_storage *bdev; @@ -4508,7 +4515,7 @@ static bool remove_all_snapshots(const char *path) static bool do_lxcapi_snapshot_destroy(struct lxc_container *c, const char *snapname) { - char clonelxcpath[MAXPATHLEN]; + char clonelxcpath[PATH_MAX]; if (!c || !c->name || !c->config_path || !snapname) return false; @@ -4523,7 +4530,7 @@ WRAP_API_1(bool, lxcapi_snapshot_destroy, const char *) static bool do_lxcapi_snapshot_destroy_all(struct lxc_container *c) { - char clonelxcpath[MAXPATHLEN]; + char clonelxcpath[PATH_MAX]; if (!c || !c->name || !c->config_path) return false; @@ -4538,6 +4545,9 @@ WRAP_API(bool, lxcapi_snapshot_destroy_all) static bool do_lxcapi_may_control(struct lxc_container *c) { + if (!c) + return false; + return lxc_try_cmd(c->name, c->config_path) == 0; } @@ -4549,7 +4559,7 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add, int ret; char *tmp; pid_t pid; - char chrootpath[MAXPATHLEN]; + char chrootpath[PATH_MAX]; char *directory_path = NULL; pid = fork(); @@ -4569,8 +4579,8 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add, } /* prepare the path */ - ret = snprintf(chrootpath, MAXPATHLEN, "/proc/%d/root", init_pid); - if (ret < 0 || ret >= MAXPATHLEN) + ret = snprintf(chrootpath, PATH_MAX, "/proc/%d/root", init_pid); + if (ret < 0 || ret >= PATH_MAX) return false; ret = chroot(chrootpath); @@ -4963,7 +4973,7 @@ static int do_lxcapi_mount(struct lxc_container *c, const char *source, struct lxc_mount *mnt) { char *suff, *sret; - char template[MAXPATHLEN], path[MAXPATHLEN]; + char template[PATH_MAX], path[PATH_MAX]; pid_t pid, init_pid; struct stat sb; int ret = -1, fd = -EBADF; @@ -5665,3 +5675,16 @@ bool lxc_config_item_is_supported(const char *key) { return !!lxc_get_config(key); } + +bool lxc_has_api_extension(const char *extension) +{ + /* The NULL API extension is always present. :) */ + if (!extension) + return true; + + for (size_t i = 0; i < nr_api_extensions; i++) + if (strcmp(api_extensions[i], extension) == 0) + return true; + + return false; +}