[libvirt] [PATCH 07/15] Make console handling part of virLXCControllerPtr

Daniel P. Berrange berrange at redhat.com
Tue Jul 3 15:58:46 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Turn 'struct lxc_console' into virLXCControllerConsolePtr and make it
a part of virLXCControllerPtr

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/lxc/lxc_controller.c |  264 ++++++++++++++++++++++++++--------------------
 1 file changed, 152 insertions(+), 112 deletions(-)

diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 4c5943e..32410ec 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -80,6 +80,30 @@ struct cgroup_device_policy {
 };
 
 
+typedef struct _virLXCControllerConsole virLXCControllerConsole;
+typedef virLXCControllerConsole *virLXCControllerConsolePtr;
+struct _virLXCControllerConsole {
+    int hostWatch;
+    int hostFd;  /* PTY FD in the host OS */
+    bool hostClosed;
+    int hostEpoll;
+    bool hostBlocking;
+
+    int contWatch;
+    int contFd;  /* PTY FD in the container */
+    bool contClosed;
+    int contEpoll;
+    bool contBlocking;
+
+    int epollWatch;
+    int epollFd; /* epoll FD for dealing with EOF */
+
+    size_t fromHostLen;
+    char fromHostBuf[1024];
+    size_t fromContLen;
+    char fromContBuf[1024];
+};
+
 typedef struct _virLXCController virLXCController;
 typedef virLXCController *virLXCControllerPtr;
 struct _virLXCController {
@@ -90,6 +114,9 @@ struct _virLXCController {
 
     size_t nveths;
     char **veths;
+
+    size_t nconsoles;
+    virLXCControllerConsolePtr consoles;
 };
 
 static void virLXCControllerFree(virLXCControllerPtr ctrl);
@@ -143,6 +170,22 @@ static void virLXCControllerStopInit(virLXCControllerPtr ctrl)
 }
 
 
+static void virLXCControllerConsoleClose(virLXCControllerConsolePtr console)
+{
+    if (console->hostWatch != -1)
+        virEventRemoveHandle(console->hostWatch);
+    VIR_FORCE_CLOSE(console->hostFd);
+
+    if (console->contWatch != -1)
+        virEventRemoveHandle(console->contWatch);
+    VIR_FORCE_CLOSE(console->contFd);
+
+    if (console->epollWatch != -1)
+        virEventRemoveHandle(console->epollWatch);
+    VIR_FORCE_CLOSE(console->epollFd);
+}
+
+
 static void virLXCControllerFree(virLXCControllerPtr ctrl)
 {
     size_t i;
@@ -156,6 +199,10 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
         VIR_FREE(ctrl->veths[i]);
     VIR_FREE(ctrl->veths);
 
+    for (i = 0 ; i < ctrl->nconsoles ; i++)
+        virLXCControllerConsoleClose(&(ctrl->consoles[i]));
+    VIR_FREE(ctrl->consoles);
+
     virDomainDefFree(ctrl->def);
     VIR_FREE(ctrl->name);
 
@@ -163,6 +210,38 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
 }
 
 
