コード例 #1
0
ファイル: raid.py プロジェクト: paride/probert
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 sane_block_devices(context):
        if 'MD_NAME' in device and device.get('DEVTYPE') == 'disk':
            devname = device['DEVNAME']
            attrs = udev_get_attributes(device)
            attrs['size'] = str(read_sys_block_size_bytes(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
ファイル: dmcrypt.py プロジェクト: paride/probert
def probe(context=None, report=False):
    """ Probing for dm_crypt devices requires running dmsetup info commands
        to collect how a particular dm-X device is composed.
    """
    # ignore supplied context, we need to read udev after scan/vgchange
    context = pyudev.Context()

    crypt_devices = {}

    # look for block devices with DM_UUID and CRYPT; these are crypt devices
    for device in sane_block_devices(context):
        if 'DM_UUID' in device and device['DM_UUID'].startswith('CRYPT'):
            devname = device['DEVNAME']
            dm_info = dmsetup_info(devname)
            crypt_devices[dm_info['name']] = dm_info

    return crypt_devices
コード例 #3
0
ファイル: storage.py プロジェクト: isabella232/probert
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
コード例 #4
0
def probe(context=None):
    """ Capture detected filesystems found on discovered block devices.  """
    filesystems = {}
    if not context:
        context = pyudev.Context()

    for device in sane_block_devices(context):
        # Ignore block major=1 (ramdisk) and major=7 (loopback)
        # these won't ever be used in recreating storage on target systems.
        if device['MAJOR'] not in ["1", "7"]:
            fs_info = get_device_filesystem(device)
            # The ID_FS_ udev values come from libblkid, which contains code to
            # recognize lots of different things that block devices or their
            # partitions can contain (filesystems, lvm PVs, bcache, ...).  We
            # only want to report things that are mountable filesystems here,
            # which libblkid conveniently tags with ID_FS_USAGE=filesystem.
            # Swap is a bit of a special case because it is not a mountable
            # filesystem in the usual sense, but subiquity still needs to
            # generate mount actions for it.
            if fs_info.get("USAGE") == "filesystem" or \
               fs_info.get("TYPE") == "swap":
                filesystems[device['DEVNAME']] = fs_info

    return filesystems
コード例 #5
0
ファイル: lvm.py プロジェクト: paride/probert
def probe(context=None):
    """ Probing for LVM devices requires initiating a kernel level scan
        of block devices to look for physical volumes, volume groups and
        logical volumes.  Once detected, the prober will activate any
        volume groups detected.

        The prober will refresh the udev context which brings in addition
        information relating to LVM devices.

        This prober relies on udev detecting devices via the 'DM_UUID'
        field and for each of such devices, the prober records the
        logical volume.

        For each logical volume, the prober determines the hosting
        volume_group and records detailed information about the group
        including members.  The process is repeated to determine the
        underlying physical volumes that are used to construct a
        volume group.

        Care is taken to handle scenarios where physical volumes are
        not yet allocated to a volume group (such as a linear VG).

        On newer systems (Disco+) the lvm2 software stack provides
        a rich reporting data dump in JSON format.  On systems with
        older LVM2 stacks, the LVM probe may be incomplete.
    """
    # scan and activate lvm vgs/lvs
    lvm_scan()
    activate_volgroups()

    # ignore supplied context, we need to read udev after scan/vgchange
    context = pyudev.Context()

    lvols = {}
    vgroups = {}
    pvols = {}
    vg_report = probe_vgs_report()

    for device in sane_block_devices(context):
        if 'DM_UUID' in device and device['DM_UUID'].startswith('LVM'):
            (lv_id, new_lv) = extract_lvm_partition(device)
            if lv_id not in lvols:
                lvols[lv_id] = new_lv
            else:
                log.error('Found duplicate logical volume: %s', lv_id)
                continue

            vg_name = device['DM_VG_NAME']
            (vg_id, new_vg) = extract_lvm_volgroup(vg_name, vg_report)
            if vg_id not in vgroups:
                vgroups[vg_id] = new_vg
            else:
                log.error('Found duplicate volume group: %s', vg_id)
                continue

            if vg_id not in pvols:
                pvols[vg_id] = new_vg['devices']

    lvm = {}
    if lvols:
        lvm.update({'logical_volumes': lvols})
    if pvols:
        lvm.update({'physical_volumes': pvols})
    if vgroups:
        lvm.update({'volume_groups': vgroups})

    return lvm