Finding only disk drives using pyudev

前端 未结 2 2096
不知归路
不知归路 2021-01-20 16:33

I\'m looking to enumerate all hard disks on a computer using udev and specifically pyudev to enumerate everything:

import pyudev

context = pyudev.Context()
         


        
相关标签:
2条回答
  • 2021-01-20 17:01

    Since udev only runs on Linux kernel (at least as of now), you could filter out by MAJOR number 8 which represents all SCSI/SATA disk driver based devices.

    for device in context.list_devices(MAJOR='8'):
        if (device.device_type == 'disk'):
            print "{}, ({})".format(device.device_node, device.device_type)
    

    On my system, your code outputs the following:

    /dev/sda, (disk)
    /dev/sdf, (disk)
    /dev/sdb, (disk)
    /dev/sdc, (disk)
    /dev/sdd, (disk)
    /dev/sde, (disk)
    /dev/sr0, (disk)
    /dev/loop0, (disk)
    /dev/loop1, (disk)
    /dev/loop2, (disk)
    /dev/loop3, (disk)
    /dev/loop4, (disk)
    /dev/loop5, (disk)
    /dev/loop6, (disk)
    /dev/loop7, (disk)
    

    After filtering by major number 8, I see the following output:

    /dev/sda, (disk)
    /dev/sdf, (disk)
    /dev/sdb, (disk)
    /dev/sdc, (disk)
    /dev/sdd, (disk)
    /dev/sde, (disk)
    

    Note that you would also get USB hard drives and USB sticks in the list, since they also tend to use the same SCSI disk driver.

    I'm not really sure if IDE hard drives are mapped as sdX or hdX with the latest 2.6 or 3.x kernels. Do not have an IDE hard drive to verify and long since I have had one. :D

    UPDATE: The same device number page lists /dev/hdX to be the one used by IDE hard drives (and IDE cdroms too may be ?). If you want to filter these as well, I believe you could do something like this:

    for device in context.list_devices(DEVTYPE='disk'):
        major = device['MAJOR']
        if major == '8' or major == '3':
            print "{}, ({})".format(device.device_node, device.device_type)
    
    0 讨论(0)
  • 2021-01-20 17:11

    Since the device management under udev is very flexible, it may depend on the udev rules installed in /lib/udev/rules.d or /etc/udev/rules.d that determine what keys you can filter on.

    You can use udevadm to get a list of devices and their associated udev keys.

    sudo udevadm info --export-db
    

    Similarly, your script could be modified to output this information as follows:

    #!/usr/bin/env python
    import pyudev
    
    context = pyudev.Context()
    
    for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
        for key, value in device.iteritems():
            print '{key}={value}'.format(key=key, value=value)
        print
    

    This will allow you to determine what keys are available for filtering. On my Debian system, some of the entries look like this:

    # Loop device
    UDEV_LOG=3
    DEVPATH=/devices/virtual/block/loop0
    MAJOR=7
    MINOR=0
    DEVNAME=/dev/loop0
    DEVTYPE=disk
    SUBSYSTEM=block
    UDISKS_PRESENTATION_NOPOLICY=1
    DEVLINKS=/dev/block/7:0
    
    #cdrom
    UDEV_LOG=3
    DEVPATH=/devices/pci0000:00/0000:00:01.1/host1/target1:0:0/1:0:0:0/block/sr0
    MAJOR=11
    MINOR=0
    DEVNAME=/dev/sr0
    DEVTYPE=disk
    SUBSYSTEM=block
    ID_CDROM=1
    ID_CDROM_DVD=1
    ID_CDROM_MRW=1
    ID_CDROM_MRW_W=1
    ID_SCSI=1
    ID_VENDOR=VBOX
    ID_VENDOR_ENC=VBOX\x20\x20\x20\x20
    ID_MODEL=CD-ROM
    ID_MODEL_ENC=CD-ROM\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
    ID_REVISION=1.0
    ID_TYPE=cd
    ID_BUS=scsi
    ID_PATH=pci-0000:00:01.1-scsi-1:0:0:0
    GENERATED=1
    UDISKS_PRESENTATION_NOPOLICY=0
    DEVLINKS=/dev/block/11:0 /dev/scd0 /dev/disk/by-path/pci-0000:00:01.1-scsi-1:0:0:0 /dev/cdrom /dev/dvd
    TAGS=:udev-acl:
    
    # hard disk
    UDEV_LOG=3
    DEVPATH=/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0/block/sda
    MAJOR=8
    MINOR=0
    DEVNAME=/dev/sda
    DEVTYPE=disk
    SUBSYSTEM=block
    ID_ATA=1
    ID_TYPE=disk
    ID_BUS=ata
    

    It would be possible to filter on these key/value pairs to return just those disks which are real. The UDISKS_PRESENTATION_NOPOLICY entry for example, can be used to filter out loop devices. You can peruse the udev rules to determine how it tries to distinguish between real/virtual disks.

    Something like this will filter out cdroms and loop devices:

    devices = []
    for device in context.list_devices(subsystem='block', DEVTYPE='disk'):
        # Filter out cd drives, loop devices.
        if device.get('ID_TYPE', '') == 'cd':
            continue
        if device.get('UDISKS_PRESENTATION_NOPOLICY', '0') == '1':
            continue
        devices.append(device)
    
    print "HARD DISKS:"
    
    0 讨论(0)
提交回复
热议问题