virThreadPoolPtr virThreadPoolNewFull(size_t minWorkers, size_t maxWorkers, size_t prioWorkers, virThreadPoolJobFunc func, const char *funcName, void *opaque) { virThreadPoolPtr pool; if (minWorkers > maxWorkers) minWorkers = maxWorkers; if (VIR_ALLOC(pool) < 0) return NULL; pool->jobList.tail = pool->jobList.head = NULL; pool->jobFunc = func; pool->jobFuncName = funcName; pool->jobOpaque = opaque; if (virMutexInit(&pool->mutex) < 0) goto error; if (virCondInit(&pool->cond) < 0) goto error; if (virCondInit(&pool->quit_cond) < 0) goto error; pool->minWorkers = minWorkers; pool->maxWorkers = maxWorkers; pool->maxPrioWorkers = prioWorkers; if (virThreadPoolExpand(pool, minWorkers, false) < 0) goto error; if (prioWorkers) { if (virCondInit(&pool->prioCond) < 0) goto error; if (virThreadPoolExpand(pool, prioWorkers, true) < 0) goto error; } return pool; error: virThreadPoolFree(pool); return NULL; }
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 int libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv) { memset(&priv->job, 0, sizeof(priv->job)); if (virCondInit(&priv->job.cond) < 0) return -1; if (VIR_ALLOC(priv->job.current) < 0) return -1; return 0; }
int virNetClientSend(virNetClientPtr client, virNetMessagePtr msg, bool expectReply) { virNetClientCallPtr call; int ret = -1; PROBE(RPC_CLIENT_MSG_TX_QUEUE, "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u", client, msg->bufferLength, msg->header.prog, msg->header.vers, msg->header.proc, msg->header.type, msg->header.status, msg->header.serial); if (expectReply && (msg->bufferLength != 0) && (msg->header.status == VIR_NET_CONTINUE)) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("Attempt to send an asynchronous message with a synchronous reply")); return -1; } if (VIR_ALLOC(call) < 0) { virReportOOMError(); return -1; } virNetClientLock(client); if (virCondInit(&call->cond) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize condition variable")); goto cleanup; } msg->donefds = 0; if (msg->bufferLength) call->mode = VIR_NET_CLIENT_MODE_WAIT_TX; else call->mode = VIR_NET_CLIENT_MODE_WAIT_RX; call->msg = msg; call->expectReply = expectReply; ret = virNetClientIO(client, call); cleanup: ignore_value(virCondDestroy(&call->cond)); VIR_FREE(call); virNetClientUnlock(client); return ret; }
virDomainObjPtr vzNewDomain(vzDriverPtr driver, const char *name, const unsigned char *uuid) { virDomainDefPtr def = NULL; virDomainObjPtr dom = NULL; vzDomObjPtr pdom = NULL; if (!(def = virDomainDefNewFull(name, uuid, -1))) goto error; if (VIR_ALLOC(pdom) < 0) goto error; if (virCondInit(&pdom->cache.cond) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize condition")); goto error; } pdom->cache.stats = PRL_INVALID_HANDLE; pdom->cache.count = -1; def->virtType = VIR_DOMAIN_VIRT_VZ; if (!(dom = virDomainObjListAdd(driver->domains, def, driver->xmlopt, 0, NULL))) goto error; dom->privateData = pdom; dom->privateDataFreeFunc = prlsdkDomObjFreePrivate; dom->persistent = 1; return dom; error: if (pdom && pdom->cache.count == -1) virCondDestroy(&pdom->cache.cond); virDomainDefFree(def); VIR_FREE(pdom); return NULL; }
qemuAgentPtr qemuAgentOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, qemuAgentCallbacksPtr cb) { qemuAgentPtr mon; if (!cb || !cb->eofNotify) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("EOF notify callback must be supplied")); return NULL; } if (qemuAgentInitialize() < 0) return NULL; if (!(mon = virObjectNew(qemuAgentClass))) return NULL; if (virMutexInit(&mon->lock) < 0) { virReportSystemError(errno, "%s", _("cannot initialize monitor mutex")); VIR_FREE(mon); return NULL; } if (virCondInit(&mon->notify) < 0) { virReportSystemError(errno, "%s", _("cannot initialize monitor condition")); virMutexDestroy(&mon->lock); VIR_FREE(mon); return NULL; } mon->fd = -1; mon->vm = vm; mon->cb = cb; qemuAgentLock(mon); switch (config->type) { case VIR_DOMAIN_CHR_TYPE_UNIX: mon->fd = qemuAgentOpenUnix(config->data.nix.path, vm->pid, &mon->connectPending); break; case VIR_DOMAIN_CHR_TYPE_PTY: mon->fd = qemuAgentOpenPty(config->data.file.path); break; default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to handle monitor type: %s"), virDomainChrTypeToString(config->type)); goto cleanup; } if (mon->fd == -1) goto cleanup; if ((mon->watch = virEventAddHandle(mon->fd, VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_READABLE | (mon->connectPending ? VIR_EVENT_HANDLE_WRITABLE : 0), qemuAgentIO, mon, virObjectFreeCallback)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to register monitor events")); goto cleanup; } virObjectRef(mon); VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch); qemuAgentUnlock(mon); return mon; cleanup: /* We don't want the 'destroy' callback invoked during * cleanup from construction failure, because that can * give a double-unref on virDomainObjPtr in the caller, * so kill the callbacks now. */ mon->cb = NULL; qemuAgentUnlock(mon); qemuAgentClose(mon); return NULL; }
int vshRunConsole(virDomainPtr dom, const char *dev_name, const char *escape_seq, unsigned int flags) { int ret = -1; struct termios ttyattr; void (*old_sigquit)(int); void (*old_sigterm)(int); void (*old_sigint)(int); void (*old_sighup)(int); void (*old_sigpipe)(int); virConsolePtr con = NULL; /* Put STDIN into raw mode so that stuff typed does not echo to the screen (the TTY reads will result in it being echoed back already), and also ensure Ctrl-C, etc is blocked, and misc other bits */ if (vshMakeStdinRaw(&ttyattr, true) < 0) goto resettty; /* 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 ! */ old_sigquit = signal(SIGQUIT, do_signal); old_sigterm = signal(SIGTERM, do_signal); old_sigint = signal(SIGINT, do_signal); old_sighup = signal(SIGHUP, do_signal); old_sigpipe = signal(SIGPIPE, do_signal); got_signal = 0; if (VIR_ALLOC(con) < 0) { virReportOOMError(); goto cleanup; } con->escapeChar = vshGetEscapeChar(escape_seq); con->st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con->st) goto cleanup; if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0) goto cleanup; if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0) goto cleanup; con->stdinWatch = virEventAddHandle(STDIN_FILENO, VIR_EVENT_HANDLE_READABLE, virConsoleEventOnStdin, con, NULL); con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, NULL); virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, NULL); while (!con->quit) { if (virCondWait(&con->cond, &con->lock) < 0) { VIR_ERROR(_("unable to wait on console condition")); goto cleanup; } } ret = 0; cleanup: if (con) { if (con->st) virStreamFree(con->st); virMutexDestroy(&con->lock); ignore_value(virCondDestroy(&con->cond)); VIR_FREE(con); } /* Restore original signal handlers */ signal(SIGPIPE, old_sigpipe); signal(SIGHUP, old_sighup); signal(SIGINT, old_sigint); signal(SIGTERM, old_sigterm); signal(SIGQUIT, old_sigquit); resettty: /* Put STDIN back into the (sane?) state we found it in before starting */ tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr); return ret; }
int vshRunConsole(vshControl *ctl, virDomainPtr dom, const char *dev_name, unsigned int flags) { virConsolePtr con = NULL; int ret = -1; struct sigaction old_sigquit; struct sigaction old_sigterm; struct sigaction old_sigint; struct sigaction old_sighup; struct sigaction old_sigpipe; struct sigaction sighandler = {.sa_handler = virConsoleHandleSignal, .sa_flags = SA_SIGINFO }; sigemptyset(&sighandler.sa_mask); /* Put STDIN into raw mode so that stuff typed does not echo to the screen * (the TTY reads will result in it being echoed back already), and also * ensure Ctrl-C, etc is blocked, and misc other bits */ if (vshTTYMakeRaw(ctl, true) < 0) goto resettty; /* 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 ! */ sigaction(SIGQUIT, &sighandler, &old_sigquit); sigaction(SIGTERM, &sighandler, &old_sigterm); sigaction(SIGINT, &sighandler, &old_sigint); sigaction(SIGHUP, &sighandler, &old_sighup); sigaction(SIGPIPE, &sighandler, &old_sigpipe); if (VIR_ALLOC(con) < 0) goto cleanup; con->escapeChar = vshGetEscapeChar(ctl->escapeChar); con->st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con->st) goto cleanup; 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, con, NULL); con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, NULL); virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, NULL); while (!con->quit) { if (virCondWait(&con->cond, &con->lock) < 0) { virMutexUnlock(&con->lock); VIR_ERROR(_("unable to wait on console condition")); goto cleanup; } } virMutexUnlock(&con->lock); ret = 0; cleanup: virConsoleFree(con); /* Restore original signal handlers */ sigaction(SIGQUIT, &old_sigquit, NULL); sigaction(SIGTERM, &old_sigterm, NULL); sigaction(SIGINT, &old_sigint, NULL); sigaction(SIGHUP, &old_sighup, NULL); sigaction(SIGPIPE, &old_sigpipe, NULL); resettty: /* Put STDIN back into the (sane?) state we found it in before starting */ vshTTYRestore(ctl); return ret; }