mirror of https://gitee.com/openkylin/libvirt.git
tools: console: make console virLockableObject
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. Reviewed-by: Cole Robinson <crobinso@redhat.com> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
This commit is contained in:
parent
e3389d830c
commit
98361cc3b9
|
@ -60,9 +60,10 @@ struct virConsoleBuffer {
|
||||||
typedef struct virConsole virConsole;
|
typedef struct virConsole virConsole;
|
||||||
typedef virConsole *virConsolePtr;
|
typedef virConsole *virConsolePtr;
|
||||||
struct virConsole {
|
struct virConsole {
|
||||||
|
virObjectLockable parent;
|
||||||
|
|
||||||
virStreamPtr st;
|
virStreamPtr st;
|
||||||
bool quit;
|
bool quit;
|
||||||
virMutex lock;
|
|
||||||
virCond cond;
|
virCond cond;
|
||||||
|
|
||||||
int stdinWatch;
|
int stdinWatch;
|
||||||
|
@ -74,6 +75,19 @@ struct virConsole {
|
||||||
char escapeChar;
|
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
|
static void
|
||||||
virConsoleHandleSignal(int sig ATTRIBUTE_UNUSED)
|
virConsoleHandleSignal(int sig ATTRIBUTE_UNUSED)
|
||||||
|
@ -104,16 +118,14 @@ virConsoleShutdown(virConsolePtr con)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virConsoleFree(virConsolePtr con)
|
virConsoleDispose(void *obj)
|
||||||
{
|
{
|
||||||
if (!con)
|
virConsolePtr con = obj;
|
||||||
return;
|
|
||||||
|
|
||||||
if (con->st)
|
if (con->st)
|
||||||
virStreamFree(con->st);
|
virStreamFree(con->st);
|
||||||
virMutexDestroy(&con->lock);
|
|
||||||
virCondDestroy(&con->cond);
|
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
|
static char
|
||||||
virshGetEscapeChar(const char *s)
|
virshGetEscapeChar(const char *s)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +365,11 @@ virshRunConsole(vshControl *ctl,
|
||||||
if (vshTTYMakeRaw(ctl, true) < 0)
|
if (vshTTYMakeRaw(ctl, true) < 0)
|
||||||
goto resettty;
|
goto resettty;
|
||||||
|
|
||||||
|
if (!(con = virConsoleNew()))
|
||||||
|
goto resettty;
|
||||||
|
|
||||||
|
virObjectLock(con);
|
||||||
|
|
||||||
/* Trap all common signals so that we can safely restore the original
|
/* Trap all common signals so that we can safely restore the original
|
||||||
* terminal settings on STDIN before the process exits - people don't like
|
* terminal settings on STDIN before the process exits - people don't like
|
||||||
* being left with a messed up terminal ! */
|
* being left with a messed up terminal ! */
|
||||||
|
@ -333,9 +379,6 @@ virshRunConsole(vshControl *ctl,
|
||||||
sigaction(SIGHUP, &sighandler, &old_sighup);
|
sigaction(SIGHUP, &sighandler, &old_sighup);
|
||||||
sigaction(SIGPIPE, &sighandler, &old_sigpipe);
|
sigaction(SIGPIPE, &sighandler, &old_sigpipe);
|
||||||
|
|
||||||
if (VIR_ALLOC(con) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
con->escapeChar = virshGetEscapeChar(priv->escapeChar);
|
con->escapeChar = virshGetEscapeChar(priv->escapeChar);
|
||||||
con->st = virStreamNew(virDomainGetConnect(dom),
|
con->st = virStreamNew(virDomainGetConnect(dom),
|
||||||
VIR_STREAM_NONBLOCK);
|
VIR_STREAM_NONBLOCK);
|
||||||
|
@ -345,11 +388,6 @@ virshRunConsole(vshControl *ctl,
|
||||||
if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0)
|
if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
virMutexLock(&con->lock);
|
|
||||||
|
|
||||||
con->stdinWatch = virEventAddHandle(STDIN_FILENO,
|
con->stdinWatch = virEventAddHandle(STDIN_FILENO,
|
||||||
VIR_EVENT_HANDLE_READABLE,
|
VIR_EVENT_HANDLE_READABLE,
|
||||||
virConsoleEventOnStdin,
|
virConsoleEventOnStdin,
|
||||||
|
@ -368,19 +406,17 @@ virshRunConsole(vshControl *ctl,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
while (!con->quit) {
|
while (!con->quit) {
|
||||||
if (virCondWait(&con->cond, &con->lock) < 0) {
|
if (virCondWait(&con->cond, &con->parent.lock) < 0) {
|
||||||
virMutexUnlock(&con->lock);
|
|
||||||
VIR_ERROR(_("unable to wait on console condition"));
|
VIR_ERROR(_("unable to wait on console condition"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virMutexUnlock(&con->lock);
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virConsoleFree(con);
|
virObjectUnlock(con);
|
||||||
|
virObjectUnref(con);
|
||||||
|
|
||||||
/* Restore original signal handlers */
|
/* Restore original signal handlers */
|
||||||
sigaction(SIGQUIT, &old_sigquit, NULL);
|
sigaction(SIGQUIT, &old_sigquit, NULL);
|
||||||
|
|
Loading…
Reference in New Issue