node_device_udev.c 54.5 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
#include "node_device_udev.h"
#include "virerror.h"
35 36
#include "driver.h"
#include "datatypes.h"
37
#include "virlog.h"
38
#include "viralloc.h"
39
#include "viruuid.h"
40
#include "virbuffer.h"
41
#include "virfile.h"
42
#include "virpci.h"
43
#include "virstring.h"
44
#include "virnetdev.h"
45
#include "virmdev.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 58 59 60
typedef struct _udevEventData udevEventData;
typedef udevEventData *udevEventDataPtr;

struct _udevEventData {
    virObjectLockable parent;

61 62
    struct udev_monitor *udev_monitor;
    int watch;
63 64 65 66 67 68

    /* Thread data */
    virThread th;
    virCond threadCond;
    bool threadQuit;
    bool dataReady;
69 70
};

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
static virClassPtr udevEventDataClass;

static void
udevEventDataDispose(void *obj)
{
    struct udev *udev = NULL;
    udevEventDataPtr priv = obj;

    if (priv->watch != -1)
        virEventRemoveHandle(priv->watch);

    if (!priv->udev_monitor)
        return;

    udev = udev_monitor_get_udev(priv->udev_monitor);
    udev_monitor_unref(priv->udev_monitor);
    udev_unref(udev);
88 89

    virCondDestroy(&priv->threadCond);
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
}


static int
udevEventDataOnceInit(void)
{
    if (!(udevEventDataClass = virClassNew(virClassForObjectLockable(),
                                           "udevEventData",
                                           sizeof(udevEventData),
                                           udevEventDataDispose)))
        return -1;

    return 0;
}

VIR_ONCE_GLOBAL_INIT(udevEventData)

static udevEventDataPtr
udevEventDataNew(void)
{
    udevEventDataPtr ret = NULL;

    if (udevEventDataInitialize() < 0)
        return NULL;

    if (!(ret = virObjectLockableNew(udevEventDataClass)))
        return NULL;

118 119 120 121 122
    if (virCondInit(&ret->threadCond) < 0) {
        virObjectUnref(ret);
        return NULL;
    }

123 124 125 126
    ret->watch = -1;
    return ret;
}

127

J
Ján Tomko 已提交
128 129 130 131 132 133 134 135 136 137 138
static bool
udevHasDeviceProperty(struct udev_device *dev,
                      const char *key)
{
    if (udev_device_get_property_value(dev, key))
        return true;

    return false;
}


139 140 141
static const char *
udevGetDeviceProperty(struct udev_device *udev_device,
                      const char *property_key)
142
{
143
    const char *ret = NULL;
144

145
    ret = udev_device_get_property_value(udev_device, property_key);
146

147 148
    VIR_DEBUG("Found property key '%s' value '%s' for device with sysname '%s'",
              property_key, NULLSTR(ret), udev_device_get_sysname(udev_device));
149 150 151 152 153

    return ret;
}


154 155 156 157
static int
udevGetStringProperty(struct udev_device *udev_device,
                      const char *property_key,
                      char **value)
158
{
159 160
    if (VIR_STRDUP(*value,
                   udevGetDeviceProperty(udev_device, property_key)) < 0)
161
        return -1;
162

163
    return 0;
164 165 166
}


167 168 169 170 171
static int
udevGetIntProperty(struct udev_device *udev_device,
                   const char *property_key,
                   int *value,
                   int base)
172
{
173
    const char *str = NULL;
174

175
    str = udevGetDeviceProperty(udev_device, property_key);
176

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


186 187 188 189 190
static int
udevGetUintProperty(struct udev_device *udev_device,
                    const char *property_key,
                    unsigned int *value,
                    int base)
191
{
192
    const char *str = NULL;
193

194
    str = udevGetDeviceProperty(udev_device, property_key);
195

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


205 206 207
static const char *
udevGetDeviceSysfsAttr(struct udev_device *udev_device,
                       const char *attr_name)
208
{
209
    const char *ret = NULL;
210

211
    ret = udev_device_get_sysattr_value(udev_device, attr_name);
212 213

    VIR_DEBUG("Found sysfs attribute '%s' value '%s' "
214
              "for device with sysname '%s'",
215
              attr_name, NULLSTR(ret),
216 217 218 219 220
              udev_device_get_sysname(udev_device));
    return ret;
}


221 222 223 224
static int
udevGetStringSysfsAttr(struct udev_device *udev_device,
                       const char *attr_name,
                       char **value)
225
{
226
    if (VIR_STRDUP(*value, udevGetDeviceSysfsAttr(udev_device, attr_name)) < 0)
227
        return -1;
228

229
    virStringStripControlChars(*value);
230

231 232
    if (*value != NULL && (STREQ(*value, "")))
        VIR_FREE(*value);
233

234
    return 0;
235 236 237
}


238 239 240 241 242
static int
udevGetIntSysfsAttr(struct udev_device *udev_device,
                    const char *attr_name,
                    int *value,
                    int base)
243
{
244
    const char *str = NULL;
245

246
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
247

248
    if (str && virStrToLong_i(str, NULL, base, value) < 0) {
249 250
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to int"), str);
251
        return -1;
252 253
    }

254
    return 0;
255 256 257
}


258 259 260 261 262
static int
udevGetUintSysfsAttr(struct udev_device *udev_device,
                     const char *attr_name,
                     unsigned int *value,
                     int base)
263
{
264
    const char *str = NULL;
265

266
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
267

268
    if (str && virStrToLong_ui(str, NULL, base, value) < 0) {
269 270
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to unsigned int"), str);
271
        return -1;
272 273
    }

274
    return 0;
275 276 277
}


278 279 280 281
static int
udevGetUint64SysfsAttr(struct udev_device *udev_device,
                       const char *attr_name,
                       unsigned long long *value)
282
{
283
    const char *str = NULL;
284

285
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
286

287
    if (str && virStrToLong_ull(str, NULL, 0, value) < 0) {
288 289
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to convert '%s' to unsigned long long"), str);
J
Ján Tomko 已提交
290
        return -1;
291 292
    }

J
Ján Tomko 已提交
293
    return 0;
294 295 296
}


297 298 299 300
static int
udevGenerateDeviceName(struct udev_device *device,
                       virNodeDeviceDefPtr def,
                       const char *s)
301
{
302
    size_t i;
303 304
    virBuffer buf = VIR_BUFFER_INITIALIZER;

305
    virBufferAsprintf(&buf, "%s_%s",
306 307 308
                      udev_device_get_subsystem(device),
                      udev_device_get_sysname(device));

309
    if (s != NULL)
310
        virBufferAsprintf(&buf, "_%s", s);
311

312 313
    if (virBufferCheckError(&buf) < 0)
        return -1;
314 315 316

    def->name = virBufferContentAndReset(&buf);

317
    for (i = 0; i < strlen(def->name); i++) {
318
        if (!(c_isalnum(*(def->name + i))))
319 320 321
            *(def->name + i) = '_';
    }

322
    return 0;
323 324
}

325

326
#if HAVE_UDEV_LOGGING
327 328 329 330 331 332 333 334
typedef void
(*udevLogFunctionPtr)(struct udev *udev,
                      int priority,
                      const char *file,
                      int line,
                      const char *fn,
                      const char *format,
                      va_list args);
J
Ján Tomko 已提交
335 336

static void
337
ATTRIBUTE_FMT_PRINTF(6, 0)
J
Ján Tomko 已提交
338 339 340 341 342 343 344
udevLogFunction(struct udev *udev ATTRIBUTE_UNUSED,
                int priority,
                const char *file,
                int line,
                const char *fn,
                const char *fmt,
                va_list args)
345
{
J
Ján Tomko 已提交
346
    virBuffer buf = VIR_BUFFER_INITIALIZER;
347
    char *format = NULL;
J
Ján Tomko 已提交
348 349 350 351 352 353

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

    format = virBufferContentAndReset(&buf);

354
    virLogVMessage(&virLogSelf,
J
Ján Tomko 已提交
355 356 357 358
                   virLogPriorityFromSyslog(priority),
                   file, line, fn, NULL, format ? format : fmt, args);

    VIR_FREE(format);
359
}
360
#endif
361 362


363 364 365 366 367
static int
udevTranslatePCIIds(unsigned int vendor,
                    unsigned int product,
                    char **vendor_string,
                    char **product_string)
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
{
    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,
383
                    &vendor_name,
384 385 386
                    NULL,
                    NULL);

387
    if (VIR_STRDUP(*vendor_string, vendor_name) < 0 ||
388
        VIR_STRDUP(*product_string, device_name) < 0)
389
        return -1;
390

391
    return 0;
392 393 394
}


395 396 397
static int
udevProcessPCI(struct udev_device *device,
               virNodeDeviceDefPtr def)
398
{
399
    virNodeDevCapPCIDevPtr pci_dev = &def->caps->data.pci_dev;
400 401
    virPCIEDeviceInfoPtr pci_express = NULL;
    virPCIDevicePtr pciDev = NULL;
402
    int ret = -1;
403
    char *p;
404 405 406 407 408
    bool privileged;

    nodeDeviceLock();
    privileged = driver->privileged;
    nodeDeviceUnlock();
409

410
    if (udevGetUintProperty(device, "PCI_CLASS", &pci_dev->class, 16) < 0)
411
        goto cleanup;
412

413
    if ((p = strrchr(def->sysfs_path, '/')) == NULL ||
414 415 416 417
        virStrToLong_ui(p + 1, &p, 16, &pci_dev->domain) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &pci_dev->bus) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &pci_dev->slot) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &pci_dev->function) < 0) {
418 419
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the PCI address from sysfs path: '%s'"),
420
                       def->sysfs_path);
