Пример #1
0
def probe(context=None, report=False):
    """Initiate an mdadm assemble to awaken existing MDADM devices.
       For each md block device, extract required information needed
       to describe the array for recreation or reuse as needed.

       mdadm tooling provides information about the raid type,
       the members, the size, the name, uuids, metadata version.
    """
    mdadm_assemble()

    # ignore passed context, must read udev after assembling mdadm devices
    context = pyudev.Context()

    raids = {}
    for device in context.list_devices(subsystem='block'):
        if 'MD_NAME' in device:
            devname = device['DEVNAME']
            attrs = udev_get_attributes(device)
            attrs['size'] = str(read_sys_block_size(devname))
            devices, spares = get_mdadm_array_members(devname, device)
            cfg = dict(device)
            cfg.update({'raidlevel': device['MD_LEVEL'],
                        'devices': devices,
                        'spare_devices': spares})
            raids[devname] = cfg

    return raids
Пример #2
0
    def probe(self):
        storage = {}
        for device in self.context.list_devices(subsystem='block'):
            if device['MAJOR'] not in ["1", "7"]:
                attrs = udev_get_attributes(device)
                # update the size attr as it may only be the number
                # of blocks rather than size in bytes.
                attrs['size'] = \
                    str(self._get_device_size(device['DEVNAME']))
                storage[device['DEVNAME']] = dict(device)
                storage[device['DEVNAME']].update({'attrs': attrs})

        self.results = storage
        return storage
Пример #3
0
 def link_change(self, action, data):
     log.debug('link_change %s %s', action, data)
     for k, v in data.items():
         if isinstance(v, bytes):
             data[k] = v.decode('utf-8', 'replace')
     ifindex = data['ifindex']
     if action == 'DEL':
         if ifindex in self._links:
             del self._links[ifindex]
             self.receiver.del_link(ifindex)
         return
     if action == 'CHANGE':
         if ifindex in self._links:
             dev = self._links[ifindex]
             # Trigger a scan when a wlan device goes up
             # Not sure if this is required as devices seem to scan as soon
             # as they go up? (in which case this fails with EBUSY, so it's
             # just spam in the logs).
             if dev.type == 'wlan':
                 if (not (dev.flags & IFF_UP)) and (data['flags'] & IFF_UP):
                     try:
                         self.trigger_scan(ifindex)
                     except RuntimeError:
                         log.exception('on-up trigger_scan failed')
             dev.netlink_data = data
             # If a device appears and is immediately renamed, the
             # initial _compute_type can fail to find the sysfs
             # directory. Have another go now.
             if dev.type is None:
                 dev.type = _compute_type(dev.name)
             dev.bond = _get_bonding(dev.name, dev.netlink_data['flags'])
         self.receiver.update_link(ifindex)
         return
     udev_devices = list(self.context.list_devices(IFINDEX=str(ifindex)))
     if len(udev_devices) == 0:
         # Has disappeared already?
         return
     udev_device = udev_devices[0]
     udev_data = dict(udev_device)
     udev_data['attrs'] = udev_get_attributes(udev_device)
     link = Link.from_probe_data(data, udev_data)
     self._links[ifindex] = link
     self.receiver.new_link(ifindex, link)
Пример #4
0
def blockdev_probe(context=None):
    """ Non-class method for extracting relevant block
        devices from pyudev.Context().
    """
    def _extract_partition_table(devname):
        cmd = ['sfdisk', '--bytes', '--json', devname]
        try:
            result = subprocess.run(cmd,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.DEVNULL)
            output = result.stdout.decode('utf-8')
        except subprocess.CalledProcessError as e:
            log.error('Failed to probe partition table on %s:%s', devname, e)
            return None
        if not output:
            return None
        ptable = {}
        try:
            ptable = json.loads(output)
        except json.decoder.JSONDecodeError:
            log.exception('Failed to load sfdisk json output:')
        return ptable

    if not context:
        context = pyudev.Context()

    blockdev = {}
    for device in sane_block_devices(context):
        if device['MAJOR'] not in ["1", "7"]:
            attrs = udev_get_attributes(device)
            # update the size attr as it may only be the number
            # of blocks rather than size in bytes.
            attrs['size'] = \
                str(read_sys_block_size_bytes(device['DEVNAME']))
            blockdev[device['DEVNAME']] = dict(device)
            blockdev[device['DEVNAME']].update({'attrs': attrs})
            # include partition table info if present
            ptable = _extract_partition_table(device['DEVNAME'])
            if ptable:
                blockdev[device['DEVNAME']].update(ptable)

    return blockdev
Пример #5
0
 def link_change(self, action, data):
     log.debug('link_change %s %s', action, data)
     for k, v in data.items():
         if isinstance(data, bytes):
             data[k] = data.decode('utf-8', 'replace')
     ifindex = data['ifindex']
     if action == 'DEL':
         if ifindex in self.links:
             del self.links[ifindex]
             self.del_link(ifindex)
         return
     if action == 'CHANGE':
         if ifindex in self.links:
             dev = self.links[ifindex]
             # Trigger a scan when a wlan device goes up
             # Not sure if this is required as devices seem to scan as soon
             # as they go up? (in which case this fails with EBUSY, so it's
             # just spam in the logs).
             if dev.type == 'wlan' and (not (dev.flags & IFF_UP)) and (
                     data['flags'] & IFF_UP):
                 try:
                     self.wlan_listener.trigger_scan(ifindex)
                 except RuntimeError:
                     log.exception('on-up trigger_scan failed')
             dev.update_from_netlink_data(data)
         self.update_link(ifindex)
         return
     udev_devices = list(self.context.list_devices(IFINDEX=str(ifindex)))
     if len(udev_devices) == 0:
         # Has disappeared already?
         return
     udev_device = udev_devices[0]
     udev_data = dict(udev_device)
     udev_data['attrs'] = udev_get_attributes(udev_device)
     link = NetworkInfo(data, udev_data)
     self.links[data['ifindex']] = link
     self.new_link(ifindex, link)