node_device_udev.c 55.3 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
 */

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

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

46 47
#include "configmake.h"

48 49
#define VIR_FROM_THIS VIR_FROM_NODEDEV

50 51
VIR_LOG_INIT("node_device.node_device_udev");

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

56 57 58 59 60 61
typedef struct _udevEventData udevEventData;
typedef udevEventData *udevEventDataPtr;

struct _udevEventData {
    virObjectLockable parent;

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

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

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
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);
89 90

    virCondDestroy(&priv->threadCond);
91 92 93 94 95 96
}


static int
udevEventDataOnceInit(void)
{
97
    if (!VIR_CLASS_NEW(udevEventData, virClassForObjectLockable()))
98 99 100 101 102
        return -1;

    return 0;
}

103
VIR_ONCE_GLOBAL_INIT(udevEventData);
104 105 106 107 108 109 110 111 112 113 114 115

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

    if (udevEventDataInitialize() < 0)
        return NULL;

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

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

121 122 123 124
    ret->watch = -1;
    return ret;
}

125

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

    return false;
}


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

143
    ret = udev_device_get_property_value(udev_device, property_key);
144

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

    return ret;
}


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

161
    return 0;
162 163 164
}


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

173
    str = udevGetDeviceProperty(udev_device, property_key);
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
    return 0;
181 182 183
}


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

192
    str = udevGetDeviceProperty(udev_device, property_key);
193

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


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

209
    ret = udev_device_get_sysattr_value(udev_device, attr_name);
210 211

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


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

227
    virStringStripControlChars(*value);
228

229 230
    if (*value != NULL && (STREQ(*value, "")))
        VIR_FREE(*value);
231

232
    return 0;
233 234 235
}


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

244
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
245

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

252
    return 0;
253 254 255
}


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

264
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
265

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

272
    return 0;
273 274 275
}


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

283
    str = udevGetDeviceSysfsAttr(udev_device, attr_name);
284

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

J
Ján Tomko 已提交
291
    return 0;
292 293 294
}


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

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

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

310 311
    if (virBufferCheckError(&buf) < 0)
        return -1;
312 313 314

    def->name = virBufferContentAndReset(&buf);

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

320
    return 0;
321 322
}

323 324 325 326 327 328

static int
udevTranslatePCIIds(unsigned int vendor,
                    unsigned int product,
                    char **vendor_string,
                    char **product_string)
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
{
    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,
344
                    &vendor_name,
345 346 347
                    NULL,
                    NULL);

348
    if (VIR_STRDUP(*vendor_string, vendor_name) < 0 ||
349
        VIR_STRDUP(*product_string, device_name) < 0)
350
        return -1;
351

352
    return 0;
353 354 355
}


356 357 358
static int
udevProcessPCI(struct udev_device *device,
               virNodeDeviceDefPtr def)
359
{
360
    virNodeDevCapPCIDevPtr pci_dev = &def->caps->data.pci_dev;
361 362
    virPCIEDeviceInfoPtr pci_express = NULL;
    virPCIDevicePtr pciDev = NULL;
363
    int ret = -1;
364
    char *p;
365 366 367 368 369
    bool privileged;

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

371 372
    pci_dev->klass = -1;
    if (udevGetIntProperty(device, "PCI_CLASS", &pci_dev->klass, 16) < 0)
373
        goto cleanup;
374

375
    if ((p = strrchr(def->sysfs_path, '/')) == NULL ||
376 377 378 379
        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) {
380 381
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the PCI address from sysfs path: '%s'"),
382
                       def->sysfs_path);
383
        goto cleanup;
384 385
    }

386
    if (udevGetUintSysfsAttr(device, "vendor", &pci_dev->vendor, 16) < 0)
387
        goto cleanup;
388

389
    if (udevGetUintSysfsAttr(device, "device", &pci_dev->product, 16) < 0)
390
        goto cleanup;
391

392 393 394 395
    if (udevTranslatePCIIds(pci_dev->vendor,
                            pci_dev->product,
                            &pci_dev->vendor_name,
                            &pci_dev->product_name) != 0) {
396
        goto cleanup;
397
    }
398

399
    if (udevGenerateDeviceName(device, def, NULL) != 0)
400
        goto cleanup;
401

402 403
    /* The default value is -1, because it can't be 0
     * as zero is valid node number. */
404
    pci_dev->numa_node = -1;
405
    if (udevGetIntSysfsAttr(device, "numa_node",
406
                            &pci_dev->numa_node, 10) < 0)
407
        goto cleanup;
408

409
    if (virNodeDeviceGetPCIDynamicCaps(def->sysfs_path, pci_dev) < 0)
410
        goto cleanup;
411

412 413 414 415
    if (!(pciDev = virPCIDeviceNew(pci_dev->domain,
                                   pci_dev->bus,
                                   pci_dev->slot,
                                   pci_dev->function)))
416
        goto cleanup;
417

418
    /* We need to be root to read PCI device configs */
419
    if (privileged) {
420
        if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType) < 0)
421
            goto cleanup;
422

423 424
        if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
            if (VIR_ALLOC(pci_express) < 0)
425
                goto cleanup;
426

427 428 429
            if (virPCIDeviceHasPCIExpressLink(pciDev) > 0) {
                if (VIR_ALLOC(pci_express->link_cap) < 0 ||
                    VIR_ALLOC(pci_express->link_sta) < 0)
430
                    goto cleanup;
431 432 433 434 435 436 437

                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)
438
                    goto cleanup;
439 440 441

                pci_express->link_sta->port = -1; /* PCIe can't negotiate port. Yet :) */
            }
442 443
            pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCIE;
            pci_dev->pci_express = pci_express;
444
            pci_express = NULL;
445 446 447
        }
    }

448 449
    ret = 0;

450
 cleanup:
451
    virPCIDeviceFree(pciDev);
452
    virPCIEDeviceInfoFree(pci_express);
453 454 455
    return ret;
}

456 457 458

static int
drmGetMinorType(int minor)
M
Marc-André Lureau 已提交
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
{
    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;
    }
}

475 476 477 478

static int
udevProcessDRMDevice(struct udev_device *device,
                     virNodeDeviceDefPtr def)
M
Marc-André Lureau 已提交
479
{
480
    virNodeDevCapDRMPtr drm = &def->caps->data.drm;
M
Marc-André Lureau 已提交
481 482 483 484 485 486 487 488 489 490 491
    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;

492
    drm->type = minor;
M
Marc-André Lureau 已提交
493 494 495

    return 0;
}
496