421
        goto cleanup;
422 423
    }

424
    if (udevGetUintSysfsAttr(device, "vendor", &pci_dev->vendor, 16) < 0)
425
        goto cleanup;
426

427
    if (udevGetUintSysfsAttr(device, "device", &pci_dev->product, 16) < 0)
428
        goto cleanup;
429

430 431 432 433
    if (udevTranslatePCIIds(pci_dev->vendor,
                            pci_dev->product,
                            &pci_dev->vendor_name,
                            &pci_dev->product_name) != 0) {
434
        goto cleanup;
435
    }
436

437
    if (udevGenerateDeviceName(device, def, NULL) != 0)
438
        goto cleanup;
439

440 441
    /* The default value is -1, because it can't be 0
     * as zero is valid node number. */
442
    pci_dev->numa_node = -1;
443
    if (udevGetIntSysfsAttr(device, "numa_node",
444
                            &pci_dev->numa_node, 10) < 0)
445
        goto cleanup;
446

447
    if (virNodeDeviceGetPCIDynamicCaps(def->sysfs_path, pci_dev) < 0)
448
        goto cleanup;
449

450 451 452 453
    if (!(pciDev = virPCIDeviceNew(pci_dev->domain,
                                   pci_dev->bus,
                                   pci_dev->slot,
                                   pci_dev->function)))
454
        goto cleanup;
455

456
    /* We need to be root to read PCI device configs */
457
    if (privileged) {
458
        if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType) < 0)
459
            goto cleanup;
460

461 462
        if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
            if (VIR_ALLOC(pci_express) < 0)
463
                goto cleanup;
464

465 466 467
            if (virPCIDeviceHasPCIExpressLink(pciDev) > 0) {
                if (VIR_ALLOC(pci_express->link_cap) < 0 ||
                    VIR_ALLOC(pci_express->link_sta) < 0)
468
                    goto cleanup;
469 470 471 472 473 474 475

                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)
476
                    goto cleanup;
477 478 479

                pci_express->link_sta->port = -1; /* PCIe can't negotiate port. Yet :) */
            }
480 481
            pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCIE;
            pci_dev->pci_express = pci_express;
482
            pci_express = NULL;
483 484 485
        }
    }

486 487
    ret = 0;

488
 cleanup:
489
    virPCIDeviceFree(pciDev);
490
    virPCIEDeviceInfoFree(pci_express);
491 492 493
    return ret;
}

494 495 496

static int
drmGetMinorType(int minor)
M
Marc-André Lureau 已提交
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
{
    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;
    }
}

513 514 515 516

static int
udevProcessDRMDevice(struct udev_device *device,
                     virNodeDeviceDefPtr def)
M
Marc-André Lureau 已提交
517
{
518
    virNodeDevCapDRMPtr drm = &def->caps->data.drm;
M
Marc-André Lureau 已提交
519 520 521 522 523 524 525 526 527 528 529
    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;

530
    drm->type = minor;
M
Marc-André Lureau 已提交
531 532 533

    return 0;
}
534

535 536 537 538

static int
udevProcessUSBDevice(struct udev_device *device,
                     virNodeDeviceDefPtr def)
539
{
540
    virNodeDevCapUSBDevPtr usb_dev = &def->caps->data.usb_dev;
541

542
    if (udevGetUintProperty(device, "BUSNUM", &usb_dev->bus, 10) < 0)
543
        return -1;
544
    if (udevGetUintProperty(device, "DEVNUM", &usb_dev->device, 10) < 0)
545
        return -1;
546
    if (udevGetUintProperty(device, "ID_VENDOR_ID", &usb_dev->vendor, 16) < 0)
547
        return -1;
548

549 550
    if (udevGetStringProperty(device,
                              "ID_VENDOR_FROM_DATABASE",
551
                              &usb_dev->vendor_name) < 0)
552
        return -1;
553

554
    if (!usb_dev->vendor_name &&
555
        udevGetStringSysfsAttr(device, "manufacturer",
556
                               &usb_dev->vendor_name) < 0)
557
        return -1;
558

559
    if (udevGetUintProperty(device, "ID_MODEL_ID", &usb_dev->product, 16) < 0)
560
        return -1;
561

562 563
    if (udevGetStringProperty(device,
                              "ID_MODEL_FROM_DATABASE",
564
                              &usb_dev->product_name) < 0)
565
        return -1;
566

567
    if (!usb_dev->product_name &&
568
        udevGetStringSysfsAttr(device, "product",
569
                               &usb_dev->product_name) < 0)
570
        return -1;
571

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

575
    return 0;
576 577 578
}


579 580 581
static int
udevProcessUSBInterface(struct udev_device *device,
                        virNodeDeviceDefPtr def)
