]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
repackage previous code to new commands.c
authorMichel Normand <normand@fr.ibm.com>
Wed, 7 Oct 2009 14:06:08 +0000 (16:06 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Wed, 7 Oct 2009 14:06:08 +0000 (16:06 +0200)
move some code of start.c to new commands.c and to console.c

Signed-off-by: Michel Normand <normand@fr.ibm.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/Makefile.am
src/lxc/commands.c [new file with mode: 0644]
src/lxc/commands.h
src/lxc/console.c
src/lxc/start.c

index 269c618d95520d30f1533258adcd1290cd74d28f..641abf6cbc4555662ae5de16ddef541d87d1e8fb 100644 (file)
@@ -19,7 +19,7 @@ pkginclude_HEADERS = \
 
 liblxc_la_SOURCES = \
        arguments.c arguments.h \
-       commands.h \
+       commands.c commands.h \
        create.c \
        destroy.c \
        start.c \
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
new file mode 100644 (file)
index 0000000..98e6121
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2009
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+
+#include <lxc/lxc.h>
+
+#include "commands.h"
+#include "mainloop.h"
+#include "af_unix.h"
+
+lxc_log_define(lxc_commands, lxc);
+
+/*----------------------------------------------------------------------------
+ * functions used by processes requesting command to lxc-start
+ *--------------------------------------------------------------------------*/
+static int receive_answer(int sock, struct lxc_answer *answer)
+{
+       int ret;
+
+       ret = lxc_af_unix_recv_fd(sock, &answer->fd, answer, sizeof(*answer));
+       if (ret < 0)
+               ERROR("failed to receive answer for the command");
+
+       return ret;
+}
+
+extern int lxc_command(const char *name, struct lxc_command *command)
+{
+       struct sockaddr_un addr = { 0 };
+       int sock, ret = -1;
+       char *offset = &addr.sun_path[1];
+
+       snprintf(addr.sun_path, sizeof(addr.sun_path), "@%s", name);
+       addr.sun_path[0] = '\0';
+
+       sock = lxc_af_unix_connect(addr.sun_path);
+       if (sock < 0) {
+               WARN("failed to connect to '@%s': %s", offset, strerror(errno));
+               return -1;
+       }
+
+       ret = lxc_af_unix_send_credential(sock, &command->request,
+                                       sizeof(command->request));
+       if (ret < 0) {
+               SYSERROR("failed to send credentials");
+               goto out_close;
+       }
+
+       if (ret != sizeof(command->request)) {
+               SYSERROR("message only partially sent to '@%s'", offset);
+               goto out_close;
+       }
+
+       ret = receive_answer(sock, &command->answer);
+       if (ret < 0)
+               goto out_close;
+out:
+       return ret;
+out_close:
+       close(sock);
+       goto out;
+}
+
+/*----------------------------------------------------------------------------
+ * functions used by lxc-start process
+ *--------------------------------------------------------------------------*/
+extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info);
+extern int lxc_console_callback(int fd, struct lxc_request *request,
+                       struct lxc_handler *handler);
+
+static int trigger_command(int fd, struct lxc_request *request,
+                       struct lxc_handler *handler)
+{
+       typedef int (*callback)(int, struct lxc_request *,
+                               struct lxc_handler *);
+
+       callback cb[LXC_COMMAND_MAX] = {
+               [LXC_COMMAND_TTY] = lxc_console_callback,
+       };
+
+       if (request->type < 0 || request->type >= LXC_COMMAND_MAX)
+               return -1;
+
+       return cb[request->type](fd, request, handler);
+}
+
+static void command_fd_cleanup(int fd, struct lxc_handler *handler,
+                       struct lxc_epoll_descr *descr)
+{
+       lxc_console_remove_fd(fd, &handler->tty_info);
+       lxc_mainloop_del_handler(descr, fd);
+       close(fd);
+}
+
+static int command_handler(int fd, void *data,
+                             struct lxc_epoll_descr *descr)
+{
+       int ret;
+       struct lxc_request request;
+       struct lxc_handler *handler = data;
+
+       ret = lxc_af_unix_rcv_credential(fd, &request, sizeof(request));
+       if (ret < 0) {
+               SYSERROR("failed to receive data on command socket");
+               goto out_close;
+       }
+
+       if (!ret) {
+               DEBUG("peer has disconnected");
+               goto out_close;
+       }
+
+       if (ret != sizeof(request)) {
+               WARN("partial request, ignored");
+               goto out_close;
+       }
+
+       ret = trigger_command(fd, &request, handler);
+       if (ret) {
+               /* this is not an error, but only a request to close fd */
+               ret = 0;
+               goto out_close;
+       }
+
+out:
+       return ret;
+out_close:
+       command_fd_cleanup(fd, handler, descr);
+       goto out;
+}
+
+static int incoming_command_handler(int fd, void *data,
+                                   struct lxc_epoll_descr *descr)
+{
+       int ret = 1, connection;
+
+       connection = accept(fd, NULL, 0);
+       if (connection < 0) {
+               SYSERROR("failed to accept connection");
+               return -1;
+       }
+
+       if (setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &ret, sizeof(ret))) {
+               SYSERROR("failed to enable credential on socket");
+               goto out_close;
+       }
+
+       ret = lxc_mainloop_add_handler(descr, connection, command_handler, data);
+       if (ret) {
+               ERROR("failed to add handler");
+               goto out_close;
+       }
+
+out:
+       return ret;
+
+out_close:
+       close(connection);
+       goto out;
+}
+
+extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
+                                   struct lxc_handler *handler)
+{
+       int ret, fd;
+       struct sockaddr_un addr = { 0 };
+       char *offset = &addr.sun_path[1];
+
+       strcpy(offset, name);
+       addr.sun_path[0] = '\0';
+
+       fd = lxc_af_unix_open(addr.sun_path, SOCK_STREAM, 0);
+       if (fd < 0) {
+               ERROR("failed to create the command service point");
+               return -1;
+       }
+
+       ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler,
+                                       handler);
+       if (ret) {
+               ERROR("failed to add handler for command socket");
+               close(fd);
+       }
+
+       return ret;
+}
index 66dd6998f819f5671ef366bbb1f0eedb7007e9ce..b6c76c1f44c9bed6dd0f672e12503f837b4870e8 100644 (file)
@@ -43,4 +43,12 @@ struct lxc_command {
        struct lxc_answer answer;
 };
 