497 498 499 500

static int
udevProcessUSBDevice(struct udev_device *device,
                     virNodeDeviceDefPtr def)
501
{
502
    virNodeDevCapUSBDevPtr usb_dev = &def->caps->data.usb_dev;
503

504
    if (udevGetUintProperty(device, "BUSNUM", &usb_dev->bus, 10) < 0)
505
        return -1;
506
    if (udevGetUintProperty(device, "DEVNUM", &usb_dev->device, 10) < 0)
507
        return -1;
508
    if (udevGetUintProperty(device, "ID_VENDOR_ID", &usb_dev->vendor, 16) < 0)
509
        return -1;
510

511 512
    if (udevGetStringProperty(device,
                              "ID_VENDOR_FROM_DATABASE",
513
                              &usb_dev->vendor_name) < 0)
514
        return -1;
515

516
    if (!usb_dev->vendor_name &&
517
        udevGetStringSysfsAttr(device, "manufacturer",
518
                               &usb_dev->vendor_name) < 0)
519
        return -1;
520

521
    if (udevGetUintProperty(device, "ID_MODEL_ID", &usb_dev->product, 16) < 0)
522
        return -1;
523

524 525
    if (udevGetStringProperty(device,
                              "ID_MODEL_FROM_DATABASE",
526
                              &usb_dev->product_name) < 0)
527
        return -1;
528

529
    if (!usb_dev->product_name &&
530
        udevGetStringSysfsAttr(device, "product",
531
                               &usb_dev->product_name) < 0)
532
        return -1;
533

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

537
    return 0;
538 539 540
}


541 542 543
static int
udevProcessUSBInterface(struct udev_device *device,
                        virNodeDeviceDefPtr def)
544
{
545
    virNodeDevCapUSBIfPtr usb_if = &def->caps->data.usb_if;
546

547
    if (udevGetUintSysfsAttr(device, "bInterfaceNumber",
548
                             &usb_if->number, 16) < 0)
549
        return -1;
550

551
    if (udevGetUintSysfsAttr(device, "bInterfaceClass",
552
                             &usb_if->klass, 16) < 0)
553
        return -1;
554

555
    if (udevGetUintSysfsAttr(device, "bInterfaceSubClass",
556
                             &usb_if->subclass, 16) < 0)
557
        return -1;
558

559
    if (udevGetUintSysfsAttr(device, "bInterfaceProtocol",
560
                             &usb_if->protocol, 16) < 0)
561
        return -1;
562

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

566
    return 0;
567 568 569
}


570 571 572
static int
udevProcessNetworkInterface(struct udev_device *device,
                            virNodeDeviceDefPtr def)
573
{
D
David Allan 已提交
574
    const char *devtype = udev_device_get_devtype(device);
575
    virNodeDevCapNetPtr net = &def->caps->data.net;
576

D
David Allan 已提交
577
    if (devtype && STREQ(devtype, "wlan")) {
578
        net->subtype = VIR_NODE_DEV_CAP_NET_80211;
D
David Allan 已提交
579
    } else {
580
        net->subtype = VIR_NODE_DEV_CAP_NET_80203;
D
David Allan 已提交
581 582
    }

583 584
    if (udevGetStringProperty(device,
                              "INTERFACE",
585
                              &net->ifname) < 0)
586
        return -1;
587

588
    if (udevGetStringSysfsAttr(device, "address",
589
                               &net->address) < 0)
590
        return -1;
591

592
    if (udevGetUintSysfsAttr(device, "addr_len", &net->address_len, 0) < 0)
593
        return -1;
594

595
    if (udevGenerateDeviceName(device, def, net->address) != 0)
596
        return -1;
597

598
    if (virNetDevGetLinkInfo(net->ifname, &net->lnk) < 0)
599
        return -1;
600

601
    if (virNetDevGetFeatures(net->ifname, &net->features) < 0)
602
        return -1;
603

604
    return 0;
605 606 607
}


608
static int
J
Ján Tomko 已提交
609
udevProcessSCSIHost(struct udev_device *device G_GNUC_UNUSED,
610
                    virNodeDeviceDefPtr def)
611
{
612
    virNodeDevCapSCSIHostPtr scsi_host = &def->caps->data.scsi_host;
613
    char *filename = NULL;
J
Ján Tomko 已提交
614
    char *str;
615

616
    filename = last_component(def->sysfs_path);
617

618
    if (!(str = STRSKIP(filename, "host")) ||
619
        virStrToLong_ui(str, NULL, 0, &scsi_host->host) < 0) {
620 621 622
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse SCSI host '%s'"),
                       filename);
623
        return -1;
624 625
    }

626
    virNodeDeviceGetSCSIHostCaps(&def->caps->data.scsi_host);
627

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

631
    return 0;
632 633 634
}


635 636 637
static int
udevProcessSCSITarget(struct udev_device *device,
                      virNodeDeviceDefPtr def)
D
David Allan 已提交
638 639
{
    const char *sysname = NULL;
640
    virNodeDevCapSCSITargetPtr scsi_target = &def->caps->data.scsi_target;
D
David Allan 已提交
641 642 643

    sysname = udev_device_get_sysname(device);

644
    if (VIR_STRDUP(scsi_target->name, sysname) < 0)
645
        return -1;
D
David Allan 已提交
646

647
    virNodeDeviceGetSCSITargetCaps(def->sysfs_path, &def->caps->data.scsi_target);
648

649
    if (udevGenerateDeviceName(device, def, NULL) != 0)
650
        return -1;
D
David Allan 已提交
651

652
    return 0;
D
David Allan 已提交
653 654 655
}


656
static int
J
Ján Tomko 已提交
657
udevGetSCSIType(virNodeDeviceDefPtr def G_GNUC_UNUSED,
658 659
                unsigned int type,
                char **typestring)
