static dbus_bool_t virDBusAddWatch(DBusWatch *watch, void *data) { int flags = 0; int fd; struct virDBusWatch *info; if (VIR_ALLOC(info) < 0) return 0; if (dbus_watch_get_enabled(watch)) flags = virDBusTranslateWatchFlags(dbus_watch_get_flags(watch)); # if HAVE_DBUS_WATCH_GET_UNIX_FD fd = dbus_watch_get_unix_fd(watch); # else fd = dbus_watch_get_fd(watch); # endif info->bus = (DBusConnection *)data; info->watch = virEventAddHandle(fd, flags, virDBusWatchCallback, watch, NULL); if (info->watch < 0) { VIR_FREE(info); return 0; } dbus_watch_set_data(watch, info, virDBusWatchFree); return 1; }
static int libxlDomainObjFDRegisterEventHook(void *priv, int fd, void **hndp, short events, void *xl_priv) { int vir_events = VIR_EVENT_HANDLE_ERROR; libxlEventHookInfoPtr info; if (VIR_ALLOC(info) < 0) return -1; info->priv = priv; info->xl_priv = xl_priv; if (events & POLLIN) vir_events |= VIR_EVENT_HANDLE_READABLE; if (events & POLLOUT) vir_events |= VIR_EVENT_HANDLE_WRITABLE; info->id = virEventAddHandle(fd, vir_events, libxlDomainObjFDEventCallback, info, libxlDomainObjFDEventHookInfoFree); if (info->id < 0) { VIR_FREE(info); return -1; } *hndp = info; return 0; }
virLogHandlerPtr virLogHandlerNewPostExecRestart(virJSONValuePtr object, bool privileged, virLogHandlerShutdownInhibitor inhibitor, void *opaque) { virLogHandlerPtr handler; virJSONValuePtr files; ssize_t n; size_t i; if (!(handler = virLogHandlerNew(privileged, inhibitor, opaque))) return NULL; if (!(files = virJSONValueObjectGet(object, "files"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing files data from JSON file")); goto error; } if ((n = virJSONValueArraySize(files)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed files data from JSON file")); goto error; } for (i = 0; i < n; i++) { virLogHandlerLogFilePtr file; virJSONValuePtr child = virJSONValueArrayGet(files, i); if (!(file = virLogHandlerLogFilePostExecRestart(handler, child))) goto error; if (VIR_APPEND_ELEMENT_COPY(handler->files, handler->nfiles, file) < 0) goto error; if ((file->watch = virEventAddHandle(file->pipefd, VIR_EVENT_HANDLE_READABLE, virLogHandlerDomainLogFileEvent, handler, NULL)) < 0) { VIR_DELETE_ELEMENT(handler->files, handler->nfiles - 1, handler->nfiles); goto error; } } return handler; error: virObjectUnref(handler); return NULL; }
static int virFDStreamAddCallback(virStreamPtr st, int events, virStreamEventCallback cb, void *opaque, virFreeCallback ff) { struct virFDStreamData *fdst = st->privateData; int ret = -1; if (!fdst) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("stream is not open")); return -1; } virMutexLock(&fdst->lock); if (fdst->watch != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("stream already has a callback registered")); goto cleanup; } if ((fdst->watch = virEventAddHandle(fdst->fd, events, virFDStreamEvent, st, virFDStreamCallbackFree)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot register file watch on stream")); goto cleanup; } fdst->cbRemoved = false; fdst->cb = cb; fdst->opaque = opaque; fdst->ff = ff; fdst->events = events; fdst->abortCallbackCalled = false; virStreamRef(st); ret = 0; cleanup: virMutexUnlock(&fdst->lock); return ret; }
bhyveMonitorPtr bhyveMonitorOpen(virDomainObjPtr vm, bhyveConnPtr driver) { bhyveMonitorPtr mon = NULL; struct kevent kev; int rc; if (VIR_ALLOC(mon) < 0) return NULL; mon->driver = driver; mon->kq = kqueue(); if (mon->kq < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, "%s", _("Unable to create kqueue")); goto cleanup; } EV_SET(&kev, vm->pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, mon); rc = kevent(mon->kq, &kev, 1, NULL, 0, NULL); if (rc < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, "%s", _("Unable to register process kevent")); goto cleanup; } mon->watch = virEventAddHandle(mon->kq, VIR_EVENT_HANDLE_READABLE | VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP, bhyveMonitorIO, vm, bhyveMonitorRelease); if (mon->watch < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to register monitor events")); goto cleanup; } return mon; cleanup: bhyveMonitorRelease(mon); return NULL; }
static void lxcServerAccept(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRIBUTE_UNUSED, void *opaque) { struct lxcMonitor *monitor = opaque; int client; if ((client = accept(fd, NULL, NULL)) < 0) { /* First reflex may be simply to declare accept failure to be a fatal error. However, accept may fail when a client quits between the above poll and here. That case is not fatal, but rather to be expected, if not common, so ignore it. */ if (ignorable_accept_errno(errno)) return; virReportSystemError(errno, "%s", _("Unable to accept monitor client")); virMutexLock(&lock); quit = true; virMutexUnlock(&lock); return; } VIR_DEBUG("New client %d (old %d)\n", client, monitor->clientFd); VIR_FORCE_CLOSE(monitor->clientFd); virEventRemoveHandle(monitor->clientWatch); monitor->clientFd = client; if ((monitor->clientWatch = virEventAddHandle(monitor->clientFd, VIR_EVENT_HANDLE_READABLE, lxcClientIO, monitor, NULL)) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to watch client socket")); virMutexLock(&lock); quit = true; virMutexUnlock(&lock); return; } }
/** * virNetlinkEventServiceStart: * * start a monitor to receive netlink messages for libvirtd. * This registers a netlink socket with the event interface. * * Returns -1 if the monitor cannot be registered, 0 upon success */ int virNetlinkEventServiceStart(void) { virNetlinkEventSrvPrivatePtr srv; int fd; int ret = -1; if (server) return 0; VIR_INFO("starting netlink event service"); if (VIR_ALLOC(srv) < 0) { virReportOOMError(); return -1; } if (virMutexInit(&srv->lock) < 0) { VIR_FREE(srv); return -1; } virNetlinkEventServerLock(srv); /* Allocate a new socket and get fd */ srv->netlinknh = virNetlinkAlloc(); if (!srv->netlinknh) { virReportSystemError(errno, "%s", _("cannot allocate nlhandle for virNetlinkEvent server")); goto error_locked; } if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) { virReportSystemError(errno, "%s", _("cannot connect to netlink socket")); goto error_server; } fd = nl_socket_get_fd(srv->netlinknh); if (fd < 0) { virReportSystemError(errno, "%s", _("cannot get netlink socket fd")); goto error_server; } if (nl_socket_set_nonblocking(srv->netlinknh)) { virReportSystemError(errno, "%s", _("cannot set netlink socket nonblocking")); goto error_server; } if ((srv->eventwatch = virEventAddHandle(fd, VIR_EVENT_HANDLE_READABLE, virNetlinkEventCallback, srv, NULL)) < 0) { netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to add netlink event handle watch")); goto error_server; } srv->netlinkfd = fd; VIR_DEBUG("netlink event listener on fd: %i running", fd); ret = 0; server = srv; error_server: if (ret < 0) { nl_close(srv->netlinknh); virNetlinkFree(srv->netlinknh); } error_locked: virNetlinkEventServerUnlock(srv); if (ret < 0) { virMutexDestroy(&srv->lock); VIR_FREE(srv); } return ret; }
/** * virNetlinkEventServiceStart: * * start a monitor to receive netlink messages for libvirtd. * This registers a netlink socket with the event interface. * * @protocol: netlink protocol * @groups: broadcast groups to join in * Returns -1 if the monitor cannot be registered, 0 upon success */ int virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups) { virNetlinkEventSrvPrivatePtr srv; int fd; int ret = -1; if (protocol >= MAX_LINKS) { virReportSystemError(EINVAL, _("invalid protocol argument: %d"), protocol); return -EINVAL; } if (server[protocol]) return 0; VIR_INFO("starting netlink event service with protocol %d", protocol); if (VIR_ALLOC(srv) < 0) return -1; if (virMutexInit(&srv->lock) < 0) { VIR_FREE(srv); return -1; } virNetlinkEventServerLock(srv); /* Allocate a new socket and get fd */ if (!(srv->netlinknh = virNetlinkCreateSocket(protocol))) goto error_locked; fd = nl_socket_get_fd(srv->netlinknh); if (fd < 0) { virReportSystemError(errno, "%s", _("cannot get netlink socket fd")); goto error_server; } if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) { virReportSystemError(errno, "%s", _("cannot add netlink membership")); goto error_server; } if (nl_socket_set_nonblocking(srv->netlinknh)) { virReportSystemError(errno, "%s", _("cannot set netlink socket nonblocking")); goto error_server; } if ((srv->eventwatch = virEventAddHandle(fd, VIR_EVENT_HANDLE_READABLE, virNetlinkEventCallback, srv, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to add netlink event handle watch")); goto error_server; } srv->netlinkfd = fd; VIR_DEBUG("netlink event listener on fd: %i running", fd); ret = 0; server[protocol] = srv; error_server: if (ret < 0) { nl_close(srv->netlinknh); virNetlinkFree(srv->netlinknh); } error_locked: virNetlinkEventServerUnlock(srv); if (ret < 0) { virMutexDestroy(&srv->lock); VIR_FREE(srv); } return ret; }
/** * xenInotifyOpen: * @conn: pointer to the connection block * @name: URL for the target, NULL for local * @flags: combination of virDrvOpenFlag(s) * * Connects and starts listening for inotify events * * Returns 0 or -1 in case of error. */ int xenInotifyOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { DIR *dh; struct dirent *ent; char *path; xenUnifiedPrivatePtr priv = conn->privateData; virCheckFlags(VIR_CONNECT_RO, -1); if (priv->configDir) { priv->useXenConfigCache = 1; } else { /* /var/lib/xend/domains/<uuid>/config.sxp */ priv->configDir = XEND_DOMAINS_DIR; priv->useXenConfigCache = 0; if (VIR_ALLOC(priv->configInfoList) < 0) return -1; /* populate initial list */ if (!(dh = opendir(priv->configDir))) { virReportSystemError(errno, _("cannot open directory: %s"), priv->configDir); return -1; } while ((ent = readdir(dh))) { if (STRPREFIX(ent->d_name, ".")) continue; /* Build the full file path */ if (!(path = virFileBuildPath(priv->configDir, ent->d_name, NULL))) { closedir(dh); return -1; } if (xenInotifyAddDomainConfigInfo(conn, path) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Error adding file to config list")); closedir(dh); VIR_FREE(path); return -1; } VIR_FREE(path); } closedir(dh); } if ((priv->inotifyFD = inotify_init()) < 0) { virReportSystemError(errno, "%s", _("initializing inotify")); return -1; } VIR_DEBUG("Adding a watch on %s", priv->configDir); if (inotify_add_watch(priv->inotifyFD, priv->configDir, IN_CREATE | IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM) < 0) { virReportSystemError(errno, _("adding watch on %s"), priv->configDir); return -1; } VIR_DEBUG("Building initial config cache"); if (priv->useXenConfigCache && xenXMConfigCacheRefresh(conn) < 0) { VIR_DEBUG("Failed to enable XM config cache %s", conn->err.message); return -1; } VIR_DEBUG("Registering with event loop"); /* Add the handle for monitoring */ if ((priv->inotifyWatch = virEventAddHandle(priv->inotifyFD, VIR_EVENT_HANDLE_READABLE, xenInotifyEvent, conn, NULL)) < 0) { VIR_DEBUG("Failed to add inotify handle, disabling events"); } return 0; }
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 virshRunConsole(vshControl *ctl, virDomainPtr dom, const char *dev_name, unsigned int flags) { virConsolePtr con = NULL; virshControlPtr priv = ctl->privData; 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; 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 ! */ 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); con->escapeChar = virshGetEscapeChar(priv->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; virObjectRef(con); if ((con->stdinWatch = virEventAddHandle(STDIN_FILENO, VIR_EVENT_HANDLE_READABLE, virConsoleEventOnStdin, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if ((con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if (virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, virObjectFreeCallback) < 0) { virObjectUnref(con); goto cleanup; } while (!con->quit) { if (virCondWait(&con->cond, &con->parent.lock) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to wait on console condition")); goto cleanup; } } if (con->error.code == VIR_ERR_OK) ret = 0; cleanup: virConsoleShutdown(con); if (ret < 0) { vshResetLibvirtError(); virSetError(&con->error); vshSaveLibvirtHelperError(); } virObjectUnlock(con); virObjectUnref(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; }
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; }
/** * 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 * * Returns 0 on success or -1 in case of error */ static int lxcControllerMain(int serverFd, int clientFd, int *hostFds, int *contFds, size_t nFds, pid_t container) { struct lxcConsole *consoles; struct lxcMonitor monitor = { .serverFd = serverFd, .clientFd = clientFd, }; virErrorPtr err; int rc = -1; size_t i; if (virMutexInit(&lock) < 0) goto cleanup2; if (pipe2(sigpipe, O_CLOEXEC|O_NONBLOCK) < 0) { virReportSystemError(errno, "%s", _("Cannot create signal pipe")); goto cleanup; } if (virEventAddHandle(sigpipe[0], VIR_EVENT_HANDLE_READABLE, lxcSignalChildIO, &container, NULL) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to watch signal pipe")); goto cleanup; } if (signal(SIGCHLD, lxcSignalChildHandler) == SIG_ERR) { virReportSystemError(errno, "%s", _("Cannot install signal handler")); goto cleanup; } VIR_DEBUG("serverFd=%d clientFd=%d", serverFd, clientFd); virResetLastError(); if ((monitor.serverWatch = virEventAddHandle(monitor.serverFd, VIR_EVENT_HANDLE_READABLE, lxcServerAccept, &monitor, NULL)) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to watch monitor socket")); goto cleanup; } if (monitor.clientFd != -1 && (monitor.clientWatch = virEventAddHandle(monitor.clientFd, VIR_EVENT_HANDLE_READABLE, lxcClientIO, &monitor, NULL)) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to watch client socket")); goto cleanup; } if (VIR_ALLOC_N(consoles, nFds) < 0) { virReportOOMError(); goto cleanup; } for (i = 0 ; i < nFds ; i++) { consoles[i].hostFd = hostFds[i]; consoles[i].contFd = contFds[i]; if ((consoles[i].hostWatch = virEventAddHandle(consoles[i].hostFd, VIR_EVENT_HANDLE_READABLE, lxcConsoleIO, &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) { lxcError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to watch host console PTY")); goto cleanup; } } virMutexLock(&lock); while (!quit) { virMutexUnlock(&lock); if (virEventRunDefaultImpl() < 0) goto cleanup; virMutexLock(&lock); } virMutexUnlock(&lock); err = virGetLastError(); if (!err || err->code == VIR_ERR_OK) rc = 0; cleanup: virMutexDestroy(&lock); signal(SIGCHLD, SIG_DFL); cleanup2: VIR_FORCE_CLOSE(monitor.serverFd); VIR_FORCE_CLOSE(monitor.clientFd); VIR_FREE(consoles); return rc; }
/** * xenStoreOpen: * @conn: pointer to the connection block * @name: URL for the target, NULL for local * @flags: combination of virDrvOpenFlag(s) * * Connects to the Xen hypervisor. * * Returns 0 or -1 in case of error. */ int xenStoreOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { xenUnifiedPrivatePtr priv = conn->privateData; virCheckFlags(VIR_CONNECT_RO, -1); if (flags & VIR_CONNECT_RO) priv->xshandle = xs_daemon_open_readonly(); else priv->xshandle = xs_daemon_open(); if (priv->xshandle == NULL) { /* * not being able to connect via the socket as an unprivileged * user is rather normal, this should fallback to the proxy (or * remote) mechanism. */ if (xenHavePrivilege()) { virReportError(VIR_ERR_NO_XEN, "%s", _("failed to connect to Xen Store")); } return -1; } /* Init activeDomainList */ if (VIR_ALLOC(priv->activeDomainList) < 0) return -1; /* Init watch list before filling in domInfoList, so we can know if it is the first time through when the callback fires */ if (VIR_ALLOC(priv->xsWatchList) < 0) return -1; /* This will get called once at start */ if (xenStoreAddWatch(conn, "@releaseDomain", "releaseDomain", xenStoreDomainReleased, priv) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("adding watch @releaseDomain")); return -1; } /* The initial call of this will fill domInfoList */ if (xenStoreAddWatch(conn, "@introduceDomain", "introduceDomain", xenStoreDomainIntroduced, priv) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("adding watch @introduceDomain")); return -1; } /* Add an event handle */ if ((priv->xsWatch = virEventAddHandle(xs_fileno(priv->xshandle), VIR_EVENT_HANDLE_READABLE, xenStoreWatchEvent, conn, NULL)) < 0) VIR_DEBUG("Failed to add event handle, disabling events"); return 0; }