Commit b494d2dd by Serge Hallyn

add c->may_control

This is an api function which will return false if the container is running, and the caller may not talk to its monitor over its command socket. Otherwise - if the container is not running, or the caller may access it - it returns true. We can use this in several tools early on to prevent the segvs etc which we currently get. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarDwight Engen <dwight.engen@oracle.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent fe218ca3
...@@ -291,6 +291,36 @@ out: ...@@ -291,6 +291,36 @@ out:
return ret; return ret;
} }
int lxc_try_cmd(const char *name, const char *lxcpath)
{
int stopped, ret;
struct lxc_cmd_rr cmd = {
.req = { .cmd = LXC_CMD_GET_INIT_PID },
};
ret = lxc_cmd(name, &cmd, &stopped, lxcpath);
if (stopped)
return 0;
if (ret > 0 && cmd.rsp.ret < 0) {
errno = cmd.rsp.ret;
return -1;
}
if (ret > 0)
return 0;
/*
* At this point we weren't denied access, and the
* container *was* started. There was some inexplicable
* error in the protocol.
* I'm not clear on whether we should return -1 here, but
* we didn't receive a -EACCES, so technically it's not that
* we're not allowed to control the container - it's just not
* behaving.
*/
return 0;
}
/* Implentations of the commands and their callbacks */ /* Implentations of the commands and their callbacks */
/* /*
......
...@@ -88,5 +88,6 @@ extern int lxc_cmd_init(const char *name, struct lxc_handler *handler, ...@@ -88,5 +88,6 @@ extern int lxc_cmd_init(const char *name, struct lxc_handler *handler,
const char *lxcpath); const char *lxcpath);
extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr, extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
struct lxc_handler *handler); struct lxc_handler *handler);
extern int lxc_try_cmd(const char *name, const char *lxcpath);
#endif /* __commands_h */ #endif /* __commands_h */
...@@ -2592,6 +2592,11 @@ static bool lxcapi_snapshot_restore(struct lxc_container *c, char *snapname, cha ...@@ -2592,6 +2592,11 @@ static bool lxcapi_snapshot_restore(struct lxc_container *c, char *snapname, cha
return b; return b;
} }
static bool lxcapi_may_control(struct lxc_container *c)
{
return lxc_try_cmd(c->name, c->config_path) == 0;
}
static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...)
{ {
va_list ap; va_list ap;
...@@ -2711,6 +2716,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath ...@@ -2711,6 +2716,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->snapshot = lxcapi_snapshot; c->snapshot = lxcapi_snapshot;
c->snapshot_list = lxcapi_snapshot_list; c->snapshot_list = lxcapi_snapshot_list;
c->snapshot_restore = lxcapi_snapshot_restore; c->snapshot_restore = lxcapi_snapshot_restore;
c->may_control = lxcapi_may_control;
/* we'll allow the caller to update these later */ /* we'll allow the caller to update these later */
if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, c->config_path)) { if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, c->config_path)) {
......
...@@ -223,6 +223,12 @@ struct lxc_container { ...@@ -223,6 +223,12 @@ struct lxc_container {
* Returns true on success, false on failure. * Returns true on success, false on failure.
*/ */
bool (*snapshot_restore)(struct lxc_container *c, char *snapname, char *newname); bool (*snapshot_restore)(struct lxc_container *c, char *snapname, char *newname);
/*
* Return false if there is a control socket for the container monitor,
* and the caller may not access it. Return true otherwise.
*/
bool (*may_control)(struct lxc_container *c);
}; };
struct lxc_snapshot { struct lxc_snapshot {
......
...@@ -19,6 +19,7 @@ lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c ...@@ -19,6 +19,7 @@ lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c
lxc_usernic_test_CFLAGS = -DISTEST lxc_usernic_test_CFLAGS = -DISTEST
lxc_test_snapshot_SOURCES = snapshot.c lxc_test_snapshot_SOURCES = snapshot.c
lxc_test_concurrent_SOURCES = concurrent.c lxc_test_concurrent_SOURCES = concurrent.c
lxc_test_may_control_SOURCES = may_control.c
AM_CFLAGS=-I$(top_srcdir)/src \ AM_CFLAGS=-I$(top_srcdir)/src \
-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
...@@ -31,7 +32,7 @@ bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \ ...@@ -31,7 +32,7 @@ bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \ lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \
lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \ lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \
lxc-test-cgpath lxc-test-clonetest lxc-test-console lxc-usernic-test \ lxc-test-cgpath lxc-test-clonetest lxc-test-console lxc-usernic-test \
lxc-test-snapshot lxc-test-concurrent lxc-test-snapshot lxc-test-concurrent lxc-test-may-control
bin_SCRIPTS = lxc-test-usernic bin_SCRIPTS = lxc-test-usernic
...@@ -53,4 +54,5 @@ EXTRA_DIST = \ ...@@ -53,4 +54,5 @@ EXTRA_DIST = \
console.c \ console.c \
lxc-test-usernic \ lxc-test-usernic \
snapshot.c \ snapshot.c \
concurrent.c concurrent.c \
may_control.c
/* control.c
*
* Copyright 2013 Canonical, Inc
* Author: Serge Hallyn <serge.hallyn@ubuntu.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <lxc/lxccontainer.h>
void usage(char *me)
{
printf("Usage: %s name [lxcpath]\n", me);
exit(0);
}
int main(int argc, char *argv[])
{
char *lxcpath = NULL, *name;
bool may = false;
struct lxc_container *c;
if (argc < 2)
usage(argv[0]);
name = argv[1];
if (argc == 3)
lxcpath = argv[2];
c = lxc_container_new(name, lxcpath);
if (c)
may = c->may_control(c);
printf("You may%s control %s\n", may ? "" : " not", name);
exit(may ? 0 : 1);
}
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