mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-09 14:40:07 +00:00
lxc-ls: use fewer syscalls when doing ipc
Signed-off-by: Christian Brauner <christian.brauner@mailbox.org>
This commit is contained in:
parent
1bf4292e3f
commit
6daa3ea5ba
180
src/lxc/lxc_ls.c
180
src/lxc/lxc_ls.c
@ -103,6 +103,8 @@ static char *ls_get_config_item(struct lxc_container *c, const char *item,
|
|||||||
bool running);
|
bool running);
|
||||||
static char *ls_get_groups(struct lxc_container *c, bool running);
|
static char *ls_get_groups(struct lxc_container *c, bool running);
|
||||||
static char *ls_get_ips(struct lxc_container *c, const char *inet);
|
static char *ls_get_ips(struct lxc_container *c, const char *inet);
|
||||||
|
static int ls_recv_str(int fd, char **buf);
|
||||||
|
static int ls_send_str(int fd, const char *buf);
|
||||||
struct wrapargs {
|
struct wrapargs {
|
||||||
const struct lxc_arguments *args;
|
const struct lxc_arguments *args;
|
||||||
char **grps_must;
|
char **grps_must;
|
||||||
@ -146,14 +148,9 @@ static void ls_print_table(struct ls *l, struct lengths *lht,
|
|||||||
/*
|
/*
|
||||||
* id can only be 79 + \0 chars long.
|
* id can only be 79 + \0 chars long.
|
||||||
*/
|
*/
|
||||||
static int ls_read_and_grow_buf(const int rpipefd, char **save_buf,
|
|
||||||
const char *id, ssize_t nbytes_id,
|
|
||||||
char **read_buf, ssize_t *read_buf_len);
|
|
||||||
static int ls_remove_lock(const char *path, const char *name,
|
static int ls_remove_lock(const char *path, const char *name,
|
||||||
char **lockpath, size_t *len_lockpath, bool recalc);
|
char **lockpath, size_t *len_lockpath, bool recalc);
|
||||||
static int ls_serialize(int wpipefd, struct ls *n);
|
static int ls_serialize(int wpipefd, struct ls *n);
|
||||||
static int ls_write(const int wpipefd, const char *id, ssize_t nbytes_id,
|
|
||||||
const char *s);
|
|
||||||
static int my_parser(struct lxc_arguments *args, int c, char *arg);
|
static int my_parser(struct lxc_arguments *args, int c, char *arg);
|
||||||
|
|
||||||
static const struct option my_longopts[] = {
|
static const struct option my_longopts[] = {
|
||||||
@ -483,7 +480,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
|
|||||||
if (args->ls_nesting && running) {
|
if (args->ls_nesting && running) {
|
||||||
struct wrapargs wargs = (struct wrapargs){.args = NULL};
|
struct wrapargs wargs = (struct wrapargs){.args = NULL};
|
||||||
/* Open a socket so that the child can communicate with us. */
|
/* Open a socket so that the child can communicate with us. */
|
||||||
check = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, wargs.pipefd);
|
check = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wargs.pipefd);
|
||||||
if (check == -1)
|
if (check == -1)
|
||||||
goto put_and_next;
|
goto put_and_next;
|
||||||
|
|
||||||
@ -1004,67 +1001,86 @@ static int ls_remove_lock(const char *path, const char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ls_send_str(int fd, const char *buf)
|
||||||
|
{
|
||||||
|
size_t slen = 0;
|
||||||
|
if (buf)
|
||||||
|
slen = strlen(buf);
|
||||||
|
if (lxc_write_nointr(fd, &slen, sizeof(slen)) != sizeof(slen))
|
||||||
|
return -1;
|
||||||
|
if (slen > 0) {
|
||||||
|
if (lxc_write_nointr(fd, buf, slen) != (ssize_t)slen)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ls_serialize(int wpipefd, struct ls *n)
|
static int ls_serialize(int wpipefd, struct ls *n)
|
||||||
{
|
{
|
||||||
ssize_t nbytes = sizeof(n->ram);
|
ssize_t nbytes = sizeof(n->ram);
|
||||||
if (lxc_write_nointr(wpipefd, &n->ram, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->ram, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->swap);
|
nbytes = sizeof(n->swap);
|
||||||
if (lxc_write_nointr(wpipefd, &n->swap, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->swap, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->init);
|
nbytes = sizeof(n->init);
|
||||||
if (lxc_write_nointr(wpipefd, &n->init, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->init, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->autostart);
|
nbytes = sizeof(n->autostart);
|
||||||
if (lxc_write_nointr(wpipefd, &n->autostart, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->autostart, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->running);
|
nbytes = sizeof(n->running);
|
||||||
if (lxc_write_nointr(wpipefd, &n->running, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->running, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->nestlvl);
|
nbytes = sizeof(n->nestlvl);
|
||||||
if (lxc_write_nointr(wpipefd, &n->nestlvl, nbytes) != nbytes)
|
if (lxc_write_nointr(wpipefd, &n->nestlvl, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "NAME:", 5 + 1, n->name) == -1)
|
/* NAME */
|
||||||
|
if (ls_send_str(wpipefd, n->name) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "STATE:", 6 + 1, n->state) == -1)
|
/* STATE */
|
||||||
|
if (ls_send_str(wpipefd, n->state) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "GROUPS:", 7 + 1, n->groups) == -1)
|
/* GROUPS */
|
||||||
|
if (ls_send_str(wpipefd, n->groups) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "INTERFACE:", 10 + 1, n->interface) == -1)
|
/* INTERFACE */
|
||||||
|
if (ls_send_str(wpipefd, n->interface) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "IPV4:", 5 + 1, n->ipv4) == -1)
|
/* IPV4 */
|
||||||
|
if (ls_send_str(wpipefd, n->ipv4) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ls_write(wpipefd, "IPV6:", 5 + 1, n->ipv6) == -1)
|
/* IPV6 */
|
||||||
|
if (ls_send_str(wpipefd, n->ipv6) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ls_write(const int wpipefd, const char *id, ssize_t nbytes_id,
|
static int ls_recv_str(int fd, char **buf)
|
||||||
const char *s)
|
|
||||||
{
|
{
|
||||||
if (lxc_write_nointr(wpipefd, id, nbytes_id) != nbytes_id)
|
size_t slen = 0;
|
||||||
|
if (lxc_read_nointr(fd, &slen, sizeof(slen)) != sizeof(slen))
|
||||||
return -1;
|
return -1;
|
||||||
if (s) {
|
if (slen > 0) {
|
||||||
nbytes_id = strlen(s) + 1;
|
*buf = malloc(sizeof(char) * (slen + 1));
|
||||||
if (lxc_write_nointr(wpipefd, s, nbytes_id) != nbytes_id)
|
if (!*buf)
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
if (lxc_read_nointr(fd, *buf, slen) != (ssize_t)slen)
|
||||||
if (lxc_write_nointr(wpipefd, "\0", 1) != 1)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
(*buf)[slen] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,111 +1089,63 @@ static int ls_deserialize(int rpipefd, struct ls **m, size_t *len)
|
|||||||
struct ls *n;
|
struct ls *n;
|
||||||
size_t sublen = 0;
|
size_t sublen = 0;
|
||||||
ssize_t nbytes = 0;
|
ssize_t nbytes = 0;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
/* get length */
|
/* get length */
|
||||||
nbytes = sizeof(sublen);
|
nbytes = sizeof(sublen);
|
||||||
if (lxc_read_nointr(rpipefd, &sublen, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &sublen, (size_t)nbytes) != nbytes)
|
||||||
return -1;
|
|
||||||
|
|
||||||
char *serialized = NULL;
|
|
||||||
serialized = malloc(LINELEN * sizeof(char));
|
|
||||||
if (!serialized)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
while (sublen-- > 0) {
|
while (sublen-- > 0) {
|
||||||
n = ls_new(m, len);
|
n = ls_new(m, len);
|
||||||
if (!n)
|
if (!n)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->ram);
|
nbytes = sizeof(n->ram);
|
||||||
if (lxc_read_nointr(rpipefd, &n->ram, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->ram, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->swap);
|
nbytes = sizeof(n->swap);
|
||||||
if (lxc_read_nointr(rpipefd, &n->swap, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->swap, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->init);
|
nbytes = sizeof(n->init);
|
||||||
if (lxc_read_nointr(rpipefd, &n->init, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->init, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->autostart);
|
nbytes = sizeof(n->autostart);
|
||||||
if (lxc_read_nointr(rpipefd, &n->autostart, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->autostart, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->running);
|
nbytes = sizeof(n->running);
|
||||||
if (lxc_read_nointr(rpipefd, &n->running, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->running, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
return -1;
|
||||||
|
|
||||||
nbytes = sizeof(n->nestlvl);
|
nbytes = sizeof(n->nestlvl);
|
||||||
if (lxc_read_nointr(rpipefd, &n->nestlvl, nbytes) != nbytes)
|
if (lxc_read_nointr(rpipefd, &n->nestlvl, (size_t)nbytes) != nbytes)
|
||||||
goto out;
|
|
||||||
|
|
||||||
ssize_t buf_size = LINELEN;
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->name, "NAME:", 5 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->state, "STATE:", 6 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->groups, "GROUPS:", 7 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->interface, "INTERFACE:", 10 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->ipv4, "IPV4:", 5 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (ls_read_and_grow_buf(rpipefd, &n->ipv6, "IPV6:", 5 + 1, &serialized, &buf_size) == -1)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
free(serialized);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ls_read_and_grow_buf(const int rpipefd, char **save_buf,
|
|
||||||
const char *id, ssize_t nbytes_id,
|
|
||||||
char **read_buf, ssize_t *read_buf_len)
|
|
||||||
{
|
|
||||||
char *inc, *tmp;
|
|
||||||
char buf[80]; /* id can only be 79 + \0 long */
|
|
||||||
|
|
||||||
if (lxc_read_nointr(rpipefd, buf, nbytes_id) != nbytes_id)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (strcmp(id, buf) != 0)
|
/* NAME */
|
||||||
|
if (ls_recv_str(rpipefd, &n->name) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
inc = *read_buf;
|
/* STATE */
|
||||||
nbytes_id = 0;
|
if (ls_recv_str(rpipefd, &n->state) < 0)
|
||||||
do {
|
|
||||||
/* if the next read would overflow our buffer realloc */
|
|
||||||
if (nbytes_id + 1 >= *read_buf_len) {
|
|
||||||
*read_buf_len += LINELEN;
|
|
||||||
tmp = realloc(*read_buf, *read_buf_len);
|
|
||||||
if (!tmp)
|
|
||||||
return -1;
|
return -1;
|
||||||
*read_buf = tmp;
|
|
||||||
/* Put inc back to where it was before the realloc so we
|
|
||||||
* can keep on reading in the string. */
|
|
||||||
inc = *read_buf + nbytes_id;
|
|
||||||
}
|
|
||||||
/* only read one byte at a time */
|
|
||||||
if (lxc_read_nointr(rpipefd, inc, 1) != 1)
|
|
||||||
return -1;
|
|
||||||
nbytes_id++;
|
|
||||||
} while (*inc++ != '\0');
|
|
||||||
|
|
||||||
if (nbytes_id > 1) {
|
/* GROUPS */
|
||||||
/* save it where the caller wants it */
|
if (ls_recv_str(rpipefd, &n->groups) < 0)
|
||||||
*save_buf = strdup(*read_buf);
|
return -1;
|
||||||
if (!*save_buf)
|
|
||||||
|
/* INTERFACE */
|
||||||
|
if (ls_recv_str(rpipefd, &n->interface) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* IPV4 */
|
||||||
|
if (ls_recv_str(rpipefd, &n->ipv4) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* IPV6 */
|
||||||
|
if (ls_recv_str(rpipefd, &n->ipv6) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user