2008-11-21 12:27:11 +00:00
|
|
|
/*
|
|
|
|
* node_device_hal.c: node device enumeration - HAL-based implementation
|
|
|
|
*
|
2015-05-06 20:40:39 +00:00
|
|
|
* Copyright (C) 2011-2015 Red Hat, Inc.
|
2008-11-21 12:27:11 +00:00
|
|
|
* Copyright (C) 2008 Virtual Iron Software, Inc.
|
|
|
|
* Copyright (C) 2008 David F. Lively
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2008-11-21 12:27:11 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-21 18:49:11 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
#include <libhal.h>
|
|
|
|
|
|
|
|
#include "node_device_conf.h"
|
2015-05-06 20:40:39 +00:00
|
|
|
#include "node_device_driver.h"
|
2009-06-02 15:12:53 +00:00
|
|
|
#include "node_device_hal.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2008-11-21 12:27:11 +00:00
|
|
|
#include "driver.h"
|
|
|
|
#include "datatypes.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2019-07-11 13:19:03 +00:00
|
|
|
#include "virfile.h"
|
2012-12-13 14:52:25 +00:00
|
|
|
#include "virpci.h"
|
2019-05-23 10:34:08 +00:00
|
|
|
#include "virpidfile.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2012-04-19 14:34:35 +00:00
|
|
|
#include "virdbus.h"
|
2013-05-02 21:54:22 +00:00
|
|
|
#include "virstring.h"
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2019-05-23 10:34:08 +00:00
|
|
|
#include "configmake.h"
|
|
|
|
|
2009-06-02 15:12:53 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NODEDEV
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("node_device.node_device_hal");
|
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
/*
|
|
|
|
* Host device enumeration (HAL implementation)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define DRV_STATE_HAL_CTX(ds) ((LibHalContext *)((ds)->privateData))
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static const char *
|
|
|
|
hal_name(const char *udi)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
const char *name = strrchr(udi, '/');
|
|
|
|
if (name)
|
2013-06-01 02:52:17 +00:00
|
|
|
return name + 1;
|
2008-11-21 12:27:11 +00:00
|
|
|
return udi;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
get_str_prop(LibHalContext *ctxt, const char *udi,
|
|
|
|
const char *prop, char **val_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
char *val = libhal_device_get_property_string(ctxt, udi, prop, NULL);
|
|
|
|
|
|
|
|
if (val) {
|
|
|
|
if (*val) {
|
|
|
|
*val_p = val;
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
/* Treat empty strings as NULL values */
|
|
|
|
VIR_FREE(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
get_int_prop(LibHalContext *ctxt, const char *udi,
|
|
|
|
const char *prop, int *val_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
DBusError err;
|
|
|
|
int val;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
dbus_error_init(&err);
|
|
|
|
val = libhal_device_get_property_int(ctxt, udi, prop, &err);
|
|
|
|
rv = dbus_error_is_set(&err);
|
|
|
|
dbus_error_free(&err);
|
|
|
|
if (rv == 0)
|
|
|
|
*val_p = val;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
get_bool_prop(LibHalContext *ctxt, const char *udi,
|
|
|
|
const char *prop, int *val_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
DBusError err;
|
|
|
|
int val;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
dbus_error_init(&err);
|
|
|
|
val = libhal_device_get_property_bool(ctxt, udi, prop, &err);
|
|
|
|
rv = dbus_error_is_set(&err);
|
|
|
|
dbus_error_free(&err);
|
|
|
|
if (rv == 0)
|
|
|
|
*val_p = val;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
get_uint64_prop(LibHalContext *ctxt, const char *udi,
|
|
|
|
const char *prop, unsigned long long *val_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
DBusError err;
|
|
|
|
unsigned long long val;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
dbus_error_init(&err);
|
|
|
|
val = libhal_device_get_property_uint64(ctxt, udi, prop, &err);
|
|
|
|
rv = dbus_error_is_set(&err);
|
|
|
|
dbus_error_free(&err);
|
|
|
|
if (rv == 0)
|
|
|
|
*val_p = val;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_pci_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
char *sysfs_path;
|
|
|
|
|
|
|
|
if (get_str_prop(ctx, udi, "pci.linux.sysfs_path", &sysfs_path) == 0) {
|
|
|
|
char *p = strrchr(sysfs_path, '/');
|
|
|
|
if (p) {
|
2014-07-21 14:32:53 +00:00
|
|
|
ignore_value(virStrToLong_ui(p+1, &p, 16, &d->pci_dev.domain));
|
|
|
|
ignore_value(virStrToLong_ui(p+1, &p, 16, &d->pci_dev.bus));
|
|
|
|
ignore_value(virStrToLong_ui(p+1, &p, 16, &d->pci_dev.slot));
|
|
|
|
ignore_value(virStrToLong_ui(p+1, &p, 16, &d->pci_dev.function));
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
2009-12-14 13:44:12 +00:00
|
|
|
|
2018-01-18 10:07:25 +00:00
|
|
|
if (virNodeDeviceGetPCIDynamicCaps(sysfs_path, &d->pci_dev) < 0) {
|
2013-03-25 13:10:51 +00:00
|
|
|
VIR_FREE(sysfs_path);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-11-21 12:27:11 +00:00
|
|
|
VIR_FREE(sysfs_path);
|
|
|
|
}
|
2009-12-14 13:44:12 +00:00
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)get_int_prop(ctx, udi, "pci.vendor_id", (int *)&d->pci_dev.vendor);
|
|
|
|
if (get_str_prop(ctx, udi, "pci.vendor", &d->pci_dev.vendor_name) != 0)
|
|
|
|
(void)get_str_prop(ctx, udi, "info.vendor", &d->pci_dev.vendor_name);
|
|
|
|
(void)get_int_prop(ctx, udi, "pci.product_id", (int *)&d->pci_dev.product);
|
|
|
|
if (get_str_prop(ctx, udi, "pci.product", &d->pci_dev.product_name) != 0)
|
|
|
|
(void)get_str_prop(ctx, udi, "info.product", &d->pci_dev.product_name);
|
2009-12-14 13:44:12 +00:00
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_usb_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
(void)get_int_prop(ctx, udi, "usb.interface.number",
|
|
|
|
(int *)&d->usb_if.number);
|
|
|
|
(void)get_int_prop(ctx, udi, "usb.interface.class",
|
2019-03-18 13:32:55 +00:00
|
|
|
(int *)&d->usb_if.klass);
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)get_int_prop(ctx, udi, "usb.interface.subclass",
|
|
|
|
(int *)&d->usb_if.subclass);
|
|
|
|
(void)get_int_prop(ctx, udi, "usb.interface.protocol",
|
|
|
|
(int *)&d->usb_if.protocol);
|
|
|
|
(void)get_str_prop(ctx, udi, "usb.interface.description",
|
|
|
|
&d->usb_if.description);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_usb_device_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
(void)get_int_prop(ctx, udi, "usb_device.bus_number",
|
|
|
|
(int *)&d->usb_dev.bus);
|
|
|
|
(void)get_int_prop(ctx, udi, "usb_device.linux.device_number",
|
|
|
|
(int *)&d->usb_dev.device);
|
|
|
|
(void)get_int_prop(ctx, udi, "usb_device.vendor_id",
|
|
|
|
(int *)&d->usb_dev.vendor);
|
|
|
|
if (get_str_prop(ctx, udi, "usb_device.vendor",
|
|
|
|
&d->usb_dev.vendor_name) != 0)
|
|
|
|
(void)get_str_prop(ctx, udi, "info.vendor", &d->usb_dev.vendor_name);
|
|
|
|
(void)get_int_prop(ctx, udi, "usb_device.product_id",
|
|
|
|
(int *)&d->usb_dev.product);
|
|
|
|
if (get_str_prop(ctx, udi, "usb_device.product",
|
|
|
|
&d->usb_dev.product_name) != 0)
|
|
|
|
(void)get_str_prop(ctx, udi, "info.product", &d->usb_dev.product_name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_net_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
unsigned long long dummy;
|
2008-11-25 10:37:02 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "net.interface", &d->net.ifname);
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "net.address", &d->net.address);
|
|
|
|
if (get_uint64_prop(ctx, udi, "net.80203.mac_address",
|
|
|
|
&dummy) == 0)
|
|
|
|
d->net.subtype = VIR_NODE_DEV_CAP_NET_80203;
|
|
|
|
else if (get_uint64_prop(ctx, udi, "net.80211.mac_address",
|
|
|
|
&dummy) == 0)
|
|
|
|
d->net.subtype = VIR_NODE_DEV_CAP_NET_80211;
|
|
|
|
else
|
|
|
|
d->net.subtype = VIR_NODE_DEV_CAP_NET_LAST;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_scsi_host_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2009-06-02 15:12:53 +00:00
|
|
|
int retval = 0;
|
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)get_int_prop(ctx, udi, "scsi_host.host", (int *)&d->scsi_host.host);
|
2009-06-02 15:12:53 +00:00
|
|
|
|
2018-01-12 15:23:30 +00:00
|
|
|
retval = virNodeDeviceGetSCSIHostCaps(&d->scsi_host);
|
2009-06-02 15:12:53 +00:00
|
|
|
|
2014-11-13 14:24:17 +00:00
|
|
|
if (retval == -1)
|
2009-06-02 15:12:53 +00:00
|
|
|
goto out;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
out:
|
2009-06-02 15:12:53 +00:00
|
|
|
return retval;
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_scsi_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
(void)get_int_prop(ctx, udi, "scsi.host", (int *)&d->scsi.host);
|
|
|
|
(void)get_int_prop(ctx, udi, "scsi.bus", (int *)&d->scsi.bus);
|
|
|
|
(void)get_int_prop(ctx, udi, "scsi.target", (int *)&d->scsi.target);
|
|
|
|
(void)get_int_prop(ctx, udi, "scsi.lun", (int *)&d->scsi.lun);
|
|
|
|
(void)get_str_prop(ctx, udi, "scsi.type", &d->scsi.type);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_storage_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
int val;
|
2008-11-21 12:46:39 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "block.device", &d->storage.block);
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "storage.bus", &d->storage.bus);
|
|
|
|
(void)get_str_prop(ctx, udi, "storage.drive_type", &d->storage.drive_type);
|
|
|
|
(void)get_str_prop(ctx, udi, "storage.model", &d->storage.model);
|
|
|
|
(void)get_str_prop(ctx, udi, "storage.vendor", &d->storage.vendor);
|
2009-06-11 14:25:19 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "storage.serial", &d->storage.serial);
|
2008-11-21 12:27:11 +00:00
|
|
|
if (get_bool_prop(ctx, udi, "storage.removable", &val) == 0 && val) {
|
|
|
|
d->storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;
|
2009-03-02 17:41:13 +00:00
|
|
|
if (get_bool_prop(ctx, udi, "storage.removable.media_available",
|
|
|
|
&val) == 0 && val) {
|
2008-11-21 12:27:11 +00:00
|
|
|
d->storage.flags |=
|
|
|
|
VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
|
|
|
|
(void)get_uint64_prop(ctx, udi, "storage.removable.media_size",
|
|
|
|
&d->storage.removable_media_size);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
(void)get_uint64_prop(ctx, udi, "storage.size", &d->storage.size);
|
|
|
|
}
|
|
|
|
if (get_bool_prop(ctx, udi, "storage.hotpluggable", &val) == 0 && val)
|
|
|
|
d->storage.flags |= VIR_NODE_DEV_CAP_STORAGE_HOTPLUGGABLE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-03 10:05:33 +00:00
|
|
|
static int
|
|
|
|
gather_scsi_generic_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2013-06-03 10:05:33 +00:00
|
|
|
{
|
|
|
|
(void)get_str_prop(ctx, udi, "scsi_generic.device", &d->sg.path);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_system_cap(LibHalContext *ctx, const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr d)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
char *uuidstr;
|
|
|
|
|
|
|
|
(void)get_str_prop(ctx, udi, "system.product", &d->system.product_name);
|
|
|
|
(void)get_str_prop(ctx, udi, "system.hardware.vendor",
|
|
|
|
&d->system.hardware.vendor_name);
|
|
|
|
(void)get_str_prop(ctx, udi, "system.hardware.version",
|
|
|
|
&d->system.hardware.version);
|
|
|
|
(void)get_str_prop(ctx, udi, "system.hardware.serial",
|
|
|
|
&d->system.hardware.serial);
|
|
|
|
if (get_str_prop(ctx, udi, "system.hardware.uuid", &uuidstr) == 0) {
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(uuidstr, d->system.hardware.uuid));
|
2008-11-21 12:27:11 +00:00
|
|
|
VIR_FREE(uuidstr);
|
|
|
|
}
|
|
|
|
(void)get_str_prop(ctx, udi, "system.firmware.vendor",
|
|
|
|
&d->system.firmware.vendor_name);
|
|
|
|
(void)get_str_prop(ctx, udi, "system.firmware.version",
|
|
|
|
&d->system.firmware.version);
|
|
|
|
(void)get_str_prop(ctx, udi, "system.firmware.release_date",
|
|
|
|
&d->system.firmware.release_date);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct _caps_tbl_entry {
|
|
|
|
const char *cap_name;
|
2014-05-11 15:08:48 +00:00
|
|
|
virNodeDevCapType type;
|
2008-11-21 12:27:11 +00:00
|
|
|
int (*gather_fn)(LibHalContext *ctx,
|
|
|
|
const char *udi,
|
2015-05-08 16:55:00 +00:00
|
|
|
virNodeDevCapDataPtr data);
|
2008-11-21 12:27:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct _caps_tbl_entry caps_tbl_entry;
|
|
|
|
|
|
|
|
static caps_tbl_entry caps_tbl[] = {
|
|
|
|
{ "system", VIR_NODE_DEV_CAP_SYSTEM, gather_system_cap },
|
|
|
|
{ "pci", VIR_NODE_DEV_CAP_PCI_DEV, gather_pci_cap },
|
|
|
|
{ "usb", VIR_NODE_DEV_CAP_USB_INTERFACE, gather_usb_cap },
|
|
|
|
{ "usb_device", VIR_NODE_DEV_CAP_USB_DEV, gather_usb_device_cap },
|
|
|
|
{ "net", VIR_NODE_DEV_CAP_NET, gather_net_cap },
|
|
|
|
{ "scsi_host", VIR_NODE_DEV_CAP_SCSI_HOST, gather_scsi_host_cap },
|
|
|
|
{ "scsi", VIR_NODE_DEV_CAP_SCSI, gather_scsi_cap },
|
|
|
|
{ "storage", VIR_NODE_DEV_CAP_STORAGE, gather_storage_cap },
|
2013-06-03 10:05:33 +00:00
|
|
|
{ "scsi_generic", VIR_NODE_DEV_CAP_SCSI_GENERIC, gather_scsi_generic_cap },
|
2008-11-21 12:27:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* qsort/bsearch string comparator */
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
cmpstringp(const void *p1, const void *p2)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
/* from man 3 qsort */
|
|
|
|
return strcmp(* (char * const *) p1, * (char * const *) p2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_capability(LibHalContext *ctx, const char *udi,
|
|
|
|
const char *cap_name,
|
|
|
|
virNodeDevCapsDefPtr *caps_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
caps_tbl_entry *entry;
|
|
|
|
|
2019-10-15 11:55:26 +00:00
|
|
|
entry = bsearch(&cap_name, caps_tbl, G_N_ELEMENTS(caps_tbl),
|
2008-11-21 12:27:11 +00:00
|
|
|
sizeof(caps_tbl[0]), cmpstringp);
|
|
|
|
|
|
|
|
if (entry) {
|
|
|
|
virNodeDevCapsDefPtr caps;
|
|
|
|
if (VIR_ALLOC(caps) < 0)
|
|
|
|
return ENOMEM;
|
2015-05-21 17:23:56 +00:00
|
|
|
caps->data.type = entry->type;
|
2008-11-21 12:27:11 +00:00
|
|
|
if (entry->gather_fn) {
|
|
|
|
int rv = (*entry->gather_fn)(ctx, udi, &caps->data);
|
|
|
|
if (rv != 0) {
|
|
|
|
virNodeDevCapsDefFree(caps);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
caps->next = *caps_p;
|
|
|
|
*caps_p = caps;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
gather_capabilities(LibHalContext *ctx, const char *udi,
|
|
|
|
virNodeDevCapsDefPtr *caps_p)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
char *bus_name = NULL;
|
|
|
|
virNodeDevCapsDefPtr caps = NULL;
|
2009-11-10 11:56:11 +00:00
|
|
|
char **hal_cap_names = NULL;
|
Convert 'int i' to 'size_t i' in src/node_device/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int rv;
|
|
|
|
size_t i;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
|
|
|
if (STREQ(udi, "/org/freedesktop/Hal/devices/computer")) {
|
|
|
|
rv = gather_capability(ctx, udi, "system", &caps);
|
|
|
|
if (rv != 0)
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
2009-03-16 10:56:01 +00:00
|
|
|
if (get_str_prop(ctx, udi, "info.subsystem", &bus_name) == 0 ||
|
|
|
|
get_str_prop(ctx, udi, "linux.subsystem", &bus_name) == 0) {
|
2008-11-21 12:27:11 +00:00
|
|
|
rv = gather_capability(ctx, udi, bus_name, &caps);
|
|
|
|
if (rv != 0)
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
hal_cap_names = libhal_device_get_property_strlist(ctx, udi,
|
|
|
|
"info.capabilities",
|
|
|
|
NULL);
|
|
|
|
if (hal_cap_names) {
|
|
|
|
for (i = 0; hal_cap_names[i]; i++) {
|
|
|
|
if (! (bus_name && STREQ(hal_cap_names[i], bus_name))) {
|
|
|
|
rv = gather_capability(ctx, udi, hal_cap_names[i], &caps);
|
|
|
|
if (rv != 0)
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; hal_cap_names[i]; i++)
|
|
|
|
VIR_FREE(hal_cap_names[i]);
|
|
|
|
VIR_FREE(hal_cap_names);
|
|
|
|
}
|
|
|
|
VIR_FREE(bus_name);
|
|
|
|
|
|
|
|
*caps_p = caps;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
failure:
|
|
|
|
VIR_FREE(bus_name);
|
|
|
|
if (hal_cap_names) {
|
|
|
|
for (i = 0; hal_cap_names[i]; i++)
|
|
|
|
VIR_FREE(hal_cap_names[i]);
|
|
|
|
VIR_FREE(hal_cap_names);
|
|
|
|
}
|
|
|
|
while (caps) {
|
|
|
|
virNodeDevCapsDefPtr next = caps->next;
|
|
|
|
virNodeDevCapsDefFree(caps);
|
|
|
|
caps = next;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
|
|
|
dev_create(const char *udi)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2008-12-04 21:48:31 +00:00
|
|
|
LibHalContext *ctx;
|
2008-11-21 12:27:11 +00:00
|
|
|
char *parent_key = NULL;
|
2017-05-12 16:45:16 +00:00
|
|
|
virNodeDeviceObjPtr obj = NULL;
|
2008-12-04 21:48:31 +00:00
|
|
|
virNodeDeviceDefPtr def = NULL;
|
2017-06-03 11:36:01 +00:00
|
|
|
virNodeDeviceDefPtr objdef;
|
2008-11-21 12:27:11 +00:00
|
|
|
const char *name = hal_name(udi);
|
|
|
|
int rv;
|
2009-06-12 13:12:55 +00:00
|
|
|
char *devicePath = NULL;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceLock();
|
|
|
|
ctx = DRV_STATE_HAL_CTX(driver);
|
2008-12-04 21:48:31 +00:00
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0)
|
|
|
|
goto failure;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2019-10-20 11:49:46 +00:00
|
|
|
def->name = g_strdup(name);
|
2008-11-21 12:27:11 +00:00
|
|
|
|
|
|
|
if (get_str_prop(ctx, udi, "info.parent", &parent_key) == 0) {
|
2019-10-20 11:49:46 +00:00
|
|
|
def->parent = g_strdup(hal_name(parent_key));
|
2013-05-03 12:44:20 +00:00
|
|
|
VIR_FREE(parent_key);
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:48:31 +00:00
|
|
|
rv = gather_capabilities(ctx, udi, &def->caps);
|
2008-11-21 12:27:11 +00:00
|
|
|
if (rv != 0) goto failure;
|
|
|
|
|
2008-12-04 21:48:31 +00:00
|
|
|
if (def->caps == NULL)
|
|
|
|
goto cleanup;
|
2008-11-21 12:46:39 +00:00
|
|
|
|
2009-06-12 13:12:55 +00:00
|
|
|
/* Some devices don't have a path in sysfs, so ignore failure */
|
2010-03-02 14:51:57 +00:00
|
|
|
(void)get_str_prop(ctx, udi, "linux.sysfs_path", &devicePath);
|
2009-06-12 13:12:55 +00:00
|
|
|
|
2017-05-12 18:47:17 +00:00
|
|
|
if (!(obj = virNodeDeviceObjListAssignDef(driver->devs, def))) {
|
2009-06-12 13:12:55 +00:00
|
|
|
VIR_FREE(devicePath);
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
2009-06-12 13:12:55 +00:00
|
|
|
}
|
2017-05-12 16:45:16 +00:00
|
|
|
objdef = virNodeDeviceObjGetDef(obj);
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2017-06-03 11:36:01 +00:00
|
|
|
objdef->sysfs_path = devicePath;
|
2009-06-12 13:12:55 +00:00
|
|
|
|
2017-05-15 15:00:59 +00:00
|
|
|
virNodeDeviceObjEndAPI(&obj);
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
2008-11-21 12:27:11 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
failure:
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("FAILED TO ADD dev %s", name);
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2010-05-17 20:38:59 +00:00
|
|
|
virNodeDeviceDefFree(def);
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
|
|
|
dev_refresh(const char *udi)
|
2009-05-19 13:26:14 +00:00
|
|
|
{
|
|
|
|
const char *name = hal_name(udi);
|
2017-05-12 16:45:16 +00:00
|
|
|
virNodeDeviceObjPtr obj;
|
2009-05-19 13:26:14 +00:00
|
|
|
|
2017-05-12 18:47:17 +00:00
|
|
|
if ((obj = virNodeDeviceObjListFindByName(driver->devs, name))) {
|
2009-05-19 13:26:14 +00:00
|
|
|
/* Simply "rediscover" device -- incrementally handling changes
|
|
|
|
* to sub-capabilities (like net.80203) is nasty ... so avoid it.
|
|
|
|
*/
|
2017-05-12 18:47:17 +00:00
|
|
|
virNodeDeviceObjListRemove(driver->devs, obj);
|
2017-05-15 15:00:59 +00:00
|
|
|
virObjectUnref(obj);
|
2009-05-19 13:26:14 +00:00
|
|
|
dev_create(udi);
|
2017-06-29 20:51:54 +00:00
|
|
|
} else {
|
|
|
|
VIR_DEBUG("no device named %s", name);
|
2017-06-02 13:04:29 +00:00
|
|
|
}
|
2009-05-19 13:26:14 +00:00
|
|
|
}
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
2019-10-14 12:45:33 +00:00
|
|
|
device_added(LibHalContext *ctx G_GNUC_UNUSED,
|
2013-06-01 02:52:17 +00:00
|
|
|
const char *udi)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("%s", hal_name(udi));
|
2008-12-04 21:48:31 +00:00
|
|
|
dev_create(udi);
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
2019-10-14 12:45:33 +00:00
|
|
|
device_removed(LibHalContext *ctx G_GNUC_UNUSED,
|
2013-06-01 02:52:17 +00:00
|
|
|
const char *udi)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
const char *name = hal_name(udi);
|
2017-05-12 16:45:16 +00:00
|
|
|
virNodeDeviceObjPtr obj;
|
2008-12-04 21:48:31 +00:00
|
|
|
|
2017-05-12 18:47:17 +00:00
|
|
|
obj = virNodeDeviceObjListFindByName(driver->devs, name);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("%s", name);
|
2017-05-12 16:45:16 +00:00
|
|
|
if (obj)
|
2017-05-12 18:47:17 +00:00
|
|
|
virNodeDeviceObjListRemove(driver->devs, obj);
|
2008-11-21 12:27:11 +00:00
|
|
|
else
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("no device named %s", name);
|
2017-05-15 15:00:59 +00:00
|
|
|
virObjectUnref(obj);
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
|
|
|
device_cap_added(LibHalContext *ctx,
|
|
|
|
const char *udi, const char *cap)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
const char *name = hal_name(udi);
|
2017-05-12 16:45:16 +00:00
|
|
|
virNodeDeviceObjPtr obj;
|
2017-06-03 11:36:01 +00:00
|
|
|
virNodeDeviceDefPtr def;
|
2008-12-04 21:48:31 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("%s %s", cap, name);
|
2017-06-29 20:51:54 +00:00
|
|
|
if ((obj = virNodeDeviceObjListFindByName(driver->devs, name))) {
|
2017-05-12 16:45:16 +00:00
|
|
|
def = virNodeDeviceObjGetDef(obj);
|
2017-06-03 11:36:01 +00:00
|
|
|
(void)gather_capability(ctx, udi, cap, &def->caps);
|
2017-05-15 15:00:59 +00:00
|
|
|
virNodeDeviceObjEndAPI(&obj);
|
2008-12-04 21:48:31 +00:00
|
|
|
} else {
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("no device named %s", name);
|
2008-12-04 21:48:31 +00:00
|
|
|
}
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
2019-10-14 12:45:33 +00:00
|
|
|
device_cap_lost(LibHalContext *ctx G_GNUC_UNUSED,
|
2013-06-01 02:52:17 +00:00
|
|
|
const char *udi,
|
|
|
|
const char *cap)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
const char *name = hal_name(udi);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("%s %s", cap, name);
|
2009-05-19 13:26:14 +00:00
|
|
|
|
|
|
|
dev_refresh(udi);
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static void
|
2019-10-14 12:45:33 +00:00
|
|
|
device_prop_modified(LibHalContext *ctx G_GNUC_UNUSED,
|
2013-06-01 02:52:17 +00:00
|
|
|
const char *udi,
|
|
|
|
const char *key,
|
2019-10-14 12:45:33 +00:00
|
|
|
dbus_bool_t is_removed G_GNUC_UNUSED,
|
|
|
|
dbus_bool_t is_added G_GNUC_UNUSED)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
const char *name = hal_name(udi);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("%s %s", name, key);
|
2008-12-04 21:48:31 +00:00
|
|
|
|
2009-05-19 13:26:14 +00:00
|
|
|
dev_refresh(udi);
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
2019-10-14 12:45:33 +00:00
|
|
|
nodeStateInitialize(bool privileged G_GNUC_UNUSED,
|
|
|
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
|
|
|
void *opaque G_GNUC_UNUSED)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
|
|
|
LibHalContext *hal_ctx = NULL;
|
|
|
|
char **udi = NULL;
|
Convert 'int i' to 'size_t i' in src/node_device/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int num_devs;
|
|
|
|
size_t i;
|
2019-07-23 12:05:18 +00:00
|
|
|
int ret = VIR_DRV_STATE_INIT_ERROR;
|
2012-04-19 14:34:35 +00:00
|
|
|
DBusConnection *sysbus;
|
|
|
|
DBusError err;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
|
|
|
/* Ensure caps_tbl is sorted by capability name */
|
2019-10-15 11:55:26 +00:00
|
|
|
qsort(caps_tbl, G_N_ELEMENTS(caps_tbl), sizeof(caps_tbl[0]),
|
2008-11-21 12:27:11 +00:00
|
|
|
cmpstringp);
|
|
|
|
|
2014-11-17 16:30:27 +00:00
|
|
|
if (VIR_ALLOC(driver) < 0)
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2019-05-23 10:34:08 +00:00
|
|
|
driver->lockFD = -1;
|
2014-11-17 16:30:27 +00:00
|
|
|
if (virMutexInit(&driver->lock) < 0) {
|
|
|
|
VIR_FREE(driver);
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2009-01-15 19:56:05 +00:00
|
|
|
}
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceLock();
|
2008-12-04 21:48:31 +00:00
|
|
|
|
2019-05-23 10:34:08 +00:00
|
|
|
if (privileged) {
|
2019-10-22 13:26:14 +00:00
|
|
|
driver->stateDir = g_strdup_printf("%s/libvirt/nodedev", RUNSTATEDIR);
|
2019-05-23 10:34:08 +00:00
|
|
|
} else {
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *rundir = NULL;
|
2019-05-23 10:34:08 +00:00
|
|
|
|
|
|
|
if (!(rundir = virGetUserRuntimeDirectory()))
|
|
|
|
goto failure;
|
2019-10-22 13:26:14 +00:00
|
|
|
driver->stateDir = g_strdup_printf("%s/nodedev/run", rundir);
|
2019-05-23 10:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (virFileMakePathWithMode(driver->stateDir, S_IRWXU) < 0) {
|
|
|
|
virReportSystemError(errno, _("cannot create state directory '%s'"),
|
|
|
|
driver->stateDir);
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((driver->lockFD =
|
2019-07-11 14:57:34 +00:00
|
|
|
virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0)
|
2019-05-23 10:34:08 +00:00
|
|
|
goto failure;
|
|
|
|
|
2017-05-12 17:51:25 +00:00
|
|
|
if (!(driver->devs = virNodeDeviceObjListNew()))
|
|
|
|
goto failure;
|
|
|
|
|
2013-10-31 15:45:12 +00:00
|
|
|
dbus_error_init(&err);
|
2012-04-19 14:34:35 +00:00
|
|
|
if (!(sysbus = virDBusGetSystemBus())) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("DBus not available, disabling HAL driver: %s"),
|
|
|
|
virGetLastErrorMessage());
|
2019-07-23 12:05:18 +00:00
|
|
|
ret = VIR_DRV_STATE_INIT_SKIPPED;
|
2012-04-19 14:34:35 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
2009-03-02 11:13:37 +00:00
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
hal_ctx = libhal_ctx_new();
|
|
|
|
if (hal_ctx == NULL) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("libhal_ctx_new returned NULL"));
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
2009-03-02 11:13:37 +00:00
|
|
|
|
2012-04-19 14:34:35 +00:00
|
|
|
if (!libhal_ctx_set_dbus_connection(hal_ctx, sysbus)) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("libhal_ctx_set_dbus_connection failed"));
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
if (!libhal_ctx_init(hal_ctx, &err)) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("libhal_ctx_init failed, haldaemon is probably "
|
|
|
|
"not running"));
|
2009-11-13 10:36:01 +00:00
|
|
|
/* We don't want to show a fatal error here,
|
|
|
|
otherwise entire libvirtd shuts down when
|
|
|
|
hald isn't running */
|
2019-07-23 12:05:18 +00:00
|
|
|
ret = VIR_DRV_STATE_INIT_SKIPPED;
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
2009-11-12 14:10:45 +00:00
|
|
|
/* Populate with known devices */
|
2014-11-17 16:30:27 +00:00
|
|
|
driver->privateData = hal_ctx;
|
2009-11-12 14:10:45 +00:00
|
|
|
|
|
|
|
/* We need to unlock state now, since setting these callbacks cause
|
|
|
|
* a dbus RPC call, and while this call is waiting for the reply,
|
|
|
|
* a signal may already arrive, triggering the callback and thus
|
|
|
|
* requiring the lock !
|
|
|
|
*/
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
2009-11-12 14:10:45 +00:00
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
/* Register HAL event callbacks */
|
|
|
|
if (!libhal_ctx_set_device_added(hal_ctx, device_added) ||
|
|
|
|
!libhal_ctx_set_device_removed(hal_ctx, device_removed) ||
|
|
|
|
!libhal_ctx_set_device_new_capability(hal_ctx, device_cap_added) ||
|
|
|
|
!libhal_ctx_set_device_lost_capability(hal_ctx, device_cap_lost) ||
|
2009-05-19 13:35:57 +00:00
|
|
|
!libhal_ctx_set_device_property_modified(hal_ctx, device_prop_modified) ||
|
2009-05-20 13:37:30 +00:00
|
|
|
!libhal_device_property_watch_all(hal_ctx, &err)) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("setting up HAL callbacks failed"));
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
udi = libhal_get_all_devices(hal_ctx, &num_devs, &err);
|
|
|
|
if (udi == NULL) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("libhal_get_all_devices failed"));
|
2008-11-21 12:27:11 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
2008-12-04 21:48:31 +00:00
|
|
|
for (i = 0; i < num_devs; i++) {
|
2008-11-21 12:27:11 +00:00
|
|
|
dev_create(udi[i]);
|
2008-12-04 21:48:31 +00:00
|
|
|
VIR_FREE(udi[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(udi);
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_COMPLETE;
|
2008-11-21 12:27:11 +00:00
|
|
|
|
|
|
|
failure:
|
|
|
|
if (dbus_error_is_set(&err)) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("%s: %s"), err.name, err.message);
|
2008-11-21 12:27:11 +00:00
|
|
|
dbus_error_free(&err);
|
|
|
|
}
|
2017-05-12 17:51:25 +00:00
|
|
|
virNodeDeviceObjListFree(driver->devs);
|
2008-11-21 12:27:11 +00:00
|
|
|
if (hal_ctx)
|
|
|
|
(void)libhal_ctx_free(hal_ctx);
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
|
|
|
VIR_FREE(driver);
|
2008-11-21 12:27:11 +00:00
|
|
|
|
2009-11-13 10:36:01 +00:00
|
|
|
return ret;
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
nodeStateCleanup(void)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2014-11-17 16:30:27 +00:00
|
|
|
if (driver) {
|
|
|
|
nodeDeviceLock();
|
|
|
|
LibHalContext *hal_ctx = DRV_STATE_HAL_CTX(driver);
|
2017-05-12 17:51:25 +00:00
|
|
|
virNodeDeviceObjListFree(driver->devs);
|
2008-11-21 12:27:11 +00:00
|
|
|
(void)libhal_ctx_shutdown(hal_ctx, NULL);
|
|
|
|
(void)libhal_ctx_free(hal_ctx);
|
2019-05-23 10:34:08 +00:00
|
|
|
if (driver->lockFD != -1)
|
|
|
|
virPidFileRelease(driver->stateDir, "driver", driver->lockFD);
|
|
|
|
|
|
|
|
VIR_FREE(driver->stateDir);
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
|
|
|
virMutexDestroy(&driver->lock);
|
|
|
|
VIR_FREE(driver);
|
2008-11-21 12:27:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
static int
|
|
|
|
nodeStateReload(void)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2009-06-03 11:24:21 +00:00
|
|
|
DBusError err;
|
|
|
|
char **udi = NULL;
|
Convert 'int i' to 'size_t i' in src/node_device/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int num_devs;
|
|
|
|
size_t i;
|
2009-06-03 11:24:21 +00:00
|
|
|
LibHalContext *hal_ctx;
|
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("Reloading HAL device state");
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceLock();
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("Removing existing objects");
|
2017-07-18 11:19:05 +00:00
|
|
|
virNodeDeviceObjListFree(driver->devs);
|
2014-11-17 16:30:27 +00:00
|
|
|
nodeDeviceUnlock();
|
2009-06-03 11:24:21 +00:00
|
|
|
|
2014-11-17 16:30:27 +00:00
|
|
|
hal_ctx = DRV_STATE_HAL_CTX(driver);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("Creating new objects");
|
2009-06-03 11:24:21 +00:00
|
|
|
dbus_error_init(&err);
|
|
|
|
udi = libhal_get_all_devices(hal_ctx, &num_devs, &err);
|
|
|
|
if (udi == NULL) {
|
2016-06-08 13:20:27 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("libhal_get_all_devices failed"));
|
2009-06-03 11:24:21 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
for (i = 0; i < num_devs; i++) {
|
|
|
|
dev_create(udi[i]);
|
|
|
|
VIR_FREE(udi[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(udi);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("HAL device reload complete");
|
2009-06-03 11:24:21 +00:00
|
|
|
|
|
|
|
return 0;
|
2008-11-21 12:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-23 10:15:48 +00:00
|
|
|
static virNodeDeviceDriver halNodeDeviceDriver = {
|
2015-01-20 16:16:26 +00:00
|
|
|
.name = "HAL",
|
2013-04-22 17:26:01 +00:00
|
|
|
.nodeNumOfDevices = nodeNumOfDevices, /* 0.5.0 */
|
|
|
|
.nodeListDevices = nodeListDevices, /* 0.5.0 */
|
2013-04-29 09:20:17 +00:00
|
|
|
.connectListAllNodeDevices = nodeConnectListAllNodeDevices, /* 0.10.2 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.nodeDeviceLookupByName = nodeDeviceLookupByName, /* 0.5.0 */
|
|
|
|
.nodeDeviceLookupSCSIHostByWWN = nodeDeviceLookupSCSIHostByWWN, /* 1.0.2 */
|
|
|
|
.nodeDeviceGetXMLDesc = nodeDeviceGetXMLDesc, /* 0.5.0 */
|
|
|
|
.nodeDeviceGetParent = nodeDeviceGetParent, /* 0.5.0 */
|
|
|
|
.nodeDeviceNumOfCaps = nodeDeviceNumOfCaps, /* 0.5.0 */
|
|
|
|
.nodeDeviceListCaps = nodeDeviceListCaps, /* 0.5.0 */
|
|
|
|
.nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.6.5 */
|
|
|
|
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.6.5 */
|
2008-11-21 12:27:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-01-26 11:16:00 +00:00
|
|
|
static virHypervisorDriver halHypervisorDriver = {
|
|
|
|
.name = "nodedev",
|
|
|
|
.connectOpen = nodeConnectOpen, /* 4.1.0 */
|
|
|
|
.connectClose = nodeConnectClose, /* 4.1.0 */
|
|
|
|
.connectIsEncrypted = nodeConnectIsEncrypted, /* 4.1.0 */
|
|
|
|
.connectIsSecure = nodeConnectIsSecure, /* 4.1.0 */
|
|
|
|
.connectIsAlive = nodeConnectIsAlive, /* 4.1.0 */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static virConnectDriver halConnectDriver = {
|
2018-03-28 09:53:31 +00:00
|
|
|
.localOnly = true,
|
2018-03-27 14:51:45 +00:00
|
|
|
.uriSchemes = (const char *[]){ "nodedev", NULL },
|
2018-01-26 11:16:00 +00:00
|
|
|
.hypervisorDriver = &halHypervisorDriver,
|
|
|
|
.nodeDeviceDriver = &halNodeDeviceDriver,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-11-21 12:27:11 +00:00
|
|
|
static virStateDriver halStateDriver = {
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
.name = "HAL",
|
2013-04-29 09:20:17 +00:00
|
|
|
.stateInitialize = nodeStateInitialize, /* 0.5.0 */
|
|
|
|
.stateCleanup = nodeStateCleanup, /* 0.5.0 */
|
|
|
|
.stateReload = nodeStateReload, /* 0.5.0 */
|
2008-11-21 12:27:11 +00:00
|
|
|
};
|
|
|
|
|
2013-06-01 02:52:17 +00:00
|
|
|
int
|
|
|
|
halNodeRegister(void)
|
2008-11-21 12:27:11 +00:00
|
|
|
{
|
2018-01-26 11:16:00 +00:00
|
|
|
if (virRegisterConnectDriver(&halConnectDriver, false) < 0)
|
|
|
|
return -1;
|
2015-01-20 16:16:26 +00:00
|
|
|
if (virSetSharedNodeDeviceDriver(&halNodeDeviceDriver) < 0)
|
2008-11-21 12:27:11 +00:00
|
|
|
return -1;
|
|
|
|
return virRegisterStateDriver(&halStateDriver);
|
|
|
|
}
|