+extern int lxc_command(const char *name, struct lxc_command *command);
+
+struct lxc_epoll_descr;
+struct lxc_handler;
+
+extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
+                                   struct lxc_handler *handler);
+
 #endif
index 18946e1fb0b7011d7daa0902aaa9ce3fd022bcfa..d32941c168e63163f03989a7033476d839e67b21 100644 (file)
 #include <sys/types.h>
 #include <sys/un.h>
 
-#include "af_unix.h"
-#include "error.h"
-
-#include <lxc/log.h>
+#include <lxc/lxc.h>
 #include "commands.h"
+#include "af_unix.h"
 
 lxc_log_define(lxc_console, lxc);
 
-static int receive_answer(int sock, struct lxc_answer *answer)
-{
-       int ret;
-
-       ret = lxc_af_unix_recv_fd(sock, &answer->fd, answer, sizeof(*answer));
-       if (ret < 0)
-               ERROR("failed to receive answer for the command");
-
-       return ret;
-}
-
-static int send_command(const char *name, struct lxc_command *command)
-{
-       struct sockaddr_un addr = { 0 };
-       int sock, ret = -1;
-       char *offset = &addr.sun_path[1];
-
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "@%s", name);
-       addr.sun_path[0] = '\0';
-
-       sock = lxc_af_unix_connect(addr.sun_path);
-       if (sock < 0) {
-               WARN("failed to connect to '@%s': %s", offset, strerror(errno));
-               return -1;
-       }
-
-       ret = lxc_af_unix_send_credential(sock, &command->request,
-                                       sizeof(command->request));
-       if (ret < 0) {
-               SYSERROR("failed to send credentials");
-               goto out_close;
-       }
-
-       if (ret != sizeof(command->request)) {
-               SYSERROR("message only partially sent to '@%s'", offset);
-               goto out_close;
-       }
-
-       ret = receive_answer(sock, &command->answer);
-       if (ret < 0)
-               goto out_close;
-out:
-       return ret;
-out_close:
-       close(sock);
-       goto out;
-}
-
 extern int lxc_console(const char *name, int ttynum, int *fd)
 {
        int ret;
@@ -90,7 +40,7 @@ extern int lxc_console(const char *name, int ttynum, int *fd)
                .request = { .type = LXC_COMMAND_TTY, .data = ttynum },
        };
 