+static int virLXCControllerAddConsole(virLXCControllerPtr ctrl,
+                                      int hostFd)
+{
+    if (VIR_EXPAND_N(ctrl->consoles, ctrl->nconsoles, 1) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+    ctrl->consoles[ctrl->nconsoles-1].hostFd = hostFd;
+    ctrl->consoles[ctrl->nconsoles-1].hostWatch = -1;
+
+    ctrl->consoles[ctrl->nconsoles-1].contFd = -1;
+    ctrl->consoles[ctrl->nconsoles-1].contWatch = -1;
+
+    ctrl->consoles[ctrl->nconsoles-1].epollFd = -1;
+    ctrl->consoles[ctrl->nconsoles-1].epollWatch = -1;
+    return 0;
+}
+
+
+static int virLXCControllerConsoleSetNonblocking(virLXCControllerConsolePtr console)
+{
+    if (virSetBlocking(console->hostFd, false) < 0 ||
+        virSetBlocking(console->contFd, false) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Unable to set console file descriptor non-blocking"));
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int virLXCControllerValidateNICs(virLXCControllerPtr ctrl)
 {
     if (ctrl->def->nnets != ctrl->nveths) {
@@ -176,6 +255,19 @@ static int virLXCControllerValidateNICs(virLXCControllerPtr ctrl)
 }
 
 
+static int virLXCControllerValidateConsoles(virLXCControllerPtr ctrl)
+{
+    if (ctrl->def->nconsoles != ctrl->nconsoles) {
+        lxcError(VIR_ERR_INTERNAL_ERROR,
+                 _("expecting %d consoles, but got %zu tty file handlers"),
+                 ctrl->def->nconsoles, ctrl->nconsoles);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int lxcGetLoopFD(char **dev_name)
 {
     int fd = -1;
@@ -830,29 +922,6 @@ static void virLXCControllerSignalChildIO(int watch ATTRIBUTE_UNUSED,
 }
 
 
-struct lxcConsole {
-
-    int hostWatch;
-    int hostFd;  /* PTY FD in the host OS */
-    bool hostClosed;
-    int hostEpoll;
-    bool hostBlocking;
-
-    int contWatch;
-    int contFd;  /* PTY FD in the container */
-    bool contClosed;
-    int contEpoll;
-    bool contBlocking;
-
-    int epollWatch;
-    int epollFd; /* epoll FD for dealing with EOF */
-
-    size_t fromHostLen;
-    char fromHostBuf[1024];
-    size_t fromContLen;
-    char fromContBuf[1024];
-};
-
 struct lxcMonitor {
     int serverWatch;
     int serverFd;  /* Server listen socket */
@@ -936,7 +1005,7 @@ static void lxcServerAccept(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRI
     }
 }
 
-static void lxcConsoleUpdateWatch(struct lxcConsole *console)
+static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr console)
 {
     int hostEvents = 0;
     int contEvents = 0;
@@ -1038,9 +1107,9 @@ cleanup:
 }
 
 
-static void lxcEpollIO(int watch, int fd, int events, void *opaque)
+static void virLXCControllerConsoleEPoll(int watch, int fd, int events, void *opaque)
 {
-    struct lxcConsole *console = opaque;
+    virLXCControllerConsolePtr console = opaque;
 
     virMutexLock(&lock);
     VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu",
@@ -1076,7 +1145,7 @@ static void lxcEpollIO(int watch, int fd, int events, void *opaque)
             } else {
                 console->contClosed = false;
             }
-            lxcConsoleUpdateWatch(console);
+            virLXCControllerConsoleUpdateWatch(console);
             break;
         }
     }
@@ -1085,9 +1154,9 @@ cleanup:
     virMutexUnlock(&lock);
 }
 
-static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
+static void virLXCControllerConsoleIO(int watch, int fd, int events, void *opaque)
 {
-    struct lxcConsole *console = opaque;
+    virLXCControllerConsolePtr console = opaque;
 
     virMutexLock(&lock);
     VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu",
@@ -1166,7 +1235,7 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
         VIR_DEBUG("Got EOF on %d %d", watch, fd);
     }
 
-    lxcConsoleUpdateWatch(console);
+    virLXCControllerConsoleUpdateWatch(console);
     virMutexUnlock(&lock);
     return;
 
@@ -1183,8 +1252,6 @@ error:
  * lxcControllerMain
  * @serverFd: server socket fd to accept client requests
  * @clientFd: initial client which is the libvirtd daemon
- * @hostFd: open fd for application facing Pty
- * @contFd: open fd for container facing Pty
  *
  * Processes I/O on consoles and the monitor
  *
@@ -1192,12 +1259,8 @@ error:
  */
 static int virLXCControllerMain(virLXCControllerPtr ctrl,
                                 int serverFd,
-                                int clientFd,
-                                int *hostFds,
-                                int *contFds,
-                                size_t nFds)
+                                int clientFd)
 {
-    struct lxcConsole *consoles = NULL;
     struct lxcMonitor monitor = {
         .serverFd = serverFd,
         .clientFd = clientFd,
@@ -1256,53 +1319,38 @@ static int virLXCControllerMain(virLXCControllerPtr ctrl,
         goto cleanup;
     }
 
-    if (VIR_ALLOC_N(consoles, nFds) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    for (i = 0 ; i < nFds ; i++) {
-        consoles[i].epollFd = -1;
-        consoles[i].epollWatch = -1;
-        consoles[i].hostWatch = -1;
-        consoles[i].contWatch = -1;
-    }
-
-    for (i = 0 ; i < nFds ; i++) {
-        consoles[i].hostFd = hostFds[i];
-        consoles[i].contFd = contFds[i];
-
-        if ((consoles[i].epollFd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
+    for (i = 0 ; i < ctrl->nconsoles ; i++) {
+        if ((ctrl->consoles[i].epollFd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
             virReportSystemError(errno, "%s",
                                  _("Unable to create epoll fd"));
             goto cleanup;
         }
 
-        if ((consoles[i].epollWatch = virEventAddHandle(consoles[i].epollFd,
-                                                        VIR_EVENT_HANDLE_READABLE,
-                                                        lxcEpollIO,
-                                                        &consoles[i],
-                                                        NULL)) < 0) {
+        if ((ctrl->consoles[i].epollWatch = virEventAddHandle(ctrl->consoles[i].epollFd,
+                                                              VIR_EVENT_HANDLE_READABLE,
+                                                              virLXCControllerConsoleEPoll,
+                                                              &(ctrl->consoles[i]),
+                                                              NULL)) < 0) {
             lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
                      _("Unable to watch epoll FD"));
             goto cleanup;
         }
 
-        if ((consoles[i].hostWatch = virEventAddHandle(consoles[i].hostFd,
-                                                       VIR_EVENT_HANDLE_READABLE,
-                                                       lxcConsoleIO,
-                                                       &consoles[i],
-                                                       NULL)) < 0) {
+        if ((ctrl->consoles[i].hostWatch = virEventAddHandle(ctrl->consoles[i].hostFd,
+                                                             VIR_EVENT_HANDLE_READABLE,
+                                                             virLXCControllerConsoleIO,
+                                                             &(ctrl->consoles[i]),
+                                                             NULL)) < 0) {
             lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
                      _("Unable to watch host console PTY"));
             goto cleanup;
         }
 
-        if ((consoles[i].contWatch = virEventAddHandle(consoles[i].contFd,
-                                                       VIR_EVENT_HANDLE_READABLE,
-                                                       lxcConsoleIO,
-                                                       &consoles[i],
-                                                       NULL)) < 0) {
+        if ((ctrl->consoles[i].contWatch = virEventAddHandle(ctrl->consoles[i].contFd,
+                                                             VIR_EVENT_HANDLE_READABLE,
+                                                             virLXCControllerConsoleIO,
+                                                             &(ctrl->consoles[i]),
+                                                             NULL)) < 0) {
             lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
                      _("Unable to watch host console PTY"));
             goto cleanup;
@@ -1329,17 +1377,9 @@ cleanup2:
     VIR_FORCE_CLOSE(monitor.serverFd);
     VIR_FORCE_CLOSE(monitor.clientFd);
 
-    for (i = 0 ; i < nFds ; i++) {
-        if (consoles[i].epollWatch != -1)
-            virEventRemoveHandle(consoles[i].epollWatch);
-        VIR_FORCE_CLOSE(consoles[i].epollFd);
-        if (consoles[i].contWatch != -1)
-            virEventRemoveHandle(consoles[i].contWatch);
-        if (consoles[i].hostWatch != -1)
-            virEventRemoveHandle(consoles[i].hostWatch);
-    }
+    for (i = 0 ; i < ctrl->nconsoles ; i++)
+        virLXCControllerConsoleClose(&(ctrl->consoles[i]));
 
-    VIR_FREE(consoles);
     return rc;
 }
 
@@ -1464,15 +1504,12 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
                     virSecurityManagerPtr securityDriver,
                     int monitor,
                     int client,
-                    int *ttyFDs,
-                    size_t nttyFDs,
                     int handshakefd)
 {
     int rc = -1;
     int control[2] = { -1, -1};
     int containerhandshake[2] = { -1, -1 };
-    int *containerTtyFDs = NULL;
-    char **containerTtyPaths = NULL;
+    char **containerTTYPaths = NULL;
     virDomainFSDefPtr root;
     char *devpts = NULL;
     char *devptmx = NULL;
@@ -1481,11 +1518,7 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
     size_t i;
     char *mount_options = NULL;
 
-    if (VIR_ALLOC_N(containerTtyFDs, nttyFDs) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-    if (VIR_ALLOC_N(containerTtyPaths, nttyFDs) < 0) {
+    if (VIR_ALLOC_N(containerTTYPaths, ctrl->nconsoles) < 0) {
         virReportOOMError();
         goto cleanup;
     }
@@ -1591,27 +1624,28 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
             VIR_FREE(devptmx);
         }
     } else {
-        if (nttyFDs != 1) {
+        if (ctrl->nconsoles != 1) {
             lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
-                     _("Expected exactly one TTY fd, but got %zu"), nttyFDs);
+                     _("Expected exactly one console, but got %zu"),
+                     ctrl->nconsoles);
             goto cleanup;
         }
     }
 
-    for (i = 0 ; i < nttyFDs ; i++) {
+    for (i = 0 ; i < ctrl->nconsoles ; i++) {
         if (devptmx) {
             VIR_DEBUG("Opening tty on private %s", devptmx);
             if (lxcCreateTty(devptmx,
-                             &containerTtyFDs[i],
-                             &containerTtyPaths[i]) < 0) {
+                             &ctrl->consoles[i].contFd,
+                             &containerTTYPaths[i]) < 0) {
                 virReportSystemError(errno, "%s",
                                      _("Failed to allocate tty"));
                 goto cleanup;
             }
         } else {
             VIR_DEBUG("Opening tty on shared /dev/ptmx");
-            if (virFileOpenTty(&containerTtyFDs[i],
-                               &containerTtyPaths[i],
+            if (virFileOpenTty(&ctrl->consoles[i].contFd,
+                               &containerTTYPaths[i],
                                0) < 0) {
                 virReportSystemError(errno, "%s",
                                      _("Failed to allocate tty"));
@@ -1629,8 +1663,8 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
                                            ctrl->veths,
                                            control[1],
                                            containerhandshake[1],
-                                           containerTtyPaths,
-                                           nttyFDs)) < 0)
+                                           containerTTYPaths,
+                                           ctrl->nconsoles)) < 0)
         goto cleanup;
     VIR_FORCE_CLOSE(control[1]);
     VIR_FORCE_CLOSE(containerhandshake[1]);
@@ -1674,16 +1708,11 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
                              _("Unable to set file descriptor non-blocking"));
         goto cleanup;
     }
-    for (i = 0 ; i < nttyFDs ; i++) {
-        if (virSetBlocking(ttyFDs[i], false) < 0 ||
-            virSetBlocking(containerTtyFDs[i], false) < 0) {
-            virReportSystemError(errno, "%s",
-                                 _("Unable to set file descriptor non-blocking"));
+    for (i = 0 ; i < ctrl->nconsoles ; i++)
+        if (virLXCControllerConsoleSetNonblocking(&(ctrl->consoles[i])) < 0)
             goto cleanup;
-        }
-    }
 
-    rc = virLXCControllerMain(ctrl, monitor, client, ttyFDs, containerTtyFDs, nttyFDs);
+    rc = virLXCControllerMain(ctrl, monitor, client);
     monitor = client = -1;
 
 cleanup:
@@ -1696,12 +1725,9 @@ cleanup:
     VIR_FORCE_CLOSE(containerhandshake[0]);
     VIR_FORCE_CLOSE(containerhandshake[1]);
 
-    for (i = 0 ; i < nttyFDs ; i++)
-        VIR_FREE(containerTtyPaths[i]);
-    VIR_FREE(containerTtyPaths);
-    for (i = 0 ; i < nttyFDs ; i++)
-        VIR_FORCE_CLOSE(containerTtyFDs[i]);
-    VIR_FREE(containerTtyFDs);
+    for (i = 0 ; i < ctrl->nconsoles ; i++)
+        VIR_FREE(containerTTYPaths[i]);
+    VIR_FREE(containerTTYPaths);
 
     for (i = 0 ; i < nloopDevs ; i++)
         VIR_FORCE_CLOSE(loopDevs[i]);
@@ -1741,6 +1767,7 @@ int main(int argc, char *argv[])
     size_t nttyFDs = 0;
     virSecurityManagerPtr securityDriver = NULL;
     virLXCControllerPtr ctrl = NULL;
+    size_t i;
 
     if (setlocale(LC_ALL, "") == NULL ||
         bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
@@ -1873,9 +1900,18 @@ int main(int argc, char *argv[])
     ctrl->veths = veths;
     ctrl->nveths = nveths;
 
+    for (i = 0 ; i < nttyFDs ; i++) {
+        if (virLXCControllerAddConsole(ctrl, ttyFDs[i]) < 0)
+            goto cleanup;
+        ttyFDs[i] = -1;
+    }
+
     if (virLXCControllerValidateNICs(ctrl) < 0)
         goto cleanup;
 
+    if (virLXCControllerValidateConsoles(ctrl) < 0)
+        goto cleanup;
+
     if ((sockpath = lxcMonitorPath(ctrl)) == NULL)
         goto cleanup;
 
@@ -1923,7 +1959,7 @@ int main(int argc, char *argv[])
 
     rc = virLXCControllerRun(ctrl, securityDriver,
                              monitor, client,
-                             ttyFDs, nttyFDs, handshakefd);
+                             handshakefd);
 
 cleanup:
     virPidFileDelete(LXC_STATE_DIR, name);
@@ -1931,6 +1967,10 @@ cleanup:
     if (sockpath)
         unlink(sockpath);
     VIR_FREE(sockpath);
+    for (i = 0 ; i < nttyFDs ; i++)
+        VIR_FORCE_CLOSE(ttyFDs[i]);
+    VIR_FREE(ttyFDs);
+
     virLXCControllerFree(ctrl);
 
     return rc ? EXIT_FAILURE : EXIT_SUCCESS;
-- 
1.7.10.4




More information about the libvir-list mailing list