582
{
583
    virNodeDevCapUSBIfPtr usb_if = &def->caps->data.usb_if;
584

585
    if (udevGetUintSysfsAttr(device, "bInterfaceNumber",
586
                             &usb_if->number, 16) < 0)
587
        return -1;
588

589
    if (udevGetUintSysfsAttr(device, "bInterfaceClass",
590
                             &usb_if->_class, 16) < 0)
591
        return -1;
592

593
    if (udevGetUintSysfsAttr(device, "bInterfaceSubClass",
594
                             &usb_if->subclass, 16) < 0)
595
        return -1;
596

597
    if (udevGetUintSysfsAttr(device, "bInterfaceProtocol",
598
                             &usb_if->protocol, 16) < 0)
599
        return -1;
600

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

604
    return 0;
605 606 607
}


608 609 610
static int
udevProcessNetworkInterface(struct udev_device *device,
                            virNodeDeviceDefPtr def)
611
{
D
David Allan 已提交
612
    const char *devtype = udev_device_get_devtype(device);
613
    virNodeDevCapNetPtr net = &def->caps->data.net;
614

D
David Allan 已提交
615
    if (devtype && STREQ(devtype, "wlan")) {
616
        net->subtype = VIR_NODE_DEV_CAP_NET_80211;
D
David Allan 已提交
617
    } else {
618
        net->subtype = VIR_NODE_DEV_CAP_NET_80203;
D
David Allan 已提交
619 620
    }

621 622
    if (udevGetStringProperty(device,
                              "INTERFACE",
623
                              &net->ifname) < 0)
624
        return -1;
625

626
    if (udevGetStringSysfsAttr(device, "address",
627
                               &net->address) < 0)
628
        return -1;
629

630
    if (udevGetUintSysfsAttr(device, "addr_len", &net->address_len, 0) < 0)
631
        return -1;
632

633
    if (udevGenerateDeviceName(device, def, net->address) != 0)
634
        return -1;
635

636
    if (virNetDevGetLinkInfo(net->ifname, &net->lnk) < 0)
637
        return -1;
638

639
    if (virNetDevGetFeatures(net->ifname, &net->features) < 0)
640
        return -1;
641

642
    return 0;
643 644 645
}


646 647 648
static int
udevProcessSCSIHost(struct udev_device *device ATTRIBUTE_UNUSED,
                    virNodeDeviceDefPtr def)
649
{
650
    virNodeDevCapSCSIHostPtr scsi_host = &def->caps->data.scsi_host;
651
    char *filename = NULL;
J
Ján Tomko 已提交
652
    char *str;
653

654
    filename = last_component(def->sysfs_path);
655

656
    if (!(str = STRSKIP(filename, "host")) ||
657
        virStrToLong_ui(str, NULL, 0, &scsi_host->host) < 0) {
658 659 660
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse SCSI host '%s'"),
                       filename);
661
        return -1;
662 663
    }

664
    virNodeDeviceGetSCSIHostCaps(&def->caps->data.scsi_host);
665

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

669
    return 0;
670 671 672
}


673 674 675
static int
udevProcessSCSITarget(struct udev_device *device,
                      virNodeDeviceDefPtr def)
D
David Allan 已提交
676 677
{
    const char *sysname = NULL;
678
    virNodeDevCapSCSITargetPtr scsi_target = &def->caps->data.scsi_target;
D
David Allan 已提交
679 680 681

    sysname = udev_device_get_sysname(device);

682
    if (VIR_STRDUP(scsi_target->name, sysname) < 0)
683
        return -1;
D
David Allan 已提交
684

685
    virNodeDeviceGetSCSITargetCaps(def->sysfs_path, &def->caps->data.scsi_target);
686

687
    if (udevGenerateDeviceName(device, def, NULL) != 0)
688
        return -1;
D
David Allan 已提交
689

690
    return 0;
D
David Allan 已提交
691 692 693
}


694 695 696 697
static int
udevGetSCSIType(virNodeDeviceDefPtr def ATTRIBUTE_UNUSED,
                unsigned int type,
                char **typestring)
698 699 700 701 702 703 704 705
{
    int ret = 0;
    int foundtype = 1;

    *typestring = NULL;

    switch (type) {
    case TYPE_DISK:
706
        ignore_value(VIR_STRDUP(*typestring, "disk"));
707 708
        break;
    case TYPE_TAPE:
709
        ignore_value(VIR_STRDUP(*typestring, "tape"));
710 711
        break;
    case TYPE_PROCESSOR:
712
        ignore_value(VIR_STRDUP(*typestring, "processor"));
713 714
        break;
    case TYPE_WORM:
715
        ignore_value(VIR_STRDUP(*typestring, "worm"));
716 717
        break;
    case TYPE_ROM:
718
        ignore_value(VIR_STRDUP(*typestring, "cdrom"));
719 720
        break;
    case TYPE_SCANNER:
721
        ignore_value(VIR_STRDUP(*typestring, "scanner"));
722 723
        break;
    case TYPE_MOD:
724
        ignore_value(VIR_STRDUP(*typestring, "mod"));
725 726
        break;
    case TYPE_MEDIUM_CHANGER:
727
        ignore_value(VIR_STRDUP(*typestring, "changer"));
728 729
        break;
    case TYPE_ENCLOSURE:
730
        ignore_value(VIR_STRDUP(*typestring, "enclosure"));
731
        break;
732
    case TYPE_RAID:
733
        ignore_value(VIR_STRDUP(*typestring, "raid"));
734
        break;
735 736 737 738 739 740 741 742 743 744
    case TYPE_NO_LUN:
    default:
        foundtype = 0;
        break;
    }

    if (*typestring == NULL) {
        if (foundtype == 1) {
            ret = -1;
        } else {
745 746
            VIR_DEBUG("Failed to find SCSI device type %d for %s",
                      type, def->sysfs_path);
747 748 749 750 751 752 753
        }
    }

    return ret;
}


754 755 756
static int
udevProcessSCSIDevice(struct udev_device *device ATTRIBUTE_UNUSED,
                      virNodeDeviceDefPtr def)
757 758 759
{
    int ret = -1;
    unsigned int tmp = 0;
760
    virNodeDevCapSCSIPtr scsi = &def->caps->data.scsi;
761 762
    char *filename = NULL, *p = NULL;

763
    filename = last_component(def->sysfs_path);
764

765 766 767 768
    if (virStrToLong_ui(filename, &p, 10, &scsi->host) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &scsi->bus) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &scsi->target) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 10, &scsi->lun) < 0) {
769 770 771 772
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the SCSI address from filename: '%s'"),
                       filename);
        return -1;
773 774
    }

775 776
    if (udev_device_get_sysattr_value(device, "type")) {
        if (udevGetUintSysfsAttr(device, "type", &tmp, 0) < 0)
777
            goto cleanup;
778

779
        if (udevGetSCSIType(def, tmp, &scsi->type) < 0)
780
            goto cleanup;
781 782
    }

783
    if (udevGenerateDeviceName(device, def, NULL) != 0)
784
        goto cleanup;
785 786 787

    ret = 0;

788
 cleanup:
789
    if (ret != 0) {
790 791 792
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to process SCSI device with sysfs path '%s'"),
                       def->sysfs_path);
793 794 795 796 797
    }
    return ret;
}


798 799 800
static int
udevProcessDisk(struct udev_device *device,
                virNodeDeviceDefPtr def)
801
{
802
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
803

804
    if (udevGetUint64SysfsAttr(device, "size", &storage->num_blocks) < 0)
805
        return -1;
806

J
Ján Tomko 已提交
807
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
808
                               &storage->logical_block_size) < 0)