660 661 662 663 664 665 666 667
{
    int ret = 0;
    int foundtype = 1;

    *typestring = NULL;

    switch (type) {
    case TYPE_DISK:
668
        *typestring = g_strdup("disk");
669 670
        break;
    case TYPE_TAPE:
671
        *typestring = g_strdup("tape");
672 673
        break;
    case TYPE_PROCESSOR:
674
        *typestring = g_strdup("processor");
675 676
        break;
    case TYPE_WORM:
677
        *typestring = g_strdup("worm");
678 679
        break;
    case TYPE_ROM:
680
        *typestring = g_strdup("cdrom");
681 682
        break;
    case TYPE_SCANNER:
683
        *typestring = g_strdup("scanner");
684 685
        break;
    case TYPE_MOD:
686
        *typestring = g_strdup("mod");
687 688
        break;
    case TYPE_MEDIUM_CHANGER:
689
        *typestring = g_strdup("changer");
690 691
        break;
    case TYPE_ENCLOSURE:
692
        *typestring = g_strdup("enclosure");
693
        break;
694
    case TYPE_RAID:
695
        *typestring = g_strdup("raid");
696
        break;
697 698 699 700 701 702 703 704 705 706
    case TYPE_NO_LUN:
    default:
        foundtype = 0;
        break;
    }

    if (*typestring == NULL) {
        if (foundtype == 1) {
            ret = -1;
        } else {
707 708
            VIR_DEBUG("Failed to find SCSI device type %d for %s",
                      type, def->sysfs_path);
709 710 711 712 713 714 715
        }
    }

    return ret;
}


716
static int
J
Ján Tomko 已提交
717
udevProcessSCSIDevice(struct udev_device *device G_GNUC_UNUSED,
718
                      virNodeDeviceDefPtr def)
719 720 721
{
    int ret = -1;
    unsigned int tmp = 0;
722
    virNodeDevCapSCSIPtr scsi = &def->caps->data.scsi;
723 724
    char *filename = NULL, *p = NULL;

725
    filename = last_component(def->sysfs_path);
726

727 728 729 730
    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) {
731 732 733 734
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to parse the SCSI address from filename: '%s'"),
                       filename);
        return -1;
735 736
    }

737 738
    if (udev_device_get_sysattr_value(device, "type")) {
        if (udevGetUintSysfsAttr(device, "type", &tmp, 0) < 0)
739
            goto cleanup;
740

741
        if (udevGetSCSIType(def, tmp, &scsi->type) < 0)
742
            goto cleanup;
743 744
    }

745
    if (udevGenerateDeviceName(device, def, NULL) != 0)
746
        goto cleanup;
747 748 749

    ret = 0;

750
 cleanup:
751
    if (ret != 0) {
752 753 754
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to process SCSI device with sysfs path '%s'"),
                       def->sysfs_path);
755 756 757 758 759
    }
    return ret;
}


760 761 762
static int
udevProcessDisk(struct udev_device *device,
                virNodeDeviceDefPtr def)
763
{
764
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
765

766
    if (udevGetUint64SysfsAttr(device, "size", &storage->num_blocks) < 0)
767
        return -1;
768

J
Ján Tomko 已提交
769
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
770
                               &storage->logical_block_size) < 0)
771
        return -1;
772

773
    storage->size = storage->num_blocks * storage->logical_block_size;
774

775
    return 0;
776 777 778
}


779 780 781 782
static int
udevProcessRemoveableMedia(struct udev_device *device,
                           virNodeDeviceDefPtr def,
                           int has_media)
783
{
784
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
J
Ján Tomko 已提交
785
    int is_removable = 0;
786

787 788 789
    if (udevGetIntSysfsAttr(device, "removable", &is_removable, 0) < 0)
        return -1;
    if (is_removable == 1)
790 791
        def->caps->data.storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;

J
Ján Tomko 已提交
792 793
    if (!has_media)
        return 0;
794

J
Ján Tomko 已提交
795 796
    def->caps->data.storage.flags |=
        VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
797

J
Ján Tomko 已提交
798
    if (udevGetStringProperty(device, "ID_FS_LABEL",
799
                              &storage->media_label) < 0)
J
Ján Tomko 已提交
800
        return -1;
801

J
Ján Tomko 已提交
802
    if (udevGetUint64SysfsAttr(device, "size",
803
                               &storage->num_blocks) < 0)
J
Ján Tomko 已提交
804
        return -1;
805

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

J
Ján Tomko 已提交
810 811 812 813 814 815 816
    /* 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;
817

J
Ján Tomko 已提交
818
    return 0;
819 820
}

821 822 823 824

static int
udevProcessCDROM(struct udev_device *device,
                 virNodeDeviceDefPtr def)
825 826 827 828 829 830 831 832
{
    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);
833
    if (VIR_STRDUP(def->caps->data.storage.drive_type, "cdrom") < 0)
834
        return -1;
835

836 837
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA") &&
        udevGetIntProperty(device, "ID_CDROM_MEDIA", &has_media, 0) < 0)
838
        return -1;
839

840
    return udevProcessRemoveableMedia(device, def, has_media);
841 842
}

843 844 845 846

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

850
    if (udevHasDeviceProperty(device, "ID_CDROM_MEDIA")) {
851
        /* USB floppy */
852 853
        if (udevGetIntProperty(device, "DKD_MEDIA_AVAILABLE", &has_media, 0) < 0)
            return -1;
854
    } else if (udevHasDeviceProperty(device, "ID_FS_LABEL")) {
855 856 857 858 859 860
        /* Legacy floppy */
        has_media = 1;
    }

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

862

863 864 865
static int
udevProcessSD(struct udev_device *device,
              virNodeDeviceDefPtr def)
866
{
867
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
868

J
Ján Tomko 已提交
869
    if (udevGetUint64SysfsAttr(device, "size",
870
                               &storage->num_blocks) < 0)
871
        return -1;
872

J
Ján Tomko 已提交
873
    if (udevGetUint64SysfsAttr(device, "queue/logical_block_size",
874
                               &storage->logical_block_size) < 0)
875
        return -1;
876

877
    storage->size = storage->num_blocks * storage->logical_block_size;
878

879
    return 0;
880 881 882
}


883 884 885 886
/* 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. */
887 888
static int
udevKludgeStorageType(virNodeDeviceDefPtr def)
889
{
890 891 892
    VIR_DEBUG("Could not find definitive storage type for device "
              "with sysfs path '%s', trying to guess it",
              def->sysfs_path);
893

894 895 896
    /* virtio disk */
    if (STRPREFIX(def->caps->data.storage.block, "/dev/vd") &&
        VIR_STRDUP(def->caps->data.storage.drive_type, "disk") > 0) {
897
        VIR_DEBUG("Found storage type '%s' for device "
898
                  "with sysfs path '%s'",
899 900
                  def->caps->data.storage.drive_type,
                  def->sysfs_path);
901
        return 0;
902
    }
903 904 905
    VIR_DEBUG("Could not determine storage type "
              "for device with sysfs path '%s'", def->sysfs_path);
    return -1;
906 907 908
}


