Improve virsh create --console behavior

When starting a guest via libvirt (`virsh create --console`), early
console output was missed because the guest was started first and then
the console was attached. This patch changes this to the following
sequence:

1. create a paused transient guest
2. attach the console
3. resume the guest

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Marc Hartmayer 2023-09-28 17:37:10 +02:00 committed by Michal Privoznik
parent a99ed65db2
commit 0eca9ba316

View File

@ -8216,6 +8216,20 @@ static const vshCmdOptDef opts_create[] = {
{.name = NULL} {.name = NULL}
}; };
static virshDomain *
virshDomainCreateXMLHelper(virConnectPtr conn,
const char *xmlDesc,
unsigned int nfds,
int *fds,
unsigned int flags)
{
if (nfds) {
return virDomainCreateXMLWithFiles(conn, xmlDesc, nfds, fds, flags);
}
return virDomainCreateXML(conn, xmlDesc, flags);
}
static bool static bool
cmdCreate(vshControl *ctl, const vshCmd *cmd) cmdCreate(vshControl *ctl, const vshCmd *cmd)
{ {
@ -8224,6 +8238,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
g_autofree char *buffer = NULL; g_autofree char *buffer = NULL;
#ifndef WIN32 #ifndef WIN32
bool console = vshCommandOptBool(cmd, "console"); bool console = vshCommandOptBool(cmd, "console");
bool resume_domain = false;
#endif #endif
unsigned int flags = 0; unsigned int flags = 0;
size_t nfds = 0; size_t nfds = 0;
@ -8239,8 +8254,14 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
if (virshFetchPassFdsList(ctl, cmd, &nfds, &fds) < 0) if (virshFetchPassFdsList(ctl, cmd, &nfds, &fds) < 0)
return false; return false;
if (vshCommandOptBool(cmd, "paused")) if (vshCommandOptBool(cmd, "paused")) {
flags |= VIR_DOMAIN_START_PAUSED; flags |= VIR_DOMAIN_START_PAUSED;
#ifndef WIN32
} else if (console) {
flags |= VIR_DOMAIN_START_PAUSED;
resume_domain = true;
#endif
}
if (vshCommandOptBool(cmd, "autodestroy")) if (vshCommandOptBool(cmd, "autodestroy"))
flags |= VIR_DOMAIN_START_AUTODESTROY; flags |= VIR_DOMAIN_START_AUTODESTROY;
if (vshCommandOptBool(cmd, "validate")) if (vshCommandOptBool(cmd, "validate"))
@ -8248,10 +8269,18 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "reset-nvram")) if (vshCommandOptBool(cmd, "reset-nvram"))
flags |= VIR_DOMAIN_START_RESET_NVRAM; flags |= VIR_DOMAIN_START_RESET_NVRAM;
if (nfds) dom = virshDomainCreateXMLHelper(priv->conn, buffer, nfds, fds, flags);
dom = virDomainCreateXMLWithFiles(priv->conn, buffer, nfds, fds, flags); #ifndef WIN32
else /* If the driver does not support the paused flag, let's fallback to the old
dom = virDomainCreateXML(priv->conn, buffer, flags); * behavior without the flag. */
if (!dom && resume_domain && last_error && last_error->code == VIR_ERR_INVALID_ARG) {
vshResetLibvirtError();
flags &= ~VIR_DOMAIN_START_PAUSED;
resume_domain = false;
dom = virshDomainCreateXMLHelper(priv->conn, buffer, nfds, fds, flags);
}
#endif
if (!dom) { if (!dom) {
vshError(ctl, _("Failed to create domain from %1$s"), from); vshError(ctl, _("Failed to create domain from %1$s"), from);
@ -8262,7 +8291,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
virDomainGetName(dom), from); virDomainGetName(dom), from);
#ifndef WIN32 #ifndef WIN32
if (console) if (console)
cmdRunConsole(ctl, dom, NULL, false, 0); cmdRunConsole(ctl, dom, NULL, resume_domain, 0);
#endif #endif
return true; return true;
} }