mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Port QEMU driver to use USB/PCI device helpers
* src/qemu_driver.c: Remove usbfs/sysfs iterator code and call into generic helper APIs instead when setting device permissions
This commit is contained in:
parent
ec31cd76c9
commit
c42c1b8a5e
@ -65,6 +65,7 @@
|
|||||||
#include "domain_conf.h"
|
#include "domain_conf.h"
|
||||||
#include "node_device_conf.h"
|
#include "node_device_conf.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
#include "hostusb.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
|
|
||||||
@ -1768,31 +1769,62 @@ static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *
|
|||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#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,
|
static int qemuDomainSetHostdevUSBOwnership(virConnectPtr conn,
|
||||||
virDomainHostdevDefPtr def,
|
virDomainHostdevDefPtr def,
|
||||||
uid_t uid, gid_t gid)
|
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 :-( */
|
/* XXX what todo for USB devs assigned based on product/vendor ? Doom :-( */
|
||||||
if (!def->source.subsys.u.usb.bus ||
|
if (!def->source.subsys.u.usb.bus ||
|
||||||
!def->source.subsys.u.usb.device)
|
!def->source.subsys.u.usb.device)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (virAsprintf(&usbpath, "/dev/bus/usb/%03d/%03d",
|
usbDevice *dev = usbGetDevice(conn,
|
||||||
def->source.subsys.u.usb.bus,
|
def->source.subsys.u.usb.bus,
|
||||||
def->source.subsys.u.usb.device) < 0) {
|
def->source.subsys.u.usb.device);
|
||||||
virReportOOMError(conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_DEBUG("Setting ownership on %s to %d:%d", usbpath, uid, gid);
|
if (!dev)
|
||||||
if (chown(usbpath, uid, gid) < 0) {
|
goto cleanup;
|
||||||
virReportSystemError(conn, errno, _("cannot set ownership on %s"), usbpath);
|
|
||||||
VIR_FREE(usbpath);
|
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;
|
||||||
|
|
||||||
|
if (chown(file, owner->uid, owner->gid) < 0) {
|
||||||
|
virReportSystemError(conn, errno, _("cannot set ownership on %s"), file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
VIR_FREE(usbpath);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1801,54 +1833,23 @@ static int qemuDomainSetHostdevPCIOwnership(virConnectPtr conn,
|
|||||||
virDomainHostdevDefPtr def,
|
virDomainHostdevDefPtr def,
|
||||||
uid_t uid, gid_t gid)
|
uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
char *pcidir = NULL;
|
struct qemuFileOwner owner = { uid, gid };
|
||||||
char *file = NULL;
|
|
||||||
DIR *dir = NULL;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct dirent *ent;
|
|
||||||
|
|
||||||
if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
|
pciDevice *dev = pciGetDevice(conn,
|
||||||
def->source.subsys.u.pci.domain,
|
def->source.subsys.u.pci.domain,
|
||||||
def->source.subsys.u.pci.bus,
|
def->source.subsys.u.pci.bus,
|
||||||
def->source.subsys.u.pci.slot,
|
def->source.subsys.u.pci.slot,
|
||||||
def->source.subsys.u.pci.function) < 0) {
|
def->source.subsys.u.pci.function);
|
||||||
virReportOOMError(conn);
|
|
||||||
|
if (!dev)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dir = opendir(pcidir))) {
|
ret = pciDeviceFileIterate(conn, dev,
|
||||||
virReportSystemError(conn, errno,
|
qemuDomainSetHostdevPCIOwnershipActor, &owner);
|
||||||
_("cannot open %s"), pcidir);
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
pciFreeDevice(conn, dev);
|
||||||
cleanup:
|
cleanup:
|
||||||
if (dir)
|
|
||||||
closedir(dir);
|
|
||||||
VIR_FREE(file);
|
|
||||||
VIR_FREE(pcidir);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user