]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-ls: use fewer syscalls when doing ipc
authorChristian Brauner <christian.brauner@mailbox.org>
Wed, 27 Apr 2016 12:27:51 +0000 (14:27 +0200)
committerChristian Brauner <christian.brauner@mailbox.org>
Thu, 28 Apr 2016 21:45:00 +0000 (23:45 +0200)
Signed-off-by: Christian Brauner <christian.brauner@mailbox.org>
src/lxc/lxc_ls.c

index 1a9969aa8659e2ee216ef2a897dc0bc9dffa0cba..97c5d469de49c839b36d40581c2e24136c782351 100644 (file)
@@ -103,6 +103,8 @@ static char *ls_get_config_item(struct lxc_container *c, const char *item,
                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 int ls_recv_str(int fd, char **buf);
+static int ls_send_str(int fd, const char *buf);
 struct wrapargs {
        const struct lxc_arguments *args;
        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.
  */
-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,
                char **lockpath, size_t *len_lockpath, bool recalc);
 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 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) {
                        struct wrapargs wargs = (struct wrapargs){.args = NULL};
                        /* 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)
                                goto put_and_next;
 
@@ -1004,67 +1001,86 @@ static int ls_remove_lock(const char *path, const char *name,
        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)
 {
        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;
 
        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;
 
        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;
 
        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;
 
        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;
 
        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;
 
-       if (ls_write(wpipefd, "NAME:", 5 + 1, n->name) == -1)
+       /* NAME */
+       if (ls_send_str(wpipefd, n->name) < 0)
                return -1;
 
-       if (ls_write(wpipefd, "STATE:", 6 + 1, n->state) == -1)
+       /* STATE */
+       if (ls_send_str(wpipefd, n->state) < 0)
                return -1;
 
-       if (ls_write(wpipefd, "GROUPS:", 7 + 1, n->groups) == -1)
+       /* GROUPS */
+       if (ls_send_str(wpipefd, n->groups) < 0)
                return -1;
 
-       if (ls_write(wpipefd, "INTERFACE:", 10 + 1, n->interface) == -1)
+       /* INTERFACE */
+       if (ls_send_str(wpipefd, n->interface) < 0)
                return -1;
 
-       if (ls_write(wpipefd, "IPV4:", 5 + 1, n->ipv4) == -1)
+       /* IPV4 */
+       if (ls_send_str(wpipefd, n->ipv4) < 0)
                return -1;
 
-       if (ls_write(wpipefd, "IPV6:", 5 + 1, n->ipv6) == -1)
+       /* IPV6 */
+       if (ls_send_str(wpipefd, n->ipv6) < 0)
                return -1;
 
        return 0;
 }
 
-static int ls_write(const int wpipefd, const char *id, ssize_t nbytes_id,
-               const char *s)
+static int ls_recv_str(int fd, char **buf)
 {
-       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;
-       if (s) {
-               nbytes_id = strlen(s) + 1;
-               if (lxc_write_nointr(wpipefd, s, nbytes_id) != nbytes_id)
+       if (slen > 0) {
+               *buf = malloc(sizeof(char) * (slen + 1));
+               if (!*buf)
                        return -1;
-       } else {
-               if (lxc_write_nointr(wpipefd, "\0", 1) != 1)
+               if (lxc_read_nointr(fd, *buf, slen) != (ssize_t)slen)
                        return -1;
+               (*buf)[slen] = '\0';
        }
-
        return 0;
 }
 
@@ -1073,111 +1089,63 @@ static int ls_deserialize(int rpipefd, struct ls **m, size_t *len)
        struct ls *n;
        size_t sublen = 0;
        ssize_t nbytes = 0;
-       int ret = -1;
 
        /* get length */
        nbytes = sizeof(sublen);
-       if (lxc_read_nointr(rpipefd, &sublen, nbytes) != nbytes)
-               return -1;
-
-       char *serialized = NULL;
-       serialized = malloc(LINELEN * sizeof(char));
-       if (!serialized)
+       if (lxc_read_nointr(rpipefd, &sublen, (size_t)nbytes) != nbytes)
                return -1;
 
        while (sublen-- > 0) {
                n = ls_new(m, len);
                if (!n)
-                       goto out;
+                       return -1;
 
                nbytes = sizeof(n->ram);
-               if (lxc_read_nointr(rpipefd, &n->ram, nbytes) != nbytes)
-                       goto out;
+               if (lxc_read_nointr(rpipefd, &n->ram, (size_t)nbytes) != nbytes)
+                       return -1;
 
                nbytes = sizeof(n->swap);
-               if (lxc_read_nointr(rpipefd, &n->swap, nbytes) != nbytes)
-                       goto out;
+               if (lxc_read_nointr(rpipefd, &n->swap, (size_t)nbytes) != nbytes)
+                       return -1;
 
                nbytes = sizeof(n->init);
-               if (lxc_read_nointr(rpipefd, &n->init, nbytes) != nbytes)
-                       goto out;
+               if (lxc_read_nointr(rpipefd, &n->init, (size_t)nbytes) != nbytes)
+                       return -1;
 
                nbytes = sizeof(n->autostart);
-               if (lxc_read_nointr(rpipefd, &n->autostart, nbytes) != nbytes)
-                       goto out;
+               if (lxc_read_nointr(rpipefd, &n->autostart, (size_t)nbytes) != nbytes)
+                       return -1;
 
                nbytes = sizeof(n->running);
-               if (lxc_read_nointr(rpipefd, &n->running, nbytes) != nbytes)
-                       goto out;
+               if (lxc_read_nointr(rpipefd, &n->running, (size_t)nbytes) != nbytes)
+                       return -1;
 
                nbytes = sizeof(n->nestlvl);
-               if (lxc_read_nointr(rpipefd, &n->nestlvl, 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);
+               if (lxc_read_nointr(rpipefd, &n->nestlvl, (size_t)nbytes) != nbytes)
+                       return -1;
 
-       return ret;
-}
+               /* NAME */
+               if (ls_recv_str(rpipefd, &n->name) < 0)
+                       return -1;
 
-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 */
+               /* STATE */
+               if (ls_recv_str(rpipefd, &n->state) < 0)
+                       return -1;
 
-       if (lxc_read_nointr(rpipefd, buf, nbytes_id) != nbytes_id)
-               return -1;
+               /* GROUPS */
+               if (ls_recv_str(rpipefd, &n->groups) < 0)
+                       return -1;
 
-       if (strcmp(id, buf) != 0)
-               return -1;
+               /* INTERFACE */
+               if (ls_recv_str(rpipefd, &n->interface) < 0)
+                       return -1;
 
-       inc = *read_buf;
-       nbytes_id = 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;
-                       *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)
+               /* IPV4 */
+               if (ls_recv_str(rpipefd, &n->ipv4) < 0)
                        return -1;
-               nbytes_id++;
-       } while (*inc++ != '\0');
 
-       if (nbytes_id > 1) {
-               /* save it where the caller wants it */
-               *save_buf = strdup(*read_buf);
-               if (!*save_buf)
+               /* IPV6 */
+               if (ls_recv_str(rpipefd, &n->ipv6) < 0)
                        return -1;
        }