909 910 911
static int
udevProcessStorage(struct udev_device *device,
                   virNodeDeviceDefPtr def)
912
{
913
    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
914
    int ret = -1;
915
    const char* devnode;
916

917
    devnode = udev_device_get_devnode(device);
918
    if (!devnode) {
919
        VIR_DEBUG("No devnode for '%s'", udev_device_get_devpath(device));
920
        goto cleanup;
921
    }
922

923
    if (VIR_STRDUP(storage->block, devnode) < 0)
924
        goto cleanup;
925

926
    if (udevGetStringProperty(device, "ID_BUS", &storage->bus) < 0)
927
        goto cleanup;
928
    if (udevGetStringProperty(device, "ID_SERIAL", &storage->serial) < 0)
929
        goto cleanup;
930

931
    if (udevGetStringSysfsAttr(device, "device/vendor", &storage->vendor) < 0)
932
        goto cleanup;
933 934 935
    if (def->caps->data.storage.vendor)
        virTrimSpaces(def->caps->data.storage.vendor, NULL);

936
    if (udevGetStringSysfsAttr(device, "device/model", &storage->model) < 0)
937
        goto cleanup;
938 939
    if (def->caps->data.storage.model)
        virTrimSpaces(def->caps->data.storage.model, NULL);
940 941 942 943 944
    /* 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. */

945
    if (udevGetStringProperty(device, "ID_TYPE", &storage->drive_type) < 0)
946
        goto cleanup;
947

948
    if (!storage->drive_type ||
949
        STREQ(def->caps->data.storage.drive_type, "generic")) {
950 951
        int val = 0;
        const char *str = NULL;
952 953 954

        /* All floppy drives have the ID_DRIVE_FLOPPY prop. This is
         * needed since legacy floppies don't have a drive_type */
955
        if (udevGetIntProperty(device, "ID_DRIVE_FLOPPY", &val, 0) < 0)
956
            goto cleanup;
957 958
        else if (val == 1)
            str = "floppy";
959

960
        if (!str) {
961
            if (udevGetIntProperty(device, "ID_CDROM", &val, 0) < 0)
962
                goto cleanup;
963 964 965
            else if (val == 1)
                str = "cd";
        }
966

967
        if (!str) {
968
            if (udevGetIntProperty(device, "ID_DRIVE_FLASH_SD", &val, 0) < 0)
969
                goto cleanup;
970 971 972
            if (val == 1)
                str = "sd";
        }
973

974
        if (str) {
975
            if (VIR_STRDUP(storage->drive_type, str) < 0)
976
                goto cleanup;
977 978
        } else {
            /* If udev doesn't have it, perhaps we can guess it. */
979
            if (udevKludgeStorageType(def) != 0)
980
                goto cleanup;
981 982 983 984 985 986 987
        }
    }

    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);
988 989
    } else if (STREQ(def->caps->data.storage.drive_type, "floppy")) {
        ret = udevProcessFloppy(device, def);
990 991
    } else if (STREQ(def->caps->data.storage.drive_type, "sd")) {
        ret = udevProcessSD(device, def);
992
    } else {
993 994
        VIR_DEBUG("Unsupported storage type '%s'",
                  def->caps->data.storage.drive_type);
995
        goto cleanup;
996 997
    }

998
    if (udevGenerateDeviceName(device, def, storage->serial) != 0)
999
        goto cleanup;
1000

1001
 cleanup:
1002
    VIR_DEBUG("Storage ret=%d", ret);
1003 1004 1005
    return ret;
}

1006

1007
static int
1008
udevProcessSCSIGeneric(struct udev_device *dev,
1009 1010
                       virNodeDeviceDefPtr def)
{
1011 1012
    if (udevGetStringProperty(dev, "DEVNAME", &def->caps->data.sg.path) < 0 ||
        !def->caps->data.sg.path)
1013 1014 1015 1016 1017 1018 1019 1020
        return -1;

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

    return 0;
}

1021

1022 1023 1024 1025 1026 1027 1028 1029
static int
udevProcessMediatedDevice(struct udev_device *dev,
                          virNodeDeviceDefPtr def)
{
    int ret = -1;
    const char *uuidstr = NULL;
    int iommugrp = -1;
    char *linkpath = NULL;
1030
    char *canonicalpath = NULL;
1031 1032
    virNodeDevCapMdevPtr data = &def->caps->data.mdev;

1033 1034 1035 1036 1037 1038 1039 1040
    /* 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)
1041 1042
        goto cleanup;

1043 1044 1045 1046 1047 1048 1049
    if (virFileWaitForExists(linkpath, 1, 100) < 0) {
        virReportSystemError(errno,
                             _("failed to wait for file '%s' to appear"),
                             linkpath);
        goto cleanup;
    }

1050 1051
    if (virFileResolveLink(linkpath, &canonicalpath) < 0) {
        virReportSystemError(errno, _("failed to resolve '%s'"), linkpath);
1052
        goto cleanup;
1053
    }
1054

1055
    if (VIR_STRDUP(data->type, last_component(canonicalpath)) < 0)
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
        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);
1070
    VIR_FREE(canonicalpath);
1071 1072 1073
    return ret;
}

B
Bjoern Walk 已提交
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103

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;
}


1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
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;
}

1132

1133 1134
static int
udevGetDeviceType(struct udev_device *device,
1135
                  virNodeDevCapType *type)
1136 1137
{
    const char *devtype = NULL;
1138
    char *subsystem = NULL;
1139
    int ret = -1;
D
David Allan 已提交
1140

1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
    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 已提交
1159 1160
        else if (STREQ(devtype, "drm_minor"))
            *type = VIR_NODE_DEV_CAP_DRM;
1161 1162
    } else {
        /* PCI devices don't set the DEVTYPE property. */
1163
        if (udevHasDeviceProperty(device, "PCI_CLASS"))
1164
            *type = VIR_NODE_DEV_CAP_PCI_DEV;
1165

1166 1167 1168 1169
        /* 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. */
1170
        if (udevHasDeviceProperty(device, "INTERFACE"))
1171
            *type = VIR_NODE_DEV_CAP_NET;
1172

B
Bjoern Walk 已提交
1173 1174
        /* The following devices do not set the DEVTYPE property, therefore
         * we need to rely on the SUBSYSTEM property */
1175 1176 1177 1178
        if (udevGetStringProperty(device, "SUBSYSTEM", &subsystem) < 0)
            return -1;

        if (STREQ_NULLABLE(subsystem, "scsi_generic"))
1179
            *type = VIR_NODE_DEV_CAP_SCSI_GENERIC;
1180 1181
        else if (STREQ_NULLABLE(subsystem, "mdev"))
            *type = VIR_NODE_DEV_CAP_MDEV;
B
Bjoern Walk 已提交
1182 1183
        else if (STREQ_NULLABLE(subsystem, "ccw"))
            *type = VIR_NODE_DEV_CAP_CCW_DEV;
1184

1185
        VIR_FREE(subsystem);
1186 1187
    }

