[lxc-devel] [PATCH] handle unprivileged user calls more gracefully (v2)
S.Çağlar Onur
caglar at 10ur.org
Sat Jan 18 18:31:14 UTC 2014
On Sat, Jan 18, 2014 at 12:38 AM, S.Çağlar Onur <caglar at 10ur.org> wrote:
> On Sat, Jan 18, 2014 at 12:12 AM, Stéphane Graber <stgraber at ubuntu.com> wrote:
>> On Sat, Jan 18, 2014 at 12:03:19AM -0500, S.Çağlar Onur wrote:
>>> On Sat, Jan 18, 2014 at 12:00 AM, Stéphane Graber <stgraber at ubuntu.com> wrote:
>>> > On Fri, Jan 17, 2014 at 11:58:17PM -0500, S.Çağlar Onur wrote:
>>> >> On Fri, Jan 17, 2014 at 11:49 PM, Stéphane Graber <stgraber at ubuntu.com> wrote:
>>> >> > On Fri, Jan 17, 2014 at 11:34:50PM -0500, S.Çağlar Onur wrote:
>>> >> >> Return an error if the function is not supposed to be called by an unprivileged user.
>>> >> >> Otherwise those calls fail in the middle of their execution with different reasons.
>>> >> >>
>>> >> >> changes since v1:
>>> >> >> - am_unpriv is now a simple geteuid check,
>>> >> >> - API functions are now providing error messages,
>>> >> >> - lxc-info, lxc-attach and lxc-execute are now checking geteuid
>>> >> >>
>>> >> >
>>> >> > That looks much better to me, though I disagree that lxc-execute doesn't
>>> >> > work. It certainly is a bit restricted compared ot its system
>>> >> > equivalent, but all of those limitations will be the same as with
>>> >> > lxc-start.
>>> >> >
>>> >> > stgraber at castiana:~$ lxc-execute -n p1 -- /bin/bash
>>> >> > lxc-init: failed to mount /proc : Device or resource busy
>>> >> > lxc-init: failed to mount /dev/shm : No such file or directory
>>> >> > root at p1:/#
>>> >>
>>> >> Hmm then I must be having some kind of trouble here with it. I can
>>> >> start/stop containers just fine
>>> >>
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples] lxc-start -d -n rubik
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples] lxc-ls --fancy
>>> >> NAME STATE IPV4 IPV6 AUTOSTART
>>> >> -------------------------------------------
>>> >> rubik RUNNING UNKNOWN UNKNOWN NO
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples] lxc-stop -n rubik
>>> >>
>>> >> sudo variant works just fine
>>> >>
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples] sudo
>>> >> lxc-execute -n p1 -- /bin/bash
>>> >> root at oOo:/home/caglar/go/src/github.com/caglar10ur/lxc/examples# exit
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples]
>>> >>
>>> >> but plain one gives this
>>> >>
>>> >> [caglar at oOo:~/go/src/github.com/caglar10ur/lxc/examples] lxc-execute
>>> >> -n p1 -- /bin/bash
>>> >> lxc-execute: Operation not permitted - failed to clone
>>> >>
>>> >> lxc-execute: failed to clone(0x6c020000): Operation not permitted
>>> >> lxc-execute: Operation not permitted - failed to fork into a new namespace
>>> >> lxc-execute: failed to spawn 'p1'
>>> >
>>> > Try rubik instead of p1.
>>>
>>> [caglar at oOo:~/Projects/lxc(master)] lxc-execute -n rubik -- /bin/bash
>>> lxc-execute: No such file or directory - failed to mount
>>> '/sys/firmware/efi/efivars' on
>>> '/usr/lib/x86_64-linux-gnu/lxc/rootfs/sys/firmware/efi/efivars'
>
>> That's because you aren't on an EFI system.
>
> Yep and commenting out that line from
> /usr/share/lxc/config/ubuntu.userns.conf solves that
>
>>
>>> lxc-execute: Failed to find an lxc-init
>>> lxc-execute: invalid sequence number 1. expected 4
>>> lxc-execute: failed to spawn 'rubik'
>>
>> That's because you don't have lxc-init installed in the container's rootfs.
>
> Ahh, actually I have but apparently my host system uses
> "/usr/libexec/lxc/lxc-init" but installing lxc package inside the
> container puts the lxc-init into
> "/usr/lib/x86_64-linux-gnu/lxc/lxc-init". Adding some debug code
> helped to find that
>
> [caglar at oOo:~/Projects/lxc(master)] lxc-execute -n rubik -- ls
> lxc-execute: LOOKING /usr/libexec/lxc/lxc-init
> lxc-execute: LOOKING /usr/lib/lxc/lxc-init
> lxc-execute: LOOKING /sbin/lxc-init
> lxc-execute: Failed to find an lxc-init
>
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/hugetlb/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/perf_event/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/blkio/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/freezer/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/devices/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/memory/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/cpuacct/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/cpu/caglar/rubik-3
>>> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
>>> /sys/fs/cgroup/cpuset/caglar/rubik-3
>>
>> That's because the container is already running.
>
> Nope, guessing those are just artifact of not being able to find lxc-init.
>
> [caglar at oOo:~/Projects/lxc(master)] lxc-ls --fancy
> NAME STATE IPV4 IPV6 AUTOSTART
> -------------------------------------
> rubik STOPPED - - NO
> [caglar at oOo:~/Projects/lxc(master)] lxc-execute -n rubik -- /bin/bash
> lxc-execute: Failed to find an lxc-init
> lxc-execute: invalid sequence number 1. expected 4
> lxc-execute: failed to spawn 'rubik'
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/hugetlb/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/perf_event/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/blkio/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/freezer/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/devices/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/memory/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/cpuacct/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/cpu/caglar/rubik-16
> lxc-execute: Device or resource busy - cgroup_rmdir: failed to delete
> /sys/fs/cgroup/cpuset/caglar/rubik-16
> [caglar at oOo:~/Projects/lxc(master)]
>
> Will try to fix the path confusion and try again, tomorrow :)
Still couldn't manage to run lxc-execute by I'm assuming this is all
happening because of my system. I'll drop lxc_execute.c part of this
patch and add following change to it to fix lxc-ls (for non-running
container case otherwise it shows and error) and then resubmit, if you
are OK with it.
diff --git a/src/lxc/lxc-ls b/src/lxc/lxc-ls
index 1ed7da4..68c0b41 100755
--- a/src/lxc/lxc-ls
+++ b/src/lxc/lxc-ls
@@ -264,14 +264,14 @@ for container_name in
lxc.list_containers(config_path=nest_lxcpath):
continue
# FIXME: We should get get_ips working as non-root
- if container.running and (not SUPPORT_SETNS_NET
- or os.geteuid() != 0):
- entry[protocol] = 'UNKNOWN'
- continue
-
- ips = container.get_ips(family=family)
- if ips:
- entry[protocol] = ", ".join(ips)
+ if container.running:
+ if not SUPPORT_SETNS_NET or os.geteuid() != 0:
+ entry[protocol] = 'UNKNOWN'
+ continue
+
+ ips = container.get_ips(family=family)
+ if ips:
+ entry[protocol] = ", ".join(ips)
# Append the container
containers.append(entry)
>>>
>>> I realized that I'm using cgmanager on this box, maybe I'm observing
>>> this because of it?
>>>
>>> >>
>>> >>
>>> >> > It may be worth teaching lxc_init a bit about unprivileged containers
>>> >> > but besides that, if all I wanted to do was run a command using that
>>> >> > container rootfs, it'd work.
>>> >> >
>>> >> > The rest I think looks good and hopefully we can drop quite a few of
>>> >> > those before the 1.0 release. It shouldn't be too hard to get basic dir
>>> >> > cloning working and a good chunk of the rest would get resolved if we
>>> >> > had attach working.
>>> >> >
>>> >> > Ideally, we'd release with only the snapshot functions and the
>>> >> > add/remove device function disabled as those simply aren't doable at
>>> >> > this point.
>>> >> >
>>> >> >> Signed-off-by: S.Çağlar Onur <caglar at 10ur.org>
>>> >> >> ---
>>> >> >> src/lxc/lxc_attach.c | 5 ++++
>>> >> >> src/lxc/lxc_execute.c | 5 ++++
>>> >> >> src/lxc/lxc_info.c | 20 +++++++------
>>> >> >> src/lxc/lxccontainer.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++----
>>> >> >> 4 files changed, 95 insertions(+), 13 deletions(-)
>>> >> >>
>>> >> >> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
>>> >> >> index 6744c05..1159d09 100644
>>> >> >> --- a/src/lxc/lxc_attach.c
>>> >> >> +++ b/src/lxc/lxc_attach.c
>>> >> >> @@ -188,6 +188,11 @@ int main(int argc, char *argv[])
>>> >> >> lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
>>> >> >> lxc_attach_command_t command;
>>> >> >>
>>> >> >> + if (geteuid() != 0) {
>>> >> >> + ERROR("lxc-attach is not currently supported with unprivileged containers");
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> ret = lxc_caps_init();
>>> >> >> if (ret)
>>> >> >> return ret;
>>> >> >> diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c
>>> >> >> index 6a54bf6..8177ed3 100644
>>> >> >> --- a/src/lxc/lxc_execute.c
>>> >> >> +++ b/src/lxc/lxc_execute.c
>>> >> >> @@ -92,6 +92,11 @@ int main(int argc, char *argv[])
>>> >> >> char *rcfile;
>>> >> >> struct lxc_conf *conf;
>>> >> >>
>>> >> >> + if (geteuid() != 0) {
>>> >> >> + ERROR("lxc-execute is not currently supported with unprivileged containers");
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> lxc_list_init(&defines);
>>> >> >>
>>> >> >> if (lxc_caps_init())
>>> >> >> diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c
>>> >> >> index b515087..0990036 100644
>>> >> >> --- a/src/lxc/lxc_info.c
>>> >> >> +++ b/src/lxc/lxc_info.c
>>> >> >> @@ -310,15 +310,19 @@ static int print_info(const char *name, const char *lxcpath)
>>> >> >> }
>>> >> >>
>>> >> >> if (ips) {
>>> >> >> - char **addresses = c->get_ips(c, NULL, NULL, 0);
>>> >> >> - if (addresses) {
>>> >> >> - char *address;
>>> >> >> - i = 0;
>>> >> >> - while (addresses[i]) {
>>> >> >> - address = addresses[i];
>>> >> >> - print_info_msg_str("IP:", address);
>>> >> >> - i++;
>>> >> >> + if (geteuid() == 0) {
>>> >> >> + char **addresses = c->get_ips(c, NULL, NULL, 0);
>>> >> >> + if (addresses) {
>>> >> >> + char *address;
>>> >> >> + i = 0;
>>> >> >> + while (addresses[i]) {
>>> >> >> + address = addresses[i];
>>> >> >> + print_info_msg_str("IP:", address);
>>> >> >> + i++;
>>> >> >> + }
>>> >> >> }
>>> >> >> + } else {
>>> >> >> + print_info_msg_str("IP:", "UNKNOWN");
>>> >> >> }
>>> >> >> }
>>> >> >>
>>> >> >> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
>>> >> >> index 0bebdff..368cb46 100644
>>> >> >> --- a/src/lxc/lxccontainer.c
>>> >> >> +++ b/src/lxc/lxccontainer.c
>>> >> >> @@ -62,8 +62,14 @@
>>> >> >>
>>> >> >> #define MAX_BUFFER 4096
>>> >> >>
>>> >> >> +#define NOT_SUPPORTED_ERROR "the requested function %s is not currently supported with unprivileged containers"
>>> >> >> +
>>> >> >> lxc_log_define(lxc_container, lxc);
>>> >> >>
>>> >> >> +inline static bool am_unpriv() {
>>> >> >> + return geteuid() != 0;
>>> >> >> +}
>>> >> >> +
>>> >> >> static bool file_exists(const char *f)
>>> >> >> {
>>> >> >> struct stat statbuf;
>>> >> >> @@ -1489,6 +1495,11 @@ static char** lxcapi_get_interfaces(struct lxc_container *c)
>>> >> >> char **interfaces = NULL;
>>> >> >> int old_netns = -1, new_netns = -1;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + goto out;
>>> >> >> + }
>>> >> >> +
>>> >> >> if (!enter_to_ns(c, &old_netns, &new_netns))
>>> >> >> goto out;
>>> >> >>
>>> >> >> @@ -1538,6 +1549,11 @@ static char** lxcapi_get_ips(struct lxc_container *c, const char* interface, con
>>> >> >> char *address = NULL;
>>> >> >> int old_netns = -1, new_netns = -1;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + goto out;
>>> >> >> + }
>>> >> >> +
>>> >> >> if (!enter_to_ns(c, &old_netns, &new_netns))
>>> >> >> goto out;
>>> >> >>
>>> >> >> @@ -1818,7 +1834,7 @@ static int lxc_rmdir_onedev_wrapper(void *data)
>>> >> >> static bool lxcapi_destroy(struct lxc_container *c)
>>> >> >> {
>>> >> >> struct bdev *r = NULL;
>>> >> >> - bool bret = false, am_unpriv;
>>> >> >> + bool bret = false;
>>> >> >> int ret;
>>> >> >>
>>> >> >> if (!c || !lxcapi_is_defined(c))
>>> >> >> @@ -1833,14 +1849,12 @@ static bool lxcapi_destroy(struct lxc_container *c)
>>> >> >> goto out;
>>> >> >> }
>>> >> >>
>>> >> >> - am_unpriv = c->lxc_conf && geteuid() != 0 && !lxc_list_empty(&c->lxc_conf->id_map);
>>> >> >> -
>>> >> >> if (c->lxc_conf && has_snapshots(c)) {
>>> >> >> ERROR("container %s has dependent snapshots", c->name);
>>> >> >> goto out;
>>> >> >> }
>>> >> >>
>>> >> >> - if (!am_unpriv && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
>>> >> >> + if (!am_unpriv() && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
>>> >> >> r = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
>>> >> >> if (r) {
>>> >> >> if (r->ops->destroy(r) < 0) {
>>> >> >> @@ -1857,7 +1871,7 @@ static bool lxcapi_destroy(struct lxc_container *c)
>>> >> >> const char *p1 = lxcapi_get_config_path(c);
>>> >> >> char *path = alloca(strlen(p1) + strlen(c->name) + 2);
>>> >> >> sprintf(path, "%s/%s", p1, c->name);
>>> >> >> - if (am_unpriv)
>>> >> >> + if (am_unpriv())
>>> >> >> ret = userns_exec_1(c->lxc_conf, lxc_rmdir_onedev_wrapper, path);
>>> >> >> else
>>> >> >> ret = lxc_rmdir_onedev(path);
>>> >> >> @@ -2406,6 +2420,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
>>> >> >> if (!c || !c->is_defined(c))
>>> >> >> return NULL;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return NULL;
>>> >> >> + }
>>> >> >> +
>>> >> >> if (container_mem_lock(c))
>>> >> >> return NULL;
>>> >> >>
>>> >> >> @@ -2515,6 +2534,11 @@ static bool lxcapi_rename(struct lxc_container *c, const char *newname)
>>> >> >> if (!c || !c->name || !c->config_path)
>>> >> >> return false;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return false;
>>> >> >> + }
>>> >> >> +
>>> >> >> bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
>>> >> >> if (!bdev) {
>>> >> >> ERROR("Failed to find original backing store type");
>>> >> >> @@ -2543,6 +2567,11 @@ static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_functio
>>> >> >> if (!c)
>>> >> >> return -1;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> return lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process);
>>> >> >> }
>>> >> >>
>>> >> >> @@ -2555,6 +2584,11 @@ static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t
>>> >> >> if (!c)
>>> >> >> return -1;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> command.program = (char*)program;
>>> >> >> command.argv = (char**)argv;
>>> >> >> r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
>>> >> >> @@ -2587,6 +2621,11 @@ static int lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
>>> >> >> struct lxc_container *c2;
>>> >> >> char snappath[MAXPATHLEN], newname[20];
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> // /var/lib/lxc -> /var/lib/lxcsnaps \0
>>> >> >> ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
>>> >> >> if (ret < 0 || ret >= MAXPATHLEN)
>>> >> >> @@ -2724,6 +2763,12 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r
>>> >> >>
>>> >> >> if (!c || !lxcapi_is_defined(c))
>>> >> >> return -1;
>>> >> >> +
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> // snappath is ${lxcpath}snaps/${lxcname}/
>>> >> >> dirlen = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
>>> >> >> if (dirlen < 0 || dirlen >= MAXPATHLEN) {
>>> >> >> @@ -2802,6 +2847,11 @@ static bool lxcapi_snapshot_restore(struct lxc_container *c, const char *snapnam
>>> >> >> if (!c || !c->name || !c->config_path)
>>> >> >> return false;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return false;
>>> >> >> + }
>>> >> >> +
>>> >> >> bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
>>> >> >> if (!bdev) {
>>> >> >> ERROR("Failed to find original backing store type");
>>> >> >> @@ -2851,6 +2901,11 @@ static bool lxcapi_snapshot_destroy(struct lxc_container *c, const char *snapnam
>>> >> >> if (!c || !c->name || !c->config_path)
>>> >> >> return false;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return false;
>>> >> >> + }
>>> >> >> +
>>> >> >> ret = snprintf(clonelxcpath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
>>> >> >> if (ret < 0 || ret >= MAXPATHLEN)
>>> >> >> goto err;
>>> >> >> @@ -2967,11 +3022,19 @@ out:
>>> >> >>
>>> >> >> static bool lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
>>> >> >> {
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return false;
>>> >> >> + }
>>> >> >> return add_remove_device_node(c, src_path, dest_path, true);
>>> >> >> }
>>> >> >>
>>> >> >> static bool lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
>>> >> >> {
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return false;
>>> >> >> + }
>>> >> >> return add_remove_device_node(c, src_path, dest_path, false);
>>> >> >> }
>>> >> >>
>>> >> >> @@ -2984,6 +3047,11 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t
>>> >> >> if (!c)
>>> >> >> return -1;
>>> >> >>
>>> >> >> + if (am_unpriv()) {
>>> >> >> + ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
>>> >> >> + return -1;
>>> >> >> + }
>>> >> >> +
>>> >> >> va_start(ap, arg);
>>> >> >> argv = lxc_va_arg_list_to_argv_const(ap, 1);
>>> >> >> va_end(ap);
>>> >> >> --
>>> >> >> 1.8.3.2
>>> >> >>
>>> >> >> _______________________________________________
>>> >> >> lxc-devel mailing list
>>> >> >> lxc-devel at lists.linuxcontainers.org
>>> >> >> http://lists.linuxcontainers.org/listinfo/lxc-devel
>>> >> >
>>> >> > --
>>> >> > Stéphane Graber
>>> >> > Ubuntu developer
>>> >> > http://www.ubuntu.com
>>> >> >
>>> >> > _______________________________________________
>>> >> > lxc-devel mailing list
>>> >> > lxc-devel at lists.linuxcontainers.org
>>> >> > http://lists.linuxcontainers.org/listinfo/lxc-devel
>>> >> >
>>> >>
>>> >>
>>> >>
>>> >> --
>>> >> S.Çağlar Onur <caglar at 10ur.org>
>>> >> _______________________________________________
>>> >> lxc-devel mailing list
>>> >> lxc-devel at lists.linuxcontainers.org
>>> >> http://lists.linuxcontainers.org/listinfo/lxc-devel
>>> >
>>> > --
>>> > Stéphane Graber
>>> > Ubuntu developer
>>> > http://www.ubuntu.com
>>> >
>>> > _______________________________________________
>>> > lxc-devel mailing list
>>> > lxc-devel at lists.linuxcontainers.org
>>> > http://lists.linuxcontainers.org/listinfo/lxc-devel
>>> >
>>>
>>>
>>>
>>> --
>>> S.Çağlar Onur <caglar at 10ur.org>
>>> _______________________________________________
>>> lxc-devel mailing list
>>> lxc-devel at lists.linuxcontainers.org
>>> http://lists.linuxcontainers.org/listinfo/lxc-devel
>>
>> --
>> Stéphane Graber
>> Ubuntu developer
>> http://www.ubuntu.com
>>
>> _______________________________________________
>> lxc-devel mailing list
>> lxc-devel at lists.linuxcontainers.org
>> http://lists.linuxcontainers.org/listinfo/lxc-devel
>>
>
>
>
> --
> S.Çağlar Onur <caglar at 10ur.org>
--
S.Çağlar Onur <caglar at 10ur.org>
More information about the lxc-devel
mailing list