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