809
        return -1;
810

811
    storage->size = storage->num_blocks * storage->logical_block_size;
812

813
    return 0;
814 815 816
}


817 818 819 820
static int
udevProcessRemoveableMedia(struct udev_device *device,
                           virNodeDeviceDefPtr def,
                           int has_media)
821
{
822
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
J
Ján Tomko 已提交
823
    int is_removable = 0;
824

825 826 827
    if (udevGetIntSysfsAttr(device, "removable", &is_removable, 0) < 0)
        return -1;
    if (is_removable == 1)
828 829
        def->caps->data.storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;

J
Ján Tomko 已提交
830 831
    if (!has_media)
        return 0;
832

J
Ján Tomko 已提交
833 834
    def->caps->data.storage.flags |=
        VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
835

J
Ján Tomko 已提交
836
    if (udevGetStringProperty(device, "ID_FS_LABEL",
837
                              &storage->media_label) < 0)
J
Ján Tomko 已提交
838
        return -1;
839

J
Ján Tomko 已提交
840
    if (udevGetUint64SysfsAttr(device, "size",
841
                               &storage->num_blocks) < 0)
J
Ján Tomko 已提交
842
        return -1;
843

J
Ján Tomko 已提交
844
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
845
                               &storage->logical_block_size) < 0)
J
Ján Tomko 已提交
846
        return -1;
847

J
Ján Tomko 已提交
848 849 850 851 852 853 854
    /* 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;
855

J
Ján Tomko 已提交
856
    return 0;
857 858
}

859 860 861 862

static int
udevProcessCDROM(struct udev_device *device,
                 virNodeDeviceDefPtr def)
863 864 865 866 867 868 869 870
{
    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);
871
    if (VIR_STRDUP(def->caps->data.storage.drive_type, "cdrom") < 0)
872
        return -1;
873

874 875
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA") &&
        udevGetIntProperty(device, "ID_CDROM_MEDIA", &has_media, 0) < 0)
876
        return -1;
877

878
    return udevProcessRemoveableMedia(device, def, has_media);
879 880
}

881 882 883 884

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

888
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA")) {
889
        /* USB floppy */
890 891
        if (udevGetIntProperty(device, "DKD_MEDIA_AVAILABLE", &has_media, 0) < 0)
            return -1;
892
    } else if (udevHasDeviceProperty(device, "ID_FS_LABEL")) {
893 894 895 896 897 898
        /* Legacy floppy */
        has_media = 1;
    }

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

900

901 902 903
static int
udevProcessSD(struct udev_device *device,
              virNodeDeviceDefPtr def)
904
{
905
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
906

J
Ján Tomko 已提交
907
    if (udevGetUint64SysfsAttr(device, "size",
908
                               &storage->num_blocks) < 0)
909
        return -1;
910

J
Ján Tomko 已提交
911
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
912
                               &storage->logical_block_size) < 0)
913
        return -1;
914

915
    storage->size = storage->num_blocks * storage->logical_block_size;
916

917
    return 0;
918 919 920
}


921 922 923 924
/* 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. */
925 926
static int
udevKludgeStorageType(virNodeDeviceDefPtr def)
927
{
928 929 930
    VIR_DEBUG("Could not find definitive storage type for device "
              "with sysfs path '%s', trying to guess it",
              def->sysfs_path);
931

932 933 934
    /* virtio disk */
    if (STRPREFIX(def->caps->data.storage.block, "/dev/vd") &&
        VIR_STRDUP(def->caps->data.storage.drive_type, "disk") > 0) {
935
        VIR_DEBUG("Found storage type '%s' for device "
936
                  "with sysfs path '%s'",
937 938
                  def->caps->data.storage.drive_type,
                  def->sysfs_path);
939
        return 0;
940
    }
941 942 943
    VIR_DEBUG("Could not determine storage type "
              "for device with sysfs path '%s'", def->sysfs_path);
    return -1;
944 945 946
}


947 948 949
static int
udevProcessStorage(struct udev_device *device,
                   virNodeDeviceDefPtr def)
950
{
951
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
952
    int ret = -1;
953
    const char* devnode;
954

955
    devnode = udev_device_get_devnode(device);
956
    if (!devnode) {
957
        VIR_DEBUG("No devnode for '%s'", udev_device_get_devpath(device));
958
        goto cleanup;
959
    }
960

961
    if (VIR_STRDUP(storage->block, devnode) < 0)
962
        goto cleanup;
963

964
    if (udevGetStringProperty(device, "ID_BUS", &storage->bus) < 0)
965
        goto cleanup;
966
    if (udevGetStringProperty(device, "ID_SERIAL", &storage->serial) < 0)
967
        goto cleanup;
968

969
    if (udevGetStringSysfsAttr(device, "device/vendor", &storage->vendor) < 0)
970
        goto cleanup;
971 972 973
    if (def->caps->data.storage.vendor)
        virTrimSpaces(def->caps->data.storage.vendor, NULL);

974
    if (udevGetStringSysfsAttr(device, "device/model", &storage->model) < 0)
975
        goto cleanup;
976 977
    if (def->caps->data.storage.model)
        virTrimSpaces(def->caps->data.storage.model, NULL);
978 979 980 981 982
    /* 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. */

983
    if (udevGetStringProperty(device, "ID_TYPE", &storage->drive_type) < 0)
984
        goto cleanup;
985

986
    if (!storage->drive_type ||
987
        STREQ(def->caps->data.storage.drive_type, "generic")) {
988 989
        int val = 0;
        const char *str = NULL;
990 991 992

        /* All floppy drives have the ID_DRIVE_FLOPPY prop. This is
         * needed since legacy floppies don't have a drive_type */
993
        if (udevGetIntProperty(device, "ID_DRIVE_FLOPPY", &val, 0) < 0)
994
            goto cleanup;
995 996
        else if (val == 1)
            str = "floppy";
997

998
        if (!str) {
999
            if (udevGetIntProperty(device, "ID_CDROM", &val, 0) < 0)
1000
                goto cleanup;
1001 1002 1003
            else if (val == 1)
                str = "cd";
        }
1004

1005
        if (!str) {
1006
            if (udevGetIntProperty(device, "ID_DRIVE_FLASH_SD", &val, 0) < 0)
1007
                goto cleanup;
1008 1009 1010
            if (val == 1)
                str = "sd";
        }
1011

1012
        if (str) {
1013
            if (VIR_STRDUP(storage->drive_type, str) < 0)
1014
                goto cleanup;
1015 1016
        } else {
            /* If udev doesn't have it, perhaps we can guess it. */
1017
            if (udevKludgeStorageType(def) != 0)
1018
                goto cleanup;
1019 1020 1021 1022 1023 1024 1025
        }
    }

    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);
1026 1027
    } else if (STREQ(def->caps->data.storage.drive_type, "floppy")) {
        ret = udevProcessFloppy(device, def);
1028 1029
    } else if (STREQ(def->caps->data.storage.drive_type, "sd")) {
        ret = udevProcessSD(device, def);
1030
    } else {
1031 1032
        VIR_DEBUG("Unsupported storage type '%s'",
                  def->caps->data.storage.drive_type);
1033
        goto cleanup;
1034 1035
    }

1036
    if (udevGenerateDeviceName(device, def, storage->serial) != 0)
