Enable FD passing when starting guests with virsh

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@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-07-11 16:32:14 +01:00
parent 11693bc6f0
commit afb50d79db
2 changed files with 90 additions and 5 deletions

View File

@ -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,11 +6485,17 @@ 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;
if (nfds)
dom = virDomainCreateXMLWithFiles(ctl->conn, buffer, nfds, fds, flags);
else
dom = virDomainCreateXML(ctl->conn, buffer, flags);
VIR_FREE(buffer);
@ -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;
}

View File

@ -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
@ -1681,7 +1687,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
@ -1695,6 +1701,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