[libvirt] [PATCH v3 1/5] tools: console: make console virLockableObject

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Mon Mar 18 09:08:16 UTC 2019


We need to turn console into virObject object because stream/fd callbacks
can be called from the event loop thread after freeing console
in main thread. It is convinient to turn into virLockableObject as
we have mutex in console object.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
---
 tools/virsh-console.c | 74 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 55 insertions(+), 19 deletions(-)

diff --git a/tools/virsh-console.c b/tools/virsh-console.c
index 045a636..763b395 100644
--- a/tools/virsh-console.c
+++ b/tools/virsh-console.c
@@ -60,9 +60,10 @@ struct virConsoleBuffer {
 typedef struct virConsole virConsole;
 typedef virConsole *virConsolePtr;
 struct virConsole {
+    virObjectLockable parent;
+
     virStreamPtr st;
     bool quit;
-    virMutex lock;
     virCond cond;
 
     int stdinWatch;
@@ -74,6 +75,19 @@ struct virConsole {
     char escapeChar;
 };
 
+static virClassPtr virConsoleClass;
+static void virConsoleDispose(void *obj);
+
+static int
+virConsoleOnceInit(void)
+{
+    if (!VIR_CLASS_NEW(virConsole, virClassForObjectLockable()))
+        return -1;
+
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virConsole);
 
 static void
 virConsoleHandleSignal(int sig ATTRIBUTE_UNUSED)
@@ -104,16 +118,14 @@ virConsoleShutdown(virConsolePtr con)
 
 
 static void
-virConsoleFree(virConsolePtr con)
+virConsoleDispose(void *obj)
 {
-    if (!con)
-        return;
+    virConsolePtr con = obj;
 
     if (con->st)
         virStreamFree(con->st);
-    virMutexDestroy(&con->lock);
+
     virCondDestroy(&con->cond);
-    VIR_FREE(con);
 }
 
 
@@ -288,6 +300,35 @@ virConsoleEventOnStdout(int watch ATTRIBUTE_UNUSED,
 }
 
 
+static virConsolePtr
+virConsoleNew(void)
+{
+    virConsolePtr con;
+
+    if (virConsoleInitialize() < 0)
+        return NULL;
+
+    if (!(con = virObjectNew(virConsoleClass)))
+        return NULL;
+
+    if (virCondInit(&con->cond) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("cannot initialize console condition"));
+
+        goto error;
+    }
+
+    con->stdinWatch = -1;
+    con->stdoutWatch = -1;
+
+    return con;
+
+ error:
+    virObjectUnref(con);
+    return NULL;
+}
+
+
 static char
 virshGetEscapeChar(const char *s)
 {
@@ -324,6 +365,11 @@ virshRunConsole(vshControl *ctl,
     if (vshTTYMakeRaw(ctl, true) < 0)
         goto resettty;
 
+    if (!(con = virConsoleNew()))
+        goto resettty;
+
+    virObjectLock(con);
+
     /* Trap all common signals so that we can safely restore the original
      * terminal settings on STDIN before the process exits - people don't like
      * being left with a messed up terminal ! */
@@ -333,9 +379,6 @@ virshRunConsole(vshControl *ctl,
     sigaction(SIGHUP,  &sighandler, &old_sighup);
     sigaction(SIGPIPE, &sighandler, &old_sigpipe);
 
-    if (VIR_ALLOC(con) < 0)
-        goto cleanup;
-
     con->escapeChar = virshGetEscapeChar(priv->escapeChar);
     con->st = virStreamNew(virDomainGetConnect(dom),
                            VIR_STREAM_NONBLOCK);
@@ -345,11 +388,6 @@ virshRunConsole(vshControl *ctl,
     if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0)
         goto cleanup;
 
-    if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0)
-        goto cleanup;
-
-    virMutexLock(&con->lock);
-
     con->stdinWatch = virEventAddHandle(STDIN_FILENO,
                                         VIR_EVENT_HANDLE_READABLE,
                                         virConsoleEventOnStdin,
@@ -368,19 +406,17 @@ virshRunConsole(vshControl *ctl,
                               NULL);
 
     while (!con->quit) {
-        if (virCondWait(&con->cond, &con->lock) < 0) {
-            virMutexUnlock(&con->lock);
+        if (virCondWait(&con->cond, &con->parent.lock) < 0) {
             VIR_ERROR(_("unable to wait on console condition"));
             goto cleanup;
         }
     }
 
-    virMutexUnlock(&con->lock);
-
     ret = 0;
 
  cleanup:
-    virConsoleFree(con);
+    virObjectUnlock(con);
+    virObjectUnref(con);
 
     /* Restore original signal handlers */
     sigaction(SIGQUIT, &old_sigquit, NULL);
-- 
1.8.3.1




More information about the libvir-list mailing list