* src/qemu_driver.c: Remove usbfs/sysfs iterator code and call
into generic helper APIs instead when setting device permissions
---
src/qemu_driver.c | 107 +++++++++++++++++++++++++++--------------------------
1 files changed, 54 insertions(+), 53 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 3ebe802..e9a09df 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -65,6 +65,7 @@
#include "domain_conf.h"
#include "node_device_conf.h"
#include "pci.h"
+#include "hostusb.h"
#include "security.h"
#include "cgroup.h"
@@ -1683,31 +1684,62 @@ static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct
qemud_driver *
#ifdef __linux__
+struct qemuFileOwner {
+ uid_t uid;
+ gid_t gid;
+};
+
+static int qemuDomainSetHostdevUSBOwnershipActor(virConnectPtr conn,
+ usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file, void *opaque)
+{
+ struct qemuFileOwner *owner = opaque;
+
+ if (chown(file, owner->uid, owner->gid) < 0) {
+ virReportSystemError(conn, errno, _("cannot set ownership on %s"),
file);
+ return -1;
+ }
+
+ return 0;
+}
+
static int qemuDomainSetHostdevUSBOwnership(virConnectPtr conn,
virDomainHostdevDefPtr def,
uid_t uid, gid_t gid)
{
- char *usbpath = NULL;
+ struct qemuFileOwner owner = { uid, gid };
+ int ret = -1;
/* XXX what todo for USB devs assigned based on product/vendor ? Doom :-( */
if (!def->source.subsys.u.usb.bus ||
!def->source.subsys.u.usb.device)
return 0;
- if (virAsprintf(&usbpath, "/dev/bus/usb/%03d/%03d",
- def->source.subsys.u.usb.bus,
- def->source.subsys.u.usb.device) < 0) {
- virReportOOMError(conn);
- return -1;
- }
+ usbDevice *dev = usbGetDevice(conn,
+ def->source.subsys.u.usb.bus,
+ def->source.subsys.u.usb.device);
+
+ if (!dev)
+ goto cleanup;
+
+ ret = usbDeviceFileIterate(conn, dev,
+ qemuDomainSetHostdevUSBOwnershipActor, &owner);
+
+ usbFreeDevice(conn, dev);
+cleanup:
+ return ret;
+}
+
+static int qemuDomainSetHostdevPCIOwnershipActor(virConnectPtr conn,
+ pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file, void *opaque)
+{
+ struct qemuFileOwner *owner = opaque;
- VIR_DEBUG("Setting ownership on %s to %d:%d", usbpath, uid, gid);
- if (chown(usbpath, uid, gid) < 0) {
- virReportSystemError(conn, errno, _("cannot set ownership on %s"),
usbpath);
- VIR_FREE(usbpath);
+ if (chown(file, owner->uid, owner->gid) < 0) {
+ virReportSystemError(conn, errno, _("cannot set ownership on %s"),
file);
return -1;
}
- VIR_FREE(usbpath);
return 0;
}
@@ -1716,54 +1748,23 @@ static int qemuDomainSetHostdevPCIOwnership(virConnectPtr conn,
virDomainHostdevDefPtr def,
uid_t uid, gid_t gid)
{
- char *pcidir = NULL;
- char *file = NULL;
- DIR *dir = NULL;
+ struct qemuFileOwner owner = { uid, gid };
int ret = -1;
- struct dirent *ent;
- if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
- def->source.subsys.u.pci.domain,
- def->source.subsys.u.pci.bus,
- def->source.subsys.u.pci.slot,
- def->source.subsys.u.pci.function) < 0) {
- virReportOOMError(conn);
- goto cleanup;
- }
+ pciDevice *dev = pciGetDevice(conn,
+ def->source.subsys.u.pci.domain,
+ def->source.subsys.u.pci.bus,
+ def->source.subsys.u.pci.slot,
+ def->source.subsys.u.pci.function);
- if (!(dir = opendir(pcidir))) {
- virReportSystemError(conn, errno,
- _("cannot open %s"), pcidir);
+ if (!dev)
goto cleanup;
- }
- while ((ent = readdir(dir)) != NULL) {
- /* QEMU device assignment requires:
- * $PCIDIR/config, $PCIDIR/resource, $PCIDIR/resourceNNN, $PCIDIR/rom
- */
- if (STREQ(ent->d_name, "config") ||
- STRPREFIX(ent->d_name, "resource") ||
- STREQ(ent->d_name, "rom")) {
- if (virAsprintf(&file, "%s/%s", pcidir, ent->d_name) < 0)
{
- virReportOOMError(conn);
- goto cleanup;
- }
- VIR_DEBUG("Setting ownership on %s to %d:%d", file, uid, gid);
- if (chown(file, uid, gid) < 0) {
- virReportSystemError(conn, errno, _("cannot set ownership on
%s"), file);
- goto cleanup;
- }
- VIR_FREE(file);
- }
- }
-
- ret = 0;
+ ret = pciDeviceFileIterate(conn, dev,
+ qemuDomainSetHostdevPCIOwnershipActor, &owner);
+ pciFreeDevice(conn, dev);
cleanup:
- if (dir)
- closedir(dir);
- VIR_FREE(file);
- VIR_FREE(pcidir);
return ret;
}
#endif
--
1.6.2.5