mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
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:
parent
11693bc6f0
commit
afb50d79db
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user