1037
        goto cleanup;
1038

1039
 cleanup:
1040
    VIR_DEBUG("Storage ret=%d", ret);
1041 1042 1043
    return ret;
}

1044

1045
static int
1046
udevProcessSCSIGeneric(struct udev_device *dev,
1047 1048
                       virNodeDeviceDefPtr def)
{
1049 1050
    if (udevGetStringProperty(dev, "DEVNAME", &def->caps->data.sg.path) < 0 ||
        !def->caps->data.sg.path)
1051 1052 1053 1054 1055 1056 1057 1058
        return -1;

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

    return 0;
}

1059

1060 1061 1062 1063 1064 1065 1066 1067
static int
udevProcessMediatedDevice(struct udev_device *dev,
                          virNodeDeviceDefPtr def)
{
    int ret = -1;
    const char *uuidstr = NULL;
    int iommugrp = -1;
    char *linkpath = NULL;
1068
    char *canonicalpath = NULL;
1069 1070
    virNodeDevCapMdevPtr data = &def->caps->data.mdev;

1071 1072 1073 1074 1075 1076 1077 1078
    /* Because of a kernel uevent race, we might get the 'add' event prior to
     * the sysfs tree being ready, so any attempt to access any sysfs attribute
     * would result in ENOENT and us dropping the device, so let's work around
     * it by waiting for the attributes to become available.
     */

    if (virAsprintf(&linkpath, "%s/mdev_type",
                    udev_device_get_syspath(dev)) < 0)
1079 1080
        goto cleanup;

1081 1082 1083 1084 1085 1086 1087
    if (virFileWaitForExists(linkpath, 1, 100) < 0) {
        virReportSystemError(errno,
                             _("failed to wait for file '%s' to appear"),
                             linkpath);
        goto cleanup;
    }

1088 1089
    if (virFileResolveLink(linkpath, &canonicalpath) < 0) {
        virReportSystemError(errno, _("failed to resolve '%s'"), linkpath);
1090
        goto cleanup;
1091
    }
1092

1093
    if (VIR_STRDUP(data->type, last_component(canonicalpath)) < 0)
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
        goto cleanup;

    uuidstr = udev_device_get_sysname(dev);
    if ((iommugrp = virMediatedDeviceGetIOMMUGroupNum(uuidstr)) < 0)
        goto cleanup;

    if (udevGenerateDeviceName(dev, def, NULL) != 0)
        goto cleanup;

    data->iommuGroupNumber = iommugrp;

    ret = 0;
 cleanup:
    VIR_FREE(linkpath);
1108
    VIR_FREE(canonicalpath);
1109 1110 1111
    return ret;
}

B
Bjoern Walk 已提交
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141

static int
udevProcessCCW(struct udev_device *device,
               virNodeDeviceDefPtr def)
{
    int online;
    char *p;
    virNodeDevCapDataPtr data = &def->caps->data;

    /* process only online devices to keep the list sane */
    if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1)
        return -1;

    if ((p = strrchr(def->sysfs_path, '/')) == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.cssid) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.ssid) < 0 || p == NULL ||
        virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.devno) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the CCW address from sysfs path: '%s'"),
                       def->sysfs_path);
        return -1;
    }

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

    return 0;
}


1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
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;
}

1170

1171 1172
static int
udevGetDeviceType(struct udev_device *device,
1173
                  virNodeDevCapType *type)
1174 1175
{
    const char *devtype = NULL;
1176
    char *subsystem = NULL;
1177
    int ret = -1;
D
David Allan 已提交
1178

1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
    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 已提交
1197 1198
        else if (STREQ(devtype, "drm_minor"))
            *type = VIR_NODE_DEV_CAP_DRM;
1199 1200
    } else {
        /* PCI devices don't set the DEVTYPE property. */
1201
        if (udevHasDeviceProperty(device, "PCI_CLASS"))
1202
            *type = VIR_NODE_DEV_CAP_PCI_DEV;
1203

1204 1205 1206 1207
        /* 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. */
1208
        if (udevHasDeviceProperty(device, "INTERFACE"))
1209
            *type = VIR_NODE_DEV_CAP_NET;
1210

B
Bjoern Walk 已提交
1211 1212
        /* The following devices do not set the DEVTYPE property, therefore
         * we need to rely on the SUBSYSTEM property */
1213 1214 1215 1216
        if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) < 0)
            return -1;

        if (STREQ_NULLABLE(subsystem, "scsi_generic"))
1217
            *type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
1218 1219
        else if (STREQ_NULLABLE(subsystem, "mdev"))
            *type = VIR_NODE_DEV_CAP_MDEV;
B
Bjoern Walk 已提交
1220 1221
        else if (STREQ_NULLABLE(subsystem, "ccw"))
            *type = VIR_NODE_DEV_CAP_CCW_DEV;
1222

1223
        VIR_FREE(subsystem);
1224 1225
    }

1226 1227 1228 1229 1230 1231
    if (!*type)
        VIR_DEBUG("Could not determine device type for device "
                  "with sysfs name '%s'",
                  udev_device_get_sysname(device));
    else
        ret = 0;
1232 1233 1234 1235 1236

    return ret;
}


1237 1238 1239
static int
udevGetDeviceDetails(struct udev_device *device,
                     virNodeDeviceDefPtr def)
1240
{
1241
    switch (def->caps->data.type) {
1242
    case VIR_NODE_DEV_CAP_PCI_DEV:
1243
        return udevProcessPCI(device, def);
1244
    case VIR_NODE_DEV_CAP_USB_DEV:
1245
        return udevProcessUSBDevice(device, def);
1246
    case VIR_NODE_DEV_CAP_USB_INTERFACE:
1247
        return udevProcessUSBInterface(device, def);
1248
    case VIR_NODE_DEV_CAP_NET:
1249
        return udevProcessNetworkInterface(device, def);
1250
    case VIR_NODE_DEV_CAP_SCSI_HOST:
1251
        return udevProcessSCSIHost(device, def);
D
David Allan 已提交
1252
    case VIR_NODE_DEV_CAP_SCSI_TARGET:
1253
        return udevProcessSCSITarget(device, def);
1254
    case VIR_NODE_DEV_CAP_SCSI:
1255
        return udevProcessSCSIDevice(device, def);
1256
    case VIR_NODE_DEV_CAP_STORAGE:
1257
        return udevProcessStorage(device, def);
1258
    case VIR_NODE_DEV_CAP_SCSI_GENERIC:
1259
        return udevProcessSCSIGeneric(device, def);
M
Marc-André Lureau 已提交
1260
    case VIR_NODE_DEV_CAP_DRM:
1261
        return udevProcessDRMDevice(device, def);
1262
    case VIR_NODE_DEV_CAP_MDEV:
1263
        return udevProcessMediatedDevice(device, def);
B
Bjoern Walk 已提交
1264 1265
    case VIR_NODE_DEV_CAP_CCW_DEV:
        return udevProcessCCW(device, def);
1266
    case VIR_NODE_DEV_CAP_MDEV_TYPES:
1267 1268 1269 1270
    case VIR_NODE_DEV_CAP_SYSTEM:
    case VIR_NODE_DEV_CAP_FC_HOST:
    case VIR_NODE_DEV_CAP_VPORTS:
    case VIR_NODE_DEV_CAP_LAST:
1271 1272 1273
        break;
    }

1274
    return 0;
1275 1276 1277
}