-       ret = send_command(name, &command);
+       ret = lxc_command(name, &command);
        if (ret < 0) {
                ERROR("failed to send command");
                return -1;
@@ -110,3 +60,64 @@ extern int lxc_console(const char *name, int ttynum, int *fd)
        INFO("tty %d allocated", ttynum);
        return 0;
 }
+
+/*----------------------------------------------------------------------------
+ * functions used by lxc-start mainloop
+ * to handle above command request.
+ *--------------------------------------------------------------------------*/
+extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info)
+{
+       int i;
+
+       for (i = 0; i < tty_info->nbtty; i++) {
+
+               if (tty_info->pty_info[i].busy != fd)
+                       continue;
+
+               tty_info->pty_info[i].busy = 0;
+       }
+
+       return;
+}
+
+extern int lxc_console_callback(int fd, struct lxc_request *request,
+                       struct lxc_handler *handler)
+{
+       int ttynum = request->data;
+       struct lxc_tty_info *tty_info = &handler->tty_info;
+
+       if (ttynum > 0) {
+               if (ttynum > tty_info->nbtty)
+                       goto out_close;
+
+               if (tty_info->pty_info[ttynum - 1].busy)
+                       goto out_close;
+
+               goto out_send;
+       }
+
+       /* fixup index tty1 => [0] */
+       for (ttynum = 1;
+            ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy;
+            ttynum++);
+
+       /* we didn't find any available slot for tty */
+       if (ttynum > tty_info->nbtty)
+               goto out_close;
+
+out_send:
+       if (lxc_af_unix_send_fd(fd, tty_info->pty_info[ttynum - 1].master,
+                               &ttynum, sizeof(ttynum)) < 0) {
+               ERROR("failed to send tty to client");
+               goto out_close;
+       }
+
+       tty_info->pty_info[ttynum - 1].busy = fd;
+
+       return 0;
+
+out_close:
+       /* the close fd and related cleanup will be done by caller */
+       return 1;
+}
+
index c96dfb3afbbd0406ad472ce8d9b53dab892f9d75..3c705111f1ceed66ba4032486855ead662fdf8a1 100644 (file)
@@ -133,41 +133,6 @@ static int setup_sigchld_fd(sigset_t *oldmask)
        return fd;
 }
 