1188 1189 1190 1191 1192 1193
    if (!*type)
        VIR_DEBUG("Could not determine device type for device "
                  "with sysfs name '%s'",
                  udev_device_get_sysname(device));
    else
        ret = 0;
1194 1195 1196 1197 1198

    return ret;
}


1199 1200 1201
static int
udevGetDeviceDetails(struct udev_device *device,
                     virNodeDeviceDefPtr def)
1202
{
1203
    switch (def->caps->data.type) {
1204
    case VIR_NODE_DEV_CAP_PCI_DEV:
1205
        return udevProcessPCI(device, def);
1206
    case VIR_NODE_DEV_CAP_USB_DEV:
1207
        return udevProcessUSBDevice(device, def);
1208
    case VIR_NODE_DEV_CAP_USB_INTERFACE:
1209
        return udevProcessUSBInterface(device, def);
1210
    case VIR_NODE_DEV_CAP_NET:
1211
        return udevProcessNetworkInterface(device, def);
1212
    case VIR_NODE_DEV_CAP_SCSI_HOST:
1213
        return udevProcessSCSIHost(device, def);
D
David Allan 已提交
1214
    case VIR_NODE_DEV_CAP_SCSI_TARGET:
1215
        return udevProcessSCSITarget(device, def);
1216
    case VIR_NODE_DEV_CAP_SCSI:
1217
        return udevProcessSCSIDevice(device, def);
1218
    case VIR_NODE_DEV_CAP_STORAGE:
1219
        return udevProcessStorage(device, def);
1220
    case VIR_NODE_DEV_CAP_SCSI_GENERIC:
1221
        return udevProcessSCSIGeneric(device, def);
M
Marc-André Lureau 已提交
1222
    case VIR_NODE_DEV_CAP_DRM:
1223
        return udevProcessDRMDevice(device, def);
1224
    case VIR_NODE_DEV_CAP_MDEV:
1225
        return udevProcessMediatedDevice(device, def);
B
Bjoern Walk 已提交
1226 1227
    case VIR_NODE_DEV_CAP_CCW_DEV:
        return udevProcessCCW(device, def);
1228
    case VIR_NODE_DEV_CAP_MDEV_TYPES:
1229 1230 1231 1232
    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:
1233 1234 1235
        break;
    }

1236
    return 0;
1237 1238 1239
}


1240 1241
static int
udevRemoveOneDevice(struct udev_device *device)
1242
{
1243
    virNodeDeviceObjPtr obj = NULL;
1244
    virNodeDeviceDefPtr def;
1245
    virObjectEventPtr event = NULL;
1246 1247 1248
    const char *name = NULL;

    name = udev_device_get_syspath(device);
1249
    if (!(obj = virNodeDeviceObjListFindBySysfsPath(driver->devs, name))) {
1250 1251
        VIR_DEBUG("Failed to find device to remove that has udev name '%s'",
                  name);
1252
        return -1;
1253
    }
1254
    def = virNodeDeviceObjGetDef(obj);
1255

1256
    event = virNodeDeviceEventLifecycleNew(def->name,
1257 1258 1259 1260
                                           VIR_NODE_DEVICE_EVENT_DELETED,
                                           0);

    VIR_DEBUG("Removing device '%s' with sysfs path '%s'",
1261
              def->name, name);
1262
    virNodeDeviceObjListRemove(driver->devs, obj);
1263
    virObjectUnref(obj);
1264

1265
    virObjectEventStateQueue(driver->nodeDeviceEventState, event);
1266
    return 0;
1267 1268 1269
}


1270 1271 1272
static int
udevSetParent(struct udev_device *device,
              virNodeDeviceDefPtr def)
1273 1274 1275
{
    struct udev_device *parent_device = NULL;
    const char *parent_sysfs_path = NULL;
1276
    virNodeDeviceObjPtr obj = NULL;
1277
    virNodeDeviceDefPtr objdef;
1278 1279
    int ret = -1;

1280 1281
    parent_device = device;
    do {
1282

1283
        parent_device = udev_device_get_parent(parent_device);
1284
        if (parent_device == NULL)
1285
            break;
1286

1287 1288
        parent_sysfs_path = udev_device_get_syspath(parent_device);
        if (parent_sysfs_path == NULL) {
1289 1290 1291
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Could not get syspath for parent of '%s'"),
                           udev_device_get_syspath(parent_device));
1292
            goto cleanup;
1293 1294
        }

1295 1296
        if ((obj = virNodeDeviceObjListFindBySysfsPath(driver->devs,
                                                       parent_sysfs_path))) {
1297
            objdef = virNodeDeviceObjGetDef(obj);
1298
            if (VIR_STRDUP(def->parent, objdef->name) < 0) {
1299
                virNodeDeviceObjEndAPI(&obj);
1300
                goto cleanup;
1301
            }
1302
            virNodeDeviceObjEndAPI(&obj);
1303

1304
            if (VIR_STRDUP(def->parent_sysfs_path, parent_sysfs_path) < 0)
1305
                goto cleanup;
1306 1307 1308 1309
        }

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

1310 1311
    if (!def->parent)
        def->parent = g_strdup("computer");
1312 1313 1314

    ret = 0;

1315
 cleanup:
1316 1317 1318 1319
    return ret;
}


