On 6/22/22 23:26, Jonathon Jongsma wrote:
---
When you send this for review, please split it into more patches.
There's too much going on in this single patch.
include/libvirt/virterror.h | 1 +
po/POTFILES | 1 +
src/qemu/meson.build | 1 +
src/qemu/qemu_block.c | 64 +-
src/qemu/qemu_block.h | 1 +
src/qemu/qemu_command.c | 26 +-
src/qemu/qemu_conf.c | 19 +
src/qemu/qemu_conf.h | 5 +
src/qemu/qemu_domain.c | 110 ++-
src/qemu/qemu_domain.h | 5 +
src/qemu/qemu_driver.c | 4 +-
src/qemu/qemu_extdevice.c | 25 +
src/qemu/qemu_nbdkit.c | 629 ++++++++++++++++++
src/qemu/qemu_nbdkit.h | 89 +++
src/qemu/qemu_validate.c | 22 +-
src/qemu/qemu_validate.h | 4 +-
src/util/virerror.c | 1 +
tests/qemublocktest.c | 8 +-
tests/qemustatusxml2xmldata/modern-in.xml | 1 -
...sk-cdrom-network-nbdkit.x86_64-latest.args | 42 ++
.../disk-cdrom-network-nbdkit.xml | 1 +
...isk-network-http-nbdkit.x86_64-latest.args | 45 ++
.../disk-network-http-nbdkit.xml | 1 +
...work-source-curl-nbdkit.x86_64-latest.args | 49 ++
.../disk-network-source-curl-nbdkit.xml | 1 +
...isk-network-source-curl.x86_64-latest.args | 53 ++
.../disk-network-source-curl.xml | 71 ++
tests/qemuxml2argvtest.c | 12 +
tests/testutilsqemu.c | 16 +
tests/testutilsqemu.h | 4 +
30 files changed, 1278 insertions(+), 33 deletions(-)
create mode 100644 src/qemu/qemu_nbdkit.c
create mode 100644 src/qemu/qemu_nbdkit.h
create mode 100644 tests/qemuxml2argvdata/disk-cdrom-network-nbdkit.x86_64-latest.args
create mode 120000 tests/qemuxml2argvdata/disk-cdrom-network-nbdkit.xml
create mode 100644 tests/qemuxml2argvdata/disk-network-http-nbdkit.x86_64-latest.args
create mode 120000 tests/qemuxml2argvdata/disk-network-http-nbdkit.xml
create mode 100644
tests/qemuxml2argvdata/disk-network-source-curl-nbdkit.x86_64-latest.args
create mode 120000 tests/qemuxml2argvdata/disk-network-source-curl-nbdkit.xml
create mode 100644 tests/qemuxml2argvdata/disk-network-source-curl.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/disk-network-source-curl.xml
+
+
+int
+qemuNbdkitProcessSetupCgroup(qemuNbdkitProcess *proc,
+ virCgroup *cgroup)
+{
+ return virCgroupAddProcess(cgroup, proc->pid);
+}
+
+
+/* FIXME: selinux permissions errors */
+int
+qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
+ virDomainObj *vm,
+ virQEMUDriver *driver)
+{
+ g_autoptr(virCommand) cmd = NULL;
+ int rc;
+ int exitstatus = 0;
+ int cmdret = 0;
+ unsigned int loops = 0;
+ int errfd = -1;
+
+ if (qemuNbdkitProcessForkCookieHandler(proc) < 0)
+ return -1;
+
Creating an extra process so that a buffer can be written into an FD
looks like an overkill.
+ if (qemuNbdkitProcessForkPasswordHandler(proc) < 0)
+ return -1;
Same here. What happens if you'd just write into these sockets (btw. can
it be just a pipe?) after virCommandRun()?
+
+ if (!(cmd = qemuNbdkitProcessBuildCommand(proc)))
+ return -1;
+> + virCommandSetErrorFD(cmd, &errfd);
+
+ if (qemuExtDeviceLogCommand(driver, vm, cmd, "nbdkit") < 0)
+ goto error;
+
+ if (qemuSecurityCommandRun(driver, vm, cmd, proc->user, proc->group,
&exitstatus, &cmdret) < 0)
+ goto error;
+
+ if (cmdret < 0 || exitstatus != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not start 'nbdkit'. exitstatus: %d"),
exitstatus);
+ goto error;
+ }
+
This or .. [1]
+ /* Wait for the pid file to appear. The file doesn't appear
until nbdkit is
+ * ready to accept connections to the socket */
+ while (!virFileExists(proc->pidfile)) {
This relies on executed binary to create pidfile. I find it more robust
when the pidfile is created by virCommand*() - also because it's going
to be locked and we can detect later on whether it's stale or not. But
more importantly - the pidfile is written before exec(). You can take
inspiration from qemuDBusStart().
+ VIR_DEBUG("waiting for nbdkit pidfile %s: %u",
proc->pidfile, loops);
+ /* wait for 100ms before checking again, but don't do it for ever */
+ if (errno == ENOENT && loops < 10) {
+ g_usleep(100 * 1000);
+ loops++;
+ } else {
+ char errbuf[1024] = { 0 };
+ if (errfd && saferead(errfd, errbuf, sizeof(errbuf) - 1) > 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("nbdkit failed to start: %s"), errbuf);
+ } else {
+ virReportSystemError(errno, "%s",
+ _("Gave up waiting for nbdkit to
start"));
+ }
+ goto error;
+ }
+ }
+
+ if ((rc = virPidFileReadPath(proc->pidfile, &proc->pid)) < 0) {
+ virReportSystemError(-rc,
+ _("Failed to read pidfile %s"),
+ proc->pidfile);
+ goto error;
+ }
+
1: ... this looks like a good place to write those secrets. Moreover, if
we'd get error writing into the pipe we know the process died.
I don't feel confident reviewing the storage part of the feature, sorry.
Michal