Commit b656b42a by S.Çağlar Onur Committed by Stéphane Graber

handle hashed command socket names (v2)

With the new hashed command socket names (e8589841), it's possible to have something like below; [caglar@qop:~/go/src/github.com/lxc/go-lxc(master)] cat /proc/net/unix | grep lxc 0000000000000000: 00000002 00000000 00010000 0001 01 53465 @lxc/d086e835c86f4b8d/command [...] list_active_containers reads /proc/net/unix to find all running containers but this new format no longer includes the container name or its lxcpath. This patch introduces two new commands (LXC_CMD_GET_NAME and LXC_CMD_GET_LXCPATH) and starts to use those in list_active_containers call. changes since v1: - added sanity check proposed by Serge Signed-off-by: 's avatarS.Çağlar Onur <caglar@10ur.org> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent f3116a83
...@@ -75,13 +75,22 @@ ...@@ -75,13 +75,22 @@
lxc_log_define(lxc_commands, lxc); lxc_log_define(lxc_commands, lxc);
static int fill_sock_name(char *path, int len, const char *name, static int fill_sock_name(char *path, int len, const char *name,
const char *lxcpath) const char *lxcpath, const char *hashed_sock_name)
{ {
char *tmppath; char *tmppath;
size_t tmplen; size_t tmplen;
uint64_t hash; uint64_t hash;
int ret; int ret;
if (hashed_sock_name != NULL) {
ret = snprintf(path, len, "lxc/%s/command", hashed_sock_name);
if (ret < 0 || ret >= len) {
ERROR("Error writing to command sock path");
return -1;
}
return 0;
}
if (!lxcpath) { if (!lxcpath) {
lxcpath = lxc_global_config_value("lxc.lxcpath"); lxcpath = lxc_global_config_value("lxc.lxcpath");
if (!lxcpath) { if (!lxcpath) {
...@@ -91,7 +100,6 @@ static int fill_sock_name(char *path, int len, const char *name, ...@@ -91,7 +100,6 @@ static int fill_sock_name(char *path, int len, const char *name,
} }
ret = snprintf(path, len, "%s/%s/command", lxcpath, name); ret = snprintf(path, len, "%s/%s/command", lxcpath, name);
if (ret < 0) { if (ret < 0) {
ERROR("Error writing to command sock path"); ERROR("Error writing to command sock path");
return -1; return -1;
...@@ -108,7 +116,7 @@ static int fill_sock_name(char *path, int len, const char *name, ...@@ -108,7 +116,7 @@ static int fill_sock_name(char *path, int len, const char *name,
return -1; return -1;
} }
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT); hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
ret = snprintf(path, len, "lxc/%016" PRIx64 "/cmd_sock", hash); ret = snprintf(path, len, "lxc/%016" PRIx64 "/command", hash);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len) {
ERROR("Command socket name too long"); ERROR("Command socket name too long");
return -1; return -1;
...@@ -127,6 +135,8 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) ...@@ -127,6 +135,8 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
[LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags",
[LXC_CMD_GET_CGROUP] = "get_cgroup", [LXC_CMD_GET_CGROUP] = "get_cgroup",
[LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item",
[LXC_CMD_GET_NAME] = "get_name",
[LXC_CMD_GET_LXCPATH] = "get_lxcpath",
}; };
if (cmd >= LXC_CMD_MAX) if (cmd >= LXC_CMD_MAX)
...@@ -259,7 +269,7 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp) ...@@ -259,7 +269,7 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
* returned in the cmd response structure. * returned in the cmd response structure.
*/ */
static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped, static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
const char *lxcpath) const char *lxcpath, const char *hashed_sock_name)
{ {
int sock, ret = -1; int sock, ret = -1;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
...@@ -270,7 +280,7 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped, ...@@ -270,7 +280,7 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
*stopped = 0; *stopped = 0;
len = sizeof(path)-1; len = sizeof(path)-1;
if (fill_sock_name(offset, len, name, lxcpath)) if (fill_sock_name(offset, len, name, lxcpath, hashed_sock_name))
return -1; return -1;
sock = lxc_abstract_unix_connect(path); sock = lxc_abstract_unix_connect(path);
...@@ -329,7 +339,7 @@ int lxc_try_cmd(const char *name, const char *lxcpath) ...@@ -329,7 +339,7 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_GET_INIT_PID }, .req = { .cmd = LXC_CMD_GET_INIT_PID },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (stopped) if (stopped)
return 0; return 0;
...@@ -369,7 +379,7 @@ pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath) ...@@ -369,7 +379,7 @@ pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_GET_INIT_PID }, .req = { .cmd = LXC_CMD_GET_INIT_PID },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -399,7 +409,7 @@ int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath) ...@@ -399,7 +409,7 @@ int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_GET_CLONE_FLAGS }, .req = { .cmd = LXC_CMD_GET_CLONE_FLAGS },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -438,7 +448,7 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, ...@@ -438,7 +448,7 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
}, },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
...@@ -497,7 +507,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item, ...@@ -497,7 +507,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
}, },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
...@@ -548,7 +558,7 @@ lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath) ...@@ -548,7 +558,7 @@ lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_GET_STATE } .req = { .cmd = LXC_CMD_GET_STATE }
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0 && stopped) if (ret < 0 && stopped)
return STOPPED; return STOPPED;
...@@ -589,7 +599,7 @@ int lxc_cmd_stop(const char *name, const char *lxcpath) ...@@ -589,7 +599,7 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_STOP }, .req = { .cmd = LXC_CMD_STOP },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) { if (ret < 0) {
if (stopped) { if (stopped) {
INFO("'%s' is already stopped", name); INFO("'%s' is already stopped", name);
...@@ -650,7 +660,7 @@ int lxc_cmd_console_winch(const char *name, const char *lxcpath) ...@@ -650,7 +660,7 @@ int lxc_cmd_console_winch(const char *name, const char *lxcpath)
.req = { .cmd = LXC_CMD_CONSOLE_WINCH }, .req = { .cmd = LXC_CMD_CONSOLE_WINCH },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -685,7 +695,7 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath) ...@@ -685,7 +695,7 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
.req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) }, .req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -744,7 +754,81 @@ out_close: ...@@ -744,7 +754,81 @@ out_close:
return 1; return 1;
} }
/*
* lxc_cmd_get_name: Returns the name of the container
*
* @hashed_sock_name: hashed socket name
*
* Returns the name on success, NULL on failure.
*/
char *lxc_cmd_get_name(const char *hashed_sock_name)
{
int ret, stopped;
struct lxc_cmd_rr cmd = {
.req = { .cmd = LXC_CMD_GET_NAME},
};
ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
if (ret < 0) {
return NULL;
}
if (cmd.rsp.ret == 0)
return cmd.rsp.data;
return NULL;
}
static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
struct lxc_cmd_rsp rsp;
memset(&rsp, 0, sizeof(rsp));
rsp.data = handler->name;
rsp.datalen = strlen(handler->name) + 1;
rsp.ret = 0;
return lxc_cmd_rsp_send(fd, &rsp);
}
/*
* lxc_cmd_get_lxcpath: Returns the lxcpath of the container
*
* @hashed_sock_name: hashed socket name
*
* Returns the lxcpath on success, NULL on failure.
*/
char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
{
int ret, stopped;
struct lxc_cmd_rr cmd = {
.req = { .cmd = LXC_CMD_GET_LXCPATH},
};
ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
if (ret < 0) {
return NULL;
}
if (cmd.rsp.ret == 0)
return cmd.rsp.data;
return NULL;
}
static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
struct lxc_cmd_rsp rsp;
memset(&rsp, 0, sizeof(rsp));
rsp.data = (char *)handler->lxcpath;
rsp.datalen = strlen(handler->lxcpath) + 1;
rsp.ret = 0;
return lxc_cmd_rsp_send(fd, &rsp);
}
static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler) struct lxc_handler *handler)
...@@ -760,6 +844,8 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, ...@@ -760,6 +844,8 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
[LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
[LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
[LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
[LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
[LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
}; };
if (req->cmd >= LXC_CMD_MAX) { if (req->cmd >= LXC_CMD_MAX) {
...@@ -887,7 +973,7 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler, ...@@ -887,7 +973,7 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
int len; int len;
len = sizeof(path)-1; len = sizeof(path)-1;
if (fill_sock_name(offset, len, name, lxcpath)) if (fill_sock_name(offset, len, name, lxcpath, NULL))
return -1; return -1;
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0); fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
......
...@@ -41,6 +41,8 @@ typedef enum { ...@@ -41,6 +41,8 @@ typedef enum {
LXC_CMD_GET_CLONE_FLAGS, LXC_CMD_GET_CLONE_FLAGS,
LXC_CMD_GET_CGROUP, LXC_CMD_GET_CGROUP,
LXC_CMD_GET_CONFIG_ITEM, LXC_CMD_GET_CONFIG_ITEM,
LXC_CMD_GET_NAME,
LXC_CMD_GET_LXCPATH,
LXC_CMD_MAX, LXC_CMD_MAX,
} lxc_cmd_t; } lxc_cmd_t;
...@@ -77,6 +79,8 @@ extern char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, ...@@ -77,6 +79,8 @@ extern char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
const char *subsystem); const char *subsystem);
extern int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath); extern int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath);
extern char *lxc_cmd_get_config_item(const char *name, const char *item, const char *lxcpath); extern char *lxc_cmd_get_config_item(const char *name, const char *item, const char *lxcpath);
extern char *lxc_cmd_get_name(const char *hashed_sock);
extern char *lxc_cmd_get_lxcpath(const char *hashed_sock);
extern pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath); extern pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath);
extern lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath); extern lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath);
extern int lxc_cmd_stop(const char *name, const char *lxcpath); extern int lxc_cmd_stop(const char *name, const char *lxcpath);
......
...@@ -3571,6 +3571,7 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -3571,6 +3571,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
char **ct_name = NULL; char **ct_name = NULL;
size_t len = 0; size_t len = 0;
struct lxc_container *c; struct lxc_container *c;
bool is_hashed;
if (!lxcpath) if (!lxcpath)
lxcpath = lxc_global_config_value("lxc.lxcpath"); lxcpath = lxc_global_config_value("lxc.lxcpath");
...@@ -3586,6 +3587,7 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -3586,6 +3587,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
return -1; return -1;
while (getline(&line, &len, f) != -1) { while (getline(&line, &len, f) != -1) {
char *p = strrchr(line, ' '), *p2; char *p = strrchr(line, ' '), *p2;
if (!p) if (!p)
continue; continue;
...@@ -3593,9 +3595,17 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -3593,9 +3595,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
if (*p != 0x40) if (*p != 0x40)
continue; continue;
p++; p++;
if (strncmp(p, lxcpath, lxcpath_len) != 0)
continue; is_hashed = false;
if (strncmp(p, lxcpath, lxcpath_len) == 0) {
p += lxcpath_len; p += lxcpath_len;
} else if (strncmp(p, "lxc/", 4) == 0) {
p += 4;
is_hashed = true;
} else {
continue;
}
while (*p == '/') while (*p == '/')
p++; p++;
...@@ -3605,6 +3615,12 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -3605,6 +3615,12 @@ int list_active_containers(const char *lxcpath, char ***nret,
continue; continue;
*p2 = '\0'; *p2 = '\0';
if (is_hashed) {
if (strncmp(lxcpath, lxc_cmd_get_lxcpath(p), lxcpath_len) != 0)
continue;
p = lxc_cmd_get_name(p);
}
if (array_contains(&ct_name, p, ct_name_cnt)) if (array_contains(&ct_name, p, ct_name_cnt))
continue; continue;
......
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