1278 1279
static int
udevRemoveOneDevice(struct udev_device *device)
1280
{
1281
    virNodeDeviceObjPtr obj = NULL;
1282
    virNodeDeviceDefPtr def;
1283
    virObjectEventPtr event = NULL;
1284 1285 1286
    const char *name = NULL;

    name = udev_device_get_syspath(device);
1287
    if (!(obj = virNodeDeviceObjListFindBySysfsPath(driver->devs, name))) {
1288 1289
        VIR_DEBUG("Failed to find device to remove that has udev name '%s'",
                  name);
1290
        return -1;
1291
    }
1292
    def = virNodeDeviceObjGetDef(obj);
1293

1294
    event = virNodeDeviceEventLifecycleNew(def->name,
1295 1296 1297 1298
                                           VIR_NODE_DEVICE_EVENT_DELETED,
                                           0);

    VIR_DEBUG("Removing device '%s' with sysfs path '%s'",
1299
              def->name, name);
1300
    virNodeDeviceObjListRemove(driver->devs, obj);
1301
    virObjectUnref(obj);
1302 1303 1304

    if (event)
        virObjectEventStateQueue(driver->nodeDeviceEventState, event);
1305
    return 0;
1306 1307 1308
}


1309 1310 1311
static int
udevSetParent(struct udev_device *device,
              virNodeDeviceDefPtr def)
1312 1313 1314
{
    struct udev_device *parent_device = NULL;
    const char *parent_sysfs_path = NULL;
1315
    virNodeDeviceObjPtr obj = NULL;
1316
    virNodeDeviceDefPtr objdef;
1317 1318
    int ret = -1;

1319 1320
    parent_device = device;
    do {
1321

1322
        parent_device = udev_device_get_parent(parent_device);
1323
        if (parent_device == NULL)
1324
            break;
1325

1326 1327
        parent_sysfs_path = udev_device_get_syspath(parent_device);
        if (parent_sysfs_path == NULL) {
1328 1329 1330
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Could not get syspath for parent of '%s'"),
                           udev_device_get_syspath(parent_device));
1331
            goto cleanup;
1332 1333
        }

1334 1335
        if ((obj = virNodeDeviceObjListFindBySysfsPath(driver->devs,
                                                       parent_sysfs_path))) {
1336
            objdef = virNodeDeviceObjGetDef(obj);
1337
            if (VIR_STRDUP(def->parent, objdef->name) < 0) {
1338
                virNodeDeviceObjEndAPI(&obj);
1339
                goto cleanup;
1340
            }
1341
            virNodeDeviceObjEndAPI(&obj);
1342

1343
            if (VIR_STRDUP(def->parent_sysfs_path, parent_sysfs_path) < 0)
1344
                goto cleanup;
1345 1346 1347 1348
        }

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

1349
    if (!def->parent && VIR_STRDUP(def->parent, "computer") < 0)
1350
        goto cleanup;
1351 1352 1353

    ret = 0;

1354
 cleanup:
1355 1356 1357 1358
    return ret;
}


1359 1360
static int
udevAddOneDevice(struct udev_device *device)
1361 1362
{
    virNodeDeviceDefPtr def = NULL;
1363
    virNodeDeviceObjPtr obj = NULL;
1364
    virNodeDeviceDefPtr objdef;
1365 1366
    virObjectEventPtr event = NULL;
    bool new_device = true;
1367 1368
    int ret = -1;

1369
    if (VIR_ALLOC(def) != 0)
1370
        goto cleanup;
1371

1372
    if (VIR_STRDUP(def->sysfs_path, udev_device_get_syspath(device)) < 0)
1373
        goto cleanup;
1374

1375
    if (udevGetStringProperty(device, "DRIVER", &def->driver) < 0)
1376
        goto cleanup;
1377

1378
    if (VIR_ALLOC(def->caps) != 0)
1379
        goto cleanup;
1380

1381
    if (udevGetDeviceType(device, &def->caps->data.type) != 0)
1382
        goto cleanup;
1383

1384 1385 1386
    if (udevGetDeviceNodes(device, def) != 0)
        goto cleanup;

1387
    if (udevGetDeviceDetails(device, def) != 0)
1388
        goto cleanup;
1389

1390
    if (udevSetParent(device, def) != 0)
1391
        goto cleanup;
1392

1393
    if ((obj = virNodeDeviceObjListFindByName(driver->devs, def->name))) {
1394
        virNodeDeviceObjEndAPI(&obj);
1395 1396 1397
        new_device = false;
    }

1398 1399
    /* If this is a device change, the old definition will be freed
     * and the current definition will take its place. */
1400
    if (!(obj = virNodeDeviceObjListAssignDef(driver->devs, def)))
1401
        goto cleanup;
1402
    objdef = virNodeDeviceObjGetDef(obj);
1403

1404
    if (new_device)
1405
        event = virNodeDeviceEventLifecycleNew(objdef->name,
1406 1407
                                               VIR_NODE_DEVICE_EVENT_CREATED,
                                               0);
1408
    else
1409
        event = virNodeDeviceEventUpdateNew(objdef->name);
1410

1411
    virNodeDeviceObjEndAPI(&obj);
1412 1413 1414

    ret = 0;

1415
 cleanup:
1416 1417 1418
    if (event)
        virObjectEventStateQueue(driver->nodeDeviceEventState, event);

1419
    if (ret != 0) {
1420
        VIR_DEBUG("Discarding device %d %p %s", ret, def,
1421
                  def ? NULLSTR(def->sysfs_path) : "");
1422 1423 1424
        virNodeDeviceDefFree(def);
    }

1425 1426 1427 1428
    return ret;
}


1429 1430 1431
static int
udevProcessDeviceListEntry(struct udev *udev,
                           struct udev_list_entry *list_entry)
1432 1433 1434 1435 1436 1437 1438 1439
{
    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);
1440

1441 1442
    if (device != NULL) {
        if (udevAddOneDevice(device) != 0) {
1443 1444
            VIR_DEBUG("Failed to create node device for udev device '%s'",
                      name);
1445 1446 1447 1448
        }
        ret = 0;
    }

1449 1450
    udev_device_unref(device);

1451 1452 1453 1454
    return ret;
}


