[libvirt] [PATCH 0/9] Resolve libvirtd hang on termination with connected long running client
by John Ferlan
RFC:
https://www.redhat.com/archives/libvir-list/2018-January/msg00318.html
Adjustments since RFC...
Patches 1&2: No change, were already R-B'd
Patch 3: Removed code as noted in code review, update commit message
Patch 4: From old series removed, see below for more details
Patch 9: no change
NB: Patches 5-8 and 10 from Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
are removed as they seemed to not be necessary
Replaced the former patch 4 with series of patches to (slowly) provide
support to disable new connections, handle removing waiting jobs, causing
the waiting workers to quit, and allow any running jobs to complete.
As it turns out, waiting for running jobs to complete cannot be done
from the virNetServerClose callbacks because that means the event loop
processing done during virNetServerRun will not allow any currently
long running worker job thread a means to complete.
So when virNetDaemonQuit is called as a result of the libvirtd signal
handlers for SIG{QUIT|INT|TERM}, instead of just causing virNetServerRun
to quit immediately, alter to using a quitRequested flag and then use
that quitRequested flag to check for long running worker threads before
causing the event loop to quit resulting in libvirtd being able to run
through the virNetDaemonClose processing.
John Ferlan (9):
libvirtd: Alter refcnt processing for domain server objects
libvirtd: Alter refcnt processing for server program objects
netserver: Remove ServiceToggle during ServerDispose
util: Introduce virThreadPoolDrain
rpc: Introduce virNetServerQuitRequested
rpc: Introduce virNetServerWorkerCount
rpc: Alter virNetDaemonQuit processing
docs: Add news article for libvirtd issue
APPLY ONLY FOR TESTING PURPOSES
daemon/libvirtd.c | 43 +++++++++++++++++++++++---------
docs/news.xml | 12 +++++++++
src/libvirt_private.syms | 1 +
src/libvirt_remote.syms | 2 ++
src/qemu/qemu_driver.c | 5 ++++
src/rpc/virnetdaemon.c | 45 +++++++++++++++++++++++++++++++++-
src/rpc/virnetserver.c | 52 ++++++++++++++++++++++++++++++++++++---
src/rpc/virnetserver.h | 4 +++
src/util/virthreadpool.c | 64 ++++++++++++++++++++++++++++++++++++++++--------
src/util/virthreadpool.h | 2 ++
10 files changed, 204 insertions(+), 26 deletions(-)
--
2.13.6
6 years, 4 months
[libvirt] Call to virDomainIsActive hangs forever
by Mathieu Tarral
Hi !
I'm submitting my messages on this mailing list to request a bit of
help on a case that I have
where a Python application makes a call to virDomainIsActive, and the
call never returns.
I have tried to investigate, but as there are no debug symbols for
libvirt on Debian Stretch,
i can only have the following GDB backtrace:
(gdb) bt
#0 pthread_cond_wait@(a)GLIBC_2.3.2 () at
../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1 0x00007f49026f5b76 in virCondWait () from /usr/lib/libvirt.so.0
#2 0x00007f4902808bab in ?? () from /usr/lib/libvirt.so.0
#3 0x00007f490280a433 in virNetClientSendWithReply () from
/usr/lib/libvirt.so.0
#4 0x00007f490280abe2 in virNetClientProgramCall () from /usr/lib/libvirt.so.0
#5 0x00007f49027e0ea4 in ?? () from /usr/lib/libvirt.so.0
#6 0x00007f49027ea1bb in ?? () from /usr/lib/libvirt.so.0
#7 0x00007f49027b0ef3 in virDomainIsActive () from /usr/lib/libvirt.so.0
#8 0x00007f4902b7fbd0 in libvirt_virDomainIsActive () from
/usr/lib/python3/dist-packages/libvirtmod.cpython-35m-x86_64-linux-gnu.so
#9 0x0000558eeec696df in PyCFunction_Call () at ../Objects/methodobject.c:109
The libvirt driver used is QEMU, and i have a specific monitoring in
place using virtual machine introspection:
https://github.com/KVM-VMI/kvm-vmi
Now this specific monitoring somehow triggers this bug, and at this
point, i don't know if
it's a corner case in the libvirt QEMU driver or not.
That's why i would like to have your lights on this.
libvirt version: 3.0.0-4
-> Could you tell me where i should look in the code ?
-> Do you have more information about this virCondWait ? Which
condition is it waiting for ?
-> How can i get the symbols without having the recompile libvirt and
install it system wide, erasing the binaries installed by the package
?
Best regards,
--
Mathieu Tarral
6 years, 5 months
[libvirt] [PATCH 00/12] Various apparmor related changes (part )
by Christian Ehrhardt
Hi,
this is a continuation of the ongoing effort to feed back Ubuntu apparmor
Delta on libvirt to the community (or to sort out remaining todos or to keep
them distro specific).
In that it is a follow on to:
- https://www.redhat.com/archives/libvir-list/2017-May/msg00630.html
- https://www.redhat.com/archives/libvir-list/2017-May/msg00887.html
I punted those we had discussions on and decided to rework in the last rounds
out of the submission.
But in exchange pulled in some more changes we had that are now ready for
discussion. That way I prepared the next set of 12 changes which I hereby
submit for your consideration into 3.11.
Christian Ehrhardt (3):
apparmor, libvirt-qemu: add default pki path of lbvirt-spice
apparmor, libvirt-qemu: add generic base vfio device
apparmor, libvirt-qemu: qemu won't call qemu-nbd
Jamie Strandboge (5):
apparmor, libvirt-qemu: Allow read access to sysfs system info
apparmor, libvirt-qemu: Allow qemu-block-extra libraries
apparmor, libvirtd: Allow ixr to /var/lib/libvirt/virtd*
apparmor, virt-aa-helper: Allow access to ecryptfs files
apparmor, virt-aa-helper: Allow access to /sys/bus/usb/devices
Serge Hallyn (3):
apparmor, libvirt-qemu: Allow use of sgabios
apparmor, libvirt-qemu: Allow read access to max_mem_regions
apparmor, libvirt-qemu: Allow access to hugepage mounts
Stefan Bader (1):
apparmor, libvirt-qemu: Silence lttng related deny messages
examples/apparmor/libvirt-qemu | 26 +++++++++++++++++++++++-
examples/apparmor/usr.lib.libvirt.virt-aa-helper | 6 ++++++
examples/apparmor/usr.sbin.libvirtd | 4 ++++
3 files changed, 35 insertions(+), 1 deletion(-)
--
2.7.4
6 years, 5 months
[libvirt] [PATCH] qemu: Honour <on_reboot/>
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1476866
For some reason, we completely ignore <on_reboot/> setting for
domains. The implementation is simply not there. It never was.
However, things are slightly more complicated. QEMU sends us two
RESET events on domain reboot. Fortunately, the event contains
this 'guest' field telling us who initiated the reboot. And since
we don't want to destroy the domain if the reset is initiated by
a user, we have to ignore those events. Whatever, just look at
the code.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_monitor.c | 4 ++--
src/qemu/qemu_monitor.h | 3 ++-
src/qemu/qemu_monitor_json.c | 8 +++++++-
src/qemu/qemu_process.c | 34 ++++++++++++++++++++++++++++++----
5 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 4c9050aff..d865e67c7 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -233,6 +233,7 @@ struct _qemuDomainObjPrivate {
bool agentError;
bool gotShutdown;
+ bool gotReset;
bool beingDestroyed;
char *pidfile;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 19082d8bf..8f81a2b28 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1344,12 +1344,12 @@ qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest)
int
-qemuMonitorEmitReset(qemuMonitorPtr mon)
+qemuMonitorEmitReset(qemuMonitorPtr mon, virTristateBool guest)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm, guest);
return ret;
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 31f7e97ba..8c33f6783 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -134,6 +134,7 @@ typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon,
void *opaque);
typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
+ virTristateBool guest,
void *opaque);
typedef int (*qemuMonitorDomainPowerdownCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
@@ -346,7 +347,7 @@ int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
long long seconds, unsigned int micros,
const char *details);
int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest);
-int qemuMonitorEmitReset(qemuMonitorPtr mon);
+int qemuMonitorEmitReset(qemuMonitorPtr mon, virTristateBool guest);
int qemuMonitorEmitPowerdown(qemuMonitorPtr mon);
int qemuMonitorEmitStop(qemuMonitorPtr mon);
int qemuMonitorEmitResume(qemuMonitorPtr mon);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index b8a68154a..8a1501ced 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -536,7 +536,13 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr da
static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
{
- qemuMonitorEmitReset(mon);
+ bool guest = false;
+ virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
+
+ if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) == 0)
+ guest_initiated = guest ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ qemuMonitorEmitReset(mon, guest_initiated);
}
static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0aecce3b1..889efc7f0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -478,27 +478,51 @@ qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
static int
qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
+ virTristateBool guest_initiated,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
- virObjectEventPtr event;
+ virObjectEventPtr event = NULL;
qemuDomainObjPrivatePtr priv;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ bool callOnReboot = false;
virObjectLock(vm);
+ priv = vm->privateData;
+
+ /* This is a bit tricky. When a guest does 'reboot' we receive RESET event
+ * twice, both times it's guest initiated. However, if users call 'virsh
+ * reset' we still receive two events but the first one is guest_initiated
+ * = no, the second one is guest_initiated = yes. Therefore, to avoid
+ * executing onReboot action in the latter case we need this complicated
+ * construction. */
+ if (guest_initiated == VIR_TRISTATE_BOOL_NO) {
+ VIR_DEBUG("Ignoring not guest initiated RESET event from domain %s",
+ vm->def->name);
+ priv->gotReset = true;
+ } else if (priv->gotReset && guest_initiated == VIR_TRISTATE_BOOL_YES) {
+ VIR_DEBUG("Ignoring second RESET event from domain %s",
+ vm->def->name);
+ priv->gotReset = false;
+ } else {
+ callOnReboot = true;
+ }
+
event = virDomainEventRebootNewFromObj(vm);
- priv = vm->privateData;
if (priv->agent)
qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_RESET);
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
VIR_WARN("Failed to save status on vm %s", vm->def->name);
+ if (callOnReboot &&
+ guest_initiated == VIR_TRISTATE_BOOL_YES &&
+ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_DESTROY)
+ qemuProcessShutdownOrReboot(driver, vm);
+
virObjectUnlock(vm);
-
qemuDomainEventQueue(driver, event);
-
virObjectUnref(cfg);
return 0;
}
@@ -555,6 +579,7 @@ qemuProcessFakeReboot(void *opaque)
goto endjob;
}
priv->gotShutdown = false;
+ priv->gotReset = false;
event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_RESUMED,
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
@@ -5320,6 +5345,7 @@ qemuProcessPrepareDomain(virConnectPtr conn,
priv->monError = false;
priv->monStart = 0;
priv->gotShutdown = false;
+ priv->gotReset = false;
VIR_DEBUG("Updating guest CPU definition");
if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < 0)
--
2.13.0
6 years, 5 months
[libvirt] [PATCH] bhyve: add support for passing stdin to loader
by Fabian Freyer
This commit adds the <bootloader_stdin> node to the domain definition,
with the following semantics:
To pass standard input verbatim to the bootloader, set
<bootloader_stdin>some stdin</bootloader_stdin>
Multiline standard input can be set using a CDATA tag:
<bootloader_stdin><![CDATA[
this standard input
will be passed in with
newlines and indentation.
]]></bootloader_stdin>
Standard input can be read from a file as follows:
<bootloader_stdin file="/path/to/some/file"/>
Signed-off-by: Fabian Freyer <fabian.freyer(a)physik.tu-berlin.de>
---
docs/formatdomain.html.in | 19 ++++++
docs/schemas/domaincommon.rng | 10 ++++
src/bhyve/bhyve_driver.c | 10 ++++
src/bhyve/bhyve_parse_command.c | 70 ++++++++++++++++++++++
src/bhyve/bhyve_process.c | 22 +++++++
src/conf/domain_conf.c | 41 +++++++++++++
src/conf/domain_conf.h | 11 ++++
.../bhyveargv2xml-loader-stdin-file.args | 9 +++
.../bhyveargv2xml-loader-stdin-file.xml | 19 ++++++
.../bhyveargv2xml-loader-stdin-multiline.args | 13 ++++
.../bhyveargv2xml-loader-stdin-multiline.xml | 21 +++++++
.../bhyveargv2xml-loader-stdin-oneline.args | 11 ++++
.../bhyveargv2xml-loader-stdin-oneline.xml | 19 ++++++
tests/bhyveargv2xmltest.c | 3 +
.../bhyvexml2argv-grub-stdin-file.args | 9 +++
.../bhyvexml2argv-grub-stdin-file.devmap | 1 +
.../bhyvexml2argv-grub-stdin-file.ldargs | 4 ++
.../bhyvexml2argv-grub-stdin-file.xml | 25 ++++++++
.../bhyvexml2argv-grub-stdin-multiline.args | 9 +++
.../bhyvexml2argv-grub-stdin-multiline.devmap | 1 +
.../bhyvexml2argv-grub-stdin-multiline.ldargs | 4 ++
.../bhyvexml2argv-grub-stdin-multiline.xml | 30 ++++++++++
.../bhyvexml2argv-grub-stdin-oneline.args | 9 +++
.../bhyvexml2argv-grub-stdin-oneline.devmap | 1 +
.../bhyvexml2argv-grub-stdin-oneline.ldargs | 4 ++
.../bhyvexml2argv-grub-stdin-oneline.xml | 25 ++++++++
tests/bhyvexml2argvtest.c | 3 +
.../bhyvexml2xmlout-grub-stdin-file.xml | 34 +++++++++++
.../bhyvexml2xmlout-grub-stdin-multiline.xml | 39 ++++++++++++
.../bhyvexml2xmlout-grub-stdin-oneline.xml | 34 +++++++++++
tests/bhyvexml2xmltest.c | 3 +
31 files changed, 513 insertions(+)
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.args
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.xml
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.args
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.xml
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.args
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.xml
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.devmap
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.xml
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.devmap
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.xml
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.devmap
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-file.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-multiline.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-oneline.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 5e99884dc..cea024235 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -245,6 +245,11 @@
...
<bootloader>/usr/bin/pygrub</bootloader>
<bootloader_args>--append single</bootloader_args>
+<bootloader_stdin><![CDATA[
+kernel (hd)/path/to/kernel
+initrd (host)/path/to/initrd
+boot
+]]>
...</pre>
<dl>
@@ -259,6 +264,20 @@
command line arguments to be passed to the bootloader.
<span class="since">Since 0.2.3</span>
</dd>
+ <dt><code>bootloader_stdin</code></dt>
+ <dd>The optional <code>bootloader_stdin</code> element specifies
+ standard input to be passed to the bootloader. To pass multiple
+ lines of standard input to the bootloader, wrap the content in
+ a CDATA tag. Instead of specifying the standard input in the
+ domain XML, the path to a file to be read may be given using the
+ <code>file</code> attribute:
+<pre>
+...
+<bootloader_stdin file="/path/to/some/file"/>
+...
+</pre>
+ <span class="since">Since 4.3.0 (bhyve only)</span>
+ </dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4cab55f05..a44d88ef3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1211,6 +1211,16 @@
<text/>
</element>
</optional>
+ <optional>
+ <choice>
+ <element name="bootloader_stdin">
+ <text/>
+ </element>
+ <element name="bootloader_stdin">
+ <attribute name="file"/>
+ </element>
+ </choice>
+ </optional>
</interleave>
</define>
<define name="osbootkernel">
diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 24c4a9c80..7ac3ad3f0 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -743,6 +743,16 @@ bhyveConnectDomainXMLToNative(virConnectPtr conn,
goto cleanup;
virBufferAdd(&buf, virCommandToString(loadcmd), -1);
+
+ if (def->os.bootloaderStdinSource == VIR_DOMAIN_BOOTLOADER_STDIN_FILE)
+ virBufferEscapeString(&buf, " < %s", def->os.bootloaderStdin);
+ else if (def->os.bootloaderStdinSource
+ == VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL) {
+ virBufferEscapeString(&buf, " << END_LOADER_STDIN\n"
+ "%s\nEND_LOADER_STDIN",
+ def->os.bootloaderStdin);
+ }
+
virBufferAddChar(&buf, '\n');
}
diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c
index fcaaed275..ef51a75f1 100644
--- a/src/bhyve/bhyve_parse_command.c
+++ b/src/bhyve/bhyve_parse_command.c
@@ -124,6 +124,8 @@ static int
bhyveCommandLineToArgv(const char *nativeConfig,
int *loader_argc,
char ***loader_argv,
+ char **loader_stdin_buffer,
+ char **loader_stdin_file,
int *bhyve_argc,
char ***bhyve_argv)
{
@@ -139,6 +141,10 @@ bhyveCommandLineToArgv(const char *nativeConfig,
char **_bhyve_argv = NULL;
char **_loader_argv = NULL;
+ virBuffer heredoc = VIR_BUFFER_INITIALIZER;
+ int in_heredoc = 0;
+ char *heredoc_delim = NULL;
+
nativeConfig_unescaped = bhyveParseCommandLineUnescape(nativeConfig);
if (nativeConfig_unescaped == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -178,6 +184,52 @@ bhyveCommandLineToArgv(const char *nativeConfig,
char **arglist = NULL;
size_t args_count = 0;
size_t args_alloc = 0;
+ char *stdin_redir = NULL;
+
+ /* are we in a heredoc? */
+ if ( in_heredoc ) {
+ if (STRPREFIX(curr, heredoc_delim)) {
+ in_heredoc = 0;
+ *loader_stdin_buffer = virBufferContentAndReset(&heredoc);
+ continue;
+ }
+
+ if (in_heredoc++ == 1)
+ virBufferAsprintf(&heredoc, "%s", curr);
+ else
+ virBufferAsprintf(&heredoc, "\n%s", curr);
+
+ continue;
+ }
+
+ /* check if this line contains standard input redirection. */
+ if ( (stdin_redir = strchr(curr, '<')) ) {
+ if (STREQLEN(stdin_redir, "<<", 2)) {
+ *stdin_redir = '\0';
+ in_heredoc = 1;
+ heredoc_delim = stdin_redir + 2;
+
+ /* skip non-alphanumeric chars */
+ while (*heredoc_delim && !c_isalnum(*heredoc_delim))
+ heredoc_delim ++;
+
+ if (!*heredoc_delim)
+ goto error;
+
+ virBufferFreeAndReset(&heredoc);
+ } else {
+ /* file redirection */
+ *stdin_redir = '\0';
+ stdin_redir ++;
+
+ /* skip non-alphanumeric chars */
+ while (*stdin_redir && !c_isalnum(*stdin_redir))
+ stdin_redir ++;
+
+ if (VIR_STRDUP(*loader_stdin_file, stdin_redir) != 1)
+ goto error;
+ }
+ }
/* iterate over each line, splitting on sequences of ' '. This code is
* adapted from qemu/qemu_parse_command.c. */
@@ -254,12 +306,16 @@ bhyveCommandLineToArgv(const char *nativeConfig,
if (!(*bhyve_argv = _bhyve_argv))
goto error;
+ if (in_heredoc)
+ goto error;
+
virStringListFree(lines);
return 0;
error:
VIR_FREE(_loader_argv);
VIR_FREE(_bhyve_argv);
+ virBufferFreeAndReset(&heredoc);
virStringListFree(lines);
return -1;
}
@@ -869,6 +925,8 @@ bhyveParseCommandLineString(const char* nativeConfig,
char **bhyve_argv = NULL;
int loader_argc = 0;
char **loader_argv = NULL;
+ char *loader_stdin_file = NULL;
+ char *loader_stdin_buffer = NULL;
if (!(def = virDomainDefNew()))
goto cleanup;
@@ -887,12 +945,21 @@ bhyveParseCommandLineString(const char* nativeConfig,
if (bhyveCommandLineToArgv(nativeConfig,
&loader_argc, &loader_argv,
+ &loader_stdin_buffer, &loader_stdin_file,
&bhyve_argc, &bhyve_argv)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Failed to convert the command string to argv-lists"));
goto error;
}
+ if (loader_stdin_file && !loader_stdin_buffer) {
+ def->os.bootloaderStdinSource = VIR_DOMAIN_BOOTLOADER_STDIN_FILE;
+ def->os.bootloaderStdin = loader_stdin_file;
+ } else if (loader_stdin_buffer && !loader_stdin_file) {
+ def->os.bootloaderStdinSource = VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL,
+ def->os.bootloaderStdin = loader_stdin_buffer;
+ }
+
if (bhyveParseBhyveCommandLine(def, xmlopt, caps, bhyve_argc, bhyve_argv))
goto error;
if (loader_argv && STREQ(loader_argv[0], "/usr/sbin/bhyveload")) {
@@ -906,9 +973,12 @@ bhyveParseCommandLineString(const char* nativeConfig,
cleanup:
virStringListFree(loader_argv);
virStringListFree(bhyve_argv);
+
return def;
error:
virDomainDefFree(def);
+ VIR_FREE(loader_stdin_buffer);
+ VIR_FREE(loader_stdin_file);
def = NULL;
goto cleanup;
}
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index 9276d7d36..1a6f783d7 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -113,6 +113,7 @@ virBhyveProcessStart(virConnectPtr conn,
bhyveDomainObjPrivatePtr priv = vm->privateData;
int ret = -1, rc;
virCapsPtr caps = NULL;
+ int stdinfd = -1;
if (virAsprintf(&logfile, "%s/%s.log",
BHYVE_LOG_DIR, vm->def->name) < 0)
@@ -173,6 +174,26 @@ virBhyveProcessStart(virConnectPtr conn,
if (!(load_cmd = virBhyveProcessBuildLoadCmd(conn, vm->def, devmap_file,
&devicemap)))
goto cleanup;
+
+ switch (vm->def->os.bootloaderStdinSource) {
+ case VIR_DOMAIN_BOOTLOADER_STDIN_NONE:
+ break;
+ case VIR_DOMAIN_BOOTLOADER_STDIN_FILE:
+ if ((stdinfd = open(vm->def->os.bootloaderStdin, O_RDONLY)) < 0) {
+ virReportSystemError(errno, _("Failed to open '%s'"),
+ vm->def->os.bootloaderStdin);
+ goto cleanup;
+ }
+ virCommandSetInputFD(load_cmd, stdinfd);
+ break;
+ case VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL:
+ virCommandSetInputBuffer(load_cmd, vm->def->os.bootloaderStdin);
+ break;
+ /* coverity[dead_error_begin] */
+ case VIR_DOMAIN_BOOTLOADER_STDIN_LAST:
+ break;
+ }
+
virCommandSetOutputFD(load_cmd, &logfd);
virCommandSetErrorFD(load_cmd, &logfd);
@@ -252,6 +273,7 @@ virBhyveProcessStart(virConnectPtr conn,
virCommandFree(load_cmd);
virCommandFree(cmd);
VIR_FREE(logfile);
+ VIR_FORCE_CLOSE(stdinfd);
VIR_FORCE_CLOSE(logfd);
return ret;
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d23182f18..d99ecf9f7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3037,6 +3037,8 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->os.bootloader);
VIR_FREE(def->os.bootloaderArgs);
+ VIR_FREE(def->os.bootloaderStdin);
+
virDomainClockDefClear(&def->clock);
VIR_FREE(def->name);
@@ -18700,6 +18702,16 @@ virDomainDefParseXML(xmlDocPtr xml,
def->os.bootloader = virXPathString("string(./bootloader)", ctxt);
def->os.bootloaderArgs = virXPathString("string(./bootloader_args)", ctxt);
+ if ((def->os.bootloaderStdin = virXPathString("string(./bootloader_stdin/"
+ "@file)", ctxt)))
+ def->os.bootloaderStdinSource = VIR_DOMAIN_BOOTLOADER_STDIN_FILE;
+ else if ((def->os.bootloaderStdin = virXPathString("string("
+ "./bootloader_stdin)",
+ ctxt)))
+ def->os.bootloaderStdinSource = VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL;
+ else
+ def->os.bootloaderStdinSource = VIR_DOMAIN_BOOTLOADER_STDIN_NONE;
+
tmp = virXPathString("string(./os/type[1])", ctxt);
if (!tmp) {
if (def->os.bootloader) {
@@ -26717,6 +26729,35 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferEscapeString(buf,
"<bootloader_args>%s</bootloader_args>\n",
def->os.bootloaderArgs);
+
+ switch (def->os.bootloaderStdinSource) {
+ case VIR_DOMAIN_BOOTLOADER_STDIN_NONE:
+ break;
+ case VIR_DOMAIN_BOOTLOADER_STDIN_FILE:
+ virBufferEscapeString(buf, "<bootloader_stdin file=\"%s\"/>\n",
+ def->os.bootloaderStdin);
+ break;
+ case VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL:
+ if (strchr(def->os.bootloaderStdin, '\n')
+ || strchr(def->os.bootloaderStdin, '<')
+ || strchr(def->os.bootloaderStdin, '>')
+ || strchr(def->os.bootloaderStdin, '&'))
+ {
+ virBufferEscapeString(buf,
+ "<bootloader_stdin><![CDATA[%s]]>"
+ "</bootloader_stdin>\n",
+ def->os.bootloaderStdin);
+ } else {
+ virBufferEscapeString(buf,
+ "<bootloader_stdin>%s"
+ "</bootloader_stdin>\n",
+ def->os.bootloaderStdin);
+ }
+ break;
+ /* coverity[dead_error_begin] */
+ case VIR_DOMAIN_BOOTLOADER_STDIN_LAST:
+ break;
+ }
}
virBufferAddLit(buf, "<os>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bbaa24137..41af6cc8a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1897,6 +1897,15 @@ struct _virDomainOSEnv {
char *value;
};
+/* Bootloader standard input source */
+typedef enum {
+ VIR_DOMAIN_BOOTLOADER_STDIN_NONE = 0,
+ VIR_DOMAIN_BOOTLOADER_STDIN_FILE,
+ VIR_DOMAIN_BOOTLOADER_STDIN_LITERAL,
+
+ VIR_DOMAIN_BOOTLOADER_STDIN_LAST
+} virDomainBootloaderStdinSource;
+
typedef struct _virDomainOSDef virDomainOSDef;
typedef virDomainOSDef *virDomainOSDefPtr;
struct _virDomainOSDef {
@@ -1923,6 +1932,8 @@ struct _virDomainOSDef {
virDomainLoaderDefPtr loader;
char *bootloader;
char *bootloaderArgs;
+ virDomainBootloaderStdinSource bootloaderStdinSource;
+ char *bootloaderStdin;
int smbios_mode;
virDomainBIOSDef bios;
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.args b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.args
new file mode 100644
index 000000000..ca51f2f04
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.args
@@ -0,0 +1,9 @@
+/usr/bin/custom-loader \
+-s ome \
+--args < path/to/some/file
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-s 0:0,hostbridge bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.xml b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.xml
new file mode 100644
index 000000000..a56a4c451
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-file.xml
@@ -0,0 +1,19 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/bin/custom-loader</bootloader>
+ <bootloader_args>-s ome --args</bootloader_args>
+ <bootloader_stdin file="path/to/some/file"/>
+ <os>
+ <type>hvm</type>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.args b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.args
new file mode 100644
index 000000000..050ddf442
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.args
@@ -0,0 +1,13 @@
+/usr/bin/custom-loader \
+-s ome \
+--args << END_OF_THIS_HEREDOC
+some
+standard input
+here
+END_OF_THIS_HEREDOC
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-s 0:0,hostbridge bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.xml b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.xml
new file mode 100644
index 000000000..496b5ea87
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-multiline.xml
@@ -0,0 +1,21 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/bin/custom-loader</bootloader>
+ <bootloader_args>-s ome --args</bootloader_args>
+ <bootloader_stdin><![CDATA[some
+standard input
+here]]></bootloader_stdin>
+ <os>
+ <type>hvm</type>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.args b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.args
new file mode 100644
index 000000000..f8bcdcddd
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.args
@@ -0,0 +1,11 @@
+/usr/bin/custom-loader \
+-s ome \
+--args << END_OF_THIS_HEREDOC
+some standard input here
+END_OF_THIS_HEREDOC
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-s 0:0,hostbridge bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.xml b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.xml
new file mode 100644
index 000000000..17c9da664
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-loader-stdin-oneline.xml
@@ -0,0 +1,19 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/bin/custom-loader</bootloader>
+ <bootloader_args>-s ome --args</bootloader_args>
+ <bootloader_stdin>some standard input here</bootloader_stdin>
+ <os>
+ <type>hvm</type>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/bhyveargv2xmltest.c b/tests/bhyveargv2xmltest.c
index e5d78530c..fef01d7da 100644
--- a/tests/bhyveargv2xmltest.c
+++ b/tests/bhyveargv2xmltest.c
@@ -187,6 +187,9 @@ mymain(void)
DO_TEST("memsize-human");
DO_TEST_FAIL("memsize-fail");
DO_TEST("custom-loader");
+ DO_TEST("loader-stdin-file");
+ DO_TEST("loader-stdin-oneline");
+ DO_TEST("loader-stdin-multiline");
DO_TEST("bhyveload-custom");
DO_TEST("bhyveload-vda");
DO_TEST_FAIL("bhyveload-name-mismatch");
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.args b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.args
new file mode 100644
index 000000000..3ba5c1160
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:ee:f5:79 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.devmap b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.devmap
new file mode 100644
index 000000000..b312bfdaf
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.devmap
@@ -0,0 +1 @@
+(hd0) /tmp/freebsd.img
\ No newline at end of file
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.ldargs
new file mode 100644
index 000000000..7d9a5155a
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.ldargs
@@ -0,0 +1,4 @@
+/usr/local/sbin/grub-bhyve \
+--root hd0,msdos1 \
+--device-map '<device.map>' \
+--memory 214 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.xml
new file mode 100644
index 000000000..f804da0db
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-file.xml
@@ -0,0 +1,25 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin file="/path/to/some/file"/>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.args b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.args
new file mode 100644
index 000000000..3ba5c1160
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:ee:f5:79 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.devmap b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.devmap
new file mode 100644
index 000000000..b312bfdaf
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.devmap
@@ -0,0 +1 @@
+(hd0) /tmp/freebsd.img
\ No newline at end of file
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.ldargs
new file mode 100644
index 000000000..7d9a5155a
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.ldargs
@@ -0,0 +1,4 @@
+/usr/local/sbin/grub-bhyve \
+--root hd0,msdos1 \
+--device-map '<device.map>' \
+--memory 214 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.xml
new file mode 100644
index 000000000..456ab0443
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-multiline.xml
@@ -0,0 +1,30 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin><![CDATA[
+multiple
+boot
+loader
+commands
+]]></bootloader_stdin>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.args b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.args
new file mode 100644
index 000000000..3ba5c1160
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:ee:f5:79 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.devmap b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.devmap
new file mode 100644
index 000000000..b312bfdaf
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.devmap
@@ -0,0 +1 @@
+(hd0) /tmp/freebsd.img
\ No newline at end of file
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.ldargs
new file mode 100644
index 000000000..7d9a5155a
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.ldargs
@@ -0,0 +1,4 @@
+/usr/local/sbin/grub-bhyve \
+--root hd0,msdos1 \
+--device-map '<device.map>' \
+--memory 214 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.xml
new file mode 100644
index 000000000..03b6987fd
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-stdin-oneline.xml
@@ -0,0 +1,25 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin>some input commands</bootloader_stdin>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 6f3b0c2eb..e4cb0592e 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -188,6 +188,9 @@ mymain(void)
DO_TEST("grub-defaults");
DO_TEST("grub-bootorder");
DO_TEST("grub-bootorder2");
+ DO_TEST("grub-stdin-file");
+ DO_TEST("grub-stdin-oneline");
+ DO_TEST("grub-stdin-multiline");
DO_TEST("bhyveload-bootorder");
DO_TEST("bhyveload-bootorder1");
DO_TEST_FAILURE("bhyveload-bootorder2");
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-file.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-file.xml
new file mode 100644
index 000000000..f07368d01
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-file.xml
@@ -0,0 +1,34 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin file="/path/to/some/file"/>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <source bridge='virbr0'/>
+ <model type='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-multiline.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-multiline.xml
new file mode 100644
index 000000000..eae6df4b4
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-multiline.xml
@@ -0,0 +1,39 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin><![CDATA[
+multiple
+boot
+loader
+commands
+]]></bootloader_stdin>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <source bridge='virbr0'/>
+ <model type='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-oneline.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-oneline.xml
new file mode 100644
index 000000000..b038a9065
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-grub-stdin-oneline.xml
@@ -0,0 +1,34 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <bootloader>/usr/local/sbin/grub-bhyve</bootloader>
+ <bootloader_stdin>some input commands</bootloader_stdin>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </controller>
+ <interface type='bridge'>
+ <mac address='52:54:00:ee:f5:79'/>
+ <source bridge='virbr0'/>
+ <model type='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c
index 4d9c1681d..fd386b504 100644
--- a/tests/bhyvexml2xmltest.c
+++ b/tests/bhyvexml2xmltest.c
@@ -98,6 +98,9 @@ mymain(void)
DO_TEST_DIFFERENT("grub-bootorder");
DO_TEST_DIFFERENT("grub-bootorder2");
DO_TEST_DIFFERENT("grub-defaults");
+ DO_TEST_DIFFERENT("grub-stdin-file");
+ DO_TEST_DIFFERENT("grub-stdin-oneline");
+ DO_TEST_DIFFERENT("grub-stdin-multiline");
DO_TEST_DIFFERENT("localtime");
DO_TEST_DIFFERENT("macaddr");
DO_TEST_DIFFERENT("metadata");
--
2.11.0
6 years, 5 months
[libvirt] [GSoC] Design ideas for implementing cleanup attribute
by Sukrit Bhatnagar
Hi,
I am interested in implementing the GCC cleanup attribute for automatic
resource freeing as part of GSoC'18. I have shared a proposal for the same.
This mail is to discuss the code design for implementing it.
Here are some of my ideas:
This attribute requires a cleanup function that is called automatically
when the corresponding variable goes out of scope. There are some functions
whose logic can be reused:
- Functions such as virCommandFree, virConfFreeList and virCgroupFree can
be directly used as cleanup functions. They have parameter and return type
valid for a cleanup function.
- Functions such as virFileClose and virFileFclose need some additional
consideration as they return a value. I think we can set some global
variable in a separate source file (just like errno variable from errno.h).
Then the value to be returned can be accessed globally.
- Functions such as virDomainEventGraphicsDispose need an entirely new
design. They are used as callbacks in object classes and passed as an
argument in virClassNew. This would require making changes to
virObjectUnref's code too. *This is the part I am not sure how to implement
cleanup logic for.*
Also, since the __attribute__((__cleanup__(anyfunc))) looks ugly, a macro
like autoclean (ideas for macro name welcome!) can be used instead. As
Martin pointed out in my proposal, for some types, this can be done right
after typedef declarations, so that the type itself contains this attribute.
Basically, at most places where VIR_FREE is used to release memory
explicitly, the corresponding variable can use the attribute. The existing
virFree function also can be reused as it takes void pointer as an argument
and returns nothing.
One of the exceptions to this will be those variables which are struct
members. The cleanup of member has to be done when the enclosing struct
variable is cleaned.
I can create new files vircleanup.{c,h} for defining cleanup functions for
types which do not have an existing cleanup/free function. This can be done
separately for each driver supported.
For example, cleanups pertaining to lxc driver will be in
src/lxc/lxc_cleanup.c.
Your suggestions are welcome.
Thanks,
Sukrit Bhatnagar
6 years, 5 months
[libvirt] [PATCH REBASE 0/5] qemu: fix domain object wait to handle monitor errors
by Nikolay Shirokovskiy
Main patch is 4th, others are misc.
Nikolay Shirokovskiy (5):
qemu: erase synchronous block job cancel mentions in comments
qemu: monitor: set error flag even in OOM conditions
utils: export virCopyError
qemu: fix domain object wait to handle monitor errors
qemu: fix races in beingDestroyed usage
src/conf/domain_conf.c | 43 ---------------------------------------
src/conf/domain_conf.h | 3 ---
src/libvirt_private.syms | 3 +--
src/qemu/qemu_domain.c | 45 +++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 7 +++++--
src/qemu/qemu_driver.c | 27 +++++++++++++++----------
src/qemu/qemu_hotplug.c | 4 ++--
src/qemu/qemu_migration.c | 12 +++++------
src/qemu/qemu_monitor.c | 5 +++++
src/qemu/qemu_process.c | 51 +++++++++++++++++++++++++++++++----------------
src/util/virerror.c | 12 ++++++++---
src/util/virerror.h | 1 +
12 files changed, 124 insertions(+), 89 deletions(-)
--
1.8.3.1
6 years, 6 months
[libvirt] [PATCH v2 0/4] Reimplement logging wildcards to use full shell glob syntax
by Daniel P. Berrangé
This series provides a more generalized support for wildcards
in logging and removes the ordering constraint.
Changed in v2:
- Improve various config file comments (Erik)
- Always use fnmatch as performance hit vs strstr
will be inconsequential in real world (Dan).
Daniel P. Berrangé (4):
Revert "util: virlog: Introduce wildcard to log filters"
log: rename virLogFlags to virLogFilterFlags to match docs
log: support logging using shell wildcard syntax
log: update docs for daemons to improve user understanding
src/locking/test_virtlockd.aug.in | 2 +-
src/locking/virtlockd.conf | 65 +++++++++++++++++++++++++----------
src/logging/test_virtlogd.aug.in | 2 +-
src/logging/virtlogd.conf | 68 +++++++++++++++++++++++++-----------
src/remote/libvirtd.conf | 72 +++++++++++++++++++++++----------------
src/remote/test_libvirtd.aug.in | 2 +-
src/util/virlog.c | 49 +++-----------------------
src/util/virlog.h | 3 +-
8 files changed, 146 insertions(+), 117 deletions(-)
--
2.14.3
6 years, 6 months
[libvirt] [PATCH v5 00/11] Basic implementation of persistent reservations
by Michal Privoznik
v5 of:
https://www.redhat.com/archives/libvir-list/2018-April/msg00736.html
diff to v4:
- John's review worked in. Partially.
Michal Privoznik (11):
virstoragefile: Introduce virStoragePRDef
qemuDomainDiskChangeSupported: Deny changing reservations
qemu: Introduce pr-manager-helper capability
qemu: Generate pr cmd line at startup
qemu_ns: Allow /dev/mapper/control for PR
qemu_cgroup: Allow /dev/mapper/control for PR
qemu: Introduce pr_helper to qemu.conf
qemu: Start PR daemon on domain startup
qemu_hotplug: Hotplug of reservations
qemu_hotplug: Hotunplug of reservations
qemu: Detect pr-manager-helper capability
docs/formatdomain.html.in | 23 +-
docs/schemas/domaincommon.rng | 34 +--
docs/schemas/storagecommon.rng | 50 +++++
m4/virt-driver-qemu.m4 | 5 +
src/conf/domain_conf.c | 38 ++++
src/libvirt_private.syms | 6 +
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 4 +
src/qemu/qemu_alias.c | 18 ++
src/qemu/qemu_alias.h | 4 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_cgroup.c | 33 ++-
src/qemu/qemu_command.c | 134 ++++++++++++
src/qemu/qemu_command.h | 5 +
src/qemu/qemu_conf.c | 7 +-
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_domain.c | 66 ++++++
src/qemu/qemu_domain.h | 5 +
src/qemu/qemu_hotplug.c | 149 ++++++++++++-
src/qemu/qemu_process.c | 232 +++++++++++++++++++++
src/qemu/qemu_process.h | 6 +
src/qemu/test_libvirtd_qemu.aug.in | 1 +
src/util/virdevmapper.c | 8 +-
src/util/virstoragefile.c | 164 +++++++++++++++
src/util/virstoragefile.h | 18 ++
tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 +
tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 +
tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 +
.../disk-virtio-scsi-reservations.args | 38 ++++
.../disk-virtio-scsi-reservations.xml | 49 +++++
tests/qemuxml2argvtest.c | 4 +
.../disk-virtio-scsi-reservations.xml | 1 +
tests/qemuxml2xmltest.c | 2 +
36 files changed, 1075 insertions(+), 39 deletions(-)
create mode 100644 tests/qemuxml2argvdata/disk-virtio-scsi-reservations.args
create mode 100644 tests/qemuxml2argvdata/disk-virtio-scsi-reservations.xml
create mode 120000 tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml
--
2.16.1
6 years, 6 months
[libvirt] [RFC 0/3] LXC with block device and enabled userns
by Radostin Stoyanov
Problem background
------------------
The LXC driver has support for the filesystem types "file" and "block"
that allow a disk image to be mounted in the guest (container). [1]
However, when user-namespace is enabled (uid/gid mapping is used) the
mount of the root filesystem block device fails. [2]
According to "man 7 user_namespaces":
Mounting block-based filesystems can be done only by a process that holds
CAP_SYS_ADMIN in the initial user namespace.
Suggested approach
------------------
Mount the root file system block device before the clone() call, then set
filesystem type to VIR_DOMAIN_FS_TYPE_MOUNT and filesystem source to the folder
where it was mounted.
Issues encountered
--------------------
This patch series implements the basic idea of the mentioned approach.
In result, a container with configured idmap and NBD filesystem is able to start.
However, on guest shutdown this kernel error [3] occurs.
Similar messages [4] occur on shutdown when NBD filesystem is used with LXC
container without idmap.
Perhaps, one reason could be that on guest shutdown the LXC driver kills qemu-nbd
process without sending disconnect for the specified device.
References
----------
[1] https://libvirt.org/formatdomain.html#elementsFilesystems
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1328946
[3] https://pastebin.com/raw/jMBk5mtG
[4] https://pastebin.com/raw/wTKbuRP9
Radostin Stoyanov (3):
lxc: Make lxcContainerMountFSBlock non static
lxc: Move up virLXCControllerAppendNBDPids
lxc: Mount NBD devices before clone
src/lxc/lxc_container.c | 58 +------------------
src/lxc/lxc_container.h | 4 ++
src/lxc/lxc_controller.c | 145 +++++++++++++++++++++++++++--------------------
3 files changed, 87 insertions(+), 120 deletions(-)
--
2.14.3
6 years, 6 months