-static int incoming_command_handler(int fd, void *data,
-                             struct lxc_epoll_descr *descr);
-
-static int command_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
-                            struct lxc_handler *handler)
-{
-       int ret, fd;
-       struct sockaddr_un addr = { 0 };
-       char *offset = &addr.sun_path[1];
-
-       strcpy(offset, name);
-       addr.sun_path[0] = '\0';
-
-       fd = lxc_af_unix_open(addr.sun_path, SOCK_STREAM, 0);
-       if (fd < 0) {
-               ERROR("failed to create the command service point");
-               return -1;
-       }
-
-       if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
-               SYSERROR("failed to close-on-exec flag");
-               close(fd);
-               return -1;
-       }
-
-       ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler,
-                                       handler);
-       if (ret) {
-               ERROR("failed to add handler for command socket");
-               close(fd);
-       }
-
-       return ret;
-}
-
 static int sigchld_handler(int fd, void *data, 
                           struct lxc_epoll_descr *descr)
 {
@@ -176,161 +141,6 @@ static int sigchld_handler(int fd, void *data,
        return 1;
 }
 
-static int command_handler(int fd, void *data,
-                             struct lxc_epoll_descr *descr);
-static int trigger_command(int fd, struct lxc_request *request,
-                       struct lxc_handler *handler,
-                       struct lxc_epoll_descr *descr);
-
-static int incoming_command_handler(int fd, void *data, struct lxc_epoll_descr *descr)
-{
-       int ret = 1, connection;
-
-       connection = accept(fd, NULL, 0);
-       if (connection < 0) {
-               SYSERROR("failed to accept connection");
-               return -1;
-       }
-
-       if (setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &ret, sizeof(ret))) {
-               SYSERROR("failed to enable credential on socket");
-               goto out_close;
-       }
-
-       ret = lxc_mainloop_add_handler(descr, connection, command_handler, data);
-       if (ret) {
-               ERROR("failed to add handler");
-               goto out_close;
-       }
-
-out:
-       return ret;
-
-out_close:
-       close(connection);
-       goto out;
-}
-
-static void ttyinfo_remove_fd(int fd, struct lxc_tty_info *tty_info)
-{
-       int i;
-
-       for (i = 0; i < tty_info->nbtty; i++) {
-
-               if (tty_info->pty_info[i].busy != fd)
-                       continue;
-
-               tty_info->pty_info[i].busy = 0;
-       }
-
-       return;
-}
-
-static void command_fd_cleanup(int fd, struct lxc_handler *handler,
-                       struct lxc_epoll_descr *descr)
-{
-       ttyinfo_remove_fd(fd, &handler->tty_info);
-       lxc_mainloop_del_handler(descr, fd);
-       close(fd);
-}
-
-static int command_handler(int fd, void *data,
-                             struct lxc_epoll_descr *descr)
-{
-       int ret;
-       struct lxc_request request;
-       struct lxc_handler *handler = data;
-
-       ret = lxc_af_unix_rcv_credential(fd, &request, sizeof(request));
-       if (ret < 0) {
-               SYSERROR("failed to receive data on command socket");
-               goto out_close;
-       }
-
-       if (!ret) {
-               DEBUG("peer has disconnected");
-               goto out_close;
-       }
-
-       if (ret != sizeof(request)) {
-               WARN("partial request, ignored");
-               goto out_close;
-       }
-
-       ret = trigger_command(fd, &request, handler, descr);
-       if (ret) {
-               /* this is not an error, but only a request to close fd */
-               ret = 0;
-               goto out_close;
-       }
-
-out:
-       return ret;
-out_close:
-       command_fd_cleanup(fd, handler, descr);
-       goto out;
-}
-
-static int ttyservice_handler(int fd, struct lxc_request *request,
-                       struct lxc_handler *handler,
-                       struct lxc_epoll_descr *descr)
-{
-       int ttynum = request->data;
-       struct lxc_tty_info *tty_info = &handler->tty_info;
-
-       if (ttynum > 0) {
-               if (ttynum > tty_info->nbtty)
-                       goto out_close;
-
-               if (tty_info->pty_info[ttynum - 1].busy)
-                       goto out_close;
-
-               goto out_send;
-       }
-
-       /* fixup index tty1 => [0] */
-       for (ttynum = 1;
-            ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy;
-            ttynum++);
-
-       /* we didn't find any available slot for tty */
-       if (ttynum > tty_info->nbtty)
-               goto out_close;
-
-out_send:
-       if (lxc_af_unix_send_fd(fd, tty_info->pty_info[ttynum - 1].master,
-                               &ttynum, sizeof(ttynum)) < 0) {
-               ERROR("failed to send tty to client");
-               goto out_close;
-       }
-
-       tty_info->pty_info[ttynum - 1].busy = fd;
-
-       return 0;
-
-out_close:
-       /* the close fd and related cleanup will be done by caller */
-       return 1;
-}
-
-static int trigger_command(int fd, struct lxc_request *request,
-                       struct lxc_handler *handler,
-                       struct lxc_epoll_descr *descr)
-{
-       typedef int (*callback)(int, struct lxc_request *,
-                               struct lxc_handler *,
-                               struct lxc_epoll_descr *descr);
-
-       callback cb[LXC_COMMAND_MAX] = {
-               [LXC_COMMAND_TTY] = ttyservice_handler,
-       };
-
-       if (request->type < 0 || request->type >= LXC_COMMAND_MAX)
-               return -1;
-
-       return cb[request->type](fd, request, handler, descr);
-}
-
 int lxc_poll(const char *name, struct lxc_handler *handler)
 {
        int sigfd = handler->sigfd;
@@ -353,7 +163,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
                goto out_mainloop_open;
        }
 
-       if (command_mainloop_add(name, &descr, handler))
+       if (lxc_command_mainloop_add(name, &descr, handler))
                goto out_mainloop_open;
 
        ret = lxc_mainloop(&descr);