1320 1321
static int
udevAddOneDevice(struct udev_device *device)
1322 1323
{
    virNodeDeviceDefPtr def = NULL;
1324
    virNodeDeviceObjPtr obj = NULL;
1325
    virNodeDeviceDefPtr objdef;
1326 1327
    virObjectEventPtr event = NULL;
    bool new_device = true;
1328 1329
    int ret = -1;

1330
    if (VIR_ALLOC(def) != 0)
1331
        goto cleanup;
1332

1333
    if (VIR_STRDUP(def->sysfs_path, udev_device_get_syspath(device)) < 0)
1334
        goto cleanup;
1335

1336
    if (udevGetStringProperty(device, "DRIVER", &def->driver) < 0)
1337
        goto cleanup;
1338

1339
    if (VIR_ALLOC(def->caps) != 0)
1340
        goto cleanup;
1341

1342
    if (udevGetDeviceType(device, &def->caps->data.type) != 0)
1343
        goto cleanup;
1344

1345 1346 1347
    if (udevGetDeviceNodes(device, def) != 0)
        goto cleanup;

1348
    if (udevGetDeviceDetails(device, def) != 0)
1349
        goto cleanup;
1350

1351
    if (udevSetParent(device, def) != 0)
1352
        goto cleanup;
1353

1354
    if ((obj = virNodeDeviceObjListFindByName(driver->devs, def->name))) {
1355
        virNodeDeviceObjEndAPI(&obj);
1356 1357 1358
        new_device = false;
    }

1359 1360
    /* If this is a device change, the old definition will be freed
     * and the current definition will take its place. */
1361
    if (!(obj = virNodeDeviceObjListAssignDef(driver->devs, def)))
1362
        goto cleanup;
1363
    objdef = virNodeDeviceObjGetDef(obj);
1364

1365
    if (new_device)
1366
        event = virNodeDeviceEventLifecycleNew(objdef->name,
1367 1368
                                               VIR_NODE_DEVICE_EVENT_CREATED,
                                               0);
1369
    else
1370
        event = virNodeDeviceEventUpdateNew(objdef->name);
1371

1372
    virNodeDeviceObjEndAPI(&obj);
1373 1374 1375

    ret = 0;

1376
 cleanup:
1377
    virObjectEventStateQueue(driver->nodeDeviceEventState, event);
1378

1379
    if (ret != 0) {
1380
        VIR_DEBUG("Discarding device %d %p %s", ret, def,
1381
                  def ? NULLSTR(def->sysfs_path) : "");
1382 1383 1384
        virNodeDeviceDefFree(def);
    }

1385 1386 1387 1388
    return ret;
}


1389 1390 1391
static int
udevProcessDeviceListEntry(struct udev *udev,
                           struct udev_list_entry *list_entry)
1392 1393 1394 1395 1396 1397 1398 1399
{
    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);
1400

1401 1402
    if (device != NULL) {
        if (udevAddOneDevice(device) != 0) {
1403 1404
            VIR_DEBUG("Failed to create node device for udev device '%s'",
                      name);
1405 1406 1407 1408
        }
        ret = 0;
    }

1409 1410
    udev_device_unref(device);

1411 1412 1413 1414
    return ret;
}


1415 1416 1417 1418 1419 1420 1421 1422
/* 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",
};

1423 1424
static int
udevEnumerateAddMatches(struct udev_enumerate *udev_enumerate)
1425 1426 1427
{
    size_t i;

1428
    for (i = 0; i < G_N_ELEMENTS(subsystem_blacklist); i++) {
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
        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;
}


1439 1440
static int
udevEnumerateDevices(struct udev *udev)
1441 1442 1443
{
    struct udev_enumerate *udev_enumerate = NULL;
    struct udev_list_entry *list_entry = NULL;
1444
    int ret = -1;
1445 1446

    udev_enumerate = udev_enumerate_new(udev);
1447 1448
    if (udevEnumerateAddMatches(udev_enumerate) < 0)
        goto cleanup;
1449

1450 1451
    if (udev_enumerate_scan_devices(udev_enumerate) < 0)
        VIR_WARN("udev scan devices failed");
1452 1453 1454 1455 1456 1457 1458

    udev_list_entry_foreach(list_entry,
                            udev_enumerate_get_list_entry(udev_enumerate)) {

        udevProcessDeviceListEntry(udev, list_entry);
    }

1459
    ret = 0;
1460
 cleanup:
1461 1462 1463 1464 1465
    udev_enumerate_unref(udev_enumerate);
    return ret;
}


1466 1467
static void
udevPCITranslateDeinit(void)
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
{
#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;
}


1479 1480
static int
nodeStateCleanup(void)
1481
{
1482 1483
    udevEventDataPtr priv = NULL;

J
Ján Tomko 已提交
1484 1485
    if (!driver)
        return -1;
1486

1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
    priv = driver->privateData;
    if (priv) {
        virObjectLock(priv);
        priv->threadQuit = true;
        virCondSignal(&priv->threadCond);
        virObjectUnlock(priv);
        virThreadJoin(&priv->th);
    }

    virObjectUnref(priv);
1497
    virObjectUnref(driver->nodeDeviceEventState);
1498

1499
    virNodeDeviceObjListFree(driver->devs);
1500 1501 1502 1503 1504

    if (driver->lockFD != -1)
        virPidFileRelease(driver->stateDir, "driver", driver->lockFD);

    VIR_FREE(driver->stateDir);
J
Ján Tomko 已提交
1505 1506
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
1507

J
Ján Tomko 已提交
1508 1509
    udevPCITranslateDeinit();
    return 0;
1510 1511 1512
}


1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
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;
}


1530 1531 1532
/* the caller must be holding the udevEventData object lock prior to calling
 * this function
 */
1533
static bool
1534
udevEventMonitorSanityCheck(udevEventDataPtr priv,
1535
                            int fd)
