node_device_udev.c 47.6 KB
Newer Older
1 2 3
/*
 * node_device_udev.c: node device enumeration - libudev implementation
 *
4
 * Copyright (C) 2009-2015 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23 24
 *
 * Author: Dave Allan <dallan@redhat.com>
 */

#include <config.h>
#include <libudev.h>
25
#include <pciaccess.h>
26 27 28
#include <scsi/scsi.h>
#include <c-ctype.h>

29
#include "dirname.h"
30
#include "node_device_conf.h"
31
#include "node_device_event.h"
32
#include "node_device_driver.h"
33 34 35
#include "node_device_linux_sysfs.h"
#include "node_device_udev.h"
#include "virerror.h"
36 37
#include "driver.h"
#include "datatypes.h"
38
#include "virlog.h"
39
#include "viralloc.h"
40
#include "viruuid.h"
41
#include "virbuffer.h"
42
#include "virfile.h"
43
#include "virpci.h"
44
#include "virstring.h"
45
#include "virnetdev.h"
46 47 48

#define VIR_FROM_THIS VIR_FROM_NODEDEV

49 50
VIR_LOG_INIT("node_device.node_device_udev");

51 52 53 54
#ifndef TYPE_RAID
# define TYPE_RAID 12
#endif

55 56 57
struct _udevPrivate {
    struct udev_monitor *udev_monitor;
    int watch;
58
    bool privileged;
59 60
};

61

J
Ján Tomko 已提交
62 63 64 65 66 67 68 69 70 71 72
static bool
udevHasDeviceProperty(struct udev_device *dev,
                      const char *key)
{
    if (udev_device_get_property_value(dev, key))
        return true;

    return false;
}


73 74
static const char *udevGetDeviceProperty(struct udev_device *udev_device,
                                         const char *property_key)
75
{
76
    const char *ret = NULL;
77

78
    ret = udev_device_get_property_value(udev_device, property_key);
79

80 81
    VIR_DEBUG("Found property key '%s' value '%s' for device with sysname '%s'",
              property_key, NULLSTR(ret), udev_device_get_sysname(udev_device));
82 83 84 85 86 87 88 89 90

    return ret;
}


static int udevGetStringProperty(struct udev_device *udev_device,
                                 const char *property_key,
                                 char **value)
{
91 92
    if (VIR_STRDUP(*value,
                   udevGetDeviceProperty(udev_device, property_key)) < 0)
93
        return -1;
94

95
    return 0;
96 97 98 99 100 101 102 103
}


static int udevGetIntProperty(struct udev_device *udev_device,
                              const char *property_key,
                              int *value,
                              int base)
{
104
    const char *str = NULL;
105

106
    str = udevGetDeviceProperty(udev_device, property_key);
107

108
    if (str && virStrToLong_i(str, NULL, base, value) < 0) {
109 110
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to int"), str);
111
        return -1;
112
    }
113
    return 0;
114 115 116 117 118 119 120 121
}


static int udevGetUintProperty(struct udev_device *udev_device,
                               const char *property_key,
                               unsigned int *value,
                               int base)
{
122
    const char *str = NULL;
123

124
    str = udevGetDeviceProperty(udev_device, property_key);
125

126
    if (str && virStrToLong_ui(str, NULL, base, value) < 0) {
127 128
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to int"), str);
129
        return -1;
130
    }
131
    return 0;
132 133 134
}


135 136
static const char *udevGetDeviceSysfsAttr(struct udev_device *udev_device,
                                          const char *attr_name)
137
{
138
    const char *ret = NULL;
139

140
    ret = udev_device_get_sysattr_value(udev_device, attr_name);
141 142

    VIR_DEBUG("Found sysfs attribute '%s' value '%s' "
143
              "for device with sysname '%s'",
144
              attr_name, NULLSTR(ret),
145 146 147 148 149 150 151 152 153
              udev_device_get_sysname(udev_device));
    return ret;
}


static int udevGetStringSysfsAttr(struct udev_device *udev_device,
                                  const char *attr_name,
                                  char **value)
{
154
    if (VIR_STRDUP(*value, udevGetDeviceSysfsAttr(udev_device, attr_name)) < 0)
155
        return -1;
156

157
    virStringStripControlChars(*value);
158

159 160
    if (*value != NULL && (STREQ(*value, "")))
        VIR_FREE(*value);
161

162
    return 0;
163 164 165 166 167 168 169 170
}


static int udevGetIntSysfsAttr(struct udev_device *udev_device,
                               const char *attr_name,
                               int *value,
                               int base)
{
171
    const char *str = NULL;
172

173
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
174

175
    if (str && virStrToLong_i(str, NULL, base, value) < 0) {
176 177
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to int"), str);
178
        return -1;
179 180
    }

181
    return 0;
182 183 184 185 186 187 188 189
}


static int udevGetUintSysfsAttr(struct udev_device *udev_device,
                                const char *attr_name,
                                unsigned int *value,
                                int base)
{
190
    const char *str = NULL;
191

192
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
193

194
    if (str && virStrToLong_ui(str, NULL, base, value) < 0) {
195 196
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to unsigned int"), str);
197
        return -1;
198 199
    }

200
    return 0;
201 202 203 204 205 206 207
}


static int udevGetUint64SysfsAttr(struct udev_device *udev_device,
                                  const char *attr_name,
                                  unsigned long long *value)
{
208
    const char *str = NULL;
209

210
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
211

212
    if (str && virStrToLong_ull(str, NULL, 0, value) < 0) {
213 214
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to unsigned long long"), str);
J
Ján Tomko 已提交
215
        return -1;
216 217
    }

J
Ján Tomko 已提交
218
    return 0;
219 220 221 222 223 224 225
}


static int udevGenerateDeviceName(struct udev_device *device,
                                  virNodeDeviceDefPtr def,
                                  const char *s)
{
226
    size_t i;
227 228
    virBuffer buf = VIR_BUFFER_INITIALIZER;

229
    virBufferAsprintf(&buf, "%s_%s",
230 231 232
                      udev_device_get_subsystem(device),
                      udev_device_get_sysname(device));

233
    if (s != NULL)
234
        virBufferAsprintf(&buf, "_%s", s);
235

236 237
    if (virBufferCheckError(&buf) < 0)
        return -1;
238 239 240

    def->name = virBufferContentAndReset(&buf);

241
    for (i = 0; i < strlen(def->name); i++) {
242
        if (!(c_isalnum(*(def->name + i))))
243 244 245
            *(def->name + i) = '_';
    }

246
    return 0;
247 248
}

249
#if HAVE_UDEV_LOGGING
J
Ján Tomko 已提交
250 251 252 253 254 255 256 257 258
typedef void (*udevLogFunctionPtr)(struct udev *udev,
                                   int priority,
                                   const char *file,
                                   int line,
                                   const char *fn,
                                   const char *format,
                                   va_list args);

static void
259
ATTRIBUTE_FMT_PRINTF(6, 0)
J
Ján Tomko 已提交
260 261 262 263 264 265 266
udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED,
                int priority,
                const char *file,
                int line,
                const char *fn,
                const char *fmt,
                va_list args)
267
{
J
Ján Tomko 已提交
268
    virBuffer buf = VIR_BUFFER_INITIALIZER;
269
    char *format = NULL;
J
Ján Tomko 已提交
270 271 272 273 274 275

    virBufferAdd(&buf, fmt, -1);
    virBufferTrim(&buf, "\n", -1);

    format = virBufferContentAndReset(&buf);

276
    virLogVMessage(&virLogSelf,
J
Ján Tomko 已提交
277 278 279 280
                   virLogPriorityFromSyslog(priority),
                   file, line, fn, NULL, format ? format : fmt, args);

    VIR_FREE(format);
281
}
282
#endif
283 284


285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
static int udevTranslatePCIIds(unsigned int vendor,
                               unsigned int product,
                               char **vendor_string,
                               char **product_string)
{
    struct pci_id_match m;
    const char *vendor_name = NULL, *device_name = NULL;

    m.vendor_id = vendor;
    m.device_id = product;
    m.subvendor_id = PCI_MATCH_ANY;
    m.subdevice_id = PCI_MATCH_ANY;
    m.device_class = 0;
    m.device_class_mask = 0;
    m.match_data = 0;

    /* pci_get_strings returns void */
    pci_get_strings(&m,
                    &device_name,
304
                    &vendor_name,
305 306 307
                    NULL,
                    NULL);

308
    if (VIR_STRDUP(*vendor_string, vendor_name) < 0 ||
309
        VIR_STRDUP(*product_string, device_name) < 0)
310
        return -1;
311

312
    return 0;
313 314 315
}


316 317 318
static int udevProcessPCI(struct udev_device *device,
                          virNodeDeviceDefPtr def)
{
319
    const char *syspath = NULL;
320
    virNodeDevCapDataPtr data = &def->caps->data;
321 322
    virPCIEDeviceInfoPtr pci_express = NULL;
    virPCIDevicePtr pciDev = NULL;
323
    udevPrivate *priv = driver->privateData;
324
    int ret = -1;
325
    char *p;
326

327
    syspath = udev_device_get_syspath(device);
328

329
    if (udevGetUintProperty(device, "PCI_CLASS", &data->pci_dev.class, 16) < 0)
330
        goto cleanup;
331

332 333 334 335 336 337 338 339
    if ((p = strrchr(syspath, '/')) == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->pci_dev.domain) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->pci_dev.bus) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->pci_dev.slot) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->pci_dev.function) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the PCI address from sysfs path: '%s'"),
                       syspath);
340
        goto cleanup;
341 342
    }

343
    if (udevGetUintSysfsAttr(device, "vendor", &data->pci_dev.vendor, 16) < 0)
344
        goto cleanup;
345

346
    if (udevGetUintSysfsAttr(device, "device", &data->pci_dev.product, 16) < 0)
347
        goto cleanup;
348

349 350 351 352
    if (udevTranslatePCIIds(data->pci_dev.vendor,
                            data->pci_dev.product,
                            &data->pci_dev.vendor_name,
                            &data->pci_dev.product_name) != 0) {
353
        goto cleanup;
354
    }
355

356
    if (udevGenerateDeviceName(device, def, NULL) != 0)
357
        goto cleanup;
358

359 360 361 362 363
    /* The default value is -1, because it can't be 0
     * as zero is valid node number. */
    data->pci_dev.numa_node = -1;
    if (udevGetIntSysfsAttr(device, "numa_node",
                            &data->pci_dev.numa_node, 10) < 0)
364
        goto cleanup;
365

366
    if (nodeDeviceSysfsGetPCIRelatedDevCaps(syspath, data) < 0)
367
        goto cleanup;
368

369 370 371 372
    if (!(pciDev = virPCIDeviceNew(data->pci_dev.domain,
                                   data->pci_dev.bus,
                                   data->pci_dev.slot,
                                   data->pci_dev.function)))
373
        goto cleanup;
374

375
    /* We need to be root to read PCI device configs */
376
    if (priv->privileged) {
377
        if (virPCIGetHeaderType(pciDev, &data->pci_dev.hdrType) < 0)
378
            goto cleanup;
379

380 381
        if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
            if (VIR_ALLOC(pci_express) < 0)
382
                goto cleanup;
383

384 385 386
            if (virPCIDeviceHasPCIExpressLink(pciDev) > 0) {
                if (VIR_ALLOC(pci_express->link_cap) < 0 ||
                    VIR_ALLOC(pci_express->link_sta) < 0)
387
                    goto cleanup;
388 389 390 391 392 393 394

                if (virPCIDeviceGetLinkCapSta(pciDev,
                                              &pci_express->link_cap->port,
                                              &pci_express->link_cap->speed,
                                              &pci_express->link_cap->width,
                                              &pci_express->link_sta->speed,
                                              &pci_express->link_sta->width) < 0)
395
                    goto cleanup;
396 397 398 399 400 401

                pci_express->link_sta->port = -1; /* PCIe can't negotiate port. Yet :) */
            }
            data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCIE;
            data->pci_dev.pci_express = pci_express;
            pci_express = NULL;
402 403 404
        }
    }

405 406
    ret = 0;

407
 cleanup:
408
    virPCIDeviceFree(pciDev);
409
    virPCIEDeviceInfoFree(pci_express);
410 411 412
    return ret;
}

M
Marc-André Lureau 已提交
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
static int drmGetMinorType(int minor)
{
    int type = minor >> 6;

    if (minor < 0)
        return -1;

    switch (type) {
    case VIR_NODE_DEV_DRM_PRIMARY:
    case VIR_NODE_DEV_DRM_CONTROL:
    case VIR_NODE_DEV_DRM_RENDER:
        return type;
    default:
        return -1;
    }
}

static int udevProcessDRMDevice(struct udev_device *device,
                                virNodeDeviceDefPtr def)
{
    virNodeDevCapDataPtr data = &def->caps->data;
    int minor;

    if (udevGenerateDeviceName(device, def, NULL) != 0)
        return -1;

    if (udevGetIntProperty(device, "MINOR", &minor, 10) < 0)
        return -1;

    if ((minor = drmGetMinorType(minor)) == -1)
        return -1;

    data->drm.type = minor;

    return 0;
}
449 450 451 452

static int udevProcessUSBDevice(struct udev_device *device,
                                virNodeDeviceDefPtr def)
{
453
    virNodeDevCapDataPtr data = &def->caps->data;
454

455
    if (udevGetUintProperty(device, "BUSNUM", &data->usb_dev.bus, 10) < 0)
456
        return -1;
457
    if (udevGetUintProperty(device, "DEVNUM", &data->usb_dev.device, 10) < 0)
458
        return -1;
459
    if (udevGetUintProperty(device, "ID_VENDOR_ID", &data->usb_dev.vendor, 16) < 0)
460
        return -1;
461

462 463 464
    if (udevGetStringProperty(device,
                              "ID_VENDOR_FROM_DATABASE",
                              &data->usb_dev.vendor_name) < 0)
465
        return -1;
466 467

    if (!data->usb_dev.vendor_name &&
468 469
        udevGetStringSysfsAttr(device, "manufacturer",
                               &data->usb_dev.vendor_name) < 0)
470
        return -1;
471

472
    if (udevGetUintProperty(device, "ID_MODEL_ID", &data->usb_dev.product, 16) < 0)
473
        return -1;
474

475 476 477
    if (udevGetStringProperty(device,
                              "ID_MODEL_FROM_DATABASE",
                              &data->usb_dev.product_name) < 0)
478
        return -1;
479 480

    if (!data->usb_dev.product_name &&
481 482
        udevGetStringSysfsAttr(device, "product",
                               &data->usb_dev.product_name) < 0)
483
        return -1;
484

485
    if (udevGenerateDeviceName(device, def, NULL) != 0)
486
        return -1;
487

488
    return 0;
489 490 491 492 493 494
}


static int udevProcessUSBInterface(struct udev_device *device,
                                   virNodeDeviceDefPtr def)
{
495
    virNodeDevCapDataPtr data = &def->caps->data;
496

497 498
    if (udevGetUintSysfsAttr(device, "bInterfaceNumber",
                             &data->usb_if.number, 16) < 0)
499
        return -1;
500

501 502
    if (udevGetUintSysfsAttr(device, "bInterfaceClass",
                             &data->usb_if._class, 16) < 0)
503
        return -1;
504

505 506
    if (udevGetUintSysfsAttr(device, "bInterfaceSubClass",
                             &data->usb_if.subclass, 16) < 0)
507
        return -1;
508

509 510
    if (udevGetUintSysfsAttr(device, "bInterfaceProtocol",
                             &data->usb_if.protocol, 16) < 0)
511
        return -1;
512

513
    if (udevGenerateDeviceName(device, def, NULL) != 0)
514
        return -1;
515

516
    return 0;
517 518 519 520 521 522
}


static int udevProcessNetworkInterface(struct udev_device *device,
                                       virNodeDeviceDefPtr def)
{
D
David Allan 已提交
523
    const char *devtype = udev_device_get_devtype(device);
524
    virNodeDevCapDataPtr data = &def->caps->data;
525

D
David Allan 已提交
526 527 528 529 530 531
    if (devtype && STREQ(devtype, "wlan")) {
        data->net.subtype = VIR_NODE_DEV_CAP_NET_80211;
    } else {
        data->net.subtype = VIR_NODE_DEV_CAP_NET_80203;
    }

532 533
    if (udevGetStringProperty(device,
                              "INTERFACE",
534
                              &data->net.ifname) < 0)
535
        return -1;
536

537 538
    if (udevGetStringSysfsAttr(device, "address",
                               &data->net.address) < 0)
539
        return -1;
540

541
    if (udevGetUintSysfsAttr(device, "addr_len", &data->net.address_len, 0) < 0)
542
        return -1;
543

544
    if (udevGenerateDeviceName(device, def, data->net.address) != 0)
545
        return -1;
546

547
    if (virNetDevGetLinkInfo(data->net.ifname, &data->net.lnk) < 0)
548
        return -1;
549

550
    if (virNetDevGetFeatures(data->net.ifname, &data->net.features) < 0)
551
        return -1;
552

553
    return 0;
554 555 556 557 558 559
}


static int udevProcessSCSIHost(struct udev_device *device ATTRIBUTE_UNUSED,
                               virNodeDeviceDefPtr def)
{
560
    virNodeDevCapDataPtr data = &def->caps->data;
561
    char *filename = NULL;
J
Ján Tomko 已提交
562
    char *str;
563

564
    filename = last_component(def->sysfs_path);
565

566 567 568 569 570
    if (!(str = STRSKIP(filename, "host")) ||
        virStrToLong_ui(str, NULL, 0, &data->scsi_host.host) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse SCSI host '%s'"),
                       filename);
571
        return -1;
572 573
    }

574
    nodeDeviceSysfsGetSCSIHostCaps(&def->caps->data);
575

576
    if (udevGenerateDeviceName(device, def, NULL) != 0)
577
        return -1;
578

579
    return 0;
580 581 582
}


D
David Allan 已提交
583 584 585 586
static int udevProcessSCSITarget(struct udev_device *device ATTRIBUTE_UNUSED,
                                 virNodeDeviceDefPtr def)
{
    const char *sysname = NULL;
587
    virNodeDevCapDataPtr data = &def->caps->data;
D
David Allan 已提交
588 589 590

    sysname = udev_device_get_sysname(device);

591
    if (VIR_STRDUP(data->scsi_target.name, sysname) < 0)
592
        return -1;
D
David Allan 已提交
593

594
    if (udevGenerateDeviceName(device, def, NULL) != 0)
595
        return -1;
D
David Allan 已提交
596

597
    return 0;
D
David Allan 已提交
598 599 600
}


601
static int udevGetSCSIType(virNodeDeviceDefPtr def ATTRIBUTE_UNUSED,
602
                           unsigned int type, char **typestring)
603 604 605 606 607 608 609 610
{
    int ret = 0;
    int foundtype = 1;

    *typestring = NULL;

    switch (type) {
    case TYPE_DISK:
611
        ignore_value(VIR_STRDUP(*typestring, "disk"));
612 613
        break;
    case TYPE_TAPE:
614
        ignore_value(VIR_STRDUP(*typestring, "tape"));
615 616
        break;
    case TYPE_PROCESSOR:
617
        ignore_value(VIR_STRDUP(*typestring, "processor"));
618 619
        break;
    case TYPE_WORM:
620
        ignore_value(VIR_STRDUP(*typestring, "worm"));
621 622
        break;
    case TYPE_ROM:
623
        ignore_value(VIR_STRDUP(*typestring, "cdrom"));
624 625
        break;
    case TYPE_SCANNER:
626
        ignore_value(VIR_STRDUP(*typestring, "scanner"));
627 628
        break;
    case TYPE_MOD:
629
        ignore_value(VIR_STRDUP(*typestring, "mod"));
630 631
        break;
    case TYPE_MEDIUM_CHANGER:
632
        ignore_value(VIR_STRDUP(*typestring, "changer"));
633 634
        break;
    case TYPE_ENCLOSURE:
635
        ignore_value(VIR_STRDUP(*typestring, "enclosure"));
636
        break;
637
    case TYPE_RAID:
638
        ignore_value(VIR_STRDUP(*typestring, "raid"));
639
        break;
640 641 642 643 644 645 646 647 648 649
    case TYPE_NO_LUN:
    default:
        foundtype = 0;
        break;
    }

    if (*typestring == NULL) {
        if (foundtype == 1) {
            ret = -1;
        } else {
650 651
            VIR_DEBUG("Failed to find SCSI device type %d for %s",
                      type, def->sysfs_path);
652 653 654 655 656 657 658 659 660 661 662 663
        }
    }

    return ret;
}


static int udevProcessSCSIDevice(struct udev_device *device ATTRIBUTE_UNUSED,
                                 virNodeDeviceDefPtr def)
{
    int ret = -1;
    unsigned int tmp = 0;
664
    virNodeDevCapDataPtr data = &def->caps->data;
665 666
    char *filename = NULL, *p = NULL;

667
    filename = last_component(def->sysfs_path);
668

669 670 671 672 673 674 675 676
    if (virStrToLong_ui(filename, &p, 10, &data->scsi.host) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &data->scsi.bus) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &data->scsi.target) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &data->scsi.lun) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the SCSI address from filename: '%s'"),
                       filename);
        return -1;
677 678
    }

679 680
    if (udev_device_get_sysattr_value(device, "type")) {
        if (udevGetUintSysfsAttr(device, "type", &tmp, 0) < 0)
681
            goto cleanup;
682 683

        if (udevGetSCSIType(def, tmp, &data->scsi.type) < 0)
684
            goto cleanup;
685 686
    }

687
    if (udevGenerateDeviceName(device, def, NULL) != 0)
688
        goto cleanup;
689 690 691

    ret = 0;

692
 cleanup:
693
    if (ret != 0) {
694 695 696
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to process SCSI device with sysfs path '%s'"),
                       def->sysfs_path);
697 698 699 700 701 702 703 704
    }
    return ret;
}


static int udevProcessDisk(struct udev_device *device,
                           virNodeDeviceDefPtr def)
{
705
    virNodeDevCapDataPtr data = &def->caps->data;
706

J
Ján Tomko 已提交
707
    if (udevGetUint64SysfsAttr(device, "size", &data->storage.num_blocks) < 0)
708
        return -1;
709

J
Ján Tomko 已提交
710 711
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
                               &data->storage.logical_block_size) < 0)
712
        return -1;
713 714 715 716

    data->storage.size = data->storage.num_blocks *
        data->storage.logical_block_size;

717
    return 0;
718 719 720
}


721 722 723
static int udevProcessRemoveableMedia(struct udev_device *device,
                                      virNodeDeviceDefPtr def,
                                      int has_media)
724
{
725
    virNodeDevCapDataPtr data = &def->caps->data;
J
Ján Tomko 已提交
726
    int is_removable = 0;
727

728 729 730
    if (udevGetIntSysfsAttr(device, "removable", &is_removable, 0) < 0)
        return -1;
    if (is_removable == 1)
731 732
        def->caps->data.storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;

J
Ján Tomko 已提交
733 734
    if (!has_media)
        return 0;
735

J
Ján Tomko 已提交
736 737
    def->caps->data.storage.flags |=
        VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
738

J
Ján Tomko 已提交
739 740 741
    if (udevGetStringProperty(device, "ID_FS_LABEL",
                              &data->storage.media_label) < 0)
        return -1;
742

J
Ján Tomko 已提交
743 744 745
    if (udevGetUint64SysfsAttr(device, "size",
                               &data->storage.num_blocks) < 0)
        return -1;
746

J
Ján Tomko 已提交
747 748 749
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
                               &data->storage.logical_block_size) < 0)
        return -1;
750

J
Ján Tomko 已提交
751 752 753 754 755 756 757
    /* XXX This calculation is wrong for the qemu virtual cdrom
     * which reports the size in 512 byte blocks, but the logical
     * block size as 2048.  I don't have a physical cdrom on a
     * devel system to see how they behave. */
    def->caps->data.storage.removable_media_size =
        def->caps->data.storage.num_blocks *
        def->caps->data.storage.logical_block_size;
758

J
Ján Tomko 已提交
759
    return 0;
760 761
}

762 763 764 765 766 767 768 769 770 771
static int udevProcessCDROM(struct udev_device *device,
                            virNodeDeviceDefPtr def)
{
    int has_media = 0;

    /* NB: the drive_type string provided by udev is different from
     * that provided by HAL; now it's "cd" instead of "cdrom" We
     * change it to cdrom to preserve compatibility with earlier
     * versions of libvirt.  */
    VIR_FREE(def->caps->data.storage.drive_type);
772
    if (VIR_STRDUP(def->caps->data.storage.drive_type, "cdrom") < 0)
773
        return -1;
774

775 776
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA") &&
        udevGetIntProperty(device, "ID_CDROM_MEDIA", &has_media, 0) < 0)
777
        return -1;
778

779
    return udevProcessRemoveableMedia(device, def, has_media);
780 781 782 783 784 785 786
}

static int udevProcessFloppy(struct udev_device *device,
                             virNodeDeviceDefPtr def)
{
    int has_media = 0;

787
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA")) {
788
        /* USB floppy */
789 790
        if (udevGetIntProperty(device, "DKD_MEDIA_AVAILABLE", &has_media, 0) < 0)
            return -1;
791
    } else if (udevHasDeviceProperty(device, "ID_FS_LABEL")) {
792 793 794 795 796 797
        /* Legacy floppy */
        has_media = 1;
    }

    return udevProcessRemoveableMedia(device, def, has_media);
}
798

799 800 801 802

static int udevProcessSD(struct udev_device *device,
                         virNodeDeviceDefPtr def)
{
803
    virNodeDevCapDataPtr data = &def->caps->data;
804

J
Ján Tomko 已提交
805 806
    if (udevGetUint64SysfsAttr(device, "size",
                               &data->storage.num_blocks) < 0)
807
        return -1;
808

J
Ján Tomko 已提交
809 810
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
                               &data->storage.logical_block_size) < 0)
811
        return -1;
812 813 814 815

    data->storage.size = data->storage.num_blocks *
        data->storage.logical_block_size;

816
    return 0;
817 818 819 820
}



821 822 823 824 825 826
/* This function exists to deal with the case in which a driver does
 * not provide a device type in the usual place, but udev told us it's
 * a storage device, and we can make a good guess at what kind of
 * storage device it is from other information that is provided. */
static int udevKludgeStorageType(virNodeDeviceDefPtr def)
{
827 828 829
    VIR_DEBUG("Could not find definitive storage type for device "
              "with sysfs path '%s', trying to guess it",
              def->sysfs_path);
830

831 832 833
    /* virtio disk */
    if (STRPREFIX(def->caps->data.storage.block, "/dev/vd") &&
        VIR_STRDUP(def->caps->data.storage.drive_type, "disk") > 0) {
834
        VIR_DEBUG("Found storage type '%s' for device "
835
                  "with sysfs path '%s'",
836 837
                  def->caps->data.storage.drive_type,
                  def->sysfs_path);
838
        return 0;
839
    }
840 841 842
    VIR_DEBUG("Could not determine storage type "
              "for device with sysfs path '%s'", def->sysfs_path);
    return -1;
843 844 845 846 847 848
}


static int udevProcessStorage(struct udev_device *device,
                              virNodeDeviceDefPtr def)
{
849
    virNodeDevCapDataPtr data = &def->caps->data;
850
    int ret = -1;
851
    const char* devnode;
852

853
    devnode = udev_device_get_devnode(device);
854
    if (!devnode) {
855
        VIR_DEBUG("No devnode for '%s'", udev_device_get_devpath(device));
856
        goto cleanup;
857
    }
858 859

    if (VIR_STRDUP(data->storage.block, devnode) < 0)
860
        goto cleanup;
861

862
    if (udevGetStringProperty(device, "ID_BUS", &data->storage.bus) < 0)
863
        goto cleanup;
864
    if (udevGetStringProperty(device, "ID_SERIAL", &data->storage.serial) < 0)
865
        goto cleanup;
866

867
    if (udevGetStringSysfsAttr(device, "device/vendor", &data->storage.vendor) < 0)
868
        goto cleanup;
869 870 871
    if (def->caps->data.storage.vendor)
        virTrimSpaces(def->caps->data.storage.vendor, NULL);

872
    if (udevGetStringSysfsAttr(device, "device/model", &data->storage.model) < 0)
873
        goto cleanup;
874 875
    if (def->caps->data.storage.model)
        virTrimSpaces(def->caps->data.storage.model, NULL);
876 877 878 879 880
    /* There is no equivalent of the hotpluggable property in libudev,
     * but storage is going toward a world in which hotpluggable is
     * expected, so I don't see a problem with not having a property
     * for it. */

881
    if (udevGetStringProperty(device, "ID_TYPE", &data->storage.drive_type) < 0)
882
        goto cleanup;
883 884

    if (!data->storage.drive_type ||
885
        STREQ(def->caps->data.storage.drive_type, "generic")) {
886 887
        int val = 0;
        const char *str = NULL;
888 889 890

        /* All floppy drives have the ID_DRIVE_FLOPPY prop. This is
         * needed since legacy floppies don't have a drive_type */
891
        if (udevGetIntProperty(device, "ID_DRIVE_FLOPPY", &val, 0) < 0)
892
            goto cleanup;
893 894
        else if (val == 1)
            str = "floppy";
895

896
        if (!str) {
897
            if (udevGetIntProperty(device, "ID_CDROM", &val, 0) < 0)
898
                goto cleanup;
899 900 901
            else if (val == 1)
                str = "cd";
        }
902

903
        if (!str) {
904
            if (udevGetIntProperty(device, "ID_DRIVE_FLASH_SD", &val, 0) < 0)
905
                goto cleanup;
906 907 908
            if (val == 1)
                str = "sd";
        }
909

910 911
        if (str) {
            if (VIR_STRDUP(data->storage.drive_type, str) < 0)
912
                goto cleanup;
913 914
        } else {
            /* If udev doesn't have it, perhaps we can guess it. */
915
            if (udevKludgeStorageType(def) != 0)
916
                goto cleanup;
917 918 919 920 921 922 923
        }
    }

    if (STREQ(def->caps->data.storage.drive_type, "cd")) {
        ret = udevProcessCDROM(device, def);
    } else if (STREQ(def->caps->data.storage.drive_type, "disk")) {
        ret = udevProcessDisk(device, def);
924 925
    } else if (STREQ(def->caps->data.storage.drive_type, "floppy")) {
        ret = udevProcessFloppy(device, def);
926 927
    } else if (STREQ(def->caps->data.storage.drive_type, "sd")) {
        ret = udevProcessSD(device, def);
928
    } else {
929 930
        VIR_DEBUG("Unsupported storage type '%s'",
                  def->caps->data.storage.drive_type);
931
        goto cleanup;
932 933
    }

934
    if (udevGenerateDeviceName(device, def, data->storage.serial) != 0)
935
        goto cleanup;
936

937
 cleanup:
938
    VIR_DEBUG("Storage ret=%d", ret);
939 940 941
    return ret;
}

942
static int
943
udevProcessSCSIGeneric(struct udev_device *dev,
944 945
                       virNodeDeviceDefPtr def)
{
946 947
    if (udevGetStringProperty(dev, "DEVNAME", &def->caps->data.sg.path) < 0 ||
        !def->caps->data.sg.path)
948 949 950 951 952 953 954 955
        return -1;

    if (udevGenerateDeviceName(dev, def, NULL) != 0)
        return -1;

    return 0;
}

956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
static int
udevGetDeviceNodes(struct udev_device *device,
                   virNodeDeviceDefPtr def)
{
    const char *devnode = NULL;
    struct udev_list_entry *list_entry = NULL;
    int n = 0;

    devnode = udev_device_get_devnode(device);

    if (VIR_STRDUP(def->devnode, devnode) < 0)
        return -1;

    udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
        n++;

    if (VIR_ALLOC_N(def->devlinks, n + 1) < 0)
        return -1;

    n = 0;
    udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
        if (VIR_STRDUP(def->devlinks[n++], udev_list_entry_get_name(list_entry)) < 0)
            return -1;
    }

    return 0;
}

984 985
static int
udevGetDeviceType(struct udev_device *device,
986
                  virNodeDevCapType *type)
987 988
{
    const char *devtype = NULL;
989
    char *subsystem = NULL;
990
    int ret = -1;
D
David Allan 已提交
991

992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
    devtype = udev_device_get_devtype(device);
    *type = 0;

    if (devtype) {
        if (STREQ(devtype, "usb_device"))
            *type = VIR_NODE_DEV_CAP_USB_DEV;
        else if (STREQ(devtype, "usb_interface"))
            *type = VIR_NODE_DEV_CAP_USB_INTERFACE;
        else if (STREQ(devtype, "scsi_host"))
            *type = VIR_NODE_DEV_CAP_SCSI_HOST;
        else if (STREQ(devtype, "scsi_target"))
            *type = VIR_NODE_DEV_CAP_SCSI_TARGET;
        else if (STREQ(devtype, "scsi_device"))
            *type = VIR_NODE_DEV_CAP_SCSI;
        else if (STREQ(devtype, "disk"))
            *type = VIR_NODE_DEV_CAP_STORAGE;
        else if (STREQ(devtype, "wlan"))
            *type = VIR_NODE_DEV_CAP_NET;
M
Marc-André Lureau 已提交
1010 1011
        else if (STREQ(devtype, "drm_minor"))
            *type = VIR_NODE_DEV_CAP_DRM;
1012 1013
    } else {
        /* PCI devices don't set the DEVTYPE property. */
1014
        if (udevHasDeviceProperty(device, "PCI_CLASS"))
1015
            *type = VIR_NODE_DEV_CAP_PCI_DEV;
1016

1017 1018 1019 1020
        /* Wired network interfaces don't set the DEVTYPE property,
         * USB devices also have an INTERFACE property, but they do
         * set DEVTYPE, so if devtype is NULL and the INTERFACE
         * property exists, we have a network device. */
1021
        if (udevHasDeviceProperty(device, "INTERFACE"))
1022
            *type = VIR_NODE_DEV_CAP_NET;
1023 1024

        /* SCSI generic device doesn't set DEVTYPE property */
1025 1026 1027 1028
        if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) < 0)
            return -1;

        if (STREQ_NULLABLE(subsystem, "scsi_generic"))
1029 1030
            *type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
        VIR_FREE(subsystem);
1031 1032
    }

1033 1034 1035 1036 1037 1038
    if (!*type)
        VIR_DEBUG("Could not determine device type for device "
                  "with sysfs name '%s'",
                  udev_device_get_sysname(device));
    else
        ret = 0;
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048

    return ret;
}


static int udevGetDeviceDetails(struct udev_device *device,
                                virNodeDeviceDefPtr def)
{
    int ret = 0;

1049
    switch (def->caps->data.type) {
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
    case VIR_NODE_DEV_CAP_SYSTEM:
        /* There's no libudev equivalent of system, so ignore it. */
        break;
    case VIR_NODE_DEV_CAP_PCI_DEV:
        ret = udevProcessPCI(device, def);
        break;
    case VIR_NODE_DEV_CAP_USB_DEV:
        ret = udevProcessUSBDevice(device, def);
        break;
    case VIR_NODE_DEV_CAP_USB_INTERFACE:
        ret = udevProcessUSBInterface(device, def);
        break;
    case VIR_NODE_DEV_CAP_NET:
        ret = udevProcessNetworkInterface(device, def);
        break;
    case VIR_NODE_DEV_CAP_SCSI_HOST:
        ret = udevProcessSCSIHost(device, def);
        break;
D
David Allan 已提交
1068 1069 1070
    case VIR_NODE_DEV_CAP_SCSI_TARGET:
        ret = udevProcessSCSITarget(device, def);
        break;
1071 1072 1073 1074 1075 1076
    case VIR_NODE_DEV_CAP_SCSI:
        ret = udevProcessSCSIDevice(device, def);
        break;
    case VIR_NODE_DEV_CAP_STORAGE:
        ret = udevProcessStorage(device, def);
        break;
1077
    case VIR_NODE_DEV_CAP_SCSI_GENERIC:
1078
        ret = udevProcessSCSIGeneric(device, def);
1079
        break;
M
Marc-André Lureau 已提交
1080 1081 1082
    case VIR_NODE_DEV_CAP_DRM:
        ret = udevProcessDRMDevice(device, def);
        break;
1083
    default:
1084 1085
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unknown device type %d"), def->caps->data.type);
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
        ret = -1;
        break;
    }

    return ret;
}


static int udevRemoveOneDevice(struct udev_device *device)
{
    virNodeDeviceObjPtr dev = NULL;
1097
    virObjectEventPtr event = NULL;
1098
    const char *name = NULL;
1099
    int ret = -1;
1100 1101

    name = udev_device_get_syspath(device);
1102
    dev = virNodeDeviceObjFindBySysfsPath(&driver->devs, name);
1103

1104
    if (!dev) {
1105 1106
        VIR_DEBUG("Failed to find device to remove that has udev name '%s'",
                  name);
1107
        goto cleanup;
1108 1109
    }

1110 1111 1112 1113 1114 1115
    event = virNodeDeviceEventLifecycleNew(dev->def->name,
                                           VIR_NODE_DEVICE_EVENT_DELETED,
                                           0);

    VIR_DEBUG("Removing device '%s' with sysfs path '%s'",
              dev->def->name, name);
1116
    virNodeDeviceObjRemove(&driver->devs, &dev);
1117 1118 1119 1120 1121

    ret = 0;
 cleanup:
    if (event)
        virObjectEventStateQueue(driver->nodeDeviceEventState, event);
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
    return ret;
}


static int udevSetParent(struct udev_device *device,
                         virNodeDeviceDefPtr def)
{
    struct udev_device *parent_device = NULL;
    const char *parent_sysfs_path = NULL;
    virNodeDeviceObjPtr dev = NULL;
    int ret = -1;

1134 1135
    parent_device = device;
    do {
1136

1137
        parent_device = udev_device_get_parent(parent_device);
1138
        if (parent_device == NULL)
1139
            break;
1140

1141 1142
        parent_sysfs_path = udev_device_get_syspath(parent_device);
        if (parent_sysfs_path == NULL) {
1143 1144 1145
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Could not get syspath for parent of '%s'"),
                           udev_device_get_syspath(parent_device));
1146
            goto cleanup;
1147 1148
        }

1149 1150
        dev = virNodeDeviceObjFindBySysfsPath(&driver->devs,
                                              parent_sysfs_path);
1151
        if (dev != NULL) {
1152 1153
            if (VIR_STRDUP(def->parent, dev->def->name) < 0) {
                virNodeDeviceObjUnlock(dev);
1154
                goto cleanup;
1155
            }
1156
            virNodeDeviceObjUnlock(dev);
1157

1158
            if (VIR_STRDUP(def->parent_sysfs_path, parent_sysfs_path) < 0)
1159
                goto cleanup;
1160 1161 1162 1163
        }

    } while (def->parent == NULL && parent_device != NULL);

1164
    if (!def->parent && VIR_STRDUP(def->parent, "computer") < 0)
1165
        goto cleanup;
1166 1167 1168

    ret = 0;

1169
 cleanup:
1170 1171 1172 1173 1174 1175 1176 1177
    return ret;
}


static int udevAddOneDevice(struct udev_device *device)
{
    virNodeDeviceDefPtr def = NULL;
    virNodeDeviceObjPtr dev = NULL;
1178 1179
    virObjectEventPtr event = NULL;
    bool new_device = true;
1180 1181
    int ret = -1;

1182
    if (VIR_ALLOC(def) != 0)
1183
        goto cleanup;
1184

1185
    if (VIR_STRDUP(def->sysfs_path, udev_device_get_syspath(device)) < 0)
1186
        goto cleanup;
1187

1188
    if (udevGetStringProperty(device, "DRIVER", &def->driver) < 0)
1189
        goto cleanup;
1190

1191
    if (VIR_ALLOC(def->caps) != 0)
1192
        goto cleanup;
1193

1194
    if (udevGetDeviceType(device, &def->caps->data.type) != 0)
1195
        goto cleanup;
1196

1197 1198 1199
    if (udevGetDeviceNodes(device, def) != 0)
        goto cleanup;

1200
    if (udevGetDeviceDetails(device, def) != 0)
1201
        goto cleanup;
1202

1203
    if (udevSetParent(device, def) != 0)
1204
        goto cleanup;
1205

1206
    dev = virNodeDeviceObjFindByName(&driver->devs, def->name);
1207 1208 1209 1210 1211
    if (dev) {
        virNodeDeviceObjUnlock(dev);
        new_device = false;
    }

1212 1213
    /* If this is a device change, the old definition will be freed
     * and the current definition will take its place. */
1214
    dev = virNodeDeviceObjAssignDef(&driver->devs, def);
1215
    if (dev == NULL)
1216
        goto cleanup;
1217

1218 1219 1220 1221
    if (new_device)
        event = virNodeDeviceEventLifecycleNew(dev->def->name,
                                               VIR_NODE_DEVICE_EVENT_CREATED,
                                               0);
1222 1223
    else
        event = virNodeDeviceEventUpdateNew(dev->def->name);
1224

1225 1226 1227 1228
    virNodeDeviceObjUnlock(dev);

    ret = 0;

1229
 cleanup:
1230 1231 1232
    if (event)
        virObjectEventStateQueue(driver->nodeDeviceEventState, event);

1233
    if (ret != 0) {
1234
        VIR_DEBUG("Discarding device %d %p %s", ret, def,
1235
                  def ? NULLSTR(def->sysfs_path) : "");
1236 1237 1238
        virNodeDeviceDefFree(def);
    }

1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
    return ret;
}


static int udevProcessDeviceListEntry(struct udev *udev,
                                      struct udev_list_entry *list_entry)
{
    struct udev_device *device;
    const char *name = NULL;
    int ret = -1;

    name = udev_list_entry_get_name(list_entry);

    device = udev_device_new_from_syspath(udev, name);
1253

1254 1255
    if (device != NULL) {
        if (udevAddOneDevice(device) != 0) {
1256 1257
            VIR_DEBUG("Failed to create node device for udev device '%s'",
                      name);
1258 1259 1260 1261
        }
        ret = 0;
    }

1262 1263
    udev_device_unref(device);

1264 1265 1266 1267
    return ret;
}


1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
/* We do not care about every device (see udevGetDeviceType).
 * Do not bother enumerating over subsystems that do not
 * contain interesting devices.
 */
const char *subsystem_blacklist[] = {
    "acpi", "tty", "vc", "i2c",
};

static int udevEnumerateAddMatches(struct udev_enumerate *udev_enumerate)
{
    size_t i;

    for (i = 0; i < ARRAY_CARDINALITY(subsystem_blacklist); i++) {
        const char *s = subsystem_blacklist[i];
        if (udev_enumerate_add_nomatch_subsystem(udev_enumerate, s) < 0) {
            virReportSystemError(errno, "%s", _("failed to add susbsystem filter"));
            return -1;
        }
    }
    return 0;
}


1291 1292 1293 1294
static int udevEnumerateDevices(struct udev *udev)
{
    struct udev_enumerate *udev_enumerate = NULL;
    struct udev_list_entry *list_entry = NULL;
1295
    int ret = -1;
1296 1297

    udev_enumerate = udev_enumerate_new(udev);
1298 1299
    if (udevEnumerateAddMatches(udev_enumerate) < 0)
        goto cleanup;
1300 1301

    ret = udev_enumerate_scan_devices(udev_enumerate);
1302
    if (ret != 0) {
1303 1304 1305
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("udev scan devices returned %d"),
                       ret);
1306
        goto cleanup;
1307 1308 1309 1310 1311 1312 1313 1314
    }

    udev_list_entry_foreach(list_entry,
                            udev_enumerate_get_list_entry(udev_enumerate)) {

        udevProcessDeviceListEntry(udev, list_entry);
    }

1315
 cleanup:
1316 1317 1318 1319 1320
    udev_enumerate_unref(udev_enumerate);
    return ret;
}


1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
static void udevPCITranslateDeinit(void)
{
#if defined __s390__ || defined __s390x_
    /* Nothing was initialized, nothing needs to be cleaned up */
#else
    /* pci_system_cleanup returns void */
    pci_system_cleanup();
#endif
    return;
}


1333
static int nodeStateCleanup(void)
1334
{
1335
    udevPrivate *priv = NULL;
1336 1337 1338
    struct udev_monitor *udev_monitor = NULL;
    struct udev *udev = NULL;

J
Ján Tomko 已提交
1339 1340
    if (!driver)
        return -1;
1341

J
Ján Tomko 已提交
1342
    nodeDeviceLock();
1343

1344
    virObjectUnref(driver->nodeDeviceEventState);
1345

J
Ján Tomko 已提交
1346
    priv = driver->privateData;
1347

1348 1349 1350
    if (priv) {
        if (priv->watch != -1)
            virEventRemoveHandle(priv->watch);
1351

1352
        udev_monitor = DRV_STATE_UDEV_MONITOR(driver);
1353

1354 1355 1356 1357
        if (udev_monitor != NULL) {
            udev = udev_monitor_get_udev(udev_monitor);
            udev_monitor_unref(udev_monitor);
        }
J
Ján Tomko 已提交
1358
    }
1359

J
Ján Tomko 已提交
1360 1361
    if (udev != NULL)
        udev_unref(udev);
1362

J
Ján Tomko 已提交
1363 1364 1365 1366 1367
    virNodeDeviceObjListFree(&driver->devs);
    nodeDeviceUnlock();
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
    VIR_FREE(priv);
1368

J
Ján Tomko 已提交
1369 1370
    udevPCITranslateDeinit();
    return 0;
1371 1372 1373 1374 1375 1376 1377 1378 1379
}


static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
                                    int fd,
                                    int events ATTRIBUTE_UNUSED,
                                    void *data ATTRIBUTE_UNUSED)
{
    struct udev_device *device = NULL;
1380
    struct udev_monitor *udev_monitor = DRV_STATE_UDEV_MONITOR(driver);
1381 1382 1383
    const char *action = NULL;
    int udev_fd = -1;

1384
    nodeDeviceLock();
1385 1386
    udev_fd = udev_monitor_get_fd(udev_monitor);
    if (fd != udev_fd) {
1387 1388 1389 1390
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("File descriptor returned by udev %d does not "
                         "match node device file descriptor %d"),
                       fd, udev_fd);
1391
        goto cleanup;
1392 1393 1394 1395
    }

    device = udev_monitor_receive_device(udev_monitor);
    if (device == NULL) {
1396 1397
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("udev_monitor_receive_device returned NULL"));
1398
        goto cleanup;
1399 1400 1401
    }

    action = udev_device_get_action(device);
1402
    VIR_DEBUG("udev action: '%s'", action);
1403 1404 1405

    if (STREQ(action, "add") || STREQ(action, "change")) {
        udevAddOneDevice(device);
1406
        goto cleanup;
1407 1408 1409 1410
    }

    if (STREQ(action, "remove")) {
        udevRemoveOneDevice(device);
1411
        goto cleanup;
1412 1413
    }

1414
 cleanup:
1415
    udev_device_unref(device);
1416
    nodeDeviceUnlock();
1417 1418 1419 1420
    return;
}


1421 1422
/* DMI is intel-compatible specific */
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1423
static void
1424
udevGetDMIData(virNodeDevCapDataPtr data)
1425 1426 1427 1428
{
    struct udev *udev = NULL;
    struct udev_device *device = NULL;

1429
    udev = udev_monitor_get_udev(DRV_STATE_UDEV_MONITOR(driver));
1430

1431 1432
    device = udev_device_new_from_syspath(udev, DMI_DEVPATH);
    if (device == NULL) {
1433 1434
        device = udev_device_new_from_syspath(udev, DMI_DEVPATH_FALLBACK);
        if (device == NULL) {
1435 1436 1437
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to get udev device for syspath '%s' or '%s'"),
                           DMI_DEVPATH, DMI_DEVPATH_FALLBACK);
1438
            return;
1439
        }
1440 1441
    }

1442 1443
    if (udevGetStringSysfsAttr(device, "product_name",
                               &data->system.product_name) < 0)
1444
        goto cleanup;
1445 1446
    if (udevGetStringSysfsAttr(device, "sys_vendor",
                               &data->system.hardware.vendor_name) < 0)
1447
        goto cleanup;
1448 1449
    if (udevGetStringSysfsAttr(device, "product_version",
                               &data->system.hardware.version) < 0)
1450
        goto cleanup;
1451 1452
    if (udevGetStringSysfsAttr(device, "product_serial",
                               &data->system.hardware.serial) < 0)
1453
        goto cleanup;
1454

1455
    if (virGetHostUUID(data->system.hardware.uuid))
1456
        goto cleanup;
1457

1458 1459
    if (udevGetStringSysfsAttr(device, "bios_vendor",
                               &data->system.firmware.vendor_name) < 0)
1460
        goto cleanup;
1461 1462
    if (udevGetStringSysfsAttr(device, "bios_version",
                               &data->system.firmware.version) < 0)
1463
        goto cleanup;
1464 1465
    if (udevGetStringSysfsAttr(device, "bios_date",
                               &data->system.firmware.release_date) < 0)
1466
        goto cleanup;
1467

1468
 cleanup:
1469
    if (device != NULL)
1470 1471 1472
        udev_device_unref(device);
    return;
}
1473
#endif
1474 1475 1476 1477 1478 1479 1480 1481


static int udevSetupSystemDev(void)
{
    virNodeDeviceDefPtr def = NULL;
    virNodeDeviceObjPtr dev = NULL;
    int ret = -1;

1482 1483
    if (VIR_ALLOC(def) < 0)
        return -1;
1484

1485
    if (VIR_STRDUP(def->name, "computer") < 0)
1486
        goto cleanup;
1487

1488
    if (VIR_ALLOC(def->caps) != 0)
1489
        goto cleanup;
1490

1491
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1492
    udevGetDMIData(&def->caps->data);
1493
#endif
1494

1495
    dev = virNodeDeviceObjAssignDef(&driver->devs, def);
1496
    if (dev == NULL)
1497
        goto cleanup;
1498 1499 1500 1501 1502

    virNodeDeviceObjUnlock(dev);

    ret = 0;

1503
 cleanup:
1504
    if (ret == -1)
1505 1506
        virNodeDeviceDefFree(def);

1507 1508 1509
    return ret;
}

1510
static int udevPCITranslateInit(bool privileged ATTRIBUTE_UNUSED)
1511
{
1512 1513 1514 1515
#if defined __s390__ || defined __s390x_
    /* On s390(x) system there is no PCI bus.
     * Therefore there is nothing to initialize here. */
#else
1516
    int rc;
1517

1518
    if ((rc = pci_system_init()) != 0) {
1519 1520 1521
        /* Ignore failure as non-root; udev is not as helpful in that
         * situation, but a non-privileged user won't benefit much
         * from udev in the first place.  */
1522
        if (errno != ENOENT && (privileged  || errno != EACCES)) {
1523 1524
            virReportSystemError(rc, "%s",
                                 _("Failed to initialize libpciaccess"));
1525
            return -1;
1526
        }
1527
    }
1528
#endif
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
    return 0;
}

static int nodeStateInitialize(bool privileged,
                               virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                               void *opaque ATTRIBUTE_UNUSED)
{
    udevPrivate *priv = NULL;
    struct udev *udev = NULL;
    int ret = -1;

1540
    if (VIR_ALLOC(priv) < 0)
1541
        return -1;
1542 1543

    priv->watch = -1;
1544
    priv->privileged = privileged;
1545

1546
    if (VIR_ALLOC(driver) < 0) {
1547
        VIR_FREE(priv);
1548
        return -1;
1549 1550
    }

1551
    if (virMutexInit(&driver->lock) < 0) {
1552 1553
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Unable to initialize mutex"));
1554
        VIR_FREE(priv);
1555
        VIR_FREE(driver);
1556
        return -1;
1557 1558
    }

1559
    driver->privateData = priv;
1560
    nodeDeviceLock();
1561
    driver->nodeDeviceEventState = virObjectEventStateNew();
1562

1563
    if (udevPCITranslateInit(privileged) < 0)
1564
        goto cleanup;
1565

1566
    udev = udev_new();
1567 1568 1569 1570 1571
    if (!udev) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to create udev context"));
        goto cleanup;
    }
1572
#if HAVE_UDEV_LOGGING
J
Ján Tomko 已提交
1573 1574
    /* cast to get rid of missing-format-attribute warning */
    udev_set_log_fn(udev, (udevLogFunctionPtr) udevLogFunction);
1575
#endif
1576

1577 1578
    priv->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
    if (priv->udev_monitor == NULL) {
1579 1580
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("udev_monitor_new_from_netlink returned NULL"));
1581
        goto cleanup;
1582 1583
    }

1584
    udev_monitor_enable_receiving(priv->udev_monitor);
1585 1586 1587 1588 1589 1590 1591 1592 1593

    /* We register the monitor with the event callback so we are
     * notified by udev of device changes before we enumerate existing
     * devices because libvirt will simply recreate the device if we
     * try to register it twice, i.e., if the device appears between
     * the time we register the callback and the time we begin
     * enumeration.  The alternative is to register the callback after
     * we enumerate, in which case we will fail to create any devices
     * that appear while the enumeration is taking place.  */
1594 1595 1596
    priv->watch = virEventAddHandle(udev_monitor_get_fd(priv->udev_monitor),
                                    VIR_EVENT_HANDLE_READABLE,
                                    udevEventHandleCallback, NULL, NULL);
1597
    if (priv->watch == -1)
1598
        goto cleanup;
1599 1600

    /* Create a fictional 'computer' device to root the device tree. */
1601
    if (udevSetupSystemDev() != 0)
1602
        goto cleanup;
1603 1604 1605

    /* Populate with known devices */

1606
    if (udevEnumerateDevices(udev) != 0)
1607
        goto cleanup;
1608 1609

    ret = 0;
1610

1611
 cleanup:
1612
    nodeDeviceUnlock();
1613

1614
    if (ret == -1)
1615
        nodeStateCleanup();
1616 1617 1618 1619
    return ret;
}


1620
static int nodeStateReload(void)
1621 1622 1623 1624 1625
{
    return 0;
}


1626
static virNodeDeviceDriver udevNodeDeviceDriver = {
1627
    .name = "udev",
1628 1629
    .nodeNumOfDevices = nodeNumOfDevices, /* 0.7.3 */
    .nodeListDevices = nodeListDevices, /* 0.7.3 */
1630
    .connectListAllNodeDevices = nodeConnectListAllNodeDevices, /* 0.10.2 */
1631 1632
    .connectNodeDeviceEventRegisterAny = nodeConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
    .connectNodeDeviceEventDeregisterAny = nodeConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
1633 1634 1635 1636 1637 1638 1639 1640
    .nodeDeviceLookupByName = nodeDeviceLookupByName, /* 0.7.3 */
    .nodeDeviceLookupSCSIHostByWWN = nodeDeviceLookupSCSIHostByWWN, /* 1.0.2 */
    .nodeDeviceGetXMLDesc = nodeDeviceGetXMLDesc, /* 0.7.3 */
    .nodeDeviceGetParent = nodeDeviceGetParent, /* 0.7.3 */
    .nodeDeviceNumOfCaps = nodeDeviceNumOfCaps, /* 0.7.3 */
    .nodeDeviceListCaps = nodeDeviceListCaps, /* 0.7.3 */
    .nodeDeviceCreateXML = nodeDeviceCreateXML, /* 0.7.3 */
    .nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
1641 1642 1643
};

static virStateDriver udevStateDriver = {
M
Matthias Bolte 已提交
1644
    .name = "udev",
1645 1646 1647
    .stateInitialize = nodeStateInitialize, /* 0.7.3 */
    .stateCleanup = nodeStateCleanup, /* 0.7.3 */
    .stateReload = nodeStateReload, /* 0.7.3 */
1648 1649 1650 1651
};

int udevNodeRegister(void)
{
1652
    VIR_DEBUG("Registering udev node device backend");
1653

1654
    if (virSetSharedNodeDeviceDriver(&udevNodeDeviceDriver) < 0)
1655 1656 1657 1658
        return -1;

    return virRegisterStateDriver(&udevStateDriver);
}