From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add a "--pass-fds N,M,..." arg to the virsh start/create methods. This allows pre-opened file descriptors from the shell to be passed on into the guest Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- tools/virsh-domain.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 13 ++++++++- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index c08b0e9..606bcdf 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -3256,9 +3256,61 @@ static const vshCmdOptDef opts_start[] = { .type = VSH_OT_BOOL, .help = N_("force fresh boot by discarding any managed save") }, + {.name = "pass-fds", + .type = VSH_OT_STRING, + .help = N_("pass file descriptors N,M,... to the guest") + }, {.name = NULL} }; +static int +cmdStartGetFDs(vshControl *ctl, + const vshCmd *cmd, + size_t *nfdsret, + int **fdsret) +{ + const char *fdopt; + char **fdlist = NULL; + int *fds = NULL; + size_t nfds = 0; + size_t i; + + *nfdsret = 0; + *fdsret = NULL; + + if (vshCommandOptString(cmd, "pass-fds", &fdopt) <= 0) + return 0; + + if (!(fdlist = virStringSplit(fdopt, ",", -1))) { + vshError(ctl, _("Unable to split FD list '%s'"), fdopt); + return -1; + } + + for (i = 0; fdlist[i] != NULL; i++) { + int fd; + if (virStrToLong_i(fdlist[i], NULL, 10, &fd) < 0) { + vshError(ctl, _("Unable to parse FD number '%s'"), fdlist[i]); + goto error; + } + if (VIR_EXPAND_N(fds, nfds, 1) < 0) { + vshError(ctl, "%s", _("Unable to allocate FD list")); + goto error; + } + fds[nfds - 1] = fd; + } + + virStringFreeList(fdlist); + + *fdsret = fds; + *nfdsret = nfds; + return 0; + +error: + virStringFreeList(fdlist); + VIR_FREE(fds); + return -1; +} + static bool cmdStart(vshControl *ctl, const vshCmd *cmd) { @@ -3269,6 +3321,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) #endif unsigned int flags = VIR_DOMAIN_NONE; int rc; + size_t nfds = 0; + int *fds = NULL; if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, VSH_BYNAME | VSH_BYUUID))) @@ -3280,6 +3334,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) return false; } + if (cmdStartGetFDs(ctl, cmd, &nfds, &fds) < 0) + return false; + if (vshCommandOptBool(cmd, "paused")) flags |= VIR_DOMAIN_START_PAUSED; if (vshCommandOptBool(cmd, "autodestroy")) @@ -3291,7 +3348,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) /* We can emulate force boot, even for older servers that reject it. */ if (flags & VIR_DOMAIN_START_FORCE_BOOT) { - if (virDomainCreateWithFlags(dom, flags) == 0) + if ((nfds ? + virDomainCreateWithFiles(dom, nfds, fds, flags) : + virDomainCreateWithFlags(dom, flags)) == 0) goto started; if (last_error->code != VIR_ERR_NO_SUPPORT && last_error->code != VIR_ERR_INVALID_ARG) { @@ -3313,8 +3372,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) } /* Prefer older API unless we have to pass a flag. */ - if ((flags ? virDomainCreateWithFlags(dom, flags) - : virDomainCreate(dom)) < 0) { + if ((nfds ? virDomainCreateWithFiles(dom, nfds, fds, flags) : + (flags ? virDomainCreateWithFlags(dom, flags) + : virDomainCreate(dom))) < 0) { vshError(ctl, _("Failed to start domain %s"), virDomainGetName(dom)); goto cleanup; } @@ -3331,6 +3391,7 @@ started: cleanup: virDomainFree(dom); + VIR_FREE(fds); return ret; } @@ -6397,6 +6458,10 @@ static const vshCmdOptDef opts_create[] = { .type = VSH_OT_BOOL, .help = N_("automatically destroy the guest when virsh disconnects") }, + {.name = "pass-fds", + .type = VSH_OT_STRING, + .help = N_("pass file descriptors N,M,... to the guest") + }, {.name = NULL} }; @@ -6411,6 +6476,8 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) bool console = vshCommandOptBool(cmd, "console"); #endif unsigned int flags = VIR_DOMAIN_NONE; + size_t nfds = 0; + int *fds = NULL; if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false; @@ -6418,12 +6485,18 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false; + if (cmdStartGetFDs(ctl, cmd, &nfds, &fds) < 0) + return false; + if (vshCommandOptBool(cmd, "paused")) flags |= VIR_DOMAIN_START_PAUSED; if (vshCommandOptBool(cmd, "autodestroy")) flags |= VIR_DOMAIN_START_AUTODESTROY; - dom = virDomainCreateXML(ctl->conn, buffer, flags); + if (nfds) + dom = virDomainCreateXMLWithFiles(ctl->conn, buffer, nfds, fds, flags); + else + dom = virDomainCreateXML(ctl->conn, buffer, flags); VIR_FREE(buffer); if (dom != NULL) { @@ -6438,6 +6511,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) vshError(ctl, _("Failed to create domain from %s"), from); ret = false; } + VIR_FREE(fds); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 94fe897..8a9d2d0 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -539,6 +539,7 @@ the I<--force> flag may be specified, requesting to disconnect any existing sessions, such as in a case of a broken connection. =item B<create> I<FILE> [I<--console>] [I<--paused>] [I<--autodestroy>] +[I<--pass-fds N,M,...>] Create a domain from an XML <file>. An easy way to create the XML <file> is to use the B<dumpxml> command to obtain the definition of a @@ -549,6 +550,11 @@ If I<--autodestroy> is requested, then the guest will be automatically destroyed when virsh closes its connection to libvirt, or otherwise exits. +If I<--pass-fds> is specified, the argument is a comma separated list +of open file descriptors which should be pass on into the guest. The +file descriptors will be re-numered in the guest, starting from 3. This +is only supported with container based virtualization. + B<Example> virsh dumpxml <domain> > domain.xml @@ -1661,7 +1667,7 @@ For strict control over ordering, use a single mode at a time and repeat the command. =item B<start> I<domain-name-or-uuid> [I<--console>] [I<--paused>] -[I<--autodestroy>] [I<--bypass-cache>] [I<--force-boot>] +[I<--autodestroy>] [I<--bypass-cache>] [I<--force-boot>] [I<--pass-fds N,M,...>] Start a (previously defined) inactive domain, either from the last B<managedsave> state, or via a fresh boot if no managedsave state is @@ -1675,6 +1681,11 @@ the restore will avoid the file system cache, although this may slow down the operation. If I<--force-boot> is specified, then any managedsave state is discarded and a fresh boot occurs. +If I<--pass-fds> is specified, the argument is a comma separated list +of open file descriptors which should be pass on into the guest. The +file descriptors will be re-numered in the guest, starting from 3. This +is only supported with container based virtualization. + =item B<suspend> I<domain> Suspend a running domain. It is kept in memory but won't be scheduled -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list