1536
{
1537
    int rc = -1;
1538

1539
    rc = udev_monitor_get_fd(priv->udev_monitor);
1540
    if (fd != rc) {
1541 1542 1543
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("File descriptor returned by udev %d does not "
                         "match node device file descriptor %d"),
1544
                       fd, rc);
1545 1546 1547 1548 1549 1550 1551 1552

        /* 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;

1553
        return false;
1554 1555
    }

1556 1557 1558 1559
    return true;
}


1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
/**
 * udevEventHandleThread
 * @opaque: unused
 *
 * Thread to handle the udevEventHandleCallback processing when udev
 * tells us there's a device change for us (add, modify, delete, etc).
 *
 * Once notified there is data to be processed, the actual @device
 * data retrieval by libudev may be delayed due to how threads are
 * scheduled. In fact, the event loop could be scheduled earlier than
 * the handler thread, thus potentially emitting the very same event
 * the handler thread is currently trying to process, simply because
 * the data hadn't been retrieved from the socket.
 *
 * NB: Some older distros, such as CentOS 6, libudev opens sockets
 * without the NONBLOCK flag which might cause issues with event
 * based algorithm. Although the issue can be mitigated by resetting
 * priv->dataReady for each event found; however, the scheduler issues
 * would still come into play.
 */
1580
static void
J
Ján Tomko 已提交
1581
udevEventHandleThread(void *opaque G_GNUC_UNUSED)
1582
{
1583
    udevEventDataPtr priv = driver->privateData;
1584 1585
    struct udev_device *device = NULL;

1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
    /* 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;
        }
1602

1603 1604
        errno = 0;
        device = udev_monitor_receive_device(priv->udev_monitor);
1605 1606
        virObjectUnlock(priv);

1607 1608 1609 1610 1611 1612
        if (!device) {
            if (errno == 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("failed to receive device from udev monitor"));
                return;
            }
1613

1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
            /* 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;
            }
1625

1626 1627 1628
            /* Trying to move the reset of the @priv->dataReady flag to
             * after the udev_monitor_receive_device wouldn't help much
             * due to event mgmt and scheduler timing. */
1629 1630 1631 1632 1633 1634 1635 1636 1637
            virObjectLock(priv);
            priv->dataReady = false;
            virObjectUnlock(priv);

            continue;
        }

        udevHandleOneDevice(device);
        udev_device_unref(device);
1638 1639 1640 1641 1642

        /* Instead of waiting for the next event after processing @device
         * data, let's keep reading from the udev monitor and only wait
         * for the next event once either a EAGAIN or a EWOULDBLOCK error
         * is encountered. */
1643
    }
1644 1645 1646
}


1647
static void
J
Ján Tomko 已提交
1648
udevEventHandleCallback(int watch G_GNUC_UNUSED,
1649
                        int fd,
J
Ján Tomko 已提交
1650 1651
                        int events G_GNUC_UNUSED,
                        void *data G_GNUC_UNUSED)
1652 1653 1654 1655 1656
{
    udevEventDataPtr priv = driver->privateData;

    virObjectLock(priv);

1657 1658 1659 1660 1661 1662 1663
    if (!udevEventMonitorSanityCheck(priv, fd))
        priv->threadQuit = true;
    else
        priv->dataReady = true;

    virCondSignal(&priv->threadCond);
    virObjectUnlock(priv);
1664 1665 1666
}


1667 1668
/* DMI is intel-compatible specific */
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1669
static void
1670
udevGetDMIData(virNodeDevCapSystemPtr syscap)
1671
{
1672
    udevEventDataPtr priv = driver->privateData;
1673 1674
    struct udev *udev = NULL;
    struct udev_device *device = NULL;
1675 1676
    virNodeDevCapSystemHardwarePtr hardware = &syscap->hardware;
    virNodeDevCapSystemFirmwarePtr firmware = &syscap->firmware;
1677

1678
    virObjectLock(priv);
1679
    udev = udev_monitor_get_udev(priv->udev_monitor);
1680

1681 1682
    device = udev_device_new_from_syspath(udev, DMI_DEVPATH);
    if (device == NULL) {
1683 1684
        device = udev_device_new_from_syspath(udev, DMI_DEVPATH_FALLBACK);
        if (device == NULL) {
1685 1686 1687
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to get udev device for syspath '%s' or '%s'"),
                           DMI_DEVPATH, DMI_DEVPATH_FALLBACK);
1688
            virObjectUnlock(priv);
1689
            return;
1690
        }
1691
    }
1692
    virObjectUnlock(priv);
1693

1694
    if (udevGetStringSysfsAttr(device, "product_name",
1695
                               &syscap->product_name) < 0)
1696
        goto cleanup;
1697
    if (udevGetStringSysfsAttr(device, "sys_vendor",
1698
                               &hardware->vendor_name) < 0)
1699
        goto cleanup;
1700
    if (udevGetStringSysfsAttr(device, "product_version",
1701
                               &hardware->version) < 0)
1702
        goto cleanup;
1703
    if (udevGetStringSysfsAttr(device, "product_serial",
1704
                               &hardware->serial) < 0)
1705
        goto cleanup;
1706

1707
    if (virGetHostUUID(hardware->uuid))
1708
        goto cleanup;
1709

1710
    if (udevGetStringSysfsAttr(device, "bios_vendor",
1711
                               &firmware->vendor_name) < 0)
1712
        goto cleanup;
1713
    if (udevGetStringSysfsAttr(device, "bios_version",
1714
                               &firmware->version) < 0)
1715
        goto cleanup;
1716
    if (udevGetStringSysfsAttr(device, "bios_date",
1717
                               &firmware->release_date) < 0)
1718
        goto cleanup;
1719

1720
 cleanup:
1721
    if (device != NULL)
1722 1723 1724
        udev_device_unref(device);
    return;
}
1725
#endif
1726 1727


1728 1729
static int
udevSetupSystemDev(void)
1730 1731
{
    virNodeDeviceDefPtr def = NULL;
1732
    virNodeDeviceObjPtr obj = NULL;
1733 1734
    int ret = -1;

1735 1736
    if (VIR_ALLOC(def) < 0)
        return -1;
1737

1738
    if (VIR_STRDUP(def->name, "computer") < 0)
1739
        goto cleanup;
1740

1741
    if (VIR_ALLOC(def->caps) != 0)
1742
        goto cleanup;
1743

1744
#if defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
1745
    udevGetDMIData(&def->caps->data.system);
1746
#endif
1747

1748
    if (!(obj = virNodeDeviceObjListAssignDef(driver->devs, def)))
1749
        goto cleanup;
1750

1751
    virNodeDeviceObjEndAPI(&obj);
1752 1753 1754

    ret = 0;

1755
 cleanup:
1756
    if (ret == -1)
1757 1758
        virNodeDeviceDefFree(def);

1759 1760 1761
    return ret;
}

1762

1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776
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);
1777 1778
    ignore_value(virEventRemoveHandle(priv->watch));
    priv->watch = -1;
1779
    priv->threadQuit = true;
1780
    virCondSignal(&priv->threadCond);
1781 1782 1783 1784
    virObjectUnlock(priv);
}


