.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)
{
#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)))
return false;
}
+ if (cmdStartGetFDs(ctl, cmd, &nfds, &fds) < 0)
+ return false;
+
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_START_PAUSED;
if (vshCommandOptBool(cmd, "autodestroy"))
/* 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) {
}
/* 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;
}
cleanup:
virDomainFree(dom);
+ VIR_FREE(fds);
return ret;
}
.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}
};
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;
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) {
vshError(ctl, _("Failed to create domain from %s"), from);
ret = false;
}
+ VIR_FREE(fds);
return ret;
}
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
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
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
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