提交 afb50d79 编写于 作者: D Daniel P. Berrange

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: NDaniel P. Berrange <berrange@redhat.com>
上级 11693bc6
...@@ -3256,9 +3256,61 @@ static const vshCmdOptDef opts_start[] = { ...@@ -3256,9 +3256,61 @@ static const vshCmdOptDef opts_start[] = {
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("force fresh boot by discarding any managed save") .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} {.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 static bool
cmdStart(vshControl *ctl, const vshCmd *cmd) cmdStart(vshControl *ctl, const vshCmd *cmd)
{ {
...@@ -3269,6 +3321,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) ...@@ -3269,6 +3321,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
#endif #endif
unsigned int flags = VIR_DOMAIN_NONE; unsigned int flags = VIR_DOMAIN_NONE;
int rc; int rc;
size_t nfds = 0;
int *fds = NULL;
if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL,
VSH_BYNAME | VSH_BYUUID))) VSH_BYNAME | VSH_BYUUID)))
...@@ -3280,6 +3334,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) ...@@ -3280,6 +3334,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
return false; return false;
} }
if (cmdStartGetFDs(ctl, cmd, &nfds, &fds) < 0)
return false;
if (vshCommandOptBool(cmd, "paused")) if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_START_PAUSED; flags |= VIR_DOMAIN_START_PAUSED;
if (vshCommandOptBool(cmd, "autodestroy")) if (vshCommandOptBool(cmd, "autodestroy"))
...@@ -3291,7 +3348,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) ...@@ -3291,7 +3348,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
/* We can emulate force boot, even for older servers that reject it. */ /* We can emulate force boot, even for older servers that reject it. */
if (flags & VIR_DOMAIN_START_FORCE_BOOT) { 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; goto started;
if (last_error->code != VIR_ERR_NO_SUPPORT && if (last_error->code != VIR_ERR_NO_SUPPORT &&
last_error->code != VIR_ERR_INVALID_ARG) { last_error->code != VIR_ERR_INVALID_ARG) {
...@@ -3313,8 +3372,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) ...@@ -3313,8 +3372,9 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
} }
/* Prefer older API unless we have to pass a flag. */ /* Prefer older API unless we have to pass a flag. */
if ((flags ? virDomainCreateWithFlags(dom, flags) if ((nfds ? virDomainCreateWithFiles(dom, nfds, fds, flags) :
: virDomainCreate(dom)) < 0) { (flags ? virDomainCreateWithFlags(dom, flags)
: virDomainCreate(dom))) < 0) {
vshError(ctl, _("Failed to start domain %s"), virDomainGetName(dom)); vshError(ctl, _("Failed to start domain %s"), virDomainGetName(dom));
goto cleanup; goto cleanup;
} }
...@@ -3331,6 +3391,7 @@ started: ...@@ -3331,6 +3391,7 @@ started:
cleanup: cleanup:
virDomainFree(dom); virDomainFree(dom);
VIR_FREE(fds);
return ret; return ret;
} }
...@@ -6397,6 +6458,10 @@ static const vshCmdOptDef opts_create[] = { ...@@ -6397,6 +6458,10 @@ static const vshCmdOptDef opts_create[] = {
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("automatically destroy the guest when virsh disconnects") .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} {.name = NULL}
}; };
...@@ -6411,6 +6476,8 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) ...@@ -6411,6 +6476,8 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
bool console = vshCommandOptBool(cmd, "console"); bool console = vshCommandOptBool(cmd, "console");
#endif #endif
unsigned int flags = VIR_DOMAIN_NONE; unsigned int flags = VIR_DOMAIN_NONE;
size_t nfds = 0;
int *fds = NULL;
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
return false; return false;
...@@ -6418,12 +6485,18 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) ...@@ -6418,12 +6485,18 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
return false; return false;
if (cmdStartGetFDs(ctl, cmd, &nfds, &fds) < 0)
return false;
if (vshCommandOptBool(cmd, "paused")) if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_START_PAUSED; flags |= VIR_DOMAIN_START_PAUSED;
if (vshCommandOptBool(cmd, "autodestroy")) if (vshCommandOptBool(cmd, "autodestroy"))
flags |= VIR_DOMAIN_START_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); VIR_FREE(buffer);
if (dom != NULL) { if (dom != NULL) {
...@@ -6438,6 +6511,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) ...@@ -6438,6 +6511,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
vshError(ctl, _("Failed to create domain from %s"), from); vshError(ctl, _("Failed to create domain from %s"), from);
ret = false; ret = false;
} }
VIR_FREE(fds);
return ret; return ret;
} }
......
...@@ -539,6 +539,7 @@ the I<--force> flag may be specified, requesting to disconnect any existing ...@@ -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. sessions, such as in a case of a broken connection.
=item B<create> I<FILE> [I<--console>] [I<--paused>] [I<--autodestroy>] =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 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 <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 ...@@ -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 destroyed when virsh closes its connection to libvirt, or otherwise
exits. 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> B<Example>
virsh dumpxml <domain> > domain.xml virsh dumpxml <domain> > domain.xml
...@@ -1681,7 +1687,7 @@ For strict control over ordering, use a single mode at a time and ...@@ -1681,7 +1687,7 @@ For strict control over ordering, use a single mode at a time and
repeat the command. repeat the command.
=item B<start> I<domain-name-or-uuid> [I<--console>] [I<--paused>] =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 Start a (previously defined) inactive domain, either from the last
B<managedsave> state, or via a fresh boot if no managedsave state is 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 ...@@ -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 down the operation. If I<--force-boot> is specified, then any
managedsave state is discarded and a fresh boot occurs. 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> =item B<suspend> I<domain>
Suspend a running domain. It is kept in memory but won't be scheduled Suspend a running domain. It is kept in memory but won't be scheduled
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册