1785
static int
J
Ján Tomko 已提交
1786
udevPCITranslateInit(bool privileged G_GNUC_UNUSED)
1787
{
1788 1789 1790 1791
#if defined __s390__ || defined __s390x_
    /* On s390(x) system there is no PCI bus.
     * Therefore there is nothing to initialize here. */
#else
1792
    int rc;
1793

1794
    if ((rc = pci_system_init()) != 0) {
1795 1796 1797
        /* 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.  */
1798
        if (errno != ENOENT && (privileged  || errno != EACCES)) {
1799 1800
            virReportSystemError(rc, "%s",
                                 _("Failed to initialize libpciaccess"));
1801
            return -1;
1802
        }
1803
    }
1804
#endif
1805 1806 1807
    return 0;
}

1808 1809 1810

static int
nodeStateInitialize(bool privileged,
J
Ján Tomko 已提交
1811 1812
                    virStateInhibitCallback callback G_GNUC_UNUSED,
                    void *opaque G_GNUC_UNUSED)
1813
{
1814
    udevEventDataPtr priv = NULL;
1815
    struct udev *udev = NULL;
1816
    virThread enumThread;
1817

1818
    if (VIR_ALLOC(driver) < 0)
1819
        return VIR_DRV_STATE_INIT_ERROR;
1820

1821
    driver->lockFD = -1;
1822
    if (virMutexInit(&driver->lock) < 0) {
1823 1824
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Unable to initialize mutex"));
1825
        VIR_FREE(driver);
1826
        return VIR_DRV_STATE_INIT_ERROR;
1827 1828
    }

1829 1830
    driver->privileged = privileged;

1831 1832
    if (privileged) {
        if (virAsprintf(&driver->stateDir,
1833
                        "%s/libvirt/nodedev", RUNSTATEDIR) < 0)
1834 1835
            goto cleanup;
    } else {
1836
        g_autofree char *rundir = NULL;
1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850

        if (!(rundir = virGetUserRuntimeDirectory()))
            goto cleanup;
        if (virAsprintf(&driver->stateDir, "%s/nodedev/run", rundir) < 0)
            goto cleanup;
    }

    if (virFileMakePathWithMode(driver->stateDir, S_IRWXU) < 0) {
        virReportSystemError(errno, _("cannot create state directory '%s'"),
                             driver->stateDir);
        goto cleanup;
    }

    if ((driver->lockFD =
1851
         virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0)
1852 1853
        goto cleanup;

1854 1855
    if (!(driver->devs = virNodeDeviceObjListNew()) ||
        !(priv = udevEventDataNew()))
1856
        goto cleanup;
1857

1858
    driver->privateData = priv;
1859
    driver->nodeDeviceEventState = virObjectEventStateNew();
1860

1861
    if (udevPCITranslateInit(privileged) < 0)
1862
        goto cleanup;
1863

1864
    udev = udev_new();
1865 1866 1867
    if (!udev) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to create udev context"));
1868
        goto cleanup;
1869
    }
1870

1871 1872
    virObjectLock(priv);

1873
    priv->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
1874
    if (!priv->udev_monitor) {
1875 1876
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("udev_monitor_new_from_netlink returned NULL"));
1877
        goto unlock;
1878 1879
    }

1880
    udev_monitor_enable_receiving(priv->udev_monitor);
1881

1882 1883 1884 1885 1886 1887 1888
    /* 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);

1889 1890 1891 1892 1893 1894
    if (virThreadCreate(&priv->th, true, udevEventHandleThread, NULL) < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to create udev handler thread"));
        goto unlock;
    }

1895 1896 1897 1898 1899 1900 1901 1902
    /* 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.  */
1903 1904 1905
    priv->watch = virEventAddHandle(udev_monitor_get_fd(priv->udev_monitor),
                                    VIR_EVENT_HANDLE_READABLE,
                                    udevEventHandleCallback, NULL, NULL);
1906
    if (priv->watch == -1)
1907
        goto unlock;
1908

1909 1910
    virObjectUnlock(priv);

1911
    /* Create a fictional 'computer' device to root the device tree. */
1912
    if (udevSetupSystemDev() != 0)
1913
        goto cleanup;
1914

1915 1916 1917 1918
    if (virThreadCreate(&enumThread, false, nodeStateInitializeEnumerate,
                        udev) < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to create udev enumerate thread"));
1919
        goto cleanup;
1920
    }
1921

1922
    return VIR_DRV_STATE_INIT_COMPLETE;
1923

1924
 cleanup:
1925
    nodeStateCleanup();
1926
    return VIR_DRV_STATE_INIT_ERROR;
1927 1928

 unlock:
1929
    virObjectUnlock(priv);
1930
    goto cleanup;
1931 1932 1933
}


1934 1935
static int
nodeStateReload(void)
1936 1937 1938 1939 1940
{
    return 0;
}


1941
static virNodeDeviceDriver udevNodeDeviceDriver = {
1942
    .name = "udev",
1943 1944
    .nodeNumOfDevices = nodeNumOfDevices, /* 0.7.3 */
    .nodeListDevices = nodeListDevices, /* 0.7.3 */
1945
    .connectListAllNodeDevices = nodeConnectListAllNodeDevices, /* 0.10.2 */
1946 1947
    .connectNodeDeviceEventRegisterAny = nodeConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
    .connectNodeDeviceEventDeregisterAny = nodeConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
1948 1949 1950 1951 1952 1953 1954 1955
    .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 */
1956 1957
};

1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969

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 = {
1970
    .localOnly = true,
1971
    .uriSchemes = (const char *[]){ "nodedev", NULL },
1972 1973 1974 1975 1976
    .hypervisorDriver = &udevHypervisorDriver,
    .nodeDeviceDriver = &udevNodeDeviceDriver,
};


1977
static virStateDriver udevStateDriver = {
M
Matthias Bolte 已提交
1978
    .name = "udev",
1979 1980 1981
    .stateInitialize = nodeStateInitialize, /* 0.7.3 */
    .stateCleanup = nodeStateCleanup, /* 0.7.3 */
    .stateReload = nodeStateReload, /* 0.7.3 */
1982 1983
};

1984 1985 1986

int
udevNodeRegister(void)
1987
{
1988
    VIR_DEBUG("Registering udev node device backend");
1989

1990 1991
    if (virRegisterConnectDriver(&udevConnectDriver, false) < 0)
        return -1;
1992
    if (virSetSharedNodeDeviceDriver(&udevNodeDeviceDriver) < 0)
1993 1994 1995 1996
        return -1;

    return virRegisterStateDriver(&udevStateDriver);
}