1455 1456 1457 1458 1459 1460 1461 1462
/* 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",
};

1463 1464
static int
udevEnumerateAddMatches(struct udev_enumerate *udev_enumerate)
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
{
    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;
}


1479 1480
static int
udevEnumerateDevices(struct udev *udev)
1481 1482 1483
{
    struct udev_enumerate *udev_enumerate = NULL;
    struct udev_list_entry *list_entry = NULL;
1484
    int ret = -1;
1485 1486

    udev_enumerate = udev_enumerate_new(udev);
1487 1488
    if (udevEnumerateAddMatches(udev_enumerate) < 0)
        goto cleanup;
1489 1490

    ret = udev_enumerate_scan_devices(udev_enumerate);
1491
    if (ret != 0) {
1492 1493 1494
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("udev scan devices returned %d"),
                       ret);
1495
        goto cleanup;
1496 1497 1498 1499 1500 1501 1502 1503
    }

    udev_list_entry_foreach(list_entry,
                            udev_enumerate_get_list_entry(udev_enumerate)) {

        udevProcessDeviceListEntry(udev, list_entry);
    }

1504
 cleanup:
1505 1506 1507 1508 1509
    udev_enumerate_unref(udev_enumerate);
    return ret;
}


1510 1511
static void
udevPCITranslateDeinit(void)
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
{
#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;
}


1523 1524
static int
nodeStateCleanup(void)
1525
{
1526 1527
    udevEventDataPtr priv = NULL;

J
Ján Tomko 已提交
1528 1529
    if (!driver)
        return -1;
1530

1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
    priv = driver->privateData;
    if (priv) {
        virObjectLock(priv);
        priv->threadQuit = true;
        virCondSignal(&priv->threadCond);
        virObjectUnlock(priv);
        virThreadJoin(&priv->th);
    }

    virObjectUnref(priv);
1541
    virObjectUnref(driver->nodeDeviceEventState);
1542

1543
    virNodeDeviceObjListFree(driver->devs);
J
Ján Tomko 已提交
1544 1545
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
1546

J
Ján Tomko 已提交
1547 1548
    udevPCITranslateDeinit();
    return 0;
1549 1550 1551
}


1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
static int
udevHandleOneDevice(struct udev_device *device)
{
    const char *action = udev_device_get_action(device);

    VIR_DEBUG("udev action: '%s'", action);

    if (STREQ(action, "add") || STREQ(action, "change"))
        return udevAddOneDevice(device);

    if (STREQ(action, "remove"))
        return udevRemoveOneDevice(device);

    return 0;
}


1569 1570 1571
/* the caller must be holding the udevEventData object lock prior to calling
 * this function
 */
1572
static bool
1573
udevEventMonitorSanityCheck(udevEventDataPtr priv,
1574
                            int fd)
1575
{
1576
    int rc = -1;
1577

1578
    rc = udev_monitor_get_fd(priv->udev_monitor);
1579
    if (fd != rc) {
1580 1581 1582
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("File descriptor returned by udev %d does not "
                         "match node device file descriptor %d"),
1583
                       fd, rc);
1584 1585 1586 1587 1588 1589 1590 1591

        /* this is a non-recoverable error, let's remove the handle, so that we
         * don't get in here again because of some spurious behaviour and report
         * the same error multiple times
         */
        virEventRemoveHandle(priv->watch);
        priv->watch = -1;

1592
        return false;
1593 1594
    }

1595 1596 1597 1598 1599
    return true;
}


static void
1600
udevEventHandleThread(void *opaque ATTRIBUTE_UNUSED)
1601
{
1602
    udevEventDataPtr priv = driver->privateData;
1603 1604
    struct udev_device *device = NULL;

1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620
    /* continue rather than break from the loop on non-fatal errors */
    while (1) {
        virObjectLock(priv);
        while (!priv->dataReady && !priv->threadQuit) {
            if (virCondWait(&priv->threadCond, &priv->parent.lock)) {
                virReportSystemError(errno, "%s",
                                     _("handler failed to wait on condition"));
                virObjectUnlock(priv);
                return;
            }
        }

        if (priv->threadQuit) {
            virObjectUnlock(priv);
            return;
        }
1621

1622 1623
        errno = 0;
        device = udev_monitor_receive_device(priv->udev_monitor);
1624 1625
        virObjectUnlock(priv);

1626 1627 1628 1629 1630 1631
        if (!device) {
            if (errno == 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("failed to receive device from udev monitor"));
                return;
            }
1632

1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
            /* POSIX allows both EAGAIN and EWOULDBLOCK to be used
             * interchangeably when the read would block or timeout was fired
             */
            VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR
            if (errno != EAGAIN && errno != EWOULDBLOCK) {
            VIR_WARNINGS_RESET
                virReportSystemError(errno, "%s",
                                     _("failed to receive device from udev "
                                       "monitor"));
                return;
            }
1644

1645 1646 1647 1648 1649 1650 1651 1652 1653 1654
            virObjectLock(priv);
            priv->dataReady = false;
            virObjectUnlock(priv);

            continue;
        }

        udevHandleOneDevice(device);
        udev_device_unref(device);
    }
1655 1656 1657
}


1658 1659 1660 1661 1662 1663 1664 1665 1666 1667
static void
udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
                        int fd,
                        int events ATTRIBUTE_UNUSED,
                        void *data ATTRIBUTE_UNUSED)
{
    udevEventDataPtr priv = driver->privateData;

    virObjectLock(priv);

1668 1669 1670 1671 1672 1673 1674
    if (!udevEventMonitorSanityCheck(priv, fd))
        priv->threadQuit = true;
    else
        priv->dataReady = true;

    virCondSignal(&priv->threadCond);
    virObjectUnlock(priv);
1675 1676 1677
}


1678 1679
/* DMI is intel-compatible specific */
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1680
static void
1681
udevGetDMIData(virNodeDevCapSystemPtr syscap)
1682
{
1683
    udevEventDataPtr priv = driver->privateData;
1684 1685
    struct udev *udev = NULL;
    struct udev_device *device = NULL;
1686 1687
    virNodeDevCapSystemHardwarePtr hardware = &syscap->hardware;
    virNodeDevCapSystemFirmwarePtr firmware = &syscap->firmware;
1688

1689
    virObjectLock(priv);
1690
    udev = udev_monitor_get_udev(priv->udev_monitor);
1691

1692 1693
    device = udev_device_new_from_syspath(udev, DMI_DEVPATH);
    if (device == NULL) {
1694 1695
        device = udev_device_new_from_syspath(udev, DMI_DEVPATH_FALLBACK);
        if (device == NULL) {
1696 1697 1698
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to get udev device for syspath '%s' or '%s'"),
                           DMI_DEVPATH, DMI_DEVPATH_FALLBACK);
1699
            virObjectUnlock(priv);
1700
            return;
1701
        }
1702
    }
1703
    virObjectUnlock(priv);
1704

1705
    if (udevGetStringSysfsAttr(device, "product_name",
1706
                               &syscap->product_name) < 0)
1707
        goto cleanup;
1708
    if (udevGetStringSysfsAttr(device, "sys_vendor",
1709
                               &hardware->vendor_name) < 0)
1710
        goto cleanup;
1711
    if (udevGetStringSysfsAttr(device, "product_version",
1712
                               &hardware->version) < 0)
1713
        goto cleanup;
1714
    if (udevGetStringSysfsAttr(device, "product_serial",
1715
                               &hardware->serial) < 0)
1716
        goto cleanup;
1717

1718
    if (virGetHostUUID(hardware->uuid))
1719
        goto cleanup;
1720

1721
    if (udevGetStringSysfsAttr(device, "bios_vendor",
1722
                               &firmware->vendor_name) < 0)
1723
        goto cleanup;
1724
    if (udevGetStringSysfsAttr(device, "bios_version",
1725
                               &firmware->version) < 0)
1726
        goto cleanup;
1727
    if (udevGetStringSysfsAttr(device, "bios_date",
1728
                               &firmware->release_date) < 0)
1729
        goto cleanup;
1730

1731
 cleanup:
1732
    if (device != NULL)
1733 1734 1735
        udev_device_unref(device);
    return;
}
1736
#endif
1737 1738


1739 1740
static int
udevSetupSystemDev(void)
1741 1742
{
    virNodeDeviceDefPtr def = NULL;
1743
    virNodeDeviceObjPtr obj = NULL;
1744 1745
    int ret = -1;

1746 1747
    if (VIR_ALLOC(def) < 0)
        return -1;
1748

1749
    if (VIR_STRDUP(def->name, "computer") < 0)
1750
        goto cleanup;
1751

1752
    if (VIR_ALLOC(def->caps) != 0)
1753
        goto cleanup;
1754

1755
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1756
    udevGetDMIData(&def->caps->data.system);
1757
#endif
1758

1759
    if (!(obj = virNodeDeviceObjListAssignDef(driver->devs, def)))
1760
        goto cleanup;
1761

1762
    virNodeDeviceObjEndAPI(&obj);
1763 1764 1765

    ret = 0;

1766
 cleanup:
1767
    if (ret == -1)
1768 1769
        virNodeDeviceDefFree(def);

1770 1771 1772
    return ret;
}

1773

1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792
static void
nodeStateInitializeEnumerate(void *opaque)
{
    struct udev *udev = opaque;
    udevEventDataPtr priv = driver->privateData;

    /* Populate with known devices */
    if (udevEnumerateDevices(udev) != 0)
        goto error;

    return;

 error:
    virObjectLock(priv);
    priv->threadQuit = true;
    virObjectUnlock(priv);
}


1793 1794
static int
udevPCITranslateInit(bool privileged ATTRIBUTE_UNUSED)
1795
{
1796 1797 1798 1799
#if defined __s390__ || defined __s390x_
    /* On s390(x) system there is no PCI bus.
     * Therefore there is nothing to initialize here. */
#else
1800
    int rc;
1801

1802
    if ((rc = pci_system_init()) != 0) {
1803 1804 1805
        /* 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.  */
1806
        if (errno != ENOENT && (privileged  || errno != EACCES)) {
1807 1808
            virReportSystemError(rc, "%s",
                                 _("Failed to initialize libpciaccess"));
1809
            return -1;
1810
        }
1811
    }
1812
#endif
1813 1814 1815
    return 0;
}

1816 1817 1818 1819 1820

static int
nodeStateInitialize(bool privileged,
                    virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                    void *opaque ATTRIBUTE_UNUSED)
1821
{
1822
    udevEventDataPtr priv = NULL;
1823
    struct udev *udev = NULL;
1824
    virThread enumThread;
1825

1826
    if (VIR_ALLOC(driver) < 0)
1827
        return -1;
1828

1829
    if (virMutexInit(&driver->lock) < 0) {
1830 1831
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Unable to initialize mutex"));
1832
        VIR_FREE(driver);
1833
        return -1;
1834 1835
    }

1836 1837
    driver->privileged = privileged;

1838 1839
    if (!(driver->devs = virNodeDeviceObjListNew()) ||
        !(priv = udevEventDataNew()))
1840
        goto cleanup;
1841

1842
    driver->privateData = priv;
1843
    driver->nodeDeviceEventState = virObjectEventStateNew();
1844

1845
    if (udevPCITranslateInit(privileged) < 0)
1846
        goto cleanup;
1847

1848
    udev = udev_new();
1849 1850 1851
    if (!udev) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to create udev context"));
1852
        goto cleanup;
1853
    }
1854
#if HAVE_UDEV_LOGGING
J
Ján Tomko 已提交
1855 1856
    /* cast to get rid of missing-format-attribute warning */
    udev_set_log_fn(udev, (udevLogFunctionPtr) udevLogFunction);
1857
#endif
1858

1859 1860
    virObjectLock(priv);

1861
    priv->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
1862
    if (!priv->udev_monitor) {
1863 1864
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("udev_monitor_new_from_netlink returned NULL"));
1865
        goto unlock;
1866 1867
    }

1868
    udev_monitor_enable_receiving(priv->udev_monitor);
1869

1870
#if HAVE_UDEV_MONITOR_SET_RECEIVE_BUFFER_SIZE
1871 1872 1873 1874 1875 1876
    /* mimic udevd's behaviour and override the systems rmem_max limit in case
     * there's a significant number of device 'add' events
     */
    if (geteuid() == 0)
        udev_monitor_set_receive_buffer_size(priv->udev_monitor,
                                             128 * 1024 * 1024);
1877
#endif
1878

1879 1880 1881 1882 1883 1884
    if (virThreadCreate(&priv->th, true, udevEventHandleThread, NULL) < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to create udev handler thread"));
        goto unlock;
    }

1885 1886 1887 1888 1889 1890 1891 1892
    /* 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.  */
1893 1894 1895
    priv->watch = virEventAddHandle(udev_monitor_get_fd(priv->udev_monitor),
                                    VIR_EVENT_HANDLE_READABLE,
                                    udevEventHandleCallback, NULL, NULL);
1896
    if (priv->watch == -1)
1897
        goto unlock;
1898

1899 1900
    virObjectUnlock(priv);

1901
    /* Create a fictional 'computer' device to root the device tree. */
1902
    if (udevSetupSystemDev() != 0)
1903
        goto cleanup;
1904

1905 1906 1907 1908
    if (virThreadCreate(&enumThread, false, nodeStateInitializeEnumerate,
                        udev) < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to create udev enumerate thread"));
1909
        goto cleanup;
1910
    }
1911

1912
    return 0;
1913

1914
 cleanup:
1915 1916
    nodeStateCleanup();
    return -1;
1917 1918

 unlock:
1919
    virObjectUnlock(priv);
1920
    goto cleanup;
1921 1922 1923
}


1924 1925
static int
nodeStateReload(void)
1926 1927 1928 1929 1930
{
    return 0;
}


1931
static virNodeDeviceDriver udevNodeDeviceDriver = {
1932
    .name = "udev",
1933 1934
    .nodeNumOfDevices = nodeNumOfDevices, /* 0.7.3 */
    .nodeListDevices = nodeListDevices, /* 0.7.3 */
1935
    .connectListAllNodeDevices = nodeConnectListAllNodeDevices, /* 0.10.2 */
1936 1937
    .connectNodeDeviceEventRegisterAny = nodeConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
    .connectNodeDeviceEventDeregisterAny = nodeConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
1938 1939 1940 1941 1942 1943 1944 1945
    .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 */
1946 1947
};

1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959

static virHypervisorDriver udevHypervisorDriver = {
    .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 udevConnectDriver = {
1960
    .localOnly = true,
1961 1962 1963 1964 1965
    .hypervisorDriver = &udevHypervisorDriver,
    .nodeDeviceDriver = &udevNodeDeviceDriver,
};


1966
static virStateDriver udevStateDriver = {
M
Matthias Bolte 已提交
1967
    .name = "udev",
1968 1969 1970
    .stateInitialize = nodeStateInitialize, /* 0.7.3 */
    .stateCleanup = nodeStateCleanup, /* 0.7.3 */
    .stateReload = nodeStateReload, /* 0.7.3 */
1971 1972
};

1973 1974 1975

int
udevNodeRegister(void)
1976
{
1977
    VIR_DEBUG("Registering udev node device backend");
1978

1979 1980
    if (virRegisterConnectDriver(&udevConnectDriver, false) < 0)
        return -1;
1981
    if (virSetSharedNodeDeviceDriver(&udevNodeDeviceDriver) < 0)
1982 1983 1984 1985
        return -1;

    return virRegisterStateDriver(&udevStateDriver);
}