Merge ~raharper/curtin:ubuntu/eoan-sru-20200130 into curtin:ubuntu/eoan

Proposed by Ryan Harper
Status: Merged
Merged at revision: 1c2b677876854b6639ae0ff8bdb6eebdf01f35e9
Proposed branch: ~raharper/curtin:ubuntu/eoan-sru-20200130
Merge into: curtin:ubuntu/eoan
Diff against target: 15603 lines (+12330/-488)
87 files modified
HACKING.rst (+3/-4)
curtin/__init__.py (+1/-1)
curtin/block/clear_holders.py (+88/-21)
curtin/block/multipath.py (+74/-2)
curtin/block/schemas.py (+7/-1)
curtin/block/zfs.py (+24/-0)
curtin/commands/block_meta.py (+99/-46)
curtin/commands/curthooks.py (+200/-53)
curtin/commands/install.py (+5/-1)
curtin/distro.py (+25/-2)
curtin/net/deps.py (+3/-3)
curtin/storage_config.py (+105/-20)
curtin/udev.py (+15/-7)
curtin/util.py (+12/-5)
debian/changelog (+63/-0)
debian/control (+1/-1)
doc/topics/config.rst (+6/-1)
doc/topics/storage.rst (+17/-2)
examples/tests/basic-dasd.yaml (+2/-2)
examples/tests/bcache-ceph-nvme-simple.yaml (+107/-0)
examples/tests/bcache-wipe-xfs.yaml (+4/-3)
examples/tests/bridging_network_v2.yaml (+38/-0)
examples/tests/dirty_disks_config.yaml (+9/-1)
examples/tests/network_mtu_networkd.yaml (+93/-0)
examples/tests/reuse-raid-member-partition.yaml (+73/-0)
examples/tests/reuse-raid-member-wipe.yaml (+71/-0)
helpers/common (+84/-13)
tests/data/probert_storage_multipath.json (+1059/-0)
tests/data/probert_storage_raid1_partitions.json (+951/-0)
tests/data/probert_storage_zlp6.json (+6980/-0)
tests/unittests/test_block.py (+26/-0)
tests/unittests/test_block_dasd.py (+1/-1)
tests/unittests/test_block_multipath.py (+87/-6)
tests/unittests/test_block_zfs.py (+26/-0)
tests/unittests/test_clear_holders.py (+131/-11)
tests/unittests/test_commands_block_meta.py (+377/-36)
tests/unittests/test_commands_collect_logs.py (+3/-1)
tests/unittests/test_curthooks.py (+311/-26)
tests/unittests/test_distro.py (+71/-0)
tests/unittests/test_storage_config.py (+114/-9)
tests/unittests/test_udev.py (+15/-14)
tests/unittests/test_util.py (+41/-1)
tests/vmtests/__init__.py (+231/-23)
tests/vmtests/helpers.py (+11/-6)
tests/vmtests/releases.py (+34/-0)
tests/vmtests/test_apt_config_cmd.py (+1/-4)
tests/vmtests/test_basic.py (+71/-81)
tests/vmtests/test_basic_dasd.py (+8/-10)
tests/vmtests/test_bcache_basic.py (+5/-0)
tests/vmtests/test_bcache_bug1718699.py (+5/-0)
tests/vmtests/test_bcache_ceph.py (+31/-0)
tests/vmtests/test_bcache_partitions.py (+5/-0)
tests/vmtests/test_fs_battery.py (+5/-0)
tests/vmtests/test_iscsi.py (+6/-0)
tests/vmtests/test_journald_reporter.py (+5/-4)
tests/vmtests/test_lvm.py (+15/-18)
tests/vmtests/test_lvm_iscsi.py (+5/-0)
tests/vmtests/test_lvm_raid.py (+4/-0)
tests/vmtests/test_lvm_root.py (+16/-1)
tests/vmtests/test_mdadm_bcache.py (+92/-12)
tests/vmtests/test_mdadm_iscsi.py (+5/-0)
tests/vmtests/test_multipath.py (+6/-0)
tests/vmtests/test_network.py (+4/-0)
tests/vmtests/test_network_alias.py (+5/-0)
tests/vmtests/test_network_bonding.py (+4/-0)
tests/vmtests/test_network_bridging.py (+23/-0)
tests/vmtests/test_network_ipv6_static.py (+4/-0)
tests/vmtests/test_network_ipv6_vlan.py (+8/-0)
tests/vmtests/test_network_mtu.py (+42/-10)
tests/vmtests/test_network_static.py (+4/-0)
tests/vmtests/test_network_static_routes.py (+5/-0)
tests/vmtests/test_network_vlan.py (+12/-0)
tests/vmtests/test_nvme.py (+5/-0)
tests/vmtests/test_old_apt_features.py (+3/-2)
tests/vmtests/test_pollinate_useragent.py (+5/-0)
tests/vmtests/test_preserve.py (+5/-0)
tests/vmtests/test_preserve_raid.py (+5/-0)
tests/vmtests/test_raid5_bcache.py (+5/-0)
tests/vmtests/test_reuse_raid_member.py (+63/-0)
tests/vmtests/test_simple.py (+16/-1)
tests/vmtests/test_uefi_basic.py (+11/-1)
tests/vmtests/test_zfsroot.py (+18/-2)
tools/block-discover-to-config (+3/-1)
tools/jenkins-runner (+50/-0)
tools/vmtest-filter (+12/-1)
tools/vmtest-sync-images (+15/-13)
tools/xkvm (+20/-4)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Needs Fixing
Dan Watkins (community) Approve
Review via email: mp+378355@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Dan Watkins (oddbloke) wrote :

After manually adding the SRU bug number, the ~19.10.1 version suffix and removing all other bug references, I see the same locally. Thanks!

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/HACKING.rst b/HACKING.rst
index d87552b..7c26a25 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -15,12 +15,11 @@ Do these things once
15 be listed in the `contributor-agreement-canonical`_ group. Unfortunately15 be listed in the `contributor-agreement-canonical`_ group. Unfortunately
16 there is no easy way to check if an organization or company you are doing16 there is no easy way to check if an organization or company you are doing
17 work for has signed. If you are unsure or have questions, email17 work for has signed. If you are unsure or have questions, email
18 `Scott Moser <mailto:scott.moser@canonical.com>`_ and18 `Josh Powers <mailto:josh.powers@canonical.com>` or ping powersj in
19 `Ryan Harper <mailto:ryan.harper@canonical.com>`_ or ping smoser or rharper19 ``#curtin`` channel via Freenode IRC.
20 in ``#curtin`` channel via Freenode IRC.
2120
22 When prompted for 'Project contact' or 'Canonical Project Manager' enter21 When prompted for 'Project contact' or 'Canonical Project Manager' enter
23 'David Britton'.22 'Josh Powers'.
2423
25* Configure git with your email and name for commit messages.24* Configure git with your email and name for commit messages.
2625
diff --git a/curtin/__init__.py b/curtin/__init__.py
index 593231e..142d288 100644
--- a/curtin/__init__.py
+++ b/curtin/__init__.py
@@ -32,6 +32,6 @@ FEATURES = [
32 'HAS_VERSION_MODULE',32 'HAS_VERSION_MODULE',
33]33]
3434
35__version__ = "19.2"35__version__ = "19.3"
3636
37# vi: ts=4 expandtab syntax=python37# vi: ts=4 expandtab syntax=python
diff --git a/curtin/block/clear_holders.py b/curtin/block/clear_holders.py
index 4a099cd..b691841 100644
--- a/curtin/block/clear_holders.py
+++ b/curtin/block/clear_holders.py
@@ -166,14 +166,27 @@ def shutdown_mdadm(device):
166166
167 blockdev = block.sysfs_to_devpath(device)167 blockdev = block.sysfs_to_devpath(device)
168168
169 LOG.info('Wiping superblock on raid device: %s', device)169 LOG.info('Discovering raid devices and spares for %s', device)
170 _wipe_superblock(blockdev, exclusive=False)
171
172 md_devs = (170 md_devs = (
173 mdadm.md_get_devices_list(blockdev) +171 mdadm.md_get_devices_list(blockdev) +
174 mdadm.md_get_spares_list(blockdev))172 mdadm.md_get_spares_list(blockdev))
175 mdadm.set_sync_action(blockdev, action="idle")173 mdadm.set_sync_action(blockdev, action="idle")
176 mdadm.set_sync_action(blockdev, action="frozen")174 mdadm.set_sync_action(blockdev, action="frozen")
175
176 LOG.info('Wiping superblock on raid device: %s', device)
177 try:
178 _wipe_superblock(blockdev, exclusive=False)
179 except ValueError as e:
180 # if the array is not functional, writes to the device may fail
181 # and _wipe_superblock will raise ValueError for short writes
182 # which happens on inactive raid volumes. In that case we
183 # shouldn't give up yet as we still want to disassemble
184 # array and wipe members. Other errors such as IOError or OSError
185 # are unwelcome and will stop deployment.
186 LOG.debug('Non-fatal error writing to array device %s, '
187 'proceeding with shutdown: %s', blockdev, e)
188
189 LOG.info('Removing raid array members: %s', md_devs)
177 for mddev in md_devs:190 for mddev in md_devs:
178 try:191 try:
179 mdadm.fail_device(blockdev, mddev)192 mdadm.fail_device(blockdev, mddev)
@@ -272,7 +285,26 @@ def wipe_superblock(device):
272 else:285 else:
273 bcache._stop_device(stop_path)286 bcache._stop_device(stop_path)
274287
275 _wipe_superblock(blockdev)288 # the blockdev (e.g. /dev/sda2) may be a multipath partition which can
289 # only be wiped via its device mapper device (e.g. /dev/dm-4)
290 # check for this and determine the correct device mapper value to use.
291 mp_dev = None
292 mp_support = multipath.multipath_supported()
293 if mp_support:
294 parent, partnum = block.get_blockdev_for_partition(blockdev)
295 parent_mpath_id = multipath.find_mpath_id_by_path(parent)
296 if parent_mpath_id is not None:
297 # construct multipath dmsetup id
298 # <mpathid>-part%d -> /dev/dm-1
299 mp_id, mp_dev = multipath.find_mpath_id_by_parent(parent_mpath_id,
300 partnum=partnum)
301 # if we don't find a mapping then the mp partition has already been
302 # wiped/removed
303 if mp_dev:
304 LOG.debug('Found multipath device over %s, wiping holder %s',
305 blockdev, mp_dev)
306
307 _wipe_superblock(mp_dev if mp_dev else blockdev)
276308
277 # if we had partitions, make sure they've been removed309 # if we had partitions, make sure they've been removed
278 if partitions:310 if partitions:
@@ -295,16 +327,19 @@ def wipe_superblock(device):
295 device, attempt + 1, len(retries), wait)327 device, attempt + 1, len(retries), wait)
296 time.sleep(wait)328 time.sleep(wait)
297329
298 # multipath partitions are separate block devices (disks)330 if mp_support:
299 if multipath.is_mpath_partition(blockdev):331 # multipath partitions are separate block devices (disks)
300 multipath.remove_partition(blockdev)332 if mp_dev or multipath.is_mpath_partition(blockdev):
301 # multipath devices must be hidden to utilize a single member (path)333 multipath.remove_partition(mp_dev if mp_dev else blockdev)
302 elif multipath.is_mpath_device(blockdev):334 # multipath devices must be hidden to utilize a single member (path)
303 mp_id = multipath.find_mpath_id(blockdev)335 elif multipath.is_mpath_device(blockdev):
304 if mp_id:336 mp_id = multipath.find_mpath_id(blockdev)
305 multipath.remove_map(mp_id)337 multipath.remove_partition(blockdev)
306 else:338 if mp_id:
307 raise RuntimeError('Failed to find multipath id for %s' % blockdev)339 multipath.remove_map(mp_id)
340 else:
341 raise RuntimeError(
342 'Failed to find multipath id for %s' % blockdev)
308343
309344
310def _wipe_superblock(blockdev, exclusive=True, strict=True):345def _wipe_superblock(blockdev, exclusive=True, strict=True):
@@ -456,25 +491,39 @@ def plan_shutdown_holder_trees(holders_trees):
456 if not isinstance(holders_trees, (list, tuple)):491 if not isinstance(holders_trees, (list, tuple)):
457 holders_trees = [holders_trees]492 holders_trees = [holders_trees]
458493
494 # sort the trees to ensure we generate a consistent plan
495 holders_trees = sorted(holders_trees, key=lambda x: x['device'])
496
497 def htree_level(tree):
498 if len(tree['holders']) == 0:
499 return 0
500 return 1 + sum(htree_level(holder) for holder in tree['holders'])
501
459 def flatten_holders_tree(tree, level=0):502 def flatten_holders_tree(tree, level=0):
460 """503 """
461 add entries from holders tree to registry with level key corresponding504 add entries from holders tree to registry with level key corresponding
462 to how many layers from raw disks the current device is at505 to how many layers from raw disks the current device is at
463 """506 """
464 device = tree['device']507 device = tree['device']
508 device_level = htree_level(tree)
465509
466 # always go with highest level if current device has been510 # always go with highest level if current device has been
467 # encountered already. since the device and everything above it is511 # encountered already. since the device and everything above it is
468 # re-added to the registry it ensures that any increase of level512 # re-added to the registry it ensures that any increase of level
469 # required here will propagate down the tree513 # required here will propagate down the tree
470 # this handles a scenario like mdadm + bcache, where the backing514 # this handles a scenario like mdadm + bcache, where the backing
471 # device for bcache is a 3nd level item like mdadm, but the cache515 # device for bcache is a 3rd level item like mdadm, but the cache
472 # device is 1st level (disk) or second level (partition), ensuring516 # device is 1st level (disk) or second level (partition), ensuring
473 # that the bcache item is always considered higher level than517 # that the bcache item is always considered higher level than
474 # anything else regardless of whether it was added to the tree via518 # anything else regardless of whether it was added to the tree via
475 # the cache device or backing device first519 # the cache device or backing device first
476 if device in reg:520 if device in reg:
477 level = max(reg[device]['level'], level)521 level = max(reg[device]['level'], level) + 1
522
523 else:
524 # first time device to registry, assume the larger value of the
525 # current level or the length of its dependencies.
526 level = max(device_level, level)
478527
479 reg[device] = {'level': level, 'device': device,528 reg[device] = {'level': level, 'device': device,
480 'dev_type': tree['dev_type']}529 'dev_type': tree['dev_type']}
@@ -487,10 +536,26 @@ def plan_shutdown_holder_trees(holders_trees):
487 for holders_tree in holders_trees:536 for holders_tree in holders_trees:
488 flatten_holders_tree(holders_tree)537 flatten_holders_tree(holders_tree)
489538
490 # return list of entry dicts with highest level first, then dev_type539 def devtype_order(dtype):
540 """Return the order in which we want to clear device types, higher
541 value should be cleared first.
542
543 :param: dtype: string. A device types name from the holders registry,
544 see _define_handlers_registry()
545 :returns: integer
546 """
547 dev_type_order = [
548 'disk', 'partition', 'bcache', 'lvm', 'raid', 'crypt']
549 return 1 + dev_type_order.index(dtype)
550
551 # return list of entry dicts with greatest htree depth. The 'level' value
552 # indicates the number of additional devices that are "below" this device.
553 # Devices must be cleared in descending 'level' value. For devices which
554 # have the same 'level' value, we sort within the 'level' by devtype order.
491 return [reg[k]555 return [reg[k]
492 for k in sorted(reg, key=lambda x: (reg[x]['level'] * -1,556 for k in sorted(reg, reverse=True,
493 reg[x]['dev_type']))]557 key=lambda x: (reg[x]['level'],
558 devtype_order(reg[x]['dev_type'])))]
494559
495560
496def format_holders_tree(holders_tree):561def format_holders_tree(holders_tree):
@@ -534,8 +599,10 @@ def assert_clear(base_paths):
534 valid = ('disk', 'partition')599 valid = ('disk', 'partition')
535 if not isinstance(base_paths, (list, tuple)):600 if not isinstance(base_paths, (list, tuple)):
536 base_paths = [base_paths]601 base_paths = [base_paths]
537 base_paths = [block.sys_block_path(path) for path in base_paths]602 base_paths = [block.sys_block_path(path, strict=False)
538 for holders_tree in [gen_holders_tree(p) for p in base_paths]:603 for path in base_paths]
604 for holders_tree in [gen_holders_tree(p)
605 for p in base_paths if os.path.exists(p)]:
539 if any(holder_type not in valid and path not in base_paths606 if any(holder_type not in valid and path not in base_paths
540 for (holder_type, path) in get_holder_types(holders_tree)):607 for (holder_type, path) in get_holder_types(holders_tree)):
541 raise OSError('Storage not clear, remaining:\n{}'608 raise OSError('Storage not clear, remaining:\n{}'
diff --git a/curtin/block/multipath.py b/curtin/block/multipath.py
index d1e8441..8ce0509 100644
--- a/curtin/block/multipath.py
+++ b/curtin/block/multipath.py
@@ -11,6 +11,7 @@ SHOW_MAPS_FMT = "name=%n multipath='%w' sysfs='%d' paths='%N'"
1111
1212
13def _extract_mpath_data(cmd, show_verb):13def _extract_mpath_data(cmd, show_verb):
14 """ Parse output from specifed command output via load_shell_content."""
14 data, _err = util.subp(cmd, capture=True)15 data, _err = util.subp(cmd, capture=True)
15 result = []16 result = []
16 for line in data.splitlines():17 for line in data.splitlines():
@@ -23,16 +24,34 @@ def _extract_mpath_data(cmd, show_verb):
2324
2425
25def show_paths():26def show_paths():
27 """ Query multipathd for paths output and return a dict of the values."""
26 cmd = ['multipathd', 'show', 'paths', 'raw', 'format', SHOW_PATHS_FMT]28 cmd = ['multipathd', 'show', 'paths', 'raw', 'format', SHOW_PATHS_FMT]
27 return _extract_mpath_data(cmd, 'paths')29 return _extract_mpath_data(cmd, 'paths')
2830
2931
30def show_maps():32def show_maps():
33 """ Query multipathd for maps output and return a dict of the values."""
31 cmd = ['multipathd', 'show', 'maps', 'raw', 'format', SHOW_MAPS_FMT]34 cmd = ['multipathd', 'show', 'maps', 'raw', 'format', SHOW_MAPS_FMT]
32 return _extract_mpath_data(cmd, 'maps')35 return _extract_mpath_data(cmd, 'maps')
3336
3437
38def dmname_to_blkdev_mapping():
39 """ Use dmsetup ls output to build a dict of DM_NAME, /dev/dm-x values."""
40 data, _err = util.subp(['dmsetup', 'ls', '-o', 'blkdevname'], capture=True)
41 mapping = {}
42 if data and data.strip() != "No devices found":
43 LOG.debug('multipath: dmsetup ls output:\n%s', data)
44 for line in data.splitlines():
45 if line:
46 dm_name, blkdev = line.split('\t')
47 # (dm-1) -> /dev/dm-1
48 mapping[dm_name] = '/dev/' + blkdev.strip('()')
49
50 return mapping
51
52
35def is_mpath_device(devpath):53def is_mpath_device(devpath):
54 """ Check if devpath is a multipath device, returns boolean. """
36 info = udev.udevadm_info(devpath)55 info = udev.udevadm_info(devpath)
37 if info.get('DM_UUID', '').startswith('mpath-'):56 if info.get('DM_UUID', '').startswith('mpath-'):
38 return True57 return True
@@ -41,6 +60,7 @@ def is_mpath_device(devpath):
4160
4261
43def is_mpath_member(devpath):62def is_mpath_member(devpath):
63 """ Check if a device is a multipath member (a path), returns boolean. """
44 try:64 try:
45 util.subp(['multipath', '-c', devpath], capture=True)65 util.subp(['multipath', '-c', devpath], capture=True)
46 return True66 return True
@@ -49,6 +69,7 @@ def is_mpath_member(devpath):
4969
5070
51def is_mpath_partition(devpath):71def is_mpath_partition(devpath):
72 """ Check if a device is a multipath partition, returns boolean. """
52 if devpath.startswith('/dev/dm-'):73 if devpath.startswith('/dev/dm-'):
53 if 'DM_PART' in udev.udevadm_info(devpath):74 if 'DM_PART' in udev.udevadm_info(devpath):
54 LOG.debug("%s is multipath device partition", devpath)75 LOG.debug("%s is multipath device partition", devpath)
@@ -58,6 +79,7 @@ def is_mpath_partition(devpath):
5879
5980
60def mpath_partition_to_mpath_id(devpath):81def mpath_partition_to_mpath_id(devpath):
82 """ Return the mpath id of a multipath partition. """
61 info = udev.udevadm_info(devpath)83 info = udev.udevadm_info(devpath)
62 if 'DM_MPATH' in info:84 if 'DM_MPATH' in info:
63 return info['DM_MPATH']85 return info['DM_MPATH']
@@ -66,9 +88,10 @@ def mpath_partition_to_mpath_id(devpath):
6688
6789
68def remove_partition(devpath, retries=10):90def remove_partition(devpath, retries=10):
91 """ Remove a multipath partition mapping. """
69 LOG.debug('multipath: removing multipath partition: %s', devpath)92 LOG.debug('multipath: removing multipath partition: %s', devpath)
70 for _ in range(0, retries):93 for _ in range(0, retries):
71 util.subp(['dmsetup', 'remove', devpath], rcs=[0, 1])94 util.subp(['dmsetup', 'remove', '--force', '--retry', devpath])
72 udev.udevadm_settle()95 udev.udevadm_settle()
73 if not os.path.exists(devpath):96 if not os.path.exists(devpath):
74 return97 return
@@ -77,10 +100,11 @@ def remove_partition(devpath, retries=10):
77100
78101
79def remove_map(map_id, retries=10):102def remove_map(map_id, retries=10):
103 """ Remove a multipath device mapping. """
80 LOG.debug('multipath: removing multipath map: %s', map_id)104 LOG.debug('multipath: removing multipath map: %s', map_id)
81 devpath = '/dev/mapper/%s' % map_id105 devpath = '/dev/mapper/%s' % map_id
82 for _ in range(0, retries):106 for _ in range(0, retries):
83 util.subp(['multipath', '-f', map_id], rcs=[0, 1])107 util.subp(['multipath', '-v3', '-R3', '-f', map_id], rcs=[0, 1])
84 udev.udevadm_settle()108 udev.udevadm_settle()
85 if not os.path.exists(devpath):109 if not os.path.exists(devpath):
86 return110 return
@@ -89,6 +113,7 @@ def remove_map(map_id, retries=10):
89113
90114
91def find_mpath_members(multipath_id, paths=None):115def find_mpath_members(multipath_id, paths=None):
116 """ Return a list of device path for each member of aspecified mpath_id."""
92 if not paths:117 if not paths:
93 paths = show_paths()118 paths = show_paths()
94119
@@ -98,6 +123,7 @@ def find_mpath_members(multipath_id, paths=None):
98123
99124
100def find_mpath_id(devpath, maps=None):125def find_mpath_id(devpath, maps=None):
126 """ Return the mpath_id associated with a specified device path. """
101 if not maps:127 if not maps:
102 maps = show_maps()128 maps = show_maps()
103129
@@ -109,3 +135,49 @@ def find_mpath_id(devpath, maps=None):
109 return mpmap['multipath']135 return mpmap['multipath']
110136
111 return None137 return None
138
139
140def find_mpath_id_by_path(devpath, paths=None):
141 """ Return the mpath_id associated with a specified device path. """
142 if not paths:
143 paths = show_paths()
144
145 for path in paths:
146 if devpath == '/dev/' + path['device']:
147 return path['multipath']
148
149 return None
150
151
152def find_mpath_id_by_parent(multipath_id, partnum=None):
153 """ Return the mpath_id associated with a specified device path. """
154 devmap = dmname_to_blkdev_mapping()
155 LOG.debug('multipath: dm_name blk map: %s', devmap)
156 dm_name = multipath_id
157 if partnum:
158 dm_name += "-part%d" % int(partnum)
159
160 return (dm_name, devmap.get(dm_name))
161
162
163def multipath_supported():
164 """Return a boolean indicating if multipath is supported."""
165 try:
166 multipath_assert_supported()
167 return True
168 except RuntimeError:
169 return False
170
171
172def multipath_assert_supported():
173 """ Determine if the runtime system supports multipath.
174 returns: True if system supports multipath
175 raises: RuntimeError: if system does not support multipath
176 """
177 missing_progs = [p for p in ('multipath', 'multipathd')
178 if not util.which(p)]
179 if missing_progs:
180 raise RuntimeError(
181 "Missing multipath utils: %s" % ','.join(missing_progs))
182
183# vi: ts=4 expandtab syntax=python
diff --git a/curtin/block/schemas.py b/curtin/block/schemas.py
index f754ccc..fc7e522 100644
--- a/curtin/block/schemas.py
+++ b/curtin/block/schemas.py
@@ -7,6 +7,8 @@ _path_nondev = r'(^/$|^(/[^/]+)+$)'
7_fstypes = ['btrfs', 'ext2', 'ext3', 'ext4', 'fat', 'fat12', 'fat16', 'fat32',7_fstypes = ['btrfs', 'ext2', 'ext3', 'ext4', 'fat', 'fat12', 'fat16', 'fat32',
8 'iso9660', 'vfat', 'jfs', 'ntfs', 'reiserfs', 'swap', 'xfs',8 'iso9660', 'vfat', 'jfs', 'ntfs', 'reiserfs', 'swap', 'xfs',
9 'zfsroot']9 'zfsroot']
10_ptables = ['dos', 'gpt', 'msdos', 'vtoc']
11_ptable_unsupported = 'unsupported'
1012
11definitions = {13definitions = {
12 'id': {'type': 'string'},14 'id': {'type': 'string'},
@@ -14,7 +16,7 @@ definitions = {
14 'devices': {'type': 'array', 'items': {'$ref': '#/definitions/ref_id'}},16 'devices': {'type': 'array', 'items': {'$ref': '#/definitions/ref_id'}},
15 'name': {'type': 'string'},17 'name': {'type': 'string'},
16 'preserve': {'type': 'boolean'},18 'preserve': {'type': 'boolean'},
17 'ptable': {'type': 'string', 'enum': ['dos', 'gpt', 'msdos']},19 'ptable': {'type': 'string', 'enum': _ptables + [_ptable_unsupported]},
18 'size': {'type': ['string', 'number'],20 'size': {'type': ['string', 'number'],
19 'minimum': 1,21 'minimum': 1,
20 'pattern': r'^([1-9]\d*(.\d+)?|\d+.\d+)(K|M|G|T)?B?'},22 'pattern': r'^([1-9]\d*(.\d+)?|\d+.\d+)(K|M|G|T)?B?'},
@@ -119,6 +121,7 @@ DISK = {
119 'properties': {121 'properties': {
120 'id': {'$ref': '#/definitions/id'},122 'id': {'$ref': '#/definitions/id'},
121 'name': {'$ref': '#/definitions/name'},123 'name': {'$ref': '#/definitions/name'},
124 'multipath': {'type': 'string'},
122 'preserve': {'$ref': '#/definitions/preserve'},125 'preserve': {'$ref': '#/definitions/preserve'},
123 'wipe': {'$ref': '#/definitions/wipe'},126 'wipe': {'$ref': '#/definitions/wipe'},
124 'type': {'const': 'disk'},127 'type': {'const': 'disk'},
@@ -265,6 +268,7 @@ PARTITION = {
265 'additionalProperties': False,268 'additionalProperties': False,
266 'properties': {269 'properties': {
267 'id': {'$ref': '#/definitions/id'},270 'id': {'$ref': '#/definitions/id'},
271 'multipath': {'type': 'string'},
268 'name': {'$ref': '#/definitions/name'},272 'name': {'$ref': '#/definitions/name'},
269 'offset': {'$ref': '#/definitions/size'}, # XXX: This is not used273 'offset': {'$ref': '#/definitions/size'}, # XXX: This is not used
270 'preserve': {'$ref': '#/definitions/preserve'},274 'preserve': {'$ref': '#/definitions/preserve'},
@@ -296,6 +300,8 @@ RAID = {
296 'devices': {'$ref': '#/definitions/devices'},300 'devices': {'$ref': '#/definitions/devices'},
297 'name': {'$ref': '#/definitions/name'},301 'name': {'$ref': '#/definitions/name'},
298 'mdname': {'$ref': '#/definitions/name'}, # XXX: Docs need updating302 'mdname': {'$ref': '#/definitions/name'}, # XXX: Docs need updating
303 'metadata': {'type': ['string', 'number']},
304 'preserve': {'$ref': '#/definitions/preserve'},
299 'ptable': {'$ref': '#/definitions/ptable'},305 'ptable': {'$ref': '#/definitions/ptable'},
300 'spare_devices': {'$ref': '#/definitions/devices'},306 'spare_devices': {'$ref': '#/definitions/devices'},
301 'type': {'const': 'raid'},307 'type': {'const': 'raid'},
diff --git a/curtin/block/zfs.py b/curtin/block/zfs.py
index dce15c3..25751d3 100644
--- a/curtin/block/zfs.py
+++ b/curtin/block/zfs.py
@@ -281,4 +281,28 @@ def device_to_poolname(devname):
281 if vdev_type == 'zfs_member' and label:281 if vdev_type == 'zfs_member' and label:
282 return label282 return label
283283
284
285def get_zpool_from_config(cfg):
286 """Parse a curtin storage config and return a list
287 of zpools that were created.
288 """
289 if not cfg:
290 return []
291
292 if 'storage' not in cfg:
293 return []
294
295 zpools = []
296 sconfig = cfg['storage']['config']
297 for item in sconfig:
298 if item['type'] == 'zpool':
299 zpools.append(item['pool'])
300 elif item['type'] == 'format':
301 if item['fstype'] == 'zfsroot':
302 # curtin.commands.blockmeta sets pool='rpool' for zfsroot
303 zpools.append('rpool')
304
305 return zpools
306
307
284# vi: ts=4 expandtab syntax=python308# vi: ts=4 expandtab syntax=python
diff --git a/curtin/commands/block_meta.py b/curtin/commands/block_meta.py
index a9110a9..f287bd4 100644
--- a/curtin/commands/block_meta.py
+++ b/curtin/commands/block_meta.py
@@ -2,6 +2,7 @@
22
3from collections import OrderedDict, namedtuple3from collections import OrderedDict, namedtuple
4from curtin import (block, config, paths, util)4from curtin import (block, config, paths, util)
5from curtin.block import schemas
5from curtin.block import (bcache, clear_holders, dasd, iscsi, lvm, mdadm, mkfs,6from curtin.block import (bcache, clear_holders, dasd, iscsi, lvm, mdadm, mkfs,
6 zfs)7 zfs)
7from curtin import distro8from curtin import distro
@@ -32,6 +33,7 @@ SIMPLE = 'simple'
32SIMPLE_BOOT = 'simple-boot'33SIMPLE_BOOT = 'simple-boot'
33CUSTOM = 'custom'34CUSTOM = 'custom'
34BCACHE_REGISTRATION_RETRY = [0.2] * 6035BCACHE_REGISTRATION_RETRY = [0.2] * 60
36PTABLE_UNSUPPORTED = schemas._ptable_unsupported
3537
36CMD_ARGUMENTS = (38CMD_ARGUMENTS = (
37 ((('-D', '--devices'),39 ((('-D', '--devices'),
@@ -58,7 +60,7 @@ CMD_ARGUMENTS = (
58@logged_time("BLOCK_META")60@logged_time("BLOCK_META")
59def block_meta(args):61def block_meta(args):
60 # main entry point for the block-meta command.62 # main entry point for the block-meta command.
61 state = util.load_command_environment()63 state = util.load_command_environment(strict=True)
62 cfg = config.load_command_config(args, state)64 cfg = config.load_command_config(args, state)
63 dd_images = util.get_dd_images(cfg.get('sources', {}))65 dd_images = util.get_dd_images(cfg.get('sources', {}))
6466
@@ -67,7 +69,7 @@ def block_meta(args):
67 if devices is None:69 if devices is None:
68 devices = []70 devices = []
69 if 'storage' in cfg:71 if 'storage' in cfg:
70 devices = get_disk_paths_from_storage_config(72 devices = get_device_paths_from_storage_config(
71 extract_storage_ordered_dict(cfg))73 extract_storage_ordered_dict(cfg))
72 if len(devices) == 0:74 if len(devices) == 0:
73 devices = cfg.get('block-meta', {}).get('devices', [])75 devices = cfg.get('block-meta', {}).get('devices', [])
@@ -258,7 +260,7 @@ def make_dname_byid(path, error_msg=None, info=None):
258260
259261
260def make_dname(volume, storage_config):262def make_dname(volume, storage_config):
261 state = util.load_command_environment()263 state = util.load_command_environment(strict=True)
262 rules_dir = os.path.join(state['scratch'], "rules.d")264 rules_dir = os.path.join(state['scratch'], "rules.d")
263 vol = storage_config.get(volume)265 vol = storage_config.get(volume)
264 path = get_path_to_storage_volume(volume, storage_config)266 path = get_path_to_storage_volume(volume, storage_config)
@@ -404,9 +406,8 @@ def get_path_to_storage_volume(volume, storage_config):
404 try:406 try:
405 if not vol_value:407 if not vol_value:
406 continue408 continue
407 if disk_key == 'serial':409 if disk_key in ['wwn', 'serial']:
408 volume_path = block.lookup_disk(vol_value)410 volume_path = block.lookup_disk(vol_value)
409 break
410 elif disk_key == 'path':411 elif disk_key == 'path':
411 if vol_value.startswith('iscsi:'):412 if vol_value.startswith('iscsi:'):
412 i = iscsi.ensure_disk_connected(vol_value)413 i = iscsi.ensure_disk_connected(vol_value)
@@ -416,21 +417,18 @@ def get_path_to_storage_volume(volume, storage_config):
416 # sys/class/block access is valid. ie, there are no417 # sys/class/block access is valid. ie, there are no
417 # udev generated values in sysfs418 # udev generated values in sysfs
418 volume_path = os.path.realpath(vol_value)419 volume_path = os.path.realpath(vol_value)
419 break
420 elif disk_key == 'wwn':
421 by_wwn = '/dev/disk/by-id/wwn-%s' % vol.get('wwn')
422 volume_path = os.path.realpath(by_wwn)
423 break
424 elif disk_key == 'device_id':420 elif disk_key == 'device_id':
425 dasd_device = dasd.DasdDevice(vol_value)421 dasd_device = dasd.DasdDevice(vol_value)
426 volume_path = dasd_device.devname422 volume_path = dasd_device.devname
427 break
428 except ValueError:423 except ValueError:
429 pass424 continue
425 # verify path exists otherwise try the next key
426 if not os.path.exists(volume_path):
427 volume_path = None
430428
431 if not volume_path:429 if volume_path is None:
432 raise ValueError("serial, wwn or path to block dev must be \430 raise ValueError("Failed to find storage volume id='%s' config: %s"
433 specified to identify disk")431 % (vol['id'], vol))
434432
435 elif vol.get('type') == "lvm_partition":433 elif vol.get('type') == "lvm_partition":
436 # For lvm partitions, a directory in /dev/ should be present with the434 # For lvm partitions, a directory in /dev/ should be present with the
@@ -536,7 +534,7 @@ def disk_handler(info, storage_config):
536534
537 if config.value_as_boolean(info.get('preserve')):535 if config.value_as_boolean(info.get('preserve')):
538 # Handle preserve flag, verifying if ptable specified in config536 # Handle preserve flag, verifying if ptable specified in config
539 if config.value_as_boolean(ptable):537 if config.value_as_boolean(ptable) and ptable != PTABLE_UNSUPPORTED:
540 current_ptable = block.get_part_table_type(disk)538 current_ptable = block.get_part_table_type(disk)
541 if not ((ptable in _dos_names and current_ptable in _dos_names) or539 if not ((ptable in _dos_names and current_ptable in _dos_names) or
542 (ptable == 'gpt' and current_ptable == 'gpt')):540 (ptable == 'gpt' and current_ptable == 'gpt')):
@@ -868,6 +866,47 @@ def mount_data(info, storage_config):
868 spec, path, fstype, ",".join(options), freq, passno, volume_path)866 spec, path, fstype, ",".join(options), freq, passno, volume_path)
869867
870868
869def _get_volume_type(device_path):
870 lsblock = block._lsblock([device_path])
871 kname = block.path_to_kname(device_path)
872 return lsblock[kname]['TYPE']
873
874
875def get_volume_spec(device_path):
876 """
877 Return the most reliable spec for a device per Ubuntu FSTAB wiki
878
879 https://wiki.ubuntu.com/FSTAB
880 """
881 info = udevadm_info(path=device_path)
882 block_type = _get_volume_type(device_path)
883
884 devlinks = []
885 if 'raid' in block_type:
886 devlinks = [link for link in info['DEVLINKS']
887 if os.path.basename(link).startswith('md-uuid-')]
888 elif block_type in ['crypt', 'lvm', 'mpath']:
889 devlinks = [link for link in info['DEVLINKS']
890 if os.path.basename(link).startswith('dm-uuid-')]
891 elif block_type in ['disk', 'part']:
892 if device_path.startswith('/dev/bcache'):
893 devlinks = [link for link in info['DEVLINKS']
894 if link.startswith('/dev/bcache/by-uuid')]
895 # on s390x prefer by-path links which are stable and unique.
896 if platform.machine() == 's390x':
897 devlinks = [link for link in info['DEVLINKS']
898 if link.startswith('/dev/disk/by-path')]
899 if len(devlinks) == 0:
900 # use FS UUID if present
901 devlinks = [link for link in info['DEVLINKS']
902 if '/by-uuid' in link]
903 if len(devlinks) == 0 and block_type == 'part':
904 devlinks = [link for link in info['DEVLINKS']
905 if '/by-partuuid' in link]
906
907 return devlinks[0] if len(devlinks) else device_path
908
909
871def fstab_line_for_data(fdata):910def fstab_line_for_data(fdata):
872 """Return a string representing fdata in /etc/fstab format.911 """Return a string representing fdata in /etc/fstab format.
873912
@@ -883,8 +922,7 @@ def fstab_line_for_data(fdata):
883 if fdata.spec is None:922 if fdata.spec is None:
884 if not fdata.device:923 if not fdata.device:
885 raise ValueError("FstabData missing both spec and device.")924 raise ValueError("FstabData missing both spec and device.")
886 uuid = block.get_volume_uuid(fdata.device)925 spec = get_volume_spec(fdata.device)
887 spec = ("UUID=%s" % uuid) if uuid else fdata.device
888 else:926 else:
889 spec = fdata.spec927 spec = fdata.spec
890928
@@ -896,8 +934,20 @@ def fstab_line_for_data(fdata):
896 else:934 else:
897 options = fdata.options935 options = fdata.options
898936
899 return ' '.join((spec, path, fdata.fstype, options,937 if path != "none":
900 fdata.freq, fdata.passno)) + "\n"938 # prefer provided spec over device
939 device = fdata.spec if fdata.spec else None
940 # if not provided a spec, derive device from calculated spec value
941 if not device:
942 device = fdata.device if fdata.device else spec
943 comment = "# %s was on %s during curtin installation" % (path, device)
944 else:
945 comment = None
946
947 entry = ' '.join((spec, path, fdata.fstype, options,
948 fdata.freq, fdata.passno)) + "\n"
949 line = '\n'.join([comment, entry] if comment else [entry])
950 return line
901951
902952
903def mount_fstab_data(fdata, target=None):953def mount_fstab_data(fdata, target=None):
@@ -960,7 +1010,7 @@ def mount_handler(info, storage_config):
960 Mount specified device under target at 'path' and generate1010 Mount specified device under target at 'path' and generate
961 fstab entry.1011 fstab entry.
962 """1012 """
963 state = util.load_command_environment()1013 state = util.load_command_environment(strict=True)
964 mount_apply(mount_data(info, storage_config),1014 mount_apply(mount_data(info, storage_config),
965 target=state.get('target'), fstab=state.get('fstab'))1015 target=state.get('target'), fstab=state.get('fstab'))
9661016
@@ -1050,7 +1100,7 @@ def lvm_partition_handler(info, storage_config):
10501100
10511101
1052def dm_crypt_handler(info, storage_config):1102def dm_crypt_handler(info, storage_config):
1053 state = util.load_command_environment()1103 state = util.load_command_environment(strict=True)
1054 volume = info.get('volume')1104 volume = info.get('volume')
1055 keysize = info.get('keysize')1105 keysize = info.get('keysize')
1056 cipher = info.get('cipher')1106 cipher = info.get('cipher')
@@ -1127,11 +1177,11 @@ def dm_crypt_handler(info, storage_config):
1127 # A crypttab will be created in the same directory as the fstab in the1177 # A crypttab will be created in the same directory as the fstab in the
1128 # configuration. This will then be copied onto the system later1178 # configuration. This will then be copied onto the system later
1129 if state['fstab']:1179 if state['fstab']:
1130 crypt_tab_location = os.path.join(os.path.split(state['fstab'])[0],1180 state_dir = os.path.dirname(state['fstab'])
1131 "crypttab")1181 crypt_tab_location = os.path.join(state_dir, "crypttab")
1132 uuid = block.get_volume_uuid(volume_path)1182 uuid = block.get_volume_uuid(volume_path)
1133 with open(crypt_tab_location, "a") as fp:1183 util.write_file(crypt_tab_location,
1134 fp.write("%s UUID=%s none luks\n" % (dm_name, uuid))1184 "%s UUID=%s none luks\n" % (dm_name, uuid), omode="a")
1135 else:1185 else:
1136 LOG.info("fstab configuration is not present in environment, so \1186 LOG.info("fstab configuration is not present in environment, so \
1137 cannot locate an appropriate directory to write crypttab in \1187 cannot locate an appropriate directory to write crypttab in \
@@ -1139,7 +1189,7 @@ def dm_crypt_handler(info, storage_config):
11391189
11401190
1141def raid_handler(info, storage_config):1191def raid_handler(info, storage_config):
1142 state = util.load_command_environment()1192 state = util.load_command_environment(strict=True)
1143 devices = info.get('devices')1193 devices = info.get('devices')
1144 raidlevel = info.get('raidlevel')1194 raidlevel = info.get('raidlevel')
1145 spare_devices = info.get('spare_devices')1195 spare_devices = info.get('spare_devices')
@@ -1196,11 +1246,10 @@ def raid_handler(info, storage_config):
1196 # The file must also be written onto the running system to enable it to run1246 # The file must also be written onto the running system to enable it to run
1197 # mdadm --assemble and continue installation1247 # mdadm --assemble and continue installation
1198 if state['fstab']:1248 if state['fstab']:
1199 mdadm_location = os.path.join(os.path.split(state['fstab'])[0],1249 state_dir = os.path.dirname(state['fstab'])
1200 "mdadm.conf")1250 mdadm_location = os.path.join(state_dir, "mdadm.conf")
1201 mdadm_scan_data = mdadm.mdadm_detail_scan()1251 mdadm_scan_data = mdadm.mdadm_detail_scan()
1202 with open(mdadm_location, "w") as fp:1252 util.write_file(mdadm_location, mdadm_scan_data)
1203 fp.write(mdadm_scan_data)
1204 else:1253 else:
1205 LOG.info("fstab configuration is not present in the environment, so \1254 LOG.info("fstab configuration is not present in the environment, so \
1206 cannot locate an appropriate directory to write mdadm.conf in, \1255 cannot locate an appropriate directory to write mdadm.conf in, \
@@ -1478,7 +1527,7 @@ def zpool_handler(info, storage_config):
1478 """1527 """
1479 zfs.zfs_assert_supported()1528 zfs.zfs_assert_supported()
14801529
1481 state = util.load_command_environment()1530 state = util.load_command_environment(strict=True)
14821531
1483 # extract /dev/disk/by-id paths for each volume used1532 # extract /dev/disk/by-id paths for each volume used
1484 vdevs = [get_path_to_storage_volume(v, storage_config)1533 vdevs = [get_path_to_storage_volume(v, storage_config)
@@ -1517,7 +1566,7 @@ def zfs_handler(info, storage_config):
1517 """1566 """
1518 zfs.zfs_assert_supported()1567 zfs.zfs_assert_supported()
15191568
1520 state = util.load_command_environment()1569 state = util.load_command_environment(strict=True)
1521 poolname = get_poolname(info, storage_config)1570 poolname = get_poolname(info, storage_config)
1522 volume = info.get('volume')1571 volume = info.get('volume')
1523 properties = info.get('properties', {})1572 properties = info.get('properties', {})
@@ -1535,20 +1584,24 @@ def zfs_handler(info, storage_config):
1535 util.write_file(state['fstab'], fstab_entry, omode='a')1584 util.write_file(state['fstab'], fstab_entry, omode='a')
15361585
15371586
1538def get_disk_paths_from_storage_config(storage_config):1587def get_device_paths_from_storage_config(storage_config):
1539 """Returns a list of disk paths in a storage config filtering out1588 """Returns a list of device paths in a storage config filtering out
1540 preserved or disks which do not have wipe configuration.1589 preserved or devices which do not have wipe configuration.
15411590
1542 :param: storage_config: Ordered dict of storage configation1591 :param: storage_config: Ordered dict of storage configation
1543 """1592 """
1544 def get_path_if_present(disk, config):1593 dpaths = []
1545 return get_path_to_storage_volume(disk, config)1594 for (k, v) in storage_config.items():
15461595 if v.get('type') in ['disk', 'partition']:
1547 return [get_path_if_present(k, storage_config)1596 if config.value_as_boolean(v.get('wipe')):
1548 for (k, v) in storage_config.items()1597 if config.value_as_boolean(v.get('preserve')):
1549 if v.get('type') == 'disk' and1598 continue
1550 config.value_as_boolean(v.get('wipe')) and1599 try:
1551 not config.value_as_boolean(v.get('preserve'))]1600 dpaths.append(
1601 get_path_to_storage_volume(k, storage_config))
1602 except Exception:
1603 pass
1604 return dpaths
15521605
15531606
1554def zfsroot_update_storage_config(storage_config):1607def zfsroot_update_storage_config(storage_config):
@@ -1685,7 +1738,7 @@ def meta_custom(args):
1685 'zpool': zpool_handler,1738 'zpool': zpool_handler,
1686 }1739 }
16871740
1688 state = util.load_command_environment()1741 state = util.load_command_environment(strict=True)
1689 cfg = config.load_command_config(args, state)1742 cfg = config.load_command_config(args, state)
16901743
1691 storage_config_dict = extract_storage_ordered_dict(cfg)1744 storage_config_dict = extract_storage_ordered_dict(cfg)
@@ -1719,7 +1772,7 @@ def meta_simple(args):
1719 """Creates a root partition. If args.mode == SIMPLE_BOOT, it will also1772 """Creates a root partition. If args.mode == SIMPLE_BOOT, it will also
1720 create a separate /boot partition.1773 create a separate /boot partition.
1721 """1774 """
1722 state = util.load_command_environment()1775 state = util.load_command_environment(strict=True)
1723 cfg = config.load_command_config(args, state)1776 cfg = config.load_command_config(args, state)
1724 if args.target is not None:1777 if args.target is not None:
1725 state['target'] = args.target1778 state['target'] = args.target
diff --git a/curtin/commands/curthooks.py b/curtin/commands/curthooks.py
index 2869c6c..542557c 100644
--- a/curtin/commands/curthooks.py
+++ b/curtin/commands/curthooks.py
@@ -104,6 +104,68 @@ def disable_overlayroot(cfg, target):
104 shutil.move(local_conf, local_conf + ".old")104 shutil.move(local_conf, local_conf + ".old")
105105
106106
107def _update_initramfs_tools(machine=None):
108 """ Return a list of binary names used to update an initramfs.
109
110 On some architectures there are helper binaries that are also
111 used and will be included in the list.
112 """
113 tools = ['update-initramfs']
114 if not machine:
115 machine = platform.machine()
116 if machine == 's390x':
117 tools.append('zipl')
118 elif machine == 'aarch64':
119 tools.append('flash-kernel')
120 return tools
121
122
123def disable_update_initramfs(cfg, target, machine=None):
124 """ Find update-initramfs tools in target and change their name. """
125 with util.ChrootableTarget(target) as in_chroot:
126 for tool in _update_initramfs_tools(machine=machine):
127 found = util.which(tool, target=target)
128 if found:
129 LOG.debug('Diverting original %s in target.', tool)
130 rename = found + '.curtin-disabled'
131 divert = ['dpkg-divert', '--add', '--rename',
132 '--divert', rename, found]
133 in_chroot.subp(divert)
134
135 # create a dummy update-initramfs which just returns true;
136 # this handles postinstall scripts which make invoke $tool
137 # directly
138 util.write_file(target + found,
139 content="#!/bin/true\n# diverted by curtin",
140 mode=0o755)
141
142
143def update_initramfs_is_disabled(target):
144 """ Return a bool indicating if initramfs tooling is disabled. """
145 disabled = []
146 with util.ChrootableTarget(target) as in_chroot:
147 out, _err = in_chroot.subp(['dpkg-divert', '--list'], capture=True)
148 disabled = [divert for divert in out.splitlines()
149 if divert.endswith('.curtin-disabled')]
150 return len(disabled) > 0
151
152
153def enable_update_initramfs(cfg, target, machine=None):
154 """ Enable initramfs update tools by restoring their original name. """
155 if update_initramfs_is_disabled(target):
156 with util.ChrootableTarget(target) as in_chroot:
157 for tool in _update_initramfs_tools(machine=machine):
158 LOG.info('Restoring %s in target for initrd updates.', tool)
159 found = util.which(tool, target=target)
160 if not found:
161 continue
162 # remove the diverted
163 util.del_file(target + found)
164 # un-divert and restore original file
165 in_chroot.subp(
166 ['dpkg-divert', '--rename', '--remove', found])
167
168
107def setup_zipl(cfg, target):169def setup_zipl(cfg, target):
108 if platform.machine() != 's390x':170 if platform.machine() != 's390x':
109 return171 return
@@ -262,6 +324,11 @@ def get_flash_kernel_pkgs(arch=None, uefi=None):
262324
263325
264def setup_kernel_img_conf(target):326def setup_kernel_img_conf(target):
327 # kernel-img.conf only needed on release prior to 19.10
328 lsb_info = distro.lsb_release(target=target)
329 if tuple(map(int, lsb_info['release'].split('.'))) >= (19, 10):
330 return
331
265 kernel_img_conf_vars = {332 kernel_img_conf_vars = {
266 'bootloader': 'no',333 'bootloader': 'no',
267 'inboot': 'yes',334 'inboot': 'yes',
@@ -420,12 +487,25 @@ def setup_grub(cfg, target, osfamily=DISTROS.debian):
420487
421 if storage_cfg_odict:488 if storage_cfg_odict:
422 storage_grub_devices = []489 storage_grub_devices = []
423 for item_id, item in storage_cfg_odict.items():490 if util.is_uefi_bootable():
424 if not item.get('grub_device'):491 # Curtin only supports creating one EFI system partition. Thus the
425 continue492 # grub_device can only be the default system partition mounted at
426 LOG.debug("checking: %s", item)493 # /boot/efi.
427 storage_grub_devices.append(494 for item_id, item in storage_cfg_odict.items():
428 get_path_to_storage_volume(item_id, storage_cfg_odict))495 if item.get('path') == '/boot/efi':
496 efi_dev_id = storage_cfg_odict[item['device']]['volume']
497 LOG.debug("checking: %s", item)
498 storage_grub_devices.append(get_path_to_storage_volume(
499 efi_dev_id, storage_cfg_odict))
500 break
501 else:
502 for item_id, item in storage_cfg_odict.items():
503 if not item.get('grub_device'):
504 continue
505 LOG.debug("checking: %s", item)
506 storage_grub_devices.append(
507 get_path_to_storage_volume(item_id, storage_cfg_odict))
508
429 if len(storage_grub_devices) > 0:509 if len(storage_grub_devices) > 0:
430 grubcfg['install_devices'] = storage_grub_devices510 grubcfg['install_devices'] = storage_grub_devices
431511
@@ -509,10 +589,7 @@ def setup_grub(cfg, target, osfamily=DISTROS.debian):
509 LOG.debug("installing grub to %s [replace_default=%s]",589 LOG.debug("installing grub to %s [replace_default=%s]",
510 instdevs, replace_default)590 instdevs, replace_default)
511591
512 # rhel lvm uses /run during grub configuration592 with util.ChrootableTarget(target):
513 chroot_mounts = (["/dev", "/proc", "/sys", "/run"]
514 if osfamily == DISTROS.redhat else None)
515 with util.ChrootableTarget(target, mounts=chroot_mounts):
516 args = ['install-grub']593 args = ['install-grub']
517 if util.is_uefi_bootable():594 if util.is_uefi_bootable():
518 args.append("--uefi")595 args.append("--uefi")
@@ -529,18 +606,66 @@ def setup_grub(cfg, target, osfamily=DISTROS.debian):
529 join_stdout_err = ['sh', '-c', 'exec "$0" "$@" 2>&1']606 join_stdout_err = ['sh', '-c', 'exec "$0" "$@" 2>&1']
530 out, _err = util.subp(607 out, _err = util.subp(
531 join_stdout_err + args + instdevs, env=env, capture=True)608 join_stdout_err + args + instdevs, env=env, capture=True)
532 LOG.debug("%s\n%s\n", args, out)609 LOG.debug("%s\n%s\n", args + instdevs, out)
533610
534 if util.is_uefi_bootable() and grubcfg.get('update_nvram', True):611 if util.is_uefi_bootable() and grubcfg.get('update_nvram', True):
535 uefi_reorder_loaders(grubcfg, target)612 uefi_reorder_loaders(grubcfg, target)
536613
537614
538def update_initramfs(target=None, all_kernels=False):615def update_initramfs(target=None, all_kernels=False):
539 cmd = ['update-initramfs', '-u']616 """ Invoke update-initramfs in the target path.
540 if all_kernels:617
541 cmd.extend(['-k', 'all'])618 Look up the installed kernel versions in the target
542 with util.ChrootableTarget(target) as in_chroot:619 to ensure that an initrd get created or updated as needed.
543 in_chroot.subp(cmd)620 This allows curtin to invoke update-initramfs exactly once
621 at the end of the install instead of multiple calls.
622 """
623 if update_initramfs_is_disabled(target):
624 return
625
626 # We keep the all_kernels flag for callers, the implementation
627 # now will operate correctly on all kernels present in the image
628 # which is almost always exactly one.
629 #
630 # Ideally curtin should be able to use update-initramfs -k all
631 # however, update-initramfs expects to be able to find out which
632 # versions of kernels are installed by using values from the
633 # kernel package invoking update-initramfs -c <kernel version>.
634 # With update-initramfs diverted, nothing captures the kernel
635 # version strings in the place where update-initramfs expects
636 # to find this information. Instead, curtin will examine
637 # /boot to see what kernels and initramfs are installed and
638 # either create or update as needed.
639 #
640 # This loop below will examine the contents of target's
641 # /boot and pattern match for kernel files. On Ubuntu this
642 # is in the form of /boot/vmlinu[xz]-<uname -r version>.
643 #
644 # For each kernel, we extract the version string and then
645 # construct the name of of the initrd file that *would*
646 # have been created when the kernel package was installed
647 # if curtin had not diverted update-initramfs to prevent
648 # duplicate initrd creation.
649 #
650 # if the initrd file exists, then we only need to invoke
651 # update-initramfs's -u (update) method. If the file does
652 # not exist, then we need to run the -c (create) method.
653 boot = paths.target_path(target, 'boot')
654 for kernel in sorted(glob.glob(boot + '/vmlinu*-*')):
655 kfile = os.path.basename(kernel)
656 # handle vmlinux or vmlinuz
657 kprefix = kfile.split('-')[0]
658 version = kfile.replace(kprefix + '-', '')
659 initrd = kernel.replace(kprefix, 'initrd.img')
660 # -u == update, -c == create
661 mode = '-u' if os.path.exists(initrd) else '-c'
662 cmd = ['update-initramfs', mode, '-k', version]
663 with util.ChrootableTarget(target) as in_chroot:
664 in_chroot.subp(cmd)
665 if not os.path.exists(initrd):
666 files = os.listdir(target + '/boot')
667 LOG.debug('Failed to find initrd %s', initrd)
668 LOG.debug('Files in target /boot: %s', files)
544669
545670
546def copy_fstab(fstab, target):671def copy_fstab(fstab, target):
@@ -548,7 +673,10 @@ def copy_fstab(fstab, target):
548 LOG.warn("fstab variable not in state, not copying fstab")673 LOG.warn("fstab variable not in state, not copying fstab")
549 return674 return
550675
551 shutil.copy(fstab, os.path.sep.join([target, 'etc/fstab']))676 content = util.load_file(fstab)
677 header = distro.fstab_header()
678 util.write_file(os.path.sep.join([target, 'etc/fstab']),
679 content="%s\n%s" % (header, content))
552680
553681
554def copy_crypttab(crypttab, target):682def copy_crypttab(crypttab, target):
@@ -884,12 +1012,21 @@ def install_missing_packages(cfg, target, osfamily=DISTROS.debian):
884 # UEFI requires grub-efi-{arch}. If a signed version of that package1012 # UEFI requires grub-efi-{arch}. If a signed version of that package
885 # exists then it will be installed.1013 # exists then it will be installed.
886 if util.is_uefi_bootable():1014 if util.is_uefi_bootable():
887 uefi_pkgs = []1015 uefi_pkgs = ['efibootmgr']
888 if osfamily == DISTROS.redhat:1016 if osfamily == DISTROS.redhat:
889 # centos/redhat doesn't support 32-bit?1017 # centos/redhat doesn't support 32-bit?
890 uefi_pkgs.extend(['grub2-efi-x64-modules'])1018 if 'grub2-efi-x64-modules' not in installed_packages:
1019 # Previously Curtin only supported unsigned GRUB due to an
1020 # upstream bug. By default lp:maas-image-builder and
1021 # packer-maas have grub preinstalled. If grub2-efi-x64-modules
1022 # is already in the image use unsigned grub so the install
1023 # doesn't require Internet access. If grub is missing use the
1024 # signed version.
1025 uefi_pkgs.extend(['grub2-efi-x64', 'shim-x64'])
891 elif osfamily == DISTROS.debian:1026 elif osfamily == DISTROS.debian:
892 arch = util.get_architecture()1027 arch = util.get_architecture()
1028 if arch == 'i386':
1029 arch = 'ia32'
893 uefi_pkgs.append('grub-efi-%s' % arch)1030 uefi_pkgs.append('grub-efi-%s' % arch)
8941031
895 # Architecture might support a signed UEFI loader1032 # Architecture might support a signed UEFI loader
@@ -1165,40 +1302,43 @@ def redhat_upgrade_cloud_init(netcfg, target=None, osfamily=DISTROS.redhat):
1165 cloud_init_yum_repo = (1302 cloud_init_yum_repo = (
1166 paths.target_path(target,1303 paths.target_path(target,
1167 'etc/yum.repos.d/curtin-cloud-init.repo'))1304 'etc/yum.repos.d/curtin-cloud-init.repo'))
1305 rhel_ver = distro.rpm_get_dist_id(target)
1168 # Inject cloud-init daily yum repo1306 # Inject cloud-init daily yum repo
1169 util.write_file(cloud_init_yum_repo,1307 util.write_file(cloud_init_yum_repo,
1170 content=cloud_init_repo(1308 content=cloud_init_repo(rhel_ver))
1171 distro.rpm_get_dist_id(target)))
11721309
1173 # we separate the installation of repository packages (epel,1310 # ensure up-to-date ca-certificates to handle https mirror
1311 # connections for epel and cloud-init-el.
1312 packages = ['ca-certificates']
1313
1314 if int(rhel_ver) < 8:
1315 # cloud-init in RHEL < 8 requires EPEL for dependencies.
1316 packages += ['epel-release']
1317 # RHEL8+ no longer ships bridge-utils. This does not effect
1318 # bridge configuration. Only install on RHEL < 8 if not
1319 # available, do not upgrade.
1320 with util.ChrootableTarget(target) as in_chroot:
1321 try:
1322 in_chroot.subp(['rpm', '-q', 'bridge-utils'],
1323 capture=False, rcs=[0])
1324 except util.ProcessExecutionError:
1325 LOG.debug(
1326 'Image missing bridge-utils package, installing')
1327 packages += ['bridge-utils']
1328
1329 packages += ['cloud-init-el-release', 'cloud-init']
1330
1331 # We separate the installation of repository packages (epel,
1174 # cloud-init-el-release) as we need a new invocation of yum1332 # cloud-init-el-release) as we need a new invocation of yum
1175 # to read the newly installed repo files.1333 # to read the newly installed repo files.
11761334 for package in packages:
1177 # ensure up-to-date ca-certificates to handle https mirror1335 distro.install_packages(
1178 # connections1336 [package], target=target, osfamily=osfamily)
1179 distro.install_packages(['ca-certificates'], target=target,
1180 osfamily=osfamily)
1181 distro.install_packages(['epel-release'], target=target,
1182 osfamily=osfamily)
1183 distro.install_packages(['cloud-init-el-release'], target=target,
1184 osfamily=osfamily)
1185 distro.install_packages(['cloud-init'], target=target,
1186 osfamily=osfamily)
11871337
1188 # remove cloud-init el-stable bootstrap repo config as the1338 # remove cloud-init el-stable bootstrap repo config as the
1189 # cloud-init-el-release package points to the correct repo1339 # cloud-init-el-release package points to the correct repo
1190 util.del_file(cloud_init_yum_repo)1340 util.del_file(cloud_init_yum_repo)
11911341
1192 # install bridge-utils if needed
1193 with util.ChrootableTarget(target) as in_chroot:
1194 try:
1195 in_chroot.subp(['rpm', '-q', 'bridge-utils'],
1196 capture=False, rcs=[0])
1197 except util.ProcessExecutionError:
1198 LOG.debug('Image missing bridge-utils package, installing')
1199 distro.install_packages(['bridge-utils'], target=target,
1200 osfamily=osfamily)
1201
1202 LOG.info('Passing network configuration through to target')1342 LOG.info('Passing network configuration through to target')
1203 net.render_netconfig_passthrough(target, netconfig={'network': netcfg})1343 net.render_netconfig_passthrough(target, netconfig={'network': netcfg})
12041344
@@ -1277,6 +1417,7 @@ def builtin_curthooks(cfg, target, state):
1277 LOG.info('Running curtin builtin curthooks')1417 LOG.info('Running curtin builtin curthooks')
1278 stack_prefix = state.get('report_stack_prefix', '')1418 stack_prefix = state.get('report_stack_prefix', '')
1279 state_etcd = os.path.split(state['fstab'])[0]1419 state_etcd = os.path.split(state['fstab'])[0]
1420 machine = platform.machine()
12801421
1281 distro_info = distro.get_distroinfo(target=target)1422 distro_info = distro.get_distroinfo(target=target)
1282 if not distro_info:1423 if not distro_info:
@@ -1291,6 +1432,7 @@ def builtin_curthooks(cfg, target, state):
1291 description="configuring apt configuring apt"):1432 description="configuring apt configuring apt"):
1292 do_apt_config(cfg, target)1433 do_apt_config(cfg, target)
1293 disable_overlayroot(cfg, target)1434 disable_overlayroot(cfg, target)
1435 disable_update_initramfs(cfg, target, machine)
12941436
1295 # LP: #1742560 prevent zfs-dkms from being installed (Xenial)1437 # LP: #1742560 prevent zfs-dkms from being installed (Xenial)
1296 if distro.lsb_release(target=target)['codename'] == 'xenial':1438 if distro.lsb_release(target=target)['codename'] == 'xenial':
@@ -1383,12 +1525,6 @@ def builtin_curthooks(cfg, target, state):
1383 description="enabling selinux autorelabel mode"):1525 description="enabling selinux autorelabel mode"):
1384 redhat_apply_selinux_autorelabel(target)1526 redhat_apply_selinux_autorelabel(target)
13851527
1386 with events.ReportEventStack(
1387 name=stack_prefix + '/updating-initramfs-configuration',
1388 reporting_enabled=True, level="INFO",
1389 description="updating initramfs configuration"):
1390 redhat_update_initramfs(target, cfg)
1391
1392 with events.ReportEventStack(1528 with events.ReportEventStack(
1393 name=stack_prefix + '/pollinate-user-agent',1529 name=stack_prefix + '/pollinate-user-agent',
1394 reporting_enabled=True, level="INFO",1530 reporting_enabled=True, level="INFO",
@@ -1424,17 +1560,28 @@ def builtin_curthooks(cfg, target, state):
1424 if os.path.isdir(udev_rules_d):1560 if os.path.isdir(udev_rules_d):
1425 copy_dname_rules(udev_rules_d, target)1561 copy_dname_rules(udev_rules_d, target)
14261562
1563 with events.ReportEventStack(
1564 name=stack_prefix + '/updating-initramfs-configuration',
1565 reporting_enabled=True, level="INFO",
1566 description="updating initramfs configuration"):
1567 if osfamily == DISTROS.debian:
1568 # re-enable update_initramfs
1569 enable_update_initramfs(cfg, target, machine)
1570 update_initramfs(target, all_kernels=True)
1571 elif osfamily == DISTROS.redhat:
1572 redhat_update_initramfs(target, cfg)
1573
1427 # As a rule, ARMv7 systems don't use grub. This may change some1574 # As a rule, ARMv7 systems don't use grub. This may change some
1428 # day, but for now, assume no. They do require the initramfs1575 # day, but for now, assume no. They do require the initramfs
1429 # to be updated, and this also triggers boot loader setup via1576 # to be updated, and this also triggers boot loader setup via
1430 # flash-kernel.1577 # flash-kernel.
1431 machine = platform.machine()
1432 if (machine.startswith('armv7') or1578 if (machine.startswith('armv7') or
1433 machine.startswith('s390x') or1579 machine.startswith('s390x') or
1434 machine.startswith('aarch64') and not util.is_uefi_bootable()):1580 machine.startswith('aarch64') and not util.is_uefi_bootable()):
1435 update_initramfs(target)1581 return
1436 else:1582
1437 setup_grub(cfg, target, osfamily=osfamily)1583 # all other paths lead to grub
1584 setup_grub(cfg, target, osfamily=osfamily)
14381585
14391586
1440def curthooks(args):1587def curthooks(args):
diff --git a/curtin/commands/install.py b/curtin/commands/install.py
index ad17508..a3471f6 100644
--- a/curtin/commands/install.py
+++ b/curtin/commands/install.py
@@ -11,7 +11,7 @@ import subprocess
11import sys11import sys
12import tempfile12import tempfile
1313
14from curtin.block import iscsi14from curtin.block import iscsi, zfs
15from curtin import config15from curtin import config
16from curtin import distro16from curtin import distro
17from curtin import util17from curtin import util
@@ -505,6 +505,10 @@ def cmd_install(args):
505 if iscsi.get_iscsi_disks_from_config(cfg):505 if iscsi.get_iscsi_disks_from_config(cfg):
506 iscsi.restart_iscsi_service()506 iscsi.restart_iscsi_service()
507507
508 for pool in zfs.get_zpool_from_config(cfg):
509 LOG.debug('Exporting ZFS zpool %s', pool)
510 zfs.zpool_export(pool)
511
508 shutil.rmtree(workingd.top)512 shutil.rmtree(workingd.top)
509513
510 apply_power_state(cfg.get('power_state'))514 apply_power_state(cfg.get('power_state'))
diff --git a/curtin/distro.py b/curtin/distro.py
index 9714515..ed178bd 100644
--- a/curtin/distro.py
+++ b/curtin/distro.py
@@ -5,6 +5,7 @@ import os
5import re5import re
6import shutil6import shutil
7import tempfile7import tempfile
8import textwrap
89
9from .paths import target_path10from .paths import target_path
10from .util import (11from .util import (
@@ -284,7 +285,13 @@ def run_yum_command(mode, args=None, opts=None, env=None, target=None,
284 if opts is None:285 if opts is None:
285 opts = []286 opts = []
286287
287 cmd = ['yum'] + defopts + opts + [mode] + args288 # dnf is a drop in replacement for yum. On newer RH based systems yum
289 # is just a sym link to dnf.
290 if which('dnf', target=target):
291 cmd = ['dnf']
292 else:
293 cmd = ['yum']
294 cmd += defopts + opts + [mode] + args
288 if not execute:295 if not execute:
289 return env, cmd296 return env, cmd
290297
@@ -311,8 +318,14 @@ def yum_install(mode, packages=None, opts=None, env=None, target=None,
311 raise ValueError(318 raise ValueError(
312 'Unsupported mode "%s" for yum package install/upgrade' % mode)319 'Unsupported mode "%s" for yum package install/upgrade' % mode)
313320
321 # dnf is a drop in replacement for yum. On newer RH based systems yum
322 # is just a sym link to dnf.
323 if which('dnf', target=target):
324 cmd = ['dnf']
325 else:
326 cmd = ['yum']
314 # download first, then install/upgrade from cache327 # download first, then install/upgrade from cache
315 cmd = ['yum'] + defopts + opts + [mode]328 cmd += defopts + opts + [mode]
316 dl_opts = ['--downloadonly', '--setopt=keepcache=1']329 dl_opts = ['--downloadonly', '--setopt=keepcache=1']
317 inst_opts = ['--cacheonly']330 inst_opts = ['--cacheonly']
318331
@@ -509,4 +522,14 @@ def get_package_version(pkg, target=None, semx=None):
509 return None522 return None
510523
511524
525def fstab_header():
526 return textwrap.dedent("""\
527# /etc/fstab: static file system information.
528#
529# Use 'blkid' to print the universally unique identifier for a
530# device; this may be used with UUID= as a more robust way to name devices
531# that works even if disks are added and removed. See fstab(5).
532#
533# <file system> <mount point> <type> <options> <dump> <pass>""")
534
512# vi: ts=4 expandtab syntax=python535# vi: ts=4 expandtab syntax=python
diff --git a/curtin/net/deps.py b/curtin/net/deps.py
index b98961d..cbebae9 100644
--- a/curtin/net/deps.py
+++ b/curtin/net/deps.py
@@ -47,11 +47,11 @@ def detect_required_packages_mapping(osfamily=DISTROS.debian):
47 distro_mapping = {47 distro_mapping = {
48 DISTROS.debian: {48 DISTROS.debian: {
49 'bond': ['ifenslave'],49 'bond': ['ifenslave'],
50 'bonds': [],50 'bonds': ['ifenslave'],
51 'bridge': ['bridge-utils'],51 'bridge': ['bridge-utils'],
52 'bridges': [],52 'bridges': ['bridge-utils'],
53 'vlan': ['vlan'],53 'vlan': ['vlan'],
54 'vlans': []},54 'vlans': ['vlan']},
55 DISTROS.redhat: {55 DISTROS.redhat: {
56 'bond': [],56 'bond': [],
57 'bonds': [],57 'bonds': [],
diff --git a/curtin/storage_config.py b/curtin/storage_config.py
index 841d868..4244b3e 100644
--- a/curtin/storage_config.py
+++ b/curtin/storage_config.py
@@ -304,7 +304,8 @@ def merge_config_trees_to_list(config_trees):
304 max_level = level304 max_level = level
305 item_cfg = tree[top_item_id]305 item_cfg = tree[top_item_id]
306 if top_item_id in reg:306 if top_item_id in reg:
307 raise ValueError('Duplicate id: %s' % top_item_id)307 LOG.warning('Dropping Duplicate id: %s' % top_item_id)
308 continue
308 reg[top_item_id] = {'level': level, 'config': item_cfg}309 reg[top_item_id] = {'level': level, 'config': item_cfg}
309310
310 def sort_level(configs):311 def sort_level(configs):
@@ -388,15 +389,15 @@ class ProbertParser(object):
388 data = {}389 data = {}
389 self.class_data = data390 self.class_data = data
390 else:391 else:
391 raise ValueError('probe_data missing %s data' %392 LOG.warning('probe_data missing %s data', self.probe_data_key)
392 self.probe_data_key)393 self.class_data = {}
393394
394 # We keep a reference to the blockdev_data on the superclass395 # We keep a reference to the blockdev_data on the superclass
395 # as each specific parser has common needs to reference396 # as each specific parser has common needs to reference
396 # this data separate from the BlockdevParser class.397 # this data separate from the BlockdevParser class.
397 self.blockdev_data = self.probe_data.get('blockdev')398 self.blockdev_data = self.probe_data.get('blockdev', {})
398 if not self.blockdev_data:399 if not self.blockdev_data:
399 raise ValueError('probe_data missing valid "blockdev" data')400 LOG.warning('probe_data missing valid "blockdev" data')
400401
401 def parse(self):402 def parse(self):
402 raise NotImplementedError()403 raise NotImplementedError()
@@ -420,14 +421,76 @@ class ProbertParser(object):
420421
421 return None422 return None
422423
424 def is_mpath(self, blockdev):
425 if blockdev.get('DM_MULTIPATH_DEVICE_PATH') == "1":
426 return True
427
428 return bool('mpath-' in blockdev.get('DM_UUID', ''))
429
430 def get_mpath_name(self, blockdev):
431 mpath_data = self.probe_data.get('multipath')
432 if not mpath_data:
433 return None
434
435 bd_name = blockdev['DEVNAME']
436 if blockdev['DEVTYPE'] == 'partition':
437 bd_name = self.partition_parent_devname(blockdev)
438 bd_name = os.path.basename(bd_name)
439 for path in mpath_data['paths']:
440 if bd_name == path['device']:
441 rv = path['multipath']
442 return rv
443
444 def find_mpath_member(self, blockdev):
445 if blockdev.get('DM_MULTIPATH_DEVICE_PATH') == "1":
446 # find all other DM_MULTIPATH_DEVICE_PATH devs with same serial
447 serial = blockdev.get('ID_SERIAL')
448 members = sorted([os.path.basename(dev['DEVNAME'])
449 for dev in self.blockdev_data.values()
450 if dev.get("ID_SERIAL", "") == serial and
451 dev['DEVTYPE'] == blockdev['DEVTYPE']])
452 # [/dev/sda, /dev/sdb]
453 # [/dev/sda1, /dev/sda2, /dev/sdb1, /dev/sdb2]
454
455 else:
456 dm_mpath = blockdev.get('DM_MPATH')
457 dm_uuid = blockdev.get('DM_UUID')
458 dm_part = blockdev.get('DM_PART')
459
460 if dm_mpath:
461 multipath = dm_mpath
462 else:
463 # part1-mpath-30000000000000064
464 # mpath-30000000000000064
465 # mpath-36005076306ffd6b60000000000002406
466 match = re.search(r'mpath\-([a-zA-Z]*|\d*)+$', dm_uuid)
467 if not match:
468 LOG.debug('Failed to extract multipath ID pattern from '
469 'DM_UUID value: "%s"', dm_uuid)
470 return None
471 # remove leading 'mpath-'
472 multipath = match.group(0)[6:]
473 mpath_data = self.probe_data.get('multipath')
474 if not mpath_data:
475 return None
476 members = sorted([path['device'] for path in mpath_data['paths']
477 if path['multipath'] == multipath])
478
479 # append partition number if present
480 if dm_part:
481 members = [member + dm_part for member in members]
482
483 if len(members):
484 return members[0]
485
486 return None
487
423 def blockdev_to_id(self, blockdev):488 def blockdev_to_id(self, blockdev):
424 """ Examine a blockdev dictionary and return a tuple of curtin489 """ Examine a blockdev dictionary and return a tuple of curtin
425 storage type and name that can be used as a value for490 storage type and name that can be used as a value for
426 storage_config ids (opaque reference to other storage_config491 storage_config ids (opaque reference to other storage_config
427 elements).492 elements).
428 """493 """
429 def is_mpath(blockdev):
430 return bool(blockdev.get('DM_UUID', '').startswith('mpath-'))
431494
432 def is_dmcrypt(blockdev):495 def is_dmcrypt(blockdev):
433 return bool(blockdev.get('DM_UUID', '').startswith('CRYPT-LUKS'))496 return bool(blockdev.get('DM_UUID', '').startswith('CRYPT-LUKS'))
@@ -441,8 +504,15 @@ class ProbertParser(object):
441 if 'DM_LV_NAME' in blockdev:504 if 'DM_LV_NAME' in blockdev:
442 devtype = 'lvm-partition'505 devtype = 'lvm-partition'
443 name = blockdev['DM_LV_NAME']506 name = blockdev['DM_LV_NAME']
444 elif is_mpath(blockdev):507 elif self.is_mpath(blockdev):
445 name = blockdev['DM_UUID']508 # extract a multipath member device
509 member = self.find_mpath_member(blockdev)
510 if member:
511 name = member
512 else:
513 name = blockdev['DM_UUID']
514 if 'DM_PART' in blockdev:
515 devtype = 'partition'
446 elif is_dmcrypt(blockdev):516 elif is_dmcrypt(blockdev):
447 devtype = 'dmcrypt'517 devtype = 'dmcrypt'
448 name = blockdev['DM_NAME']518 name = blockdev['DM_NAME']
@@ -505,7 +575,8 @@ class BcacheParser(ProbertParser):
505 msg = ('Invalid "blockdev" value for cache device '575 msg = ('Invalid "blockdev" value for cache device '
506 'uuid=%s' % cset_uuid)576 'uuid=%s' % cset_uuid)
507 if not cset_uuid:577 if not cset_uuid:
508 raise ValueError(msg)578 LOG.warning(msg)
579 return None
509580
510 for devuuid, config in cache_data.items():581 for devuuid, config in cache_data.items():
511 cache = _sb_get(config, 'cset.uuid')582 cache = _sb_get(config, 'cset.uuid')
@@ -518,6 +589,8 @@ class BcacheParser(ProbertParser):
518 by_uuid = '/dev/bcache/by-uuid/' + uuid589 by_uuid = '/dev/bcache/by-uuid/' + uuid
519 label = _sb_get(backing_data, 'dev.label')590 label = _sb_get(backing_data, 'dev.label')
520 for devname, data in blockdev_data.items():591 for devname, data in blockdev_data.items():
592 if not devname:
593 continue
521 if devname.startswith('/dev/bcache'):594 if devname.startswith('/dev/bcache'):
522 # DEVLINKS is a space separated list595 # DEVLINKS is a space separated list
523 devlinks = data.get('DEVLINKS', '').split()596 devlinks = data.get('DEVLINKS', '').split()
@@ -525,7 +598,7 @@ class BcacheParser(ProbertParser):
525 return devname598 return devname
526 if label:599 if label:
527 return label600 return label
528 raise ValueError('Failed to find bcache %s ' % (by_uuid))601 LOG.warning('Failed to find bcache %s ' % (by_uuid))
529602
530 def _cache_mode(dev_data):603 def _cache_mode(dev_data):
531 # "1 [writeback]" -> "writeback"604 # "1 [writeback]" -> "writeback"
@@ -535,12 +608,14 @@ class BcacheParser(ProbertParser):
535608
536 return None609 return None
537610
611 if not self.blockdev_data:
612 return None
613
538 backing_device = backing_data.get('blockdev')614 backing_device = backing_data.get('blockdev')
539 cache_device = _find_cache_device(backing_data, self.caching)615 cache_device = _find_cache_device(backing_data, self.caching)
540 cache_mode = _cache_mode(backing_data)616 cache_mode = _cache_mode(backing_data)
541 bcache_name = os.path.basename(617 bcache_name = os.path.basename(_find_bcache_devname(backing_uuid,
542 _find_bcache_devname(backing_uuid, backing_data,618 backing_data, self.blockdev_data))
543 self.blockdev_data))
544 bcache_entry = {'type': 'bcache', 'id': 'disk-%s' % bcache_name,619 bcache_entry = {'type': 'bcache', 'id': 'disk-%s' % bcache_name,
545 'name': bcache_name}620 'name': bcache_name}
546621
@@ -571,9 +646,10 @@ class BlockdevParser(ProbertParser):
571 errors = []646 errors = []
572647
573 for devname, data in self.blockdev_data.items():648 for devname, data in self.blockdev_data.items():
574 # skip composed devices here649 # skip composed devices here, except partitions
575 if data.get('DEVPATH', '').startswith('/devices/virtual'):650 if data.get('DEVPATH', '').startswith('/devices/virtual'):
576 continue651 if data.get('DEVTYPE', '') != "partition":
652 continue
577 entry = self.asdict(data)653 entry = self.asdict(data)
578 if entry:654 if entry:
579 try:655 try:
@@ -660,6 +736,9 @@ class BlockdevParser(ProbertParser):
660 'type': blockdev_data['DEVTYPE'],736 'type': blockdev_data['DEVTYPE'],
661 'id': self.blockdev_to_id(blockdev_data),737 'id': self.blockdev_to_id(blockdev_data),
662 }738 }
739 if blockdev_data.get('DM_MULTIPATH_DEVICE_PATH') == "1":
740 mpath_name = self.get_mpath_name(blockdev_data)
741 entry['multipath'] = mpath_name
663742
664 # default disks to gpt743 # default disks to gpt
665 if entry['type'] == 'disk':744 if entry['type'] == 'disk':
@@ -670,7 +749,11 @@ class BlockdevParser(ProbertParser):
670 entry.update(uniq_ids)749 entry.update(uniq_ids)
671750
672 if 'ID_PART_TABLE_TYPE' in blockdev_data:751 if 'ID_PART_TABLE_TYPE' in blockdev_data:
673 entry['ptable'] = blockdev_data['ID_PART_TABLE_TYPE']752 ptype = blockdev_data['ID_PART_TABLE_TYPE']
753 if ptype in schemas._ptables:
754 entry['ptable'] = ptype
755 else:
756 entry['ptable'] = schemas._ptable_unsupported
674 return entry757 return entry
675758
676 if entry['type'] == 'partition':759 if entry['type'] == 'partition':
@@ -920,7 +1003,6 @@ class RaidParser(ProbertParser):
920 Collects storage config type: raid for valid1003 Collects storage config type: raid for valid
921 data and returns tuple of lists, configs, errors.1004 data and returns tuple of lists, configs, errors.
922 """1005 """
923
924 configs = []1006 configs = []
925 errors = []1007 errors = []
926 for devname, data in self.class_data.items():1008 for devname, data in self.class_data.items():
@@ -1104,7 +1186,7 @@ class ZfsParser(ProbertParser):
1104 return (zpool_configs + zfs_configs, errors)1186 return (zpool_configs + zfs_configs, errors)
11051187
11061188
1107def extract_storage_config(probe_data):1189def extract_storage_config(probe_data, strict=False):
1108 """ Examine a probert storage dictionary and extract a curtin1190 """ Examine a probert storage dictionary and extract a curtin
1109 storage configuration that would recreate all of the1191 storage configuration that would recreate all of the
1110 storage devices present in the provided data.1192 storage devices present in the provided data.
@@ -1156,7 +1238,10 @@ def extract_storage_config(probe_data):
1156 for e in errors:1238 for e in errors:
1157 LOG.exception('Validation error: %s\n' % e)1239 LOG.exception('Validation error: %s\n' % e)
1158 if len(errors) > 0:1240 if len(errors) > 0:
1159 raise RuntimeError("Extract storage config does not validate.")1241 errmsg = "Extract storage config does not validate."
1242 LOG.warning(errmsg)
1243 if strict:
1244 raise RuntimeError(errmsg)
11601245
1161 # build and merge probed data into a valid storage config by1246 # build and merge probed data into a valid storage config by
1162 # generating a config tree for each item in the probed data1247 # generating a config tree for each item in the probed data
diff --git a/curtin/udev.py b/curtin/udev.py
index 106a7e7..e2e3dd0 100644
--- a/curtin/udev.py
+++ b/curtin/udev.py
@@ -1,6 +1,8 @@
1# This file is part of curtin. See LICENSE file for copyright and license info.1# This file is part of curtin. See LICENSE file for copyright and license info.
22
3import shlex
3import os4import os
5
4from curtin import util6from curtin import util
5from curtin.log import logged_call7from curtin.log import logged_call
68
@@ -73,7 +75,7 @@ def udevadm_info(path=None):
73 if not path:75 if not path:
74 raise ValueError('Invalid path: "%s"' % path)76 raise ValueError('Invalid path: "%s"' % path)
7577
76 info_cmd = ['udevadm', 'info', '--query=property', path]78 info_cmd = ['udevadm', 'info', '--query=property', '--export', path]
77 output, _ = util.subp(info_cmd, capture=True)79 output, _ = util.subp(info_cmd, capture=True)
7880
79 # strip for trailing empty line81 # strip for trailing empty line
@@ -87,13 +89,19 @@ def udevadm_info(path=None):
87 if not value:89 if not value:
88 value = None90 value = None
89 if value:91 if value:
90 # devlinks is a list of paths separated by space92 # preserve spaces in values to match udev database
91 # convert to a list for easy use93 parsed = shlex.split(value)
92 if key == 'DEVLINKS':94 if ' ' not in value:
93 info[key] = value.split()95 info[key] = parsed[0]
94 else:96 else:
95 # preserve spaces in values, to match udev database97 # special case some known entries with spaces, e.g. ID_SERIAL
96 info[key] = value98 # and DEVLINKS, see tests/unittests/test_udev.py
99 if key == "DEVLINKS":
100 info[key] = shlex.split(parsed[0])
101 elif key == 'ID_SERIAL':
102 info[key] = parsed[0]
103 else:
104 info[key] = parsed
97105
98 return info106 return info
99107
diff --git a/curtin/util.py b/curtin/util.py
index ebe219d..eb2228f 100644
--- a/curtin/util.py
+++ b/curtin/util.py
@@ -632,7 +632,7 @@ class ChrootableTarget(object):
632 if mounts is not None:632 if mounts is not None:
633 self.mounts = mounts633 self.mounts = mounts
634 else:634 else:
635 self.mounts = ["/dev", "/proc", "/sys"]635 self.mounts = ["/dev", "/proc", "/run", "/sys"]
636 self.umounts = []636 self.umounts = []
637 self.disabled_daemons = False637 self.disabled_daemons = False
638 self.allow_daemons = allow_daemons638 self.allow_daemons = allow_daemons
@@ -906,8 +906,9 @@ def sanitize_source(source):
906 if type(source) is dict:906 if type(source) is dict:
907 # already sanitized?907 # already sanitized?
908 return source908 return source
909 supported = ['tgz', 'dd-tgz', 'dd-tbz', 'dd-txz', 'dd-tar', 'dd-bz2',909 supported = ['tgz', 'dd-tgz', 'tbz', 'dd-tbz', 'txz', 'dd-txz', 'dd-tar',
910 'dd-gz', 'dd-xz', 'dd-raw', 'fsimage', 'fsimage-layered']910 'dd-bz2', 'dd-gz', 'dd-xz', 'dd-raw', 'fsimage',
911 'fsimage-layered']
911 deftype = 'tgz'912 deftype = 'tgz'
912 for i in supported:913 for i in supported:
913 prefix = i + ":"914 prefix = i + ":"
@@ -915,8 +916,14 @@ def sanitize_source(source):
915 return {'type': i, 'uri': source[len(prefix):]}916 return {'type': i, 'uri': source[len(prefix):]}
916917
917 # translate squashfs: to fsimage type.918 # translate squashfs: to fsimage type.
918 if source.startswith("squashfs:"):919 if source.startswith("squashfs://"):
919 return {'type': 'fsimage', 'uri': source[len("squashfs:")]}920 return {'type': 'fsimage', 'uri': source[len("squashfs://"):]}
921
922 elif source.startswith("squashfs:"):
923 LOG.warning("The squashfs: prefix is deprecated and"
924 "will be removed in a future release."
925 "Please use squashfs:// instead.")
926 return {'type': 'fsimage', 'uri': source[len("squashfs:"):]}
920927
921 if source.endswith("squashfs") or source.endswith("squash"):928 if source.endswith("squashfs") or source.endswith("squash"):
922 return {'type': 'fsimage', 'uri': source}929 return {'type': 'fsimage', 'uri': source}
diff --git a/debian/changelog b/debian/changelog
index a5c5527..6d739ab 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,66 @@
1curtin (19.3-17-g50ffca46-0ubuntu1~19.10.1) eoan; urgency=medium
2
3 * New upstream snapshot. (LP: #1861452)
4 - clear-holders: ensure we wipe device even if multipath enabled not not mp
5 - block_meta: use reliable fs_spec entries for block devices
6 - multipath: handle removal of multipath partitions correctly
7 - vmtests: skip Focal deploying Centos70 ScsiBasic
8 - vmtests: fix network mtu tests, separating ifupdown vs networkd
9 - doc: Fix kexec documentation bug. [Mike Pontillo]
10 - vmtests: Add Focal Fossa
11 - centos: Add centos/rhel 8 support, enable UEFI Secure Boot
12 [Lee Trager]
13 - Bump XFS /boot skip-by date out a while
14 - vmtest: Fix a missing unset of OUTPUT_FSTAB
15 - curthooks: handle s390x/aarch64 kernel install hooks
16 - clear-holders: handle arbitrary order of devices to clear
17 - curthooks: only run update-initramfs in target once
18 - test_network_mtu: bump fixby date for MTU tests
19 - block-discover: don't skip partitions on virtual devices
20 - block-discover: handle partial probe data
21 - Fix parsing of squashfs: uri prefix for installation sources
22 [Daniel Fox]
23 - Release 19.3
24 - Update HACKING.rst with Josh Powers contact info.
25 - t/jenkins-runner: replace $EPOCHSECONDS with 'date +%s' [Paride Legovini]
26 - curthooks: skip setup_kernel_img_conf on eoan and newer
27 - block_meta: use lookup for wwn, fix fallback from wwn, serial, path
28 - vmtest: Adjust TestScsiBasic to use dnames to find correct disk
29 - schema: Add ptable value 'unsupported'
30 - tools/xkvm: add -nographic to speed up devopt query
31 - test_block_dasd: fix random_device_id to only generate valid IDs
32 - vmtest: update skip_if_arch message
33 - Add skip_by_date to eoan ipv6 vlan test
34 - storage_config: interpret value, not presence, of
35 DM_MULTIPATH_DEVICE_PATH [Michael Hudson-Doyle]
36 - vmtest: Add skip_by_date for test_ip_output on eoan + vlans
37 - block-schema: update raid schema for preserve and metadata
38 - dasd: update partition table value to 'vtoc'
39 - clear-holders: increase the level for devices with holders by one
40 - tests: mock timestamp used in collect-log file creation
41 - ChrootableTarget: mount /run to resolve lvm/mdadm issues which
42 require it.
43 - block-discover: handle multipath disks
44 - Handle partial raid on partitions
45 - install: export zpools if present in the storage-config
46 - block-schema: allow 'mac' as partition table type
47 - jenkins-runner: disable the lockfile timeout by default [Paride Legovini]
48 - curthooks: use correct grub-efi package name on i386
49 - vmtest-sync-images: remove unused imports [Paride Legovini]
50 - vmtests: use file locking on the images [Paride Legovini]
51 - vmtest: enable arm64 [Paride Legovini]
52 - Make the vmtests/test_basic test suite run on ppc64el [Paride Legovini]
53 - vmtests: separate arch and target_arch in tests [Paride Legovini]
54 - vmtests: new decorator: skip_if_arch [Paride Legovini]
55 - vmtests: increase the VM memory for Bionic
56 - vmtests: Skip Eoan ZFS Root tests until bug fix is complete
57 - util: add support for 'tbz', 'txz' tar format types to sanitize_source
58 - net: ensure eni helper tools install if given netplan config
59 - d/control: update Depends for new probert package names
60 [Dimitri John Ledkov]
61
62 -- Ryan Harper <ryan.harper@canonical.com> Thu, 30 Jan 2020 13:46:56 -0600
63
1curtin (19.2-9-g38ce22b0-0ubuntu1) eoan; urgency=medium64curtin (19.2-9-g38ce22b0-0ubuntu1) eoan; urgency=medium
265
3 * New upstream snapshot.66 * New upstream snapshot.
diff --git a/debian/control b/debian/control
index b5b857b..9fddcbd 100644
--- a/debian/control
+++ b/debian/control
@@ -26,7 +26,7 @@ Depends: bcache-tools,
26 lvm2,26 lvm2,
27 mdadm,27 mdadm,
28 parted,28 parted,
29 probert,29 probert-storage | probert,
30 python3-curtin (= ${binary:Version}),30 python3-curtin (= ${binary:Version}),
31 udev,31 udev,
32 xfsprogs,32 xfsprogs,
diff --git a/doc/topics/config.rst b/doc/topics/config.rst
index b7cca43..59e71f3 100644
--- a/doc/topics/config.rst
+++ b/doc/topics/config.rst
@@ -393,7 +393,8 @@ Enable rebooting with kexec.
393393
394**Example**::394**Example**::
395395
396 kexec: on396 kexec:
397 mode: "on"
397398
398399
399multipath400multipath
@@ -555,6 +556,7 @@ configures the method used to copy the image to the target system.
555- **dd-**: Use ``dd`` command to write image to target.556- **dd-**: Use ``dd`` command to write image to target.
556- **cp://**: Use ``rsync`` command to copy source directory to target.557- **cp://**: Use ``rsync`` command to copy source directory to target.
557- **file://**: Use ``tar`` command to extract source to target.558- **file://**: Use ``tar`` command to extract source to target.
559- **squashfs://**: Mount squashfs image and copy contents to target.
558- **http[s]://**: Use ``wget | tar`` commands to extract source to target.560- **http[s]://**: Use ``wget | tar`` commands to extract source to target.
559- **fsimage://** mount filesystem image and copy contents to target.561- **fsimage://** mount filesystem image and copy contents to target.
560 Local file or url are supported. Filesystem can be any filesystem type562 Local file or url are supported. Filesystem can be any filesystem type
@@ -649,6 +651,9 @@ This results in Curtin downloading the following URLs::
649 sources: 651 sources:
650 - cp:///652 - cp:///
651653
654**Example squashfs from NFS mount**::
655 sources:
656 - squashfs:///media/filesystem.squashfs
652657
653**Example Copy from local tarball**::658**Example Copy from local tarball**::
654659
diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
index a1346e9..c85174d 100644
--- a/doc/topics/storage.rst
+++ b/doc/topics/storage.rst
@@ -110,7 +110,7 @@ These ``label`` values are reserved and cannot be used:
110**disk_layout**: *cdl, ldl*110**disk_layout**: *cdl, ldl*
111111
112The default ``disk_layout`` value is ``cdl``, the compaible disk layout which112The default ``disk_layout`` value is ``cdl``, the compaible disk layout which
113allows for up to 3 partitions and a MBR. The ``ldl``, Linux layout has only113allows for up to 3 partitions and a VTOC. The ``ldl``, Linux layout has only
114one partition.114one partition.
115115
116116
@@ -125,7 +125,7 @@ one partition.
125 mode: full125 mode: full
126 - id: disk0126 - id: disk0
127 type: disk127 type: disk
128 ptable: mbr128 ptable: vtoc
129 serial: 0X1520129 serial: 0X1520
130 name: root_disk130 name: root_disk
131 wipe: superblock131 wipe: superblock
@@ -278,6 +278,14 @@ and determine which device to use as a boot disk. In cases where the boot
278device is on a special volume, such as a RAID array or a LVM Logical Volume,278device is on a special volume, such as a RAID array or a LVM Logical Volume,
279it may be necessary to specify the device that will hold the grub bootloader.279it may be necessary to specify the device that will hold the grub bootloader.
280280
281**multipath**: *<multipath name or serial>*
282
283If a disk is a path in a multipath device, it may be included in the
284configuration dictionary. Currently the value is informational only.
285Curtin already detects whether disks are part of a multipath and selects
286one member path to operate upon.
287
288
281**Config Example**::289**Config Example**::
282290
283 - id: disk0291 - id: disk0
@@ -374,6 +382,13 @@ For partitions, the udev rule created relies upon disk contents, in this case
374the partition entry UUID. This will remain in effect unless the underlying disk382the partition entry UUID. This will remain in effect unless the underlying disk
375on which the partition resides has the partition table modified or wiped.383on which the partition resides has the partition table modified or wiped.
376384
385**multipath**: *<multipath name or serial>*
386
387If a partition is found on a multipath device, it may be included in the
388configuration dictionary. Currently the value is informational only.
389Curtin already detects whether partitions are part of a multipath and selects
390one member path to operate upon.
391
377392
378**Config Example**::393**Config Example**::
379394
diff --git a/examples/tests/basic-dasd.yaml b/examples/tests/basic-dasd.yaml
index 62efbf0..3b0ba0d 100644
--- a/examples/tests/basic-dasd.yaml
+++ b/examples/tests/basic-dasd.yaml
@@ -11,14 +11,14 @@ storage:
11 - id: sda11 - id: sda
12 type: disk12 type: disk
13 wipe: superblock13 wipe: superblock
14 ptable: msdos14 ptable: vtoc
15 model: QEMU HARDDISK15 model: QEMU HARDDISK
16 serial: disk-a16 serial: disk-a
17 grub_device: true17 grub_device: true
18 - id: dasdb18 - id: dasdb
19 type: disk19 type: disk
20 wipe: superblock20 wipe: superblock
21 ptable: msdos21 ptable: vtoc
22 serial: 0X152022 serial: 0X1520
23 wipe: superblock23 wipe: superblock
24 - id: sda-part124 - id: sda-part1
diff --git a/examples/tests/bcache-ceph-nvme-simple.yaml b/examples/tests/bcache-ceph-nvme-simple.yaml
25new file mode 10064425new file mode 100644
index 0000000..83cb04c
--- /dev/null
+++ b/examples/tests/bcache-ceph-nvme-simple.yaml
@@ -0,0 +1,107 @@
1storage:
2 config:
3 - grub_device: true
4 id: sda
5 model: MM1000GBKAL
6 name: sda
7 ptable: gpt
8 serial: disk-a
9 type: disk
10 wipe: superblock
11 - id: sdb
12 model: MM1000GBKAL
13 name: sdb
14 serial: disk-b
15 type: disk
16 wipe: superblock
17 - id: nvme0n1
18 model: INTEL SSDPEDME400G4
19 name: nvme0n1
20 serial: nvme-CVMD552400
21 type: disk
22 wipe: superblock
23 - backing_device: sdb
24 cache_device: nvme0n1
25 cache_mode: writeback
26 id: bcache1
27 name: bcache1
28 type: bcache
29 - device: sda
30 id: sda-part1
31 name: sda-part1
32 number: 1
33 offset: 4194304B
34 size: 5G
35 type: partition
36 uuid: 1e27e7af-26dc-4af4-9ef5-aea928204997
37 wipe: superblock
38 - device: sda
39 id: sda-part2
40 name: sda-part2
41 number: 2
42 size: 2G
43 type: partition
44 uuid: 0040d622-41f1-4596-842f-82d731ba9054
45 wipe: superblock
46 - device: sda
47 id: sda-part3
48 name: sda-part3
49 number: 3
50 size: 2G
51 type: partition
52 uuid: cb59d827-662c-4da6-b1ef-7967218bd0db
53 wipe: superblock
54 - backing_device: sda-part3
55 cache_device: nvme0n1
56 cache_mode: writeback
57 id: bcache0
58 name: bcache0
59 type: bcache
60 - fstype: fat32
61 id: sda-part1_format
62 label: efi
63 type: format
64 uuid: 27638478-d881-43e5-a93c-1cac7aa60daa
65 volume: sda-part1
66 - fstype: ext4
67 id: sda-part2_format
68 label: boot
69 type: format
70 uuid: cfd11d4f-d77f-4307-b372-b52e81c873f7
71 volume: sda-part2
72 - fstype: ext4
73 id: bcache0_format
74 label: root
75 type: format
76 uuid: 63247841-195c-4939-83e4-cb834d61f95f
77 volume: bcache0
78 - devices:
79 - bcache1
80 id: ceph-bcache-vg
81 name: ceph-bcache-vg
82 type: lvm_volgroup
83 - id: ceph-bcache-lv-0
84 name: ceph-bcache-lv-0
85 size: 3G
86 type: lvm_partition
87 volgroup: ceph-bcache-vg
88 - fstype: xfs
89 id: ceph-bcache-lv-0_format
90 volume: ceph-bcache-lv-0
91 type: format
92 - device: bcache0_format
93 id: bcache0_mount
94 options: ''
95 path: /
96 type: mount
97 - device: sda-part2_format
98 id: sda-part2_mount
99 options: ''
100 path: /boot
101 type: mount
102 - device: sda-part1_format
103 id: sda-part1_mount
104 options: ''
105 path: /boot/efi
106 type: mount
107 version: 1
diff --git a/examples/tests/bcache-wipe-xfs.yaml b/examples/tests/bcache-wipe-xfs.yaml
index 558d442..1a181a8 100644
--- a/examples/tests/bcache-wipe-xfs.yaml
+++ b/examples/tests/bcache-wipe-xfs.yaml
@@ -6,9 +6,10 @@ early_commands:
6 # would be seen as soon as the disk was partitioned and cause problems6 # would be seen as soon as the disk was partitioned and cause problems
7 # for curtin's use of the disk.7 # for curtin's use of the disk.
8 # This config recreates issue LP: #17186998 # This config recreates issue LP: #1718699
9 00_blockmeta: [env, -u, OUTPUT_FSTAB, TARGET_MOUNT_POINT=/tmp/my.bdir/target,9 00_blockmeta: [env, OUTPUT_FSTAB=/tmp/my.bdir/state/fstab,
10 WORKING_DIR=/tmp/my.bdir/work.d, curtin, --showtrace, -v,10 TARGET_MOUNT_POINT=/tmp/my.bdir/target,
11 block-meta, --umount, custom]11 WORKING_DIR=/tmp/my.bdir/work.d, curtin, --showtrace, -v,
12 block-meta, --umount, custom]
12 01_clear_holders: [curtin, clear-holders, --preserve, /dev/disk/by-id/virtio-disk-b]13 01_clear_holders: [curtin, clear-holders, --preserve, /dev/disk/by-id/virtio-disk-b]
13 02_quick_erase: [curtin, block-wipe, --mode, superblock, /dev/disk/by-id/virtio-disk-b]14 02_quick_erase: [curtin, block-wipe, --mode, superblock, /dev/disk/by-id/virtio-disk-b]
1415
diff --git a/examples/tests/bridging_network_v2.yaml b/examples/tests/bridging_network_v2.yaml
15new file mode 10064416new file mode 100644
index 0000000..b208972
--- /dev/null
+++ b/examples/tests/bridging_network_v2.yaml
@@ -0,0 +1,38 @@
1# v2 equivalent of examples/tests/bridging_network.yaml
2showtrace: true
3network:
4 version: 2
5 ethernets:
6 eth0:
7 dhcp4: true
8 match:
9 macaddress: '52:54:00:12:34:00'
10 set-name: eth0
11 eth1:
12 match:
13 macaddress: '52:54:00:12:34:02'
14 set-name: eth1
15 eth2:
16 match:
17 macaddress: '52:54:00:12:34:04'
18 set-name: eth2
19 bridges:
20 br0:
21 addresses:
22 - 192.168.14.2/24
23 interfaces:
24 - eth1
25 - eth2
26 parameters:
27 ageing-time: 250
28 forward-delay: 1
29 hello-time: 1
30 max-age: 10
31 path-cost:
32 eth1: 50
33 eth2: 75
34 port-priority:
35 eth1: 28
36 eth2: 14
37 priority: 22
38 stp: false
diff --git a/examples/tests/dirty_disks_config.yaml b/examples/tests/dirty_disks_config.yaml
index bcf3fbc..2f86f9e 100644
--- a/examples/tests/dirty_disks_config.yaml
+++ b/examples/tests/dirty_disks_config.yaml
@@ -22,6 +22,13 @@ bucket:
22 done22 done
23 swapon --show23 swapon --show
24 exit 024 exit 0
25 - &multipath_on |
26 #!/bin/sh
27 if command -v multipath; then
28 multipath -ll
29 multipath -r
30 multipath -ll
31 fi
25 - &zpool_export |32 - &zpool_export |
26 #!/bin/sh33 #!/bin/sh
27 # disable any rpools to trigger disks with zfs_member label but inactive34 # disable any rpools to trigger disks with zfs_member label but inactive
@@ -75,11 +82,12 @@ early_commands:
75 # the disks exactly as in this config before the rest of the install82 # the disks exactly as in this config before the rest of the install
76 # will just blow it all away. We have clean out other environment83 # will just blow it all away. We have clean out other environment
77 # that could unintentionally mess things up.84 # that could unintentionally mess things up.
78 01-blockmeta: [env, -u, OUTPUT_FSTAB,85 01-blockmeta: [env, OUTPUT_FSTAB=/tmp/my.bdir/state/fstab,
79 TARGET_MOUNT_POINT=/tmp/my.bdir/target,86 TARGET_MOUNT_POINT=/tmp/my.bdir/target,
80 WORKING_DIR=/tmp/my.bdir/work.d,87 WORKING_DIR=/tmp/my.bdir/work.d,
81 curtin, --showtrace, -v, block-meta, --umount, custom]88 curtin, --showtrace, -v, block-meta, --umount, custom]
82 02-enable_swaps: [sh, -c, *swapon]89 02-enable_swaps: [sh, -c, *swapon]
90 02-multipath_on: [sh, -c, *multipath_on]
83 03-disable_rpool: [sh, -c, *zpool_export]91 03-disable_rpool: [sh, -c, *zpool_export]
84 04-lvm_stop: [sh, -c, *lvm_stop]92 04-lvm_stop: [sh, -c, *lvm_stop]
85 05-mdadm_stop: [sh, -c, *mdadm_stop]93 05-mdadm_stop: [sh, -c, *mdadm_stop]
diff --git a/examples/tests/network_mtu_networkd.yaml b/examples/tests/network_mtu_networkd.yaml
86new file mode 10064494new file mode 100644
index 0000000..e2ac444
--- /dev/null
+++ b/examples/tests/network_mtu_networkd.yaml
@@ -0,0 +1,93 @@
1showtrace: true
2network:
3 version: 1
4 config:
5 - type: physical
6 name: interface0
7 mac_address: "52:54:00:12:34:00"
8 subnets:
9 - type: static
10 address: 192.168.1.2/24
11 mtu: 1601
12 - type: static
13 address: 2001:4800:78ff:1b:be76:4eff:fe06:1000
14 netmask: 'ffff:ffff:ffff:ffff::'
15 mtu: 1501
16 - type: physical
17 name: interface1
18 mac_address: "52:54:00:12:34:02"
19 subnets:
20 - type: static
21 address: 192.168.2.2/24
22 mtu: 1501
23 - type: static
24 address: 2001:4800:78ff:1b:be76:4eff:fe06:2000
25 netmask: 'ffff:ffff:ffff:ffff::'
26 mtu: 1501
27 - type: physical
28 name: interface2
29 mac_address: "52:54:00:12:34:04"
30 subnets:
31 - type: dhcp
32 - type: physical
33 name: interface4
34 mac_address: "52:54:00:12:34:08"
35 subnets:
36 - type: static
37 address: 2001:4800:78ff:1b:be76:4eff:fe06:5000
38 netmask: 'ffff:ffff:ffff:ffff::'
39 mtu: 8900
40 - type: static
41 address: 192.168.5.2/24
42 mtu: 9000
43 - type: physical
44 name: interface5
45 mac_address: "52:54:00:12:34:0c"
46 subnets:
47 - type: static
48 address: 2001:4800:78ff:1b:be76:4eff:fe06:6000
49 netmask: 'ffff:ffff:ffff:ffff::'
50 mtu: 1480
51 - type: static
52 address: 192.168.6.2/24
53 mtu: 1480
54
55write_files:
56 capture_mtu:
57 path: '/usr/local/bin/capture-mtu'
58 permissions: '0755'
59 owner: 'root:root'
60 content: |
61 #!/bin/sh
62 for x in 0 1 2 4 5; do
63 dev_mtu=$(cat /sys/class/net/interface${x}/mtu)
64 ipv6_mtu=$(cat /proc/sys/net/ipv6/conf/interface${x}/mtu)
65 sys=$(sysctl net.ipv6.conf.interface${x}.mtu)
66 echo "WARK: interface${x} dev_mtu=$dev_mtu proc_ipv6_mtu=$ipv6_mtu"
67 echo "WARK: $sys"
68 done
69
70bucket:
71 - &networkd_debug |
72 #!/bin/sh
73 MP=$TARGET_MOUNT_POINT
74 mkdir -p "${MP}/etc/systemd/system/systemd-networkd.service.d"
75 conf="${MP}/etc/systemd/system/systemd-networkd.service.d/10-debug.conf"
76 echo "[Service]" >$conf
77 echo "Environment=SYSTEMD_LOG_LEVEL=debug" >>$conf
78 echo "ExecStartPost=/usr/local/bin/capture-mtu" >>$conf
79 exit 0
80
81 - &capture_mtu |
82 #!/bin/sh -x
83 MP=$TARGET_MOUNT_POINT
84 for service in cloud-init-local cloud-init cloud-config; do
85 mkdir -p "${MP}/etc/systemd/system/${service}.service.d"
86 conf="${MP}/etc/systemd/system/${service}.service.d/10-debug.conf"
87 echo "[Service]" >$conf
88 echo "ExecStartPre=/usr/local/bin/capture-mtu" >>$conf
89 done
90
91late_commands:
92 01-networkd_debug: [sh, -c, *networkd_debug]
93 02-capture_mtu: [sh, -c, *capture_mtu]
diff --git a/examples/tests/reuse-raid-member-partition.yaml b/examples/tests/reuse-raid-member-partition.yaml
0new file mode 10064494new file mode 100644
index 0000000..3fe2d83
--- /dev/null
+++ b/examples/tests/reuse-raid-member-partition.yaml
@@ -0,0 +1,73 @@
1showtrace: true
2
3# The point of this test is to test installing to a partition that used to
4# be a RAID member where the other disks that used to be part of the
5# RAID are not present (the scenario that the disk was just grabbed
6# out of a pile of previously used disks and shoved into a server).
7
8# So what it does is to create a RAID0 out of two partition from two
9# disks, stop the RAID, wipe one of the disks and then install to the
10# other, reusing the partition that was part of the RAID.
11
12bucket:
13 - &setup |
14 parted /dev/disk/by-id/virtio-disk-a --script -- \
15 mklabel gpt \
16 mkpart primary 1GiB 2GiB \
17 mkpart primary 2GiB 9GiB
18 parted /dev/disk/by-id/virtio-disk-b --script -- \
19 mklabel gpt \
20 mkpart primary 2GiB 9GiB
21 udevadm settle
22 mdadm --create --metadata 1.2 --level 0 -n 2 /dev/md1 --assume-clean \
23 /dev/disk/by-id/virtio-disk-a-part2 /dev/disk/by-id/virtio-disk-b-part1
24 udevadm settle
25 mdadm --stop /dev/md1
26 udevadm settle
27 mdadm --zero-superblock /dev/disk/by-id/virtio-disk-b-part1
28 wipefs -a /dev/disk/by-id/virtio-disk-b
29 udevadm settle
30
31early_commands:
32 00-setup-raid: [sh, -exuc, *setup]
33
34storage:
35 config:
36 - type: disk
37 id: id_disk0
38 serial: disk-a
39 ptable: gpt
40 preserve: true
41 - type: disk
42 id: id_disk1
43 serial: disk-b
44 - type: partition
45 id: id_disk0_part1
46 preserve: true
47 device: id_disk0
48 flag: boot
49 number: 1
50 size: 1G
51 - type: partition
52 id: id_disk0_part2
53 preserve: true
54 device: id_disk0
55 number: 2
56 size: 7G
57 - type: format
58 id: id_efi_format
59 volume: id_disk0_part1
60 fstype: fat32
61 - type: format
62 id: id_root_format
63 volume: id_disk0_part2
64 fstype: ext4
65 - type: mount
66 device: id_root_format
67 id: id_root_mount
68 path: /
69 - type: mount
70 id: id_efi_mount
71 device: id_efi_format
72 path: /boot/efi
73 version: 1
diff --git a/examples/tests/reuse-raid-member-wipe.yaml b/examples/tests/reuse-raid-member-wipe.yaml
0new file mode 10064474new file mode 100644
index 0000000..84a2686
--- /dev/null
+++ b/examples/tests/reuse-raid-member-wipe.yaml
@@ -0,0 +1,71 @@
1showtrace: true
2
3# The point of this test is to test installing to a disk that contains
4# a partition that used to be a RAID member where the other parts of
5# the RAID are not present (the scenario is that the disk was just
6# grabbed out of a pile of previously used disks and shoved into a
7# server).
8
9# So what it does is to create a RAID0 out of partitions on two disks,
10# stop the RAID, wipe the superblock on one of them and then install
11# to the other using a standard partitioning scheme.
12
13bucket:
14 - &setup |
15 parted /dev/disk/by-id/virtio-disk-a --script -- \
16 mklabel gpt \
17 mkpart primary 1GiB 9GiB
18 parted /dev/disk/by-id/virtio-disk-b --script -- \
19 mklabel gpt \
20 mkpart primary 1GiB 9GiB
21 udevadm settle
22 mdadm --create --metadata 1.2 --level 0 -n 2 /dev/md1 --assume-clean \
23 /dev/disk/by-id/virtio-disk-a-part1 /dev/disk/by-id/virtio-disk-b-part1
24 udevadm settle
25 mdadm --stop /dev/md1
26 udevadm settle
27 mdadm --zero-superblock /dev/disk/by-id/virtio-disk-b-part1
28 wipefs -a /dev/disk/by-id/virtio-disk-b
29 udevadm settle
30
31early_commands:
32 00-setup-raid: [sh, -exuc, *setup]
33
34storage:
35 config:
36 - type: disk
37 id: id_disk0
38 serial: disk-a
39 ptable: gpt
40 wipe: superblock-recursive
41 - type: disk
42 id: id_disk1
43 serial: disk-b
44 - type: partition
45 id: id_disk0_part1
46 device: id_disk0
47 flag: boot
48 number: 1
49 size: 512M
50 - type: partition
51 id: id_disk0_part2
52 device: id_disk0
53 number: 2
54 size: 8G
55 - type: format
56 id: id_efi_format
57 volume: id_disk0_part1
58 fstype: fat32
59 - type: format
60 id: id_root_format
61 volume: id_disk0_part2
62 fstype: ext4
63 - type: mount
64 device: id_root_format
65 id: id_root_mount
66 path: /
67 - type: mount
68 id: id_efi_mount
69 device: id_efi_format
70 path: /boot/efi
71 version: 1
diff --git a/helpers/common b/helpers/common
index 5928150..6c8e4f0 100644
--- a/helpers/common
+++ b/helpers/common
@@ -679,7 +679,7 @@ install_grub() {
679679
680 # grub is not the bootloader you are looking for680 # grub is not the bootloader you are looking for
681 if [ "${target_arch}" = "s390x" ]; then681 if [ "${target_arch}" = "s390x" ]; then
682 return 0;682 return 0;
683 fi683 fi
684684
685 # set correct grub package685 # set correct grub package
@@ -694,7 +694,7 @@ install_grub() {
694 x86_64)694 x86_64)
695 case $rhel_ver in695 case $rhel_ver in
696 6) grub_name="grub";;696 6) grub_name="grub";;
697 7) grub_name="grub2-pc";;697 7|8) grub_name="grub2-pc";;
698 *)698 *)
699 error "Unknown rhel_ver [$rhel_ver]";699 error "Unknown rhel_ver [$rhel_ver]";
700 return 1;700 return 1;
@@ -711,7 +711,10 @@ install_grub() {
711 case "$target_arch" in711 case "$target_arch" in
712 x86_64)712 x86_64)
713 # centos 7+, no centos6 support713 # centos 7+, no centos6 support
714 grub_name="grub2-efi-x64-modules"714 # grub2-efi-x64 installs a signed grub bootloader while
715 # curtin uses grub2-efi-x64-modules to generate grubx64.efi.
716 # Either works just check that one of them is installed.
717 grub_name="grub2-efi-x64 grub2-efi-x64-modules"
715 grub_target="x86_64-efi"718 grub_target="x86_64-efi"
716 ;;719 ;;
717 amd64)720 amd64)
@@ -739,11 +742,13 @@ install_grub() {
739 error "failed to check if $grub_name installed";742 error "failed to check if $grub_name installed";
740 return 1;743 return 1;
741 fi744 fi
742 case "$tmp" in745 # Check that any of the packages in $grub_name are installed. If
743 install\ ok\ installed) :;;746 # grub_name contains multiple packages, as it does for CentOS 7+,
744 *) debug 1 "$grub_name not installed, not doing anything";747 # only one package has to be installed for this to pass.
745 return 1;;748 if ! echo $tmp | grep -q 'install ok installed'; then
746 esac749 debug 1 "$grub_name not installed, not doing anything"
750 return 1
751 fi
747752
748 local grub_d="etc/default/grub.d"753 local grub_d="etc/default/grub.d"
749 # ubuntu writes to /etc/default/grub.d/50-curtin-settings.cfg754 # ubuntu writes to /etc/default/grub.d/50-curtin-settings.cfg
@@ -822,11 +827,31 @@ install_grub() {
822 if [ "$update_nvram" -ge 1 ]; then827 if [ "$update_nvram" -ge 1 ]; then
823 nvram=""828 nvram=""
824 fi829 fi
830 if [ "${#grubdevs_new[@]}" -eq 1 ] && [ -f "${grubdevs_new[0]}" ]; then
831 # Currently UEFI can only be pointed to one system partition. If
832 # for some reason multiple install locations are given only use the
833 # first.
834 efi_dev="${grubdevs_new[0]}"
835 elif [ "${#grubdevs_new[@]}" -gt 1 ]; then
836 error "Only one grub device supported on UEFI!"
837 exit 1
838 else
839 # If no storage configuration was given try to determine the system
840 # partition.
841 efi_dev=$(awk -v "MP=${mp}/boot/efi" '$2 == MP { print $1 }' /proc/mounts)
842 fi
843 # The partition number of block device name need to be determined here
844 # so both getting the UEFI device from Curtin config and discovering it
845 # work.
846 efi_part_num=$(cat /sys/class/block/$(basename $efi_dev)/partition)
847 efi_disk="/dev/$(lsblk -no pkname $efi_dev)"
825 debug 1 "curtin uefi: installing ${grub_name} to: /boot/efi"848 debug 1 "curtin uefi: installing ${grub_name} to: /boot/efi"
826 chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc '849 chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc '
827 echo "before grub-install efiboot settings"850 echo "before grub-install efiboot settings"
828 efibootmgr -v || echo "WARN: efibootmgr exited $?"851 efibootmgr -v || echo "WARN: efibootmgr exited $?"
829 bootid="$4"852 bootid="$4"
853 efi_disk="$5"
854 efi_part_num="$6"
830 grubpost=""855 grubpost=""
831 case $bootid in856 case $bootid in
832 debian|ubuntu)857 debian|ubuntu)
@@ -836,7 +861,15 @@ install_grub() {
836 ;;861 ;;
837 centos|redhat|rhel)862 centos|redhat|rhel)
838 grubcmd="grub2-install"863 grubcmd="grub2-install"
839 grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg"864 # RHEL uses redhat instead of the os_variant rhel for the bootid.
865 if [ "$bootid" = "rhel" ]; then
866 bootid="redhat"
867 fi
868 if [ -f /boot/efi/EFI/$bootid/grubx64.efi ]; then
869 grubpost="grub2-mkconfig -o /boot/efi/EFI/$bootid/grub.cfg"
870 else
871 grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg"
872 fi
840 ;;873 ;;
841 *)874 *)
842 echo "Unsupported OS: $bootid" 1>&2875 echo "Unsupported OS: $bootid" 1>&2
@@ -852,10 +885,45 @@ install_grub() {
852 echo "$gi_out" | grep -q -- "$no_nvram" || no_nvram=""885 echo "$gi_out" | grep -q -- "$no_nvram" || no_nvram=""
853 echo "$gi_out" | grep -q -- "--target" || target=""886 echo "$gi_out" | grep -q -- "--target" || target=""
854 echo "$gi_out" | grep -q -- "--efi-directory" || efi_dir=""887 echo "$gi_out" | grep -q -- "--efi-directory" || efi_dir=""
855 $grubcmd $target $efi_dir \888
856 --bootloader-id=$bootid --recheck $no_nvram889 # Do not overwrite grubx64.efi if it already exists. grub-install
890 # generates grubx64.efi and overwrites any existing binary in
891 # /boot/efi/EFI/$bootid. This binary is not signed and will cause
892 # secure boot to fail.
893 #
894 # CentOS, RHEL, Fedora ship the signed boot loader in the package
895 # grub2-efi-x64 which installs the signed boot loader to
896 # /boot/efi/EFI/$bootid/grubx64.efi. All Curtin has to do is
897 # configure the firmware. This mirrors what Anaconda does.
898 #
899 # Debian and Ubuntu come with a patched version of grub which
900 # add the install flag --uefi-secure-boot which is enabled by
901 # default. When enabled if a signed version of grub exists on
902 # the filesystem it will be copied into /boot/efi/EFI/$bootid.
903 # Stock Ubuntu images do not ship with anything in /boot. Those
904 # files are generated by installing a kernel and grub.
905 if [ -f /boot/efi/EFI/$bootid/grubx64.efi ]; then
906 if [ -z "$no_nvram" ]; then
907 # UEFI firmware should be pointed to the shim if available to
908 # enable secure boot.
909 for boot_uefi in \
910 /boot/efi/EFI/$bootid/shimx64.efi \
911 /boot/efi/EFI/BOOT/BOOTX64.EFI \
912 /boot/efi/EFI/$bootid/grubx64.efi; do
913 if [ -f $boot_uefi ]; then
914 break
915 fi
916 done
917 loader=$(echo ${boot_uefi##/boot/efi} | sed "s|/|\\\|g")
918 efibootmgr --create --write-signature --label $bootid \
919 --disk $efi_disk --part $efi_part_num --loader $loader
920 fi
921 else
922 $grubcmd $target $efi_dir \
923 --bootloader-id=$bootid --recheck $no_nvram
924 fi
857 [ -z "$grubpost" ] || $grubpost;' \925 [ -z "$grubpost" ] || $grubpost;' \
858 -- "${grub_name}" "${grub_target}" "$nvram" "$os_variant" </dev/null ||926 -- "$grub_name" "$grub_target" "$nvram" "$os_variant" "$efi_disk" "$efi_part_num" </dev/null ||
859 { error "failed to install grub!"; return 1; }927 { error "failed to install grub!"; return 1; }
860928
861 chroot "$mp" sh -exc '929 chroot "$mp" sh -exc '
@@ -885,8 +953,11 @@ install_grub() {
885 centos|redhat|rhel)953 centos|redhat|rhel)
886 case $bootver in954 case $bootver in
887 6) grubcmd="grub-install";;955 6) grubcmd="grub-install";;
888 7) grubcmd="grub2-install"956 7|8) grubcmd="grub2-install"
889 grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg";;957 grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg";;
958 *)
959 echo "Unknown rhel_ver [$bootver]"
960 exit 1
890 esac961 esac
891 ;;962 ;;
892 *)963 *)
diff --git a/tests/data/probert_storage_multipath.json b/tests/data/probert_storage_multipath.json
893new file mode 100644964new file mode 100644
index 0000000..53d9f93
--- /dev/null
+++ b/tests/data/probert_storage_multipath.json
@@ -0,0 +1,1059 @@
1{
2 "lvm": {},
3 "raid": {},
4 "filesystem": {
5 "/dev/sr0": {
6 "BOOT_SYSTEM_ID": "EL\\x20TORITO\\x20SPECIFICATION",
7 "LABEL": "Ubuntu-Server_19.10_amd64",
8 "LABEL_ENC": "Ubuntu-Server\\x2019.10\\x20amd64",
9 "TYPE": "iso9660",
10 "USAGE": "filesystem",
11 "UUID": "2019-08-11-07-41-33-00",
12 "UUID_ENC": "2019-08-11-07-41-33-00",
13 "VERSION": "Joliet Extension"
14 },
15 "/dev/sda2": {
16 "TYPE": "ext4",
17 "USAGE": "filesystem",
18 "UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
19 "UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
20 "VERSION": "1.0"
21 },
22 "/dev/sdb2": {
23 "TYPE": "ext4",
24 "USAGE": "filesystem",
25 "UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
26 "UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
27 "VERSION": "1.0"
28 },
29 "/dev/dm-2": {
30 "TYPE": "ext4",
31 "USAGE": "filesystem",
32 "UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
33 "UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
34 "VERSION": "1.0"
35 }
36 },
37 "mount": [
38 {
39 "target": "/",
40 "source": "/cow",
41 "fstype": "overlay",
42 "options": "rw,relatime,lowerdir=//installer.squashfs://filesystem.squashfs,upperdir=/cow/upper,workdir=/cow/work",
43 "children": [
44 {
45 "target": "/sys",
46 "source": "sysfs",
47 "fstype": "sysfs",
48 "options": "rw,nosuid,nodev,noexec,relatime",
49 "children": [
50 {
51 "target": "/sys/kernel/security",
52 "source": "securityfs",
53 "fstype": "securityfs",
54 "options": "rw,nosuid,nodev,noexec,relatime"
55 },
56 {
57 "target": "/sys/fs/cgroup",
58 "source": "tmpfs",
59 "fstype": "tmpfs",
60 "options": "ro,nosuid,nodev,noexec,mode=755",
61 "children": [
62 {
63 "target": "/sys/fs/cgroup/unified",
64 "source": "cgroup2",
65 "fstype": "cgroup2",
66 "options": "rw,nosuid,nodev,noexec,relatime,nsdelegate"
67 },
68 {
69 "target": "/sys/fs/cgroup/systemd",
70 "source": "cgroup",
71 "fstype": "cgroup",
72 "options": "rw,nosuid,nodev,noexec,relatime,xattr,name=systemd"
73 },
74 {
75 "target": "/sys/fs/cgroup/cpu,cpuacct",
76 "source": "cgroup",
77 "fstype": "cgroup",
78 "options": "rw,nosuid,nodev,noexec,relatime,cpu,cpuacct"
79 },
80 {
81 "target": "/sys/fs/cgroup/devices",
82 "source": "cgroup",
83 "fstype": "cgroup",
84 "options": "rw,nosuid,nodev,noexec,relatime,devices"
85 },
86 {
87 "target": "/sys/fs/cgroup/perf_event",
88 "source": "cgroup",
89 "fstype": "cgroup",
90 "options": "rw,nosuid,nodev,noexec,relatime,perf_event"
91 },
92 {
93 "target": "/sys/fs/cgroup/hugetlb",
94 "source": "cgroup",
95 "fstype": "cgroup",
96 "options": "rw,nosuid,nodev,noexec,relatime,hugetlb"
97 },
98 {
99 "target": "/sys/fs/cgroup/rdma",
100 "source": "cgroup",
101 "fstype": "cgroup",
102 "options": "rw,nosuid,nodev,noexec,relatime,rdma"
103 },
104 {
105 "target": "/sys/fs/cgroup/net_cls,net_prio",
106 "source": "cgroup",
107 "fstype": "cgroup",
108 "options": "rw,nosuid,nodev,noexec,relatime,net_cls,net_prio"
109 },
110 {
111 "target": "/sys/fs/cgroup/freezer",
112 "source": "cgroup",
113 "fstype": "cgroup",
114 "options": "rw,nosuid,nodev,noexec,relatime,freezer"
115 },
116 {
117 "target": "/sys/fs/cgroup/cpuset",
118 "source": "cgroup",
119 "fstype": "cgroup",
120 "options": "rw,nosuid,nodev,noexec,relatime,cpuset"
121 },
122 {
123 "target": "/sys/fs/cgroup/memory",
124 "source": "cgroup",
125 "fstype": "cgroup",
126 "options": "rw,nosuid,nodev,noexec,relatime,memory"
127 },
128 {
129 "target": "/sys/fs/cgroup/blkio",
130 "source": "cgroup",
131 "fstype": "cgroup",
132 "options": "rw,nosuid,nodev,noexec,relatime,blkio"
133 },
134 {
135 "target": "/sys/fs/cgroup/pids",
136 "source": "cgroup",
137 "fstype": "cgroup",
138 "options": "rw,nosuid,nodev,noexec,relatime,pids"
139 }
140 ]
141 },
142 {
143 "target": "/sys/fs/pstore",
144 "source": "pstore",
145 "fstype": "pstore",
146 "options": "rw,nosuid,nodev,noexec,relatime"
147 },
148 {
149 "target": "/sys/fs/bpf",
150 "source": "bpf",
151 "fstype": "bpf",
152 "options": "rw,nosuid,nodev,noexec,relatime,mode=700"
153 },
154 {
155 "target": "/sys/kernel/debug",
156 "source": "debugfs",
157 "fstype": "debugfs",
158 "options": "rw,relatime"
159 },
160 {
161 "target": "/sys/kernel/config",
162 "source": "configfs",
163 "fstype": "configfs",
164 "options": "rw,relatime"
165 },
166 {
167 "target": "/sys/fs/fuse/connections",
168 "source": "fusectl",
169 "fstype": "fusectl",
170 "options": "rw,relatime"
171 }
172 ]
173 },
174 {
175 "target": "/proc",
176 "source": "proc",
177 "fstype": "proc",
178 "options": "rw,nosuid,nodev,noexec,relatime",
179 "children": [
180 {
181 "target": "/proc/sys/fs/binfmt_misc",
182 "source": "systemd-1",
183 "fstype": "autofs",
184 "options": "rw,relatime,fd=28,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13765"
185 }
186 ]
187 },
188 {
189 "target": "/dev",
190 "source": "udev",
191 "fstype": "devtmpfs",
192 "options": "rw,nosuid,relatime,size=462516k,nr_inodes=115629,mode=755",
193 "children": [
194 {
195 "target": "/dev/pts",
196 "source": "devpts",
197 "fstype": "devpts",
198 "options": "rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000"
199 },
200 {
201 "target": "/dev/shm",
202 "source": "tmpfs",
203 "fstype": "tmpfs",
204 "options": "rw,nosuid,nodev"
205 },
206 {
207 "target": "/dev/hugepages",
208 "source": "hugetlbfs",
209 "fstype": "hugetlbfs",
210 "options": "rw,relatime,pagesize=2M"
211 },
212 {
213 "target": "/dev/mqueue",
214 "source": "mqueue",
215 "fstype": "mqueue",
216 "options": "rw,relatime"
217 }
218 ]
219 },
220 {
221 "target": "/run",
222 "source": "tmpfs",
223 "fstype": "tmpfs",
224 "options": "rw,nosuid,noexec,relatime,size=100568k,mode=755",
225 "children": [
226 {
227 "target": "/run/lock",
228 "source": "tmpfs",
229 "fstype": "tmpfs",
230 "options": "rw,nosuid,nodev,noexec,relatime,size=5120k"
231 }
232 ]
233 },
234 {
235 "target": "/cdrom",
236 "source": "/dev/sr0",
237 "fstype": "iso9660",
238 "options": "ro,noatime,nojoliet,check=s,map=n,blocksize=2048"
239 },
240 {
241 "target": "/rofs",
242 "source": "/dev/loop0",
243 "fstype": "squashfs",
244 "options": "ro,noatime"
245 },
246 {
247 "target": "/usr/lib/modules",
248 "source": "/dev/loop2",
249 "fstype": "squashfs",
250 "options": "ro,relatime"
251 },
252 {
253 "target": "/media/filesystem",
254 "source": "/dev/loop0",
255 "fstype": "squashfs",
256 "options": "ro,relatime"
257 },
258 {
259 "target": "/tmp",
260 "source": "tmpfs",
261 "fstype": "tmpfs",
262 "options": "rw,nosuid,nodev,relatime"
263 },
264 {
265 "target": "/snap/core/7270",
266 "source": "/dev/loop3",
267 "fstype": "squashfs",
268 "options": "ro,nodev,relatime"
269 },
270 {
271 "target": "/snap/subiquity/1093",
272 "source": "/dev/loop4",
273 "fstype": "squashfs",
274 "options": "ro,nodev,relatime"
275 }
276 ]
277 }
278 ],
279 "multipath": {
280 "maps": [
281 {
282 "multipath": "30000000000000064",
283 "sysfs": "dm-0",
284 "paths": "2"
285 }
286 ],
287 "paths": [
288 {
289 "device": "sda",
290 "serial": "serial-a",
291 "multipath": "mpatha",
292 "host_wwnn": "[undef]",
293 "target_wwnn": "[undef]",
294 "host_wwpn": "[undef]",
295 "target_wwpn": "[undef]",
296 "host_adapter": "[undef]"
297 },
298 {
299 "device": "sdb",
300 "serial": "serial-a",
301 "multipath": "mpatha",
302 "host_wwnn": "[undef]",
303 "target_wwnn": "[undef]",
304 "host_wwpn": "[undef]",
305 "target_wwpn": "[undef]",
306 "host_adapter": "[undef]"
307 }
308 ]
309 },
310 "dmcrypt": {},
311 "blockdev": {
312 "/dev/sr0": {
313 "DEVLINKS": "/dev/disk/by-label/Ubuntu-Server\\x2019.10\\x20amd64 /dev/dvd /dev/disk/by-uuid/2019-08-11-07-41-33-00 /dev/disk/by-id/ata-QEMU_DVD-ROM_QM00003 /dev/cdrom /dev/disk/by-path/pci-0000:00:01.1-ata-2",
314 "DEVNAME": "/dev/sr0",
315 "DEVPATH": "/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/block/sr0",
316 "DEVTYPE": "disk",
317 "ID_ATA": "1",
318 "ID_BUS": "ata",
319 "ID_CDROM": "1",
320 "ID_CDROM_DVD": "1",
321 "ID_CDROM_MEDIA": "1",
322 "ID_CDROM_MEDIA_CD": "1",
323 "ID_CDROM_MEDIA_SESSION_COUNT": "1",
324 "ID_CDROM_MEDIA_TRACK_COUNT": "1",
325 "ID_CDROM_MEDIA_TRACK_COUNT_DATA": "1",
326 "ID_CDROM_MRW": "1",
327 "ID_CDROM_MRW_W": "1",
328 "ID_FOR_SEAT": "block-pci-0000_00_01_1-ata-2",
329 "ID_FS_BOOT_SYSTEM_ID": "EL\\x20TORITO\\x20SPECIFICATION",
330 "ID_FS_LABEL": "Ubuntu-Server_19.10_amd64",
331 "ID_FS_LABEL_ENC": "Ubuntu-Server\\x2019.10\\x20amd64",
332 "ID_FS_TYPE": "iso9660",
333 "ID_FS_USAGE": "filesystem",
334 "ID_FS_UUID": "2019-08-11-07-41-33-00",
335 "ID_FS_UUID_ENC": "2019-08-11-07-41-33-00",
336 "ID_FS_VERSION": "Joliet Extension",
337 "ID_MODEL": "QEMU_DVD-ROM",
338 "ID_MODEL_ENC": "QEMU\\x20DVD-ROM\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20",
339 "ID_PART_TABLE_TYPE": "dos",
340 "ID_PART_TABLE_UUID": "6612a5ed",
341 "ID_PATH": "pci-0000:00:01.1-ata-2",
342 "ID_PATH_TAG": "pci-0000_00_01_1-ata-2",
343 "ID_REVISION": "2.5+",
344 "ID_SCSI": "1",
345 "ID_SCSI_INQUIRY": "1",
346 "ID_SERIAL": "QEMU_DVD-ROM_QM00003",
347 "ID_SERIAL_SHORT": "QM00003",
348 "ID_TYPE": "cd",
349 "ID_VENDOR": "QEMU",
350 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
351 "MAJOR": "11",
352 "MINOR": "0",
353 "SCSI_MODEL": "QEMU_DVD-ROM",
354 "SCSI_MODEL_ENC": "QEMU\\x20DVD-ROM\\x20\\x20\\x20\\x20",
355 "SCSI_REVISION": "2.5+",
356 "SCSI_TPGS": "0",
357 "SCSI_TYPE": "cd/dvd",
358 "SCSI_VENDOR": "QEMU",
359 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
360 "SUBSYSTEM": "block",
361 "SYSTEMD_MOUNT_DEVICE_BOUND": "1",
362 "TAGS": ":systemd:uaccess:seat:",
363 "USEC_INITIALIZED": "1162968",
364 "attrs": {
365 "alignment_offset": "0",
366 "bdi": null,
367 "capability": "119",
368 "dev": "11:0",
369 "device": null,
370 "discard_alignment": "0",
371 "events": "media_change eject_request",
372 "events_async": "",
373 "events_poll_msecs": "-1",
374 "ext_range": "1",
375 "hidden": "0",
376 "inflight": " 0 0",
377 "range": "1",
378 "removable": "1",
379 "ro": "0",
380 "size": "2881486848",
381 "stat": " 3177 16 427476 210179 0 0 0 0 0 6880 207800 0 0 0 0",
382 "subsystem": "block",
383 "uevent": "MAJOR=11\nMINOR=0\nDEVNAME=sr0\nDEVTYPE=disk"
384 },
385 "partitiontable": {
386 "label": "dos",
387 "id": "0x6612a5ed",
388 "device": "/dev/sr0",
389 "unit": "sectors",
390 "partitions": [
391 {
392 "node": "/dev/sr0p1",
393 "start": 0,
394 "size": 1406976,
395 "type": "0",
396 "bootable": true
397 },
398 {
399 "node": "/dev/sr0p2",
400 "start": 790864,
401 "size": 7936,
402 "type": "ef"
403 }
404 ]
405 }
406 },
407 "/dev/sda": {
408 "DEVLINKS": "/dev/disk/by-id/scsi-30000000000000064 /dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:0:0 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a /dev/disk/by-id/wwn-0x0000000000000064 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a",
409 "DEVNAME": "/dev/sda",
410 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:0/2:0:0:0/block/sda",
411 "DEVTYPE": "disk",
412 "DM_DEL_PART_NODES": "1",
413 "DM_MULTIPATH_DEVICE_PATH": "1",
414 "ID_BUS": "scsi",
415 "ID_FS_TYPE": "mpath_member",
416 "ID_MODEL": "QEMU_HARDDISK",
417 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
418 "ID_PART_TABLE_TYPE": "gpt",
419 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
420 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:0:0",
421 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_0_0",
422 "ID_REVISION": "2.5+",
423 "ID_SCSI": "1",
424 "ID_SCSI_INQUIRY": "1",
425 "ID_SERIAL": "30000000000000064",
426 "ID_SERIAL_SHORT": "0000000000000064",
427 "ID_TYPE": "disk",
428 "ID_VENDOR": "QEMU",
429 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
430 "ID_WWN": "0x0000000000000064",
431 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
432 "MAJOR": "8",
433 "MINOR": "0",
434 "MPATH_SBIN_PATH": "/sbin",
435 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
436 "SCSI_IDENT_LUN_VENDOR": "serial-a",
437 "SCSI_IDENT_SERIAL": "serial-a",
438 "SCSI_MODEL": "QEMU_HARDDISK",
439 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
440 "SCSI_REVISION": "2.5+",
441 "SCSI_TPGS": "0",
442 "SCSI_TYPE": "disk",
443 "SCSI_VENDOR": "QEMU",
444 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
445 "SUBSYSTEM": "block",
446 "SYSTEMD_READY": "0",
447 "TAGS": ":systemd:",
448 "USEC_INITIALIZED": "1357719",
449 "attrs": {
450 "alignment_offset": "0",
451 "bdi": null,
452 "capability": "50",
453 "dev": "8:0",
454 "device": null,
455 "discard_alignment": "0",
456 "events": "",
457 "events_async": "",
458 "events_poll_msecs": "-1",
459 "ext_range": "256",
460 "hidden": "0",
461 "inflight": " 0 0",
462 "range": "16",
463 "removable": "0",
464 "ro": "0",
465 "size": "10737418240",
466 "stat": " 820 0 37338 127 0 0 0 0 0 452 4 0 0 0 0",
467 "subsystem": "block",
468 "uevent": "MAJOR=8\nMINOR=0\nDEVNAME=sda\nDEVTYPE=disk"
469 },
470 "partitiontable": {
471 "label": "gpt",
472 "id": "8261CD75-2234-4DBD-920A-D21A7C083C94",
473 "device": "/dev/sda",
474 "unit": "sectors",
475 "firstlba": 34,
476 "lastlba": 20971486,
477 "partitions": [
478 {
479 "node": "/dev/sda1",
480 "start": 2048,
481 "size": 2048,
482 "type": "21686148-6449-6E6F-744E-656564454649",
483 "uuid": "8088175C-362A-4B46-9603-F3595065FA73"
484 },
485 {
486 "node": "/dev/sda2",
487 "start": 4096,
488 "size": 20965376,
489 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
490 "uuid": "760493AC-7945-44C5-A6BD-58FCD6632EA7"
491 }
492 ]
493 }
494 },
495 "/dev/sda1": {
496 "DEVLINKS": "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a-part1 /dev/disk/by-id/scsi-30000000000000064-part1 /dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:0:0-part1 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a-part1 /dev/disk/by-partuuid/8088175c-362a-4b46-9603-f3595065fa73 /dev/disk/by-id/wwn-0x0000000000000064-part1",
497 "DEVNAME": "/dev/sda1",
498 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:0/2:0:0:0/block/sda/sda1",
499 "DEVTYPE": "partition",
500 "DM_MULTIPATH_DEVICE_PATH": "1",
501 "ID_BUS": "scsi",
502 "ID_FS_TYPE": "mpath_member",
503 "ID_MODEL": "QEMU_HARDDISK",
504 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
505 "ID_PART_ENTRY_DISK": "8:0",
506 "ID_PART_ENTRY_NUMBER": "1",
507 "ID_PART_ENTRY_OFFSET": "2048",
508 "ID_PART_ENTRY_SCHEME": "gpt",
509 "ID_PART_ENTRY_SIZE": "2048",
510 "ID_PART_ENTRY_TYPE": "21686148-6449-6e6f-744e-656564454649",
511 "ID_PART_ENTRY_UUID": "8088175c-362a-4b46-9603-f3595065fa73",
512 "ID_PART_TABLE_TYPE": "gpt",
513 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
514 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:0:0",
515 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_0_0",
516 "ID_REVISION": "2.5+",
517 "ID_SCSI": "1",
518 "ID_SCSI_INQUIRY": "1",
519 "ID_SERIAL": "30000000000000064",
520 "ID_SERIAL_SHORT": "0000000000000064",
521 "ID_TYPE": "disk",
522 "ID_VENDOR": "QEMU",
523 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
524 "ID_WWN": "0x0000000000000064",
525 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
526 "MAJOR": "8",
527 "MINOR": "1",
528 "PARTN": "1",
529 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
530 "SCSI_IDENT_LUN_VENDOR": "serial-a",
531 "SCSI_IDENT_SERIAL": "serial-a",
532 "SCSI_MODEL": "QEMU_HARDDISK",
533 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
534 "SCSI_REVISION": "2.5+",
535 "SCSI_TPGS": "0",
536 "SCSI_TYPE": "disk",
537 "SCSI_VENDOR": "QEMU",
538 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
539 "SUBSYSTEM": "block",
540 "SYSTEMD_READY": "0",
541 "TAGS": ":systemd:",
542 "USEC_INITIALIZED": "1409047",
543 "attrs": {
544 "alignment_offset": "0",
545 "dev": "8:1",
546 "discard_alignment": "0",
547 "inflight": " 0 0",
548 "partition": "1",
549 "ro": "0",
550 "size": "1048576",
551 "start": "2048",
552 "stat": " 167 0 1360 14 0 0 0 0 0 172 0 0 0 0 0",
553 "subsystem": "block",
554 "uevent": "MAJOR=8\nMINOR=1\nDEVNAME=sda1\nDEVTYPE=partition\nPARTN=1"
555 }
556 },
557 "/dev/sda2": {
558 "DEVLINKS": "/dev/disk/by-id/wwn-0x0000000000000064-part2 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a-part2 /dev/disk/by-uuid/80ca57a0-60b7-4328-be41-afedf915effd /dev/disk/by-partuuid/760493ac-7945-44c5-a6bd-58fcd6632ea7 /dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:0:0-part2 /dev/disk/by-id/scsi-30000000000000064-part2 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a-part2",
559 "DEVNAME": "/dev/sda2",
560 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:0/2:0:0:0/block/sda/sda2",
561 "DEVTYPE": "partition",
562 "DM_MULTIPATH_DEVICE_PATH": "1",
563 "ID_BUS": "scsi",
564 "ID_FS_TYPE": "ext4",
565 "ID_FS_USAGE": "filesystem",
566 "ID_FS_UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
567 "ID_FS_UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
568 "ID_FS_VERSION": "1.0",
569 "ID_MODEL": "QEMU_HARDDISK",
570 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
571 "ID_PART_ENTRY_DISK": "8:0",
572 "ID_PART_ENTRY_NUMBER": "2",
573 "ID_PART_ENTRY_OFFSET": "4096",
574 "ID_PART_ENTRY_SCHEME": "gpt",
575 "ID_PART_ENTRY_SIZE": "20965376",
576 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
577 "ID_PART_ENTRY_UUID": "760493ac-7945-44c5-a6bd-58fcd6632ea7",
578 "ID_PART_TABLE_TYPE": "gpt",
579 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
580 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:0:0",
581 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_0_0",
582 "ID_REVISION": "2.5+",
583 "ID_SCSI": "1",
584 "ID_SCSI_INQUIRY": "1",
585 "ID_SERIAL": "30000000000000064",
586 "ID_SERIAL_SHORT": "0000000000000064",
587 "ID_TYPE": "disk",
588 "ID_VENDOR": "QEMU",
589 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
590 "ID_WWN": "0x0000000000000064",
591 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
592 "MAJOR": "8",
593 "MINOR": "2",
594 "PARTN": "2",
595 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
596 "SCSI_IDENT_LUN_VENDOR": "serial-a",
597 "SCSI_IDENT_SERIAL": "serial-a",
598 "SCSI_MODEL": "QEMU_HARDDISK",
599 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
600 "SCSI_REVISION": "2.5+",
601 "SCSI_TPGS": "0",
602 "SCSI_TYPE": "disk",
603 "SCSI_VENDOR": "QEMU",
604 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
605 "SUBSYSTEM": "block",
606 "SYSTEMD_READY": "0",
607 "TAGS": ":systemd:",
608 "USEC_INITIALIZED": "1364238",
609 "attrs": {
610 "alignment_offset": "0",
611 "dev": "8:2",
612 "discard_alignment": "0",
613 "inflight": " 0 0",
614 "partition": "2",
615 "ro": "0",
616 "size": "10734272512",
617 "start": "4096",
618 "stat": " 268 0 17138 61 0 0 0 0 0 156 4 0 0 0 0",
619 "subsystem": "block",
620 "uevent": "MAJOR=8\nMINOR=2\nDEVNAME=sda2\nDEVTYPE=partition\nPARTN=2"
621 }
622 },
623 "/dev/sdb": {
624 "DEVLINKS": "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a /dev/disk/by-id/scsi-30000000000000064 /dev/disk/by-id/wwn-0x0000000000000064 /dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:1:0 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a",
625 "DEVNAME": "/dev/sdb",
626 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:1/2:0:1:0/block/sdb",
627 "DEVTYPE": "disk",
628 "DM_DEL_PART_NODES": "1",
629 "DM_MULTIPATH_DEVICE_PATH": "1",
630 "ID_BUS": "scsi",
631 "ID_FS_TYPE": "mpath_member",
632 "ID_MODEL": "QEMU_HARDDISK",
633 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
634 "ID_PART_TABLE_TYPE": "gpt",
635 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
636 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:1:0",
637 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_1_0",
638 "ID_REVISION": "2.5+",
639 "ID_SCSI": "1",
640 "ID_SCSI_INQUIRY": "1",
641 "ID_SERIAL": "30000000000000064",
642 "ID_SERIAL_SHORT": "0000000000000064",
643 "ID_TYPE": "disk",
644 "ID_VENDOR": "QEMU",
645 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
646 "ID_WWN": "0x0000000000000064",
647 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
648 "MAJOR": "8",
649 "MINOR": "16",
650 "MPATH_SBIN_PATH": "/sbin",
651 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
652 "SCSI_IDENT_LUN_VENDOR": "serial-a",
653 "SCSI_IDENT_SERIAL": "serial-a",
654 "SCSI_MODEL": "QEMU_HARDDISK",
655 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
656 "SCSI_REVISION": "2.5+",
657 "SCSI_TPGS": "0",
658 "SCSI_TYPE": "disk",
659 "SCSI_VENDOR": "QEMU",
660 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
661 "SUBSYSTEM": "block",
662 "SYSTEMD_READY": "0",
663 "TAGS": ":systemd:",
664 "USEC_INITIALIZED": "1342677",
665 "attrs": {
666 "alignment_offset": "0",
667 "bdi": null,
668 "capability": "50",
669 "dev": "8:16",
670 "device": null,
671 "discard_alignment": "0",
672 "events": "",
673 "events_async": "",
674 "events_poll_msecs": "-1",
675 "ext_range": "256",
676 "hidden": "0",
677 "inflight": " 0 0",
678 "range": "16",
679 "removable": "0",
680 "ro": "0",
681 "size": "10737418240",
682 "stat": " 460 0 20312 70 0 0 0 0 0 280 12 0 0 0 0",
683 "subsystem": "block",
684 "uevent": "MAJOR=8\nMINOR=16\nDEVNAME=sdb\nDEVTYPE=disk"
685 },
686 "partitiontable": {
687 "label": "gpt",
688 "id": "8261CD75-2234-4DBD-920A-D21A7C083C94",
689 "device": "/dev/sdb",
690 "unit": "sectors",
691 "firstlba": 34,
692 "lastlba": 20971486,
693 "partitions": [
694 {
695 "node": "/dev/sdb1",
696 "start": 2048,
697 "size": 2048,
698 "type": "21686148-6449-6E6F-744E-656564454649",
699 "uuid": "8088175C-362A-4B46-9603-F3595065FA73"
700 },
701 {
702 "node": "/dev/sdb2",
703 "start": 4096,
704 "size": 20965376,
705 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
706 "uuid": "760493AC-7945-44C5-A6BD-58FCD6632EA7"
707 }
708 ]
709 }
710 },
711 "/dev/sdb1": {
712 "DEVLINKS": "/dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:1:0-part1 /dev/disk/by-id/scsi-30000000000000064-part1 /dev/disk/by-partuuid/8088175c-362a-4b46-9603-f3595065fa73 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a-part1 /dev/disk/by-id/wwn-0x0000000000000064-part1 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a-part1",
713 "DEVNAME": "/dev/sdb1",
714 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:1/2:0:1:0/block/sdb/sdb1",
715 "DEVTYPE": "partition",
716 "DM_MULTIPATH_DEVICE_PATH": "1",
717 "ID_BUS": "scsi",
718 "ID_FS_TYPE": "mpath_member",
719 "ID_MODEL": "QEMU_HARDDISK",
720 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
721 "ID_PART_ENTRY_DISK": "8:16",
722 "ID_PART_ENTRY_NUMBER": "1",
723 "ID_PART_ENTRY_OFFSET": "2048",
724 "ID_PART_ENTRY_SCHEME": "gpt",
725 "ID_PART_ENTRY_SIZE": "2048",
726 "ID_PART_ENTRY_TYPE": "21686148-6449-6e6f-744e-656564454649",
727 "ID_PART_ENTRY_UUID": "8088175c-362a-4b46-9603-f3595065fa73",
728 "ID_PART_TABLE_TYPE": "gpt",
729 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
730 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:1:0",
731 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_1_0",
732 "ID_REVISION": "2.5+",
733 "ID_SCSI": "1",
734 "ID_SCSI_INQUIRY": "1",
735 "ID_SERIAL": "30000000000000064",
736 "ID_SERIAL_SHORT": "0000000000000064",
737 "ID_TYPE": "disk",
738 "ID_VENDOR": "QEMU",
739 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
740 "ID_WWN": "0x0000000000000064",
741 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
742 "MAJOR": "8",
743 "MINOR": "17",
744 "PARTN": "1",
745 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
746 "SCSI_IDENT_LUN_VENDOR": "serial-a",
747 "SCSI_IDENT_SERIAL": "serial-a",
748 "SCSI_MODEL": "QEMU_HARDDISK",
749 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
750 "SCSI_REVISION": "2.5+",
751 "SCSI_TPGS": "0",
752 "SCSI_TYPE": "disk",
753 "SCSI_VENDOR": "QEMU",
754 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
755 "SUBSYSTEM": "block",
756 "SYSTEMD_READY": "0",
757 "TAGS": ":systemd:",
758 "USEC_INITIALIZED": "1383416",
759 "attrs": {
760 "alignment_offset": "0",
761 "dev": "8:17",
762 "discard_alignment": "0",
763 "inflight": " 0 0",
764 "partition": "1",
765 "ro": "0",
766 "size": "1048576",
767 "start": "2048",
768 "stat": " 86 0 712 7 0 0 0 0 0 72 0 0 0 0 0",
769 "subsystem": "block",
770 "uevent": "MAJOR=8\nMINOR=17\nDEVNAME=sdb1\nDEVTYPE=partition\nPARTN=1"
771 }
772 },
773 "/dev/sdb2": {
774 "DEVLINKS": "/dev/disk/by-id/wwn-0x0000000000000064-part2 /dev/disk/by-id/scsi-SQEMU_QEMU_HARDDISK_serial-a-part2 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_serial-a-part2 /dev/disk/by-partuuid/760493ac-7945-44c5-a6bd-58fcd6632ea7 /dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:1:0-part2 /dev/disk/by-uuid/80ca57a0-60b7-4328-be41-afedf915effd /dev/disk/by-id/scsi-30000000000000064-part2",
775 "DEVNAME": "/dev/sdb2",
776 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio0/host2/target2:0:1/2:0:1:0/block/sdb/sdb2",
777 "DEVTYPE": "partition",
778 "DM_MULTIPATH_DEVICE_PATH": "1",
779 "ID_BUS": "scsi",
780 "ID_FS_TYPE": "ext4",
781 "ID_FS_USAGE": "filesystem",
782 "ID_FS_UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
783 "ID_FS_UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
784 "ID_FS_VERSION": "1.0",
785 "ID_MODEL": "QEMU_HARDDISK",
786 "ID_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
787 "ID_PART_ENTRY_DISK": "8:16",
788 "ID_PART_ENTRY_NUMBER": "2",
789 "ID_PART_ENTRY_OFFSET": "4096",
790 "ID_PART_ENTRY_SCHEME": "gpt",
791 "ID_PART_ENTRY_SIZE": "20965376",
792 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
793 "ID_PART_ENTRY_UUID": "760493ac-7945-44c5-a6bd-58fcd6632ea7",
794 "ID_PART_TABLE_TYPE": "gpt",
795 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
796 "ID_PATH": "pci-0000:00:04.0-scsi-0:0:1:0",
797 "ID_PATH_TAG": "pci-0000_00_04_0-scsi-0_0_1_0",
798 "ID_REVISION": "2.5+",
799 "ID_SCSI": "1",
800 "ID_SCSI_INQUIRY": "1",
801 "ID_SERIAL": "30000000000000064",
802 "ID_SERIAL_SHORT": "0000000000000064",
803 "ID_TYPE": "disk",
804 "ID_VENDOR": "QEMU",
805 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
806 "ID_WWN": "0x0000000000000064",
807 "ID_WWN_WITH_EXTENSION": "0x0000000000000064",
808 "MAJOR": "8",
809 "MINOR": "18",
810 "PARTN": "2",
811 "SCSI_IDENT_LUN_NAA_LOCAL": "0000000000000064",
812 "SCSI_IDENT_LUN_VENDOR": "serial-a",
813 "SCSI_IDENT_SERIAL": "serial-a",
814 "SCSI_MODEL": "QEMU_HARDDISK",
815 "SCSI_MODEL_ENC": "QEMU\\x20HARDDISK\\x20\\x20\\x20",
816 "SCSI_REVISION": "2.5+",
817 "SCSI_TPGS": "0",
818 "SCSI_TYPE": "disk",
819 "SCSI_VENDOR": "QEMU",
820 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
821 "SUBSYSTEM": "block",
822 "SYSTEMD_READY": "0",
823 "TAGS": ":systemd:",
824 "USEC_INITIALIZED": "1355435",
825 "attrs": {
826 "alignment_offset": "0",
827 "dev": "8:18",
828 "discard_alignment": "0",
829 "inflight": " 0 0",
830 "partition": "2",
831 "ro": "0",
832 "size": "10734272512",
833 "start": "4096",
834 "stat": " 129 0 8728 20 0 0 0 0 0 96 4 0 0 0 0",
835 "subsystem": "block",
836 "uevent": "MAJOR=8\nMINOR=18\nDEVNAME=sdb2\nDEVTYPE=partition\nPARTN=2"
837 }
838 },
839 "/dev/fd0": {
840 "DEVNAME": "/dev/fd0",
841 "DEVPATH": "/devices/platform/floppy.0/block/fd0",
842 "DEVTYPE": "disk",
843 "MAJOR": "2",
844 "MINOR": "0",
845 "SUBSYSTEM": "block",
846 "TAGS": ":systemd:",
847 "USEC_INITIALIZED": "1182861",
848 "attrs": {
849 "alignment_offset": "0",
850 "bdi": null,
851 "capability": "11",
852 "dev": "2:0",
853 "device": null,
854 "discard_alignment": "0",
855 "events": "",
856 "events_async": "",
857 "events_poll_msecs": "-1",
858 "ext_range": "1",
859 "hidden": "0",
860 "inflight": " 0 0",
861 "range": "1",
862 "removable": "1",
863 "ro": "0",
864 "size": "4096",
865 "stat": " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
866 "subsystem": "block",
867 "uevent": "MAJOR=2\nMINOR=0\nDEVNAME=fd0\nDEVTYPE=disk"
868 }
869 },
870 "/dev/dm-0": {
871 "DEVLINKS": "/dev/disk/by-id/wwn-0x0000000000000064 /dev/disk/by-id/dm-name-mpatha /dev/disk/by-id/dm-uuid-mpath-30000000000000064 /dev/mapper/mpatha",
872 "DEVNAME": "/dev/dm-0",
873 "DEVPATH": "/devices/virtual/block/dm-0",
874 "DEVTYPE": "disk",
875 "DM_NAME": "mpatha",
876 "DM_STATE": "ACTIVE",
877 "DM_SUSPENDED": "0",
878 "DM_TABLE_STATE": "LIVE",
879 "DM_TYPE": "scsi",
880 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
881 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
882 "DM_UDEV_RULES": "1",
883 "DM_UDEV_RULES_VSN": "2",
884 "DM_UUID": "mpath-30000000000000064",
885 "DM_WWN": "0x0000000000000064",
886 "ID_PART_TABLE_TYPE": "gpt",
887 "ID_PART_TABLE_UUID": "8261cd75-2234-4dbd-920a-d21a7c083c94",
888 "MAJOR": "253",
889 "MINOR": "0",
890 "MPATH_DEVICE_READY": "1",
891 "MPATH_SBIN_PATH": "/sbin",
892 "SUBSYSTEM": "block",
893 "TAGS": ":systemd:",
894 "USEC_INITIALIZED": "9639027",
895 "attrs": {
896 "alignment_offset": "0",
897 "bdi": null,
898 "capability": "10",
899 "dev": "253:0",
900 "discard_alignment": "0",
901 "events": "",
902 "events_async": "",
903 "events_poll_msecs": "-1",
904 "ext_range": "1",
905 "hidden": "0",
906 "inflight": " 0 0",
907 "range": "1",
908 "removable": "0",
909 "ro": "0",
910 "size": "10737418240",
911 "stat": " 321 0 16720 46 0 0 0 0 0 172 0 0 0 0 0",
912 "subsystem": "block",
913 "uevent": "MAJOR=253\nMINOR=0\nDEVNAME=dm-0\nDEVTYPE=disk"
914 },
915 "partitiontable": {
916 "label": "gpt",
917 "id": "8261CD75-2234-4DBD-920A-D21A7C083C94",
918 "device": "/dev/dm-0",
919 "unit": "sectors",
920 "firstlba": 34,
921 "lastlba": 20971486,
922 "partitions": [
923 {
924 "node": "/dev/mapper/mpatha-part1",
925 "start": 2048,
926 "size": 2048,
927 "type": "21686148-6449-6E6F-744E-656564454649",
928 "uuid": "8088175C-362A-4B46-9603-F3595065FA73"
929 },
930 {
931 "node": "/dev/mapper/mpatha-part2",
932 "start": 4096,
933 "size": 20965376,
934 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
935 "uuid": "760493AC-7945-44C5-A6BD-58FCD6632EA7"
936 }
937 ]
938 }
939 },
940 "/dev/dm-1": {
941 "DEVLINKS": "/dev/disk/by-id/dm-name-mpatha-part1 /dev/mapper/mpatha-part1 /dev/disk/by-id/wwn-0x0000000000000064-part1 /dev/disk/by-partuuid/8088175c-362a-4b46-9603-f3595065fa73 /dev/disk/by-id/dm-uuid-part1-mpath-30000000000000064",
942 "DEVNAME": "/dev/dm-1",
943 "DEVPATH": "/devices/virtual/block/dm-1",
944 "DEVTYPE": "disk",
945 "DM_ACTIVATION": "1",
946 "DM_MPATH": "mpatha",
947 "DM_NAME": "mpatha-part1",
948 "DM_PART": "1",
949 "DM_STATE": "ACTIVE",
950 "DM_SUBSYSTEM_UDEV_FLAG0": "1",
951 "DM_SUSPENDED": "0",
952 "DM_TABLE_STATE": "LIVE",
953 "DM_TYPE": "scsi",
954 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
955 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
956 "DM_UDEV_RULES": "1",
957 "DM_UDEV_RULES_VSN": "2",
958 "DM_UUID": "part1-mpath-30000000000000064",
959 "DM_WWN": "0x0000000000000064",
960 "ID_PART_ENTRY_DISK": "253:0",
961 "ID_PART_ENTRY_NUMBER": "1",
962 "ID_PART_ENTRY_OFFSET": "2048",
963 "ID_PART_ENTRY_SCHEME": "gpt",
964 "ID_PART_ENTRY_SIZE": "2048",
965 "ID_PART_ENTRY_TYPE": "21686148-6449-6e6f-744e-656564454649",
966 "ID_PART_ENTRY_UUID": "8088175c-362a-4b46-9603-f3595065fa73",
967 "MAJOR": "253",
968 "MINOR": "1",
969 "SUBSYSTEM": "block",
970 "TAGS": ":systemd:",
971 "USEC_INITIALIZED": "10556653",
972 "attrs": {
973 "alignment_offset": "0",
974 "bdi": null,
975 "capability": "10",
976 "dev": "253:1",
977 "discard_alignment": "0",
978 "events": "",
979 "events_async": "",
980 "events_poll_msecs": "-1",
981 "ext_range": "1",
982 "hidden": "0",
983 "inflight": " 0 0",
984 "range": "1",
985 "removable": "0",
986 "ro": "0",
987 "size": "1048576",
988 "stat": " 78 0 624 8 0 0 0 0 0 56 8 0 0 0 0",
989 "subsystem": "block",
990 "uevent": "MAJOR=253\nMINOR=1\nDEVNAME=dm-1\nDEVTYPE=disk"
991 }
992 },
993 "/dev/dm-2": {
994 "DEVLINKS": "/dev/mapper/mpatha-part2 /dev/disk/by-id/dm-uuid-part2-mpath-30000000000000064 /dev/disk/by-id/dm-name-mpatha-part2 /dev/disk/by-partuuid/760493ac-7945-44c5-a6bd-58fcd6632ea7 /dev/disk/by-uuid/80ca57a0-60b7-4328-be41-afedf915effd /dev/disk/by-id/wwn-0x0000000000000064-part2",
995 "DEVNAME": "/dev/dm-2",
996 "DEVPATH": "/devices/virtual/block/dm-2",
997 "DEVTYPE": "disk",
998 "DM_ACTIVATION": "1",
999 "DM_MPATH": "mpatha",
1000 "DM_NAME": "mpatha-part2",
1001 "DM_PART": "2",
1002 "DM_STATE": "ACTIVE",
1003 "DM_SUBSYSTEM_UDEV_FLAG0": "1",
1004 "DM_SUSPENDED": "0",
1005 "DM_TABLE_STATE": "LIVE",
1006 "DM_TYPE": "scsi",
1007 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
1008 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
1009 "DM_UDEV_RULES": "1",
1010 "DM_UDEV_RULES_VSN": "2",
1011 "DM_UUID": "part2-mpath-30000000000000064",
1012 "DM_WWN": "0x0000000000000064",
1013 "ID_FS_TYPE": "ext4",
1014 "ID_FS_USAGE": "filesystem",
1015 "ID_FS_UUID": "80ca57a0-60b7-4328-be41-afedf915effd",
1016 "ID_FS_UUID_ENC": "80ca57a0-60b7-4328-be41-afedf915effd",
1017 "ID_FS_VERSION": "1.0",
1018 "ID_PART_ENTRY_DISK": "253:0",
1019 "ID_PART_ENTRY_NUMBER": "2",
1020 "ID_PART_ENTRY_OFFSET": "4096",
1021 "ID_PART_ENTRY_SCHEME": "gpt",
1022 "ID_PART_ENTRY_SIZE": "20965376",
1023 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
1024 "ID_PART_ENTRY_UUID": "760493ac-7945-44c5-a6bd-58fcd6632ea7",
1025 "MAJOR": "253",
1026 "MINOR": "2",
1027 "SUBSYSTEM": "block",
1028 "TAGS": ":systemd:",
1029 "USEC_INITIALIZED": "10583306",
1030 "attrs": {
1031 "alignment_offset": "0",
1032 "bdi": null,
1033 "capability": "10",
1034 "dev": "253:2",
1035 "discard_alignment": "0",
1036 "events": "",
1037 "events_async": "",
1038 "events_poll_msecs": "-1",
1039 "ext_range": "1",
1040 "hidden": "0",
1041 "inflight": " 0 0",
1042 "range": "1",
1043 "removable": "0",
1044 "ro": "0",
1045 "size": "10734272512",
1046 "stat": " 91 0 8032 4 0 0 0 0 0 52 4 0 0 0 0",
1047 "subsystem": "block",
1048 "uevent": "MAJOR=253\nMINOR=2\nDEVNAME=dm-2\nDEVTYPE=disk"
1049 }
1050 }
1051 },
1052 "bcache": {
1053 "backing": {},
1054 "caching": {}
1055 },
1056 "zfs": {
1057 "zpools": {}
1058 }
1059}
diff --git a/tests/data/probert_storage_raid1_partitions.json b/tests/data/probert_storage_raid1_partitions.json
0new file mode 1006441060new file mode 100644
index 0000000..709da5a
--- /dev/null
+++ b/tests/data/probert_storage_raid1_partitions.json
@@ -0,0 +1,951 @@
1{
2 "zfs": {
3 "zpools": {}
4 },
5 "dmcrypt": {},
6 "blockdev": {
7 "/dev/sr0": {
8 "DEVLINKS": "/dev/disk/by-label/Ubuntu-Server\\x2020.04\\x20LTS\\x20ppc64 /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_drive-scsi0-0-0-0 /dev/dvd /dev/cdrom /dev/disk/by-path/pci-0000:00:02.0-scsi-0:0:0:0 /dev/disk/by-uuid/2019-11-16-08-09-20-00",
9 "DEVNAME": "/dev/sr0",
10 "DEVPATH": "/devices/pci0000:00/0000:00:02.0/virtio1/host0/target0:0:0/0:0:0:0/block/sr0",
11 "DEVTYPE": "disk",
12 "ID_BUS": "scsi",
13 "ID_CDROM": "1",
14 "ID_CDROM_CD": "1",
15 "ID_CDROM_DVD": "1",
16 "ID_CDROM_MEDIA": "1",
17 "ID_CDROM_MEDIA_DVD": "1",
18 "ID_CDROM_MEDIA_SESSION_COUNT": "1",
19 "ID_CDROM_MEDIA_STATE": "complete",
20 "ID_CDROM_MEDIA_TRACK_COUNT": "1",
21 "ID_CDROM_MEDIA_TRACK_COUNT_DATA": "1",
22 "ID_CDROM_MRW": "1",
23 "ID_CDROM_MRW_W": "1",
24 "ID_FOR_SEAT": "block-pci-0000_00_02_0-scsi-0_0_0_0",
25 "ID_FS_APPLICATION_ID": "GENISOIMAGE\\x20ISO\\x209660\\x2fHFS\\x20FILESYSTEM\\x20CREATOR\\x20\\x28C\\x29\\x201993\\x20E.YOUNGDALE\\x20\\x28C\\x29\\x201997-2006\\x20J.PEARSON\\x2fJ.SCHILLING\\x20\\x28C\\x29\\x202006-2007\\x20CDRKIT\\x20TEAM",
26 "ID_FS_LABEL": "Ubuntu-Server_20.04_LTS_ppc64",
27 "ID_FS_LABEL_ENC": "Ubuntu-Server\\x2020.04\\x20LTS\\x20ppc64",
28 "ID_FS_SYSTEM_ID": "LINUX",
29 "ID_FS_TYPE": "iso9660",
30 "ID_FS_USAGE": "filesystem",
31 "ID_FS_UUID": "2019-11-16-08-09-20-00",
32 "ID_FS_UUID_ENC": "2019-11-16-08-09-20-00",
33 "ID_MODEL": "QEMU_CD-ROM",
34 "ID_MODEL_ENC": "QEMU\\x20CD-ROM\\x20\\x20\\x20\\x20\\x20",
35 "ID_PART_TABLE_TYPE": "mac",
36 "ID_PATH": "pci-0000:00:02.0-scsi-0:0:0:0",
37 "ID_PATH_TAG": "pci-0000_00_02_0-scsi-0_0_0_0",
38 "ID_REVISION": "2.5+",
39 "ID_SCSI": "1",
40 "ID_SCSI_INQUIRY": "1",
41 "ID_SERIAL": "0QEMU_QEMU_CD-ROM_drive-scsi0-0-0-0",
42 "ID_SERIAL_SHORT": "drive-scsi0-0-0-0",
43 "ID_TYPE": "cd",
44 "ID_VENDOR": "QEMU",
45 "ID_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
46 "MAJOR": "11",
47 "MINOR": "0",
48 "SCSI_MODEL": "QEMU_CD-ROM",
49 "SCSI_MODEL_ENC": "QEMU\\x20CD-ROM\\x20\\x20\\x20\\x20\\x20",
50 "SCSI_REVISION": "2.5+",
51 "SCSI_TPGS": "0",
52 "SCSI_TYPE": "cd/dvd",
53 "SCSI_VENDOR": "QEMU",
54 "SCSI_VENDOR_ENC": "QEMU\\x20\\x20\\x20\\x20",
55 "SUBSYSTEM": "block",
56 "SYSTEMD_MOUNT_DEVICE_BOUND": "1",
57 "TAGS": ":uaccess:seat:systemd:",
58 "USEC_INITIALIZED": "626053",
59 "attrs": {
60 "alignment_offset": "0",
61 "bdi": null,
62 "capability": "119",
63 "dev": "11:0",
64 "device": null,
65 "discard_alignment": "0",
66 "events": "media_change eject_request",
67 "events_async": "",
68 "events_poll_msecs": "-1",
69 "ext_range": "1",
70 "hidden": "0",
71 "inflight": " 0 0",
72 "range": "1",
73 "removable": "1",
74 "ro": "0",
75 "size": "911030272",
76 "stat": " 6887 0 1582024 636 0 0 0 0 0 17552 64 0 0 0 0",
77 "subsystem": "block",
78 "uevent": "MAJOR=11\nMINOR=0\nDEVNAME=sr0\nDEVTYPE=disk"
79 },
80 "partitiontable": {
81 "label": "dos",
82 "id": "0x64040020",
83 "device": "/dev/sr0",
84 "unit": "sectors",
85 "partitions": [
86 {
87 "node": "/dev/sr0p1",
88 "start": 0,
89 "size": 1778756,
90 "type": "96",
91 "bootable": true
92 },
93 {
94 "node": "/dev/sr0p2",
95 "start": 2129919,
96 "size": 1936615684,
97 "type": "ff"
98 },
99 {
100 "node": "/dev/sr0p3",
101 "start": 1024,
102 "size": 0,
103 "type": "0"
104 },
105 {
106 "node": "/dev/sr0p4",
107 "start": 0,
108 "size": 0,
109 "type": "0"
110 }
111 ]
112 }
113 },
114 "/dev/vda": {
115 "DEVLINKS": "/dev/disk/by-path/pci-0000:00:04.0 /dev/disk/by-path/virtio-pci-0000:00:04.0",
116 "DEVNAME": "/dev/vda",
117 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio2/block/vda",
118 "DEVTYPE": "disk",
119 "ID_PART_TABLE_TYPE": "gpt",
120 "ID_PART_TABLE_UUID": "c43bafba-6f3f-4ac7-8c3a-3808451ad55e",
121 "ID_PATH": "pci-0000:00:04.0",
122 "ID_PATH_TAG": "pci-0000_00_04_0",
123 "MAJOR": "252",
124 "MINOR": "0",
125 "SUBSYSTEM": "block",
126 "TAGS": ":systemd:",
127 "USEC_INITIALIZED": "592200",
128 "attrs": {
129 "alignment_offset": "0",
130 "bdi": null,
131 "cache_type": "write back",
132 "capability": "50",
133 "dev": "252:0",
134 "device": null,
135 "discard_alignment": "0",
136 "events": "",
137 "events_async": "",
138 "events_poll_msecs": "-1",
139 "ext_range": "256",
140 "hidden": "0",
141 "inflight": " 0 0",
142 "range": "16",
143 "removable": "0",
144 "ro": "0",
145 "serial": "",
146 "size": "6442450944",
147 "stat": " 2923 0 473854 187 1654 3072 402696 427 0 3300 12 0 0 0 0",
148 "subsystem": "block",
149 "uevent": "MAJOR=252\nMINOR=0\nDEVNAME=vda\nDEVTYPE=disk"
150 },
151 "partitiontable": {
152 "label": "gpt",
153 "id": "C43BAFBA-6F3F-4AC7-8C3A-3808451AD55E",
154 "device": "/dev/vda",
155 "unit": "sectors",
156 "firstlba": 34,
157 "lastlba": 12582878,
158 "partitions": [
159 {
160 "node": "/dev/vda1",
161 "start": 2048,
162 "size": 16384,
163 "type": "9E1A2D38-C612-4316-AA26-8B49521E5A8B",
164 "uuid": "CFECC68C-325E-4066-8F6F-0FE4F57D1AF5"
165 },
166 {
167 "node": "/dev/vda2",
168 "start": 18432,
169 "size": 2097152,
170 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
171 "uuid": "D29ADB04-DF89-4D54-9B50-8DB8EEDAB339"
172 }
173 ]
174 }
175 },
176 "/dev/vda1": {
177 "DEVLINKS": "/dev/disk/by-path/pci-0000:00:04.0-part1 /dev/disk/by-partuuid/cfecc68c-325e-4066-8f6f-0fe4f57d1af5 /dev/disk/by-path/virtio-pci-0000:00:04.0-part1",
178 "DEVNAME": "/dev/vda1",
179 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio2/block/vda/vda1",
180 "DEVTYPE": "partition",
181 "ID_PART_ENTRY_DISK": "252:0",
182 "ID_PART_ENTRY_NUMBER": "1",
183 "ID_PART_ENTRY_OFFSET": "2048",
184 "ID_PART_ENTRY_SCHEME": "gpt",
185 "ID_PART_ENTRY_SIZE": "16384",
186 "ID_PART_ENTRY_TYPE": "9e1a2d38-c612-4316-aa26-8b49521e5a8b",
187 "ID_PART_ENTRY_UUID": "cfecc68c-325e-4066-8f6f-0fe4f57d1af5",
188 "ID_PART_TABLE_TYPE": "gpt",
189 "ID_PART_TABLE_UUID": "c43bafba-6f3f-4ac7-8c3a-3808451ad55e",
190 "ID_PATH": "pci-0000:00:04.0",
191 "ID_PATH_TAG": "pci-0000_00_04_0",
192 "ID_SCSI": "1",
193 "MAJOR": "252",
194 "MINOR": "1",
195 "PARTN": "1",
196 "SUBSYSTEM": "block",
197 "TAGS": ":systemd:",
198 "USEC_INITIALIZED": "62680508",
199 "attrs": {
200 "alignment_offset": "0",
201 "dev": "252:1",
202 "discard_alignment": "0",
203 "inflight": " 0 0",
204 "partition": "1",
205 "ro": "0",
206 "size": "8388608",
207 "start": "2048",
208 "stat": " 449 0 74496 31 6 3 1152 0 0 620 0 0 0 0 0",
209 "subsystem": "block",
210 "uevent": "MAJOR=252\nMINOR=1\nDEVNAME=vda1\nDEVTYPE=partition\nPARTN=1"
211 }
212 },
213 "/dev/vda2": {
214 "DEVLINKS": "/dev/disk/by-partuuid/d29adb04-df89-4d54-9b50-8db8eedab339 /dev/disk/by-uuid/0a3b5403-d358-4f30-9094-e5a19d60b222 /dev/disk/by-path/pci-0000:00:04.0-part2 /dev/disk/by-path/virtio-pci-0000:00:04.0-part2",
215 "DEVNAME": "/dev/vda2",
216 "DEVPATH": "/devices/pci0000:00/0000:00:04.0/virtio2/block/vda/vda2",
217 "DEVTYPE": "partition",
218 "ID_FS_TYPE": "ext4",
219 "ID_FS_USAGE": "filesystem",
220 "ID_FS_UUID": "0a3b5403-d358-4f30-9094-e5a19d60b222",
221 "ID_FS_UUID_ENC": "0a3b5403-d358-4f30-9094-e5a19d60b222",
222 "ID_FS_VERSION": "1.0",
223 "ID_PART_ENTRY_DISK": "252:0",
224 "ID_PART_ENTRY_NUMBER": "2",
225 "ID_PART_ENTRY_OFFSET": "18432",
226 "ID_PART_ENTRY_SCHEME": "gpt",
227 "ID_PART_ENTRY_SIZE": "2097152",
228 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
229 "ID_PART_ENTRY_UUID": "d29adb04-df89-4d54-9b50-8db8eedab339",
230 "ID_PART_TABLE_TYPE": "gpt",
231 "ID_PART_TABLE_UUID": "c43bafba-6f3f-4ac7-8c3a-3808451ad55e",
232 "ID_PATH": "pci-0000:00:04.0",
233 "ID_PATH_TAG": "pci-0000_00_04_0",
234 "ID_SCSI": "1",
235 "MAJOR": "252",
236 "MINOR": "2",
237 "PARTN": "2",
238 "SUBSYSTEM": "block",
239 "TAGS": ":systemd:",
240 "USEC_INITIALIZED": "62650105",
241 "attrs": {
242 "alignment_offset": "0",
243 "dev": "252:2",
244 "discard_alignment": "0",
245 "inflight": " 0 0",
246 "partition": "2",
247 "ro": "0",
248 "size": "1073741824",
249 "start": "18432",
250 "stat": " 322 0 50394 22 1522 2894 310648 343 0 756 12 0 0 0 0",
251 "subsystem": "block",
252 "uevent": "MAJOR=252\nMINOR=2\nDEVNAME=vda2\nDEVTYPE=partition\nPARTN=2"
253 }
254 },
255 "/dev/vdb": {
256 "DEVLINKS": "/dev/disk/by-path/virtio-pci-0000:00:05.0 /dev/disk/by-path/pci-0000:00:05.0",
257 "DEVNAME": "/dev/vdb",
258 "DEVPATH": "/devices/pci0000:00/0000:00:05.0/virtio3/block/vdb",
259 "DEVTYPE": "disk",
260 "ID_PART_TABLE_TYPE": "gpt",
261 "ID_PART_TABLE_UUID": "0c49cc0b-d527-4a88-a61a-4684bcdf8a5e",
262 "ID_PATH": "pci-0000:00:05.0",
263 "ID_PATH_TAG": "pci-0000_00_05_0",
264 "MAJOR": "252",
265 "MINOR": "16",
266 "SUBSYSTEM": "block",
267 "TAGS": ":systemd:",
268 "USEC_INITIALIZED": "600195",
269 "attrs": {
270 "alignment_offset": "0",
271 "bdi": null,
272 "cache_type": "write back",
273 "capability": "50",
274 "dev": "252:16",
275 "device": null,
276 "discard_alignment": "0",
277 "events": "",
278 "events_async": "",
279 "events_poll_msecs": "-1",
280 "ext_range": "256",
281 "hidden": "0",
282 "inflight": " 0 0",
283 "range": "16",
284 "removable": "0",
285 "ro": "0",
286 "serial": "",
287 "size": "6442450944",
288 "stat": " 20457 64216 10072248 3184 39416 65487 5219881 24281 0 27324 8488 0 0 0 0",
289 "subsystem": "block",
290 "uevent": "MAJOR=252\nMINOR=16\nDEVNAME=vdb\nDEVTYPE=disk"
291 },
292 "partitiontable": {
293 "label": "gpt",
294 "id": "0C49CC0B-D527-4A88-A61A-4684BCDF8A5E",
295 "device": "/dev/vdb",
296 "unit": "sectors",
297 "firstlba": 34,
298 "lastlba": 12582878,
299 "partitions": [
300 {
301 "node": "/dev/vdb1",
302 "start": 2048,
303 "size": 8388608,
304 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
305 "uuid": "408078B3-15C1-4315-A376-C2F1E3F13A63"
306 }
307 ]
308 }
309 },
310 "/dev/vdb1": {
311 "DEVLINKS": "/dev/disk/by-partuuid/408078b3-15c1-4315-a376-c2f1e3f13a63 /dev/disk/by-path/virtio-pci-0000:00:05.0-part1 /dev/disk/by-path/pci-0000:00:05.0-part1",
312 "DEVNAME": "/dev/vdb1",
313 "DEVPATH": "/devices/pci0000:00/0000:00:05.0/virtio3/block/vdb/vdb1",
314 "DEVTYPE": "partition",
315 "ID_FS_LABEL": "ubuntu-server:1",
316 "ID_FS_LABEL_ENC": "ubuntu-server:1",
317 "ID_FS_TYPE": "linux_raid_member",
318 "ID_FS_USAGE": "raid",
319 "ID_FS_UUID": "1e4e3ac4-abd1-ee76-6fdb-871a4d6677af",
320 "ID_FS_UUID_ENC": "1e4e3ac4-abd1-ee76-6fdb-871a4d6677af",
321 "ID_FS_UUID_SUB": "f1366f7f-319f-81e6-7550-edb94d240727",
322 "ID_FS_UUID_SUB_ENC": "f1366f7f-319f-81e6-7550-edb94d240727",
323 "ID_FS_VERSION": "1.2",
324 "ID_PART_ENTRY_DISK": "252:16",
325 "ID_PART_ENTRY_NUMBER": "1",
326 "ID_PART_ENTRY_OFFSET": "2048",
327 "ID_PART_ENTRY_SCHEME": "gpt",
328 "ID_PART_ENTRY_SIZE": "8388608",
329 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
330 "ID_PART_ENTRY_UUID": "408078b3-15c1-4315-a376-c2f1e3f13a63",
331 "ID_PART_TABLE_TYPE": "gpt",
332 "ID_PART_TABLE_UUID": "0c49cc0b-d527-4a88-a61a-4684bcdf8a5e",
333 "ID_PATH": "pci-0000:00:05.0",
334 "ID_PATH_TAG": "pci-0000_00_05_0",
335 "ID_SCSI": "1",
336 "MAJOR": "252",
337 "MINOR": "17",
338 "PARTN": "1",
339 "SUBSYSTEM": "block",
340 "TAGS": ":systemd:",
341 "USEC_INITIALIZED": "52064605",
342 "attrs": {
343 "alignment_offset": "0",
344 "dev": "252:17",
345 "discard_alignment": "0",
346 "inflight": " 0 0",
347 "partition": "1",
348 "ro": "0",
349 "size": "4294967296",
350 "start": "2048",
351 "stat": " 19443 64216 9896724 3125 39280 65397 5207337 24270 0 26204 8488 0 0 0 0",
352 "subsystem": "block",
353 "uevent": "MAJOR=252\nMINOR=17\nDEVNAME=vdb1\nDEVTYPE=partition\nPARTN=1"
354 }
355 },
356 "/dev/vdc": {
357 "DEVLINKS": "/dev/disk/by-path/pci-0000:00:06.0 /dev/disk/by-path/virtio-pci-0000:00:06.0",
358 "DEVNAME": "/dev/vdc",
359 "DEVPATH": "/devices/pci0000:00/0000:00:06.0/virtio4/block/vdc",
360 "DEVTYPE": "disk",
361 "ID_PART_TABLE_TYPE": "gpt",
362 "ID_PART_TABLE_UUID": "c805b10b-ded9-4519-947c-bcad1d6e81ed",
363 "ID_PATH": "pci-0000:00:06.0",
364 "ID_PATH_TAG": "pci-0000_00_06_0",
365 "MAJOR": "252",
366 "MINOR": "32",
367 "SUBSYSTEM": "block",
368 "TAGS": ":systemd:",
369 "USEC_INITIALIZED": "600459",
370 "attrs": {
371 "alignment_offset": "0",
372 "bdi": null,
373 "cache_type": "write back",
374 "capability": "50",
375 "dev": "252:32",
376 "device": null,
377 "discard_alignment": "0",
378 "events": "",
379 "events_async": "",
380 "events_poll_msecs": "-1",
381 "ext_range": "256",
382 "hidden": "0",
383 "inflight": " 0 0",
384 "range": "16",
385 "removable": "0",
386 "ro": "0",
387 "serial": "",
388 "size": "6442450944",
389 "stat": " 2791 749 264502 172 43737 126620 13598249 40301 0 19796 23016 0 0 0 0",
390 "subsystem": "block",
391 "uevent": "MAJOR=252\nMINOR=32\nDEVNAME=vdc\nDEVTYPE=disk"
392 },
393 "partitiontable": {
394 "label": "gpt",
395 "id": "C805B10B-DED9-4519-947C-BCAD1D6E81ED",
396 "device": "/dev/vdc",
397 "unit": "sectors",
398 "firstlba": 34,
399 "lastlba": 12582878,
400 "partitions": [
401 {
402 "node": "/dev/vdc1",
403 "start": 2048,
404 "size": 8388608,
405 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
406 "uuid": "69441F30-8321-4A70-A4CF-6A4B92393CD6"
407 }
408 ]
409 }
410 },
411 "/dev/vdc1": {
412 "DEVLINKS": "/dev/disk/by-partuuid/69441f30-8321-4a70-a4cf-6a4b92393cd6 /dev/disk/by-path/pci-0000:00:06.0-part1 /dev/disk/by-path/virtio-pci-0000:00:06.0-part1",
413 "DEVNAME": "/dev/vdc1",
414 "DEVPATH": "/devices/pci0000:00/0000:00:06.0/virtio4/block/vdc/vdc1",
415 "DEVTYPE": "partition",
416 "ID_FS_LABEL": "ubuntu-server:1",
417 "ID_FS_LABEL_ENC": "ubuntu-server:1",
418 "ID_FS_TYPE": "linux_raid_member",
419 "ID_FS_USAGE": "raid",
420 "ID_FS_UUID": "1e4e3ac4-abd1-ee76-6fdb-871a4d6677af",
421 "ID_FS_UUID_ENC": "1e4e3ac4-abd1-ee76-6fdb-871a4d6677af",
422 "ID_FS_UUID_SUB": "52929a1d-d9f0-e3a9-c16e-c40433201114",
423 "ID_FS_UUID_SUB_ENC": "52929a1d-d9f0-e3a9-c16e-c40433201114",
424 "ID_FS_VERSION": "1.2",
425 "ID_PART_ENTRY_DISK": "252:32",
426 "ID_PART_ENTRY_NUMBER": "1",
427 "ID_PART_ENTRY_OFFSET": "2048",
428 "ID_PART_ENTRY_SCHEME": "gpt",
429 "ID_PART_ENTRY_SIZE": "8388608",
430 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
431 "ID_PART_ENTRY_UUID": "69441f30-8321-4a70-a4cf-6a4b92393cd6",
432 "ID_PART_TABLE_TYPE": "gpt",
433 "ID_PART_TABLE_UUID": "c805b10b-ded9-4519-947c-bcad1d6e81ed",
434 "ID_PATH": "pci-0000:00:06.0",
435 "ID_PATH_TAG": "pci-0000_00_06_0",
436 "ID_SCSI": "1",
437 "MAJOR": "252",
438 "MINOR": "33",
439 "PARTN": "1",
440 "SUBSYSTEM": "block",
441 "TAGS": ":systemd:",
442 "USEC_INITIALIZED": "52548543",
443 "attrs": {
444 "alignment_offset": "0",
445 "dev": "252:33",
446 "discard_alignment": "0",
447 "inflight": " 0 0",
448 "partition": "1",
449 "ro": "0",
450 "size": "4294967296",
451 "start": "2048",
452 "stat": " 1756 749 86802 112 43601 126530 13585705 40291 0 18404 23016 0 0 0 0",
453 "subsystem": "block",
454 "uevent": "MAJOR=252\nMINOR=33\nDEVNAME=vdc1\nDEVTYPE=partition\nPARTN=1"
455 }
456 },
457 "/dev/vdd": {
458 "DEVLINKS": "/dev/disk/by-path/virtio-pci-0000:00:07.0 /dev/disk/by-uuid/00c629d6-06ab-4dfd-b21e-c3186f34105d /dev/disk/by-path/pci-0000:00:07.0",
459 "DEVNAME": "/dev/vdd",
460 "DEVPATH": "/devices/pci0000:00/0000:00:07.0/virtio5/block/vdd",
461 "DEVTYPE": "disk",
462 "ID_FS_TYPE": "ext2",
463 "ID_FS_USAGE": "filesystem",
464 "ID_FS_UUID": "00c629d6-06ab-4dfd-b21e-c3186f34105d",
465 "ID_FS_UUID_ENC": "00c629d6-06ab-4dfd-b21e-c3186f34105d",
466 "ID_FS_VERSION": "1.0",
467 "ID_PATH": "pci-0000:00:07.0",
468 "ID_PATH_TAG": "pci-0000_00_07_0",
469 "MAJOR": "252",
470 "MINOR": "48",
471 "SUBSYSTEM": "block",
472 "TAGS": ":systemd:",
473 "USEC_INITIALIZED": "563993",
474 "attrs": {
475 "alignment_offset": "0",
476 "bdi": null,
477 "cache_type": "write back",
478 "capability": "50",
479 "dev": "252:48",
480 "device": null,
481 "discard_alignment": "0",
482 "events": "",
483 "events_async": "",
484 "events_poll_msecs": "-1",
485 "ext_range": "256",
486 "hidden": "0",
487 "inflight": " 0 0",
488 "range": "16",
489 "removable": "0",
490 "ro": "1",
491 "serial": "",
492 "size": "1048576",
493 "stat": " 97 0 3367 4 2 0 0 0 0 76 0 0 0 0 0",
494 "subsystem": "block",
495 "uevent": "MAJOR=252\nMINOR=48\nDEVNAME=vdd\nDEVTYPE=disk"
496 }
497 },
498 "/dev/md1": {
499 "DEVLINKS": "/dev/disk/by-id/md-name-ubuntu-server:1 /dev/disk/by-id/md-uuid-1e4e3ac4:abd1ee76:6fdb871a:4d6677af",
500 "DEVNAME": "/dev/md1",
501 "DEVPATH": "/devices/virtual/block/md1",
502 "DEVTYPE": "disk",
503 "ID_PART_TABLE_TYPE": "gpt",
504 "ID_PART_TABLE_UUID": "18f354ee-3557-4a37-9508-c947edb21b5c",
505 "MAJOR": "9",
506 "MD_DEVICES": "2",
507 "MD_DEVICE_ev_vdb1_DEV": "/dev/vdb1",
508 "MD_DEVICE_ev_vdb1_ROLE": "0",
509 "MD_DEVICE_ev_vdc1_DEV": "/dev/vdc1",
510 "MD_DEVICE_ev_vdc1_ROLE": "1",
511 "MD_LEVEL": "raid1",
512 "MD_METADATA": "1.2",
513 "MD_NAME": "ubuntu-server:1",
514 "MD_UUID": "1e4e3ac4:abd1ee76:6fdb871a:4d6677af",
515 "MINOR": "1",
516 "SUBSYSTEM": "block",
517 "SYSTEMD_WANTS": "mdmonitor.service",
518 "TAGS": ":systemd:",
519 "USEC_INITIALIZED": "52972570",
520 "attrs": {
521 "alignment_offset": "0",
522 "bdi": null,
523 "capability": "50",
524 "dev": "9:1",
525 "discard_alignment": "0",
526 "events": "",
527 "events_async": "",
528 "events_poll_msecs": "-1",
529 "ext_range": "256",
530 "hidden": "0",
531 "inflight": " 0 0",
532 "range": "1",
533 "removable": "0",
534 "ro": "0",
535 "size": "4289724416",
536 "stat": " 20095 0 1539578 0 105192 0 5220984 0 0 0 0 0 0 0 0",
537 "subsystem": "block",
538 "uevent": "MAJOR=9\nMINOR=1\nDEVNAME=md1\nDEVTYPE=disk"
539 },
540 "partitiontable": {
541 "label": "gpt",
542 "id": "18F354EE-3557-4A37-9508-C947EDB21B5C",
543 "device": "/dev/md1",
544 "unit": "sectors",
545 "firstlba": 34,
546 "lastlba": 8378334,
547 "partitions": [
548 {
549 "node": "/dev/md1p1",
550 "start": 2048,
551 "size": 8370176,
552 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
553 "uuid": "5B3F90C0-2432-45C1-98E2-6E9E6649430E"
554 }
555 ]
556 }
557 },
558 "/dev/md1p1": {
559 "DEVLINKS": "/dev/disk/by-uuid/b312e605-d330-43ad-aa9b-2d503412977d /dev/disk/by-id/md-uuid-1e4e3ac4:abd1ee76:6fdb871a:4d6677af-part1 /dev/disk/by-id/md-name-ubuntu-server:1-part1",
560 "DEVNAME": "/dev/md1p1",
561 "DEVPATH": "/devices/virtual/block/md1/md1p1",
562 "DEVTYPE": "partition",
563 "ID_FS_TYPE": "ext4",
564 "ID_FS_USAGE": "filesystem",
565 "ID_FS_UUID": "b312e605-d330-43ad-aa9b-2d503412977d",
566 "ID_FS_UUID_ENC": "b312e605-d330-43ad-aa9b-2d503412977d",
567 "ID_FS_VERSION": "1.0",
568 "ID_PART_ENTRY_DISK": "9:1",
569 "ID_PART_ENTRY_NUMBER": "1",
570 "ID_PART_ENTRY_OFFSET": "2048",
571 "ID_PART_ENTRY_SCHEME": "gpt",
572 "ID_PART_ENTRY_SIZE": "8370176",
573 "ID_PART_ENTRY_TYPE": "0fc63daf-8483-4772-8e79-3d69d8477de4",
574 "ID_PART_ENTRY_UUID": "5b3f90c0-2432-45c1-98e2-6e9e6649430e",
575 "ID_SCSI": "1",
576 "MAJOR": "259",
577 "MD_DEVICES": "2",
578 "MD_DEVICE_ev_vdb1_DEV": "/dev/vdb1",
579 "MD_DEVICE_ev_vdb1_ROLE": "0",
580 "MD_DEVICE_ev_vdc1_DEV": "/dev/vdc1",
581 "MD_DEVICE_ev_vdc1_ROLE": "1",
582 "MD_LEVEL": "raid1",
583 "MD_METADATA": "1.2",
584 "MD_NAME": "ubuntu-server:1",
585 "MD_UUID": "1e4e3ac4:abd1ee76:6fdb871a:4d6677af",
586 "MINOR": "1",
587 "PARTN": "1",
588 "SUBSYSTEM": "block",
589 "SYSTEMD_WANTS": "mdmonitor.service",
590 "TAGS": ":systemd:",
591 "USEC_INITIALIZED": "62053949",
592 "attrs": {
593 "alignment_offset": "0",
594 "dev": "259:1",
595 "discard_alignment": "0",
596 "inflight": " 0 0",
597 "partition": "1",
598 "ro": "0",
599 "size": "4285530112",
600 "start": "2048",
601 "stat": " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
602 "subsystem": "block",
603 "uevent": "MAJOR=259\nMINOR=1\nDEVNAME=md1p1\nDEVTYPE=partition\nPARTN=1"
604 }
605 }
606 },
607 "bcache": {
608 "backing": {},
609 "caching": {}
610 },
611 "lvm": {},
612 "mount": [
613 {
614 "target": "/",
615 "source": "/cow",
616 "fstype": "overlay",
617 "options": "rw,relatime,lowerdir=/installer.squashfs:/filesystem.squashfs,upperdir=/cow/upper,workdir=/cow/work",
618 "children": [
619 {
620 "target": "/sys",
621 "source": "sysfs",
622 "fstype": "sysfs",
623 "options": "rw,nosuid,nodev,noexec,relatime",
624 "children": [
625 {
626 "target": "/sys/kernel/security",
627 "source": "securityfs",
628 "fstype": "securityfs",
629 "options": "rw,nosuid,nodev,noexec,relatime"
630 },
631 {
632 "target": "/sys/fs/cgroup",
633 "source": "tmpfs",
634 "fstype": "tmpfs",
635 "options": "ro,nosuid,nodev,noexec,mode=755",
636 "children": [
637 {
638 "target": "/sys/fs/cgroup/unified",
639 "source": "cgroup2",
640 "fstype": "cgroup2",
641 "options": "rw,nosuid,nodev,noexec,relatime,nsdelegate"
642 },
643 {
644 "target": "/sys/fs/cgroup/systemd",
645 "source": "cgroup",
646 "fstype": "cgroup",
647 "options": "rw,nosuid,nodev,noexec,relatime,xattr,name=systemd"
648 },
649 {
650 "target": "/sys/fs/cgroup/freezer",
651 "source": "cgroup",
652 "fstype": "cgroup",
653 "options": "rw,nosuid,nodev,noexec,relatime,freezer"
654 },
655 {
656 "target": "/sys/fs/cgroup/pids",
657 "source": "cgroup",
658 "fstype": "cgroup",
659 "options": "rw,nosuid,nodev,noexec,relatime,pids"
660 },
661 {
662 "target": "/sys/fs/cgroup/cpuset",
663 "source": "cgroup",
664 "fstype": "cgroup",
665 "options": "rw,nosuid,nodev,noexec,relatime,cpuset"
666 },
667 {
668 "target": "/sys/fs/cgroup/cpu,cpuacct",
669 "source": "cgroup",
670 "fstype": "cgroup",
671 "options": "rw,nosuid,nodev,noexec,relatime,cpu,cpuacct"
672 },
673 {
674 "target": "/sys/fs/cgroup/blkio",
675 "source": "cgroup",
676 "fstype": "cgroup",
677 "options": "rw,nosuid,nodev,noexec,relatime,blkio"
678 },
679 {
680 "target": "/sys/fs/cgroup/net_cls,net_prio",
681 "source": "cgroup",
682 "fstype": "cgroup",
683 "options": "rw,nosuid,nodev,noexec,relatime,net_cls,net_prio"
684 },
685 {
686 "target": "/sys/fs/cgroup/rdma",
687 "source": "cgroup",
688 "fstype": "cgroup",
689 "options": "rw,nosuid,nodev,noexec,relatime,rdma"
690 },
691 {
692 "target": "/sys/fs/cgroup/devices",
693 "source": "cgroup",
694 "fstype": "cgroup",
695 "options": "rw,nosuid,nodev,noexec,relatime,devices"
696 },
697 {
698 "target": "/sys/fs/cgroup/memory",
699 "source": "cgroup",
700 "fstype": "cgroup",
701 "options": "rw,nosuid,nodev,noexec,relatime,memory"
702 },
703 {
704 "target": "/sys/fs/cgroup/perf_event",
705 "source": "cgroup",
706 "fstype": "cgroup",
707 "options": "rw,nosuid,nodev,noexec,relatime,perf_event"
708 },
709 {
710 "target": "/sys/fs/cgroup/hugetlb",
711 "source": "cgroup",
712 "fstype": "cgroup",
713 "options": "rw,nosuid,nodev,noexec,relatime,hugetlb"
714 }
715 ]
716 },
717 {
718 "target": "/sys/fs/pstore",
719 "source": "pstore",
720 "fstype": "pstore",
721 "options": "rw,nosuid,nodev,noexec,relatime"
722 },
723 {
724 "target": "/sys/fs/bpf",
725 "source": "bpf",
726 "fstype": "bpf",
727 "options": "rw,nosuid,nodev,noexec,relatime,mode=700"
728 },
729 {
730 "target": "/sys/kernel/debug",
731 "source": "debugfs",
732 "fstype": "debugfs",
733 "options": "rw,nosuid,nodev,noexec,relatime"
734 },
735 {
736 "target": "/sys/fs/fuse/connections",
737 "source": "fusectl",
738 "fstype": "fusectl",
739 "options": "rw,nosuid,nodev,noexec,relatime"
740 },
741 {
742 "target": "/sys/kernel/config",
743 "source": "configfs",
744 "fstype": "configfs",
745 "options": "rw,nosuid,nodev,noexec,relatime"
746 }
747 ]
748 },
749 {
750 "target": "/proc",
751 "source": "proc",
752 "fstype": "proc",
753 "options": "rw,nosuid,nodev,noexec,relatime",
754 "children": [
755 {
756 "target": "/proc/sys/fs/binfmt_misc",
757 "source": "systemd-1",
758 "fstype": "autofs",
759 "options": "rw,relatime,fd=27,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13520"
760 }
761 ]
762 },
763 {
764 "target": "/dev",
765 "source": "udev",
766 "fstype": "devtmpfs",
767 "options": "rw,nosuid,relatime,size=956672k,nr_inodes=14948,mode=755",
768 "children": [
769 {
770 "target": "/dev/pts",
771 "source": "devpts",
772 "fstype": "devpts",
773 "options": "rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000"
774 },
775 {
776 "target": "/dev/shm",
777 "source": "tmpfs",
778 "fstype": "tmpfs",
779 "options": "rw,nosuid,nodev"
780 },
781 {
782 "target": "/dev/mqueue",
783 "source": "mqueue",
784 "fstype": "mqueue",
785 "options": "rw,nosuid,nodev,noexec,relatime"
786 }
787 ]
788 },
789 {
790 "target": "/run",
791 "source": "tmpfs",
792 "fstype": "tmpfs",
793 "options": "rw,nosuid,noexec,relatime,size=206720k,mode=755",
794 "children": [
795 {
796 "target": "/run/lock",
797 "source": "tmpfs",
798 "fstype": "tmpfs",
799 "options": "rw,nosuid,nodev,noexec,relatime,size=5120k"
800 }
801 ]
802 },
803 {
804 "target": "/cdrom",
805 "source": "/dev/sr0",
806 "fstype": "iso9660",
807 "options": "ro,noatime,nojoliet,check=s,map=n,blocksize=2048"
808 },
809 {
810 "target": "/rofs",
811 "source": "/dev/loop0",
812 "fstype": "squashfs",
813 "options": "ro,noatime"
814 },
815 {
816 "target": "/usr/lib/modules",
817 "source": "/dev/loop2",
818 "fstype": "squashfs",
819 "options": "ro,relatime"
820 },
821 {
822 "target": "/media/filesystem",
823 "source": "/dev/loop0",
824 "fstype": "squashfs",
825 "options": "ro,relatime"
826 },
827 {
828 "target": "/tmp",
829 "source": "tmpfs",
830 "fstype": "tmpfs",
831 "options": "rw,nosuid,nodev,relatime"
832 },
833 {
834 "target": "/subiquity_config",
835 "source": "/dev/vdd",
836 "fstype": "ext4",
837 "options": "ro,relatime"
838 },
839 {
840 "target": "/snap/core/8041",
841 "source": "/dev/loop3",
842 "fstype": "squashfs",
843 "options": "ro,nodev,relatime"
844 },
845 {
846 "target": "/snap/subiquity/1335",
847 "source": "/dev/loop4",
848 "fstype": "squashfs",
849 "options": "ro,nodev,relatime"
850 },
851 {
852 "target": "/target",
853 "source": "/dev/md1p1",
854 "fstype": "ext4",
855 "options": "rw,relatime",
856 "children": [
857 {
858 "target": "/target/run",
859 "source": "tmpfs",
860 "fstype": "tmpfs",
861 "options": "rw,nosuid,noexec,relatime,size=206720k,mode=755"
862 },
863 {
864 "target": "/target/boot",
865 "source": "/dev/vda2",
866 "fstype": "ext4",
867 "options": "rw,relatime"
868 },
869 {
870 "target": "/target/etc/apt",
871 "source": "overlay",
872 "fstype": "overlay",
873 "options": "rw,relatime,lowerdir=/target/etc/apt,upperdir=/tmp/tmp.dFi4ai53r1/upper,workdir=/tmp/tmp.dFi4ai53r1/work"
874 },
875 {
876 "target": "/target/cdrom",
877 "source": "/dev/sr0",
878 "fstype": "iso9660",
879 "options": "ro,noatime,nojoliet,check=s,map=n,blocksize=2048"
880 }
881 ]
882 }
883 ]
884 }
885 ],
886 "filesystem": {
887 "/dev/sr0": {
888 "APPLICATION_ID": "GENISOIMAGE\\x20ISO\\x209660\\x2fHFS\\x20FILESYSTEM\\x20CREATOR\\x20\\x28C\\x29\\x201993\\x20E.YOUNGDALE\\x20\\x28C\\x29\\x201997-2006\\x20J.PEARSON\\x2fJ.SCHILLING\\x20\\x28C\\x29\\x202006-2007\\x20CDRKIT\\x20TEAM",
889 "LABEL": "Ubuntu-Server_20.04_LTS_ppc64",
890 "LABEL_ENC": "Ubuntu-Server\\x2020.04\\x20LTS\\x20ppc64",
891 "SYSTEM_ID": "LINUX",
892 "TYPE": "iso9660",
893 "USAGE": "filesystem",
894 "UUID": "2019-11-16-08-09-20-00",
895 "UUID_ENC": "2019-11-16-08-09-20-00"
896 },
897 "/dev/vda2": {
898 "TYPE": "ext4",
899 "USAGE": "filesystem",
900 "UUID": "0a3b5403-d358-4f30-9094-e5a19d60b222",
901 "UUID_ENC": "0a3b5403-d358-4f30-9094-e5a19d60b222",
902 "VERSION": "1.0"
903 },
904 "/dev/vdd": {
905 "TYPE": "ext2",
906 "USAGE": "filesystem",
907 "UUID": "00c629d6-06ab-4dfd-b21e-c3186f34105d",
908 "UUID_ENC": "00c629d6-06ab-4dfd-b21e-c3186f34105d",
909 "VERSION": "1.0"
910 },
911 "/dev/md1p1": {
912 "TYPE": "ext4",
913 "USAGE": "filesystem",
914 "UUID": "b312e605-d330-43ad-aa9b-2d503412977d",
915 "UUID_ENC": "b312e605-d330-43ad-aa9b-2d503412977d",
916 "VERSION": "1.0"
917 }
918 },
919 "raid": {
920 "/dev/md1": {
921 "DEVLINKS": "/dev/disk/by-id/md-name-ubuntu-server:1 /dev/disk/by-id/md-uuid-1e4e3ac4:abd1ee76:6fdb871a:4d6677af",
922 "DEVNAME": "/dev/md1",
923 "DEVPATH": "/devices/virtual/block/md1",
924 "DEVTYPE": "disk",
925 "ID_PART_TABLE_TYPE": "gpt",
926 "ID_PART_TABLE_UUID": "18f354ee-3557-4a37-9508-c947edb21b5c",
927 "MAJOR": "9",
928 "MD_DEVICES": "2",
929 "MD_DEVICE_ev_vdb1_DEV": "/dev/vdb1",
930 "MD_DEVICE_ev_vdb1_ROLE": "0",
931 "MD_DEVICE_ev_vdc1_DEV": "/dev/vdc1",
932 "MD_DEVICE_ev_vdc1_ROLE": "1",
933 "MD_LEVEL": "raid1",
934 "MD_METADATA": "1.2",
935 "MD_NAME": "ubuntu-server:1",
936 "MD_UUID": "1e4e3ac4:abd1ee76:6fdb871a:4d6677af",
937 "MINOR": "1",
938 "SUBSYSTEM": "block",
939 "SYSTEMD_WANTS": "mdmonitor.service",
940 "TAGS": ":systemd:",
941 "USEC_INITIALIZED": "52972570",
942 "raidlevel": "raid1",
943 "devices": [
944 "/dev/vdb1",
945 "/dev/vdc1"
946 ],
947 "spare_devices": []
948 }
949 },
950 "multipath": {}
951}
diff --git a/tests/data/probert_storage_zlp6.json b/tests/data/probert_storage_zlp6.json
0new file mode 100644952new file mode 100644
index 0000000..b56a02b
--- /dev/null
+++ b/tests/data/probert_storage_zlp6.json
@@ -0,0 +1,6980 @@
1{
2 "storage": {
3 "bcache": {
4 "backing": {},
5 "caching": {}
6 },
7 "blockdev": {
8 "/dev/dasda": {
9 "DEVLINKS": "/dev/disk/by-id/ccw-IBM.750000000DXP71.1500.20 /dev/disk/by-path/ccw-0.0.1520 /dev/disk/by-uuid/3f168f0c-d0c7-4d8b-b23d-92c7476b092b",
10 "DEVNAME": "/dev/dasda",
11 "DEVPATH": "/devices/css0/0.0.0180/0.0.1520/block/dasda",
12 "DEVTYPE": "disk",
13 "ID_BUS": "ccw",
14 "ID_FS_TYPE": "bcache",
15 "ID_FS_UUID": "3f168f0c-d0c7-4d8b-b23d-92c7476b092b",
16 "ID_FS_UUID_ENC": "3f168f0c-d0c7-4d8b-b23d-92c7476b092b",
17 "ID_PATH": "ccw-0.0.1520",
18 "ID_PATH_TAG": "ccw-0_0_1520",
19 "ID_TYPE": "disk",
20 "ID_UID": "IBM.750000000DXP71.1500.20",
21 "ID_XUID": "IBM.750000000DXP71.1500.20",
22 "MAJOR": "94",
23 "MINOR": "0",
24 "MPATH_SBIN_PATH": "/sbin",
25 "SUBSYSTEM": "block",
26 "TAGS": ":systemd:",
27 "USEC_INITIALIZED": "9522332",
28 "attrs": {
29 "alignment_offset": "0",
30 "bdi": null,
31 "capability": "10",
32 "dev": "94:0",
33 "device": null,
34 "discard_alignment": "0",
35 "ext_range": "4",
36 "hidden": "0",
37 "inflight": " 0 0",
38 "range": "4",
39 "removable": "0",
40 "ro": "0",
41 "size": "59082670080",
42 "stat": " 16869 0 1012184 2450 12685 171372 4061544 74710 0 56227200 56332580",
43 "subsystem": "block",
44 "uevent": "MAJOR=94\nMINOR=0\nDEVNAME=dasda\nDEVTYPE=disk"
45 }
46 },
47 "/dev/dasdb": {
48 "DEVLINKS": "/dev/disk/by-id/ccw-IBM.750000000DXP71.1500.1f /dev/disk/by-id/ccw-0X151F /dev/disk/by-path/ccw-0.0.151f",
49 "DEVNAME": "/dev/dasdb",
50 "DEVPATH": "/devices/css0/0.0.017f/0.0.151f/block/dasdb",
51 "DEVTYPE": "disk",
52 "ID_BUS": "ccw",
53 "ID_PATH": "ccw-0.0.151f",
54 "ID_PATH_TAG": "ccw-0_0_151f",
55 "ID_SERIAL": "0X151F",
56 "ID_TYPE": "disk",
57 "ID_UID": "IBM.750000000DXP71.1500.1f",
58 "ID_XUID": "IBM.750000000DXP71.1500.1f",
59 "MAJOR": "94",
60 "MINOR": "4",
61 "MPATH_SBIN_PATH": "/sbin",
62 "SUBSYSTEM": "block",
63 "TAGS": ":systemd:",
64 "USEC_INITIALIZED": "9552537",
65 "attrs": {
66 "alignment_offset": "0",
67 "bdi": null,
68 "capability": "10",
69 "dev": "94:4",
70 "device": null,
71 "discard_alignment": "0",
72 "ext_range": "4",
73 "hidden": "0",
74 "inflight": " 0 0",
75 "range": "4",
76 "removable": "0",
77 "ro": "0",
78 "size": "59082670080",
79 "stat": " 2590 0 61872 750 0 0 0 0 0 1514773090 1514775410",
80 "subsystem": "block",
81 "uevent": "MAJOR=94\nMINOR=4\nDEVNAME=dasdb\nDEVTYPE=disk"
82 }
83 },
84 "/dev/dasdb1": {
85 "DEVLINKS": "/dev/disk/by-uuid/45824f3e-2b61-48c6-912f-6142ce21827c /dev/disk/by-id/ccw-IBM.750000000DXP71.1500.1f-part1 /dev/disk/by-path/ccw-0.0.151f-part1 /dev/disk/by-id/ccw-0X151F-part1",
86 "DEVNAME": "/dev/dasdb1",
87 "DEVPATH": "/devices/css0/0.0.017f/0.0.151f/block/dasdb/dasdb1",
88 "DEVTYPE": "partition",
89 "ID_BUS": "ccw",
90 "ID_FS_TYPE": "ext4",
91 "ID_FS_USAGE": "filesystem",
92 "ID_FS_UUID": "45824f3e-2b61-48c6-912f-6142ce21827c",
93 "ID_FS_UUID_ENC": "45824f3e-2b61-48c6-912f-6142ce21827c",
94 "ID_FS_VERSION": "1.0",
95 "ID_PATH": "ccw-0.0.151f",
96 "ID_PATH_TAG": "ccw-0_0_151f",
97 "ID_SCSI": "1",
98 "ID_SERIAL": "0X151F",
99 "ID_TYPE": "disk",
100 "ID_UID": "IBM.750000000DXP71.1500.1f",
101 "ID_XUID": "IBM.750000000DXP71.1500.1f",
102 "MAJOR": "94",
103 "MINOR": "5",
104 "PARTN": "1",
105 "SUBSYSTEM": "block",
106 "TAGS": ":systemd:",
107 "USEC_INITIALIZED": "1279563953260",
108 "attrs": {
109 "alignment_offset": "0",
110 "dev": "94:5",
111 "discard_alignment": "0",
112 "inflight": " 0 0",
113 "partition": "1",
114 "ro": "0",
115 "size": "6144000000",
116 "start": "192",
117 "stat": " 128 0 5568 160 0 0 0 0 0 280 280",
118 "subsystem": "block",
119 "uevent": "MAJOR=94\nMINOR=5\nDEVNAME=dasdb1\nDEVTYPE=partition\nPARTN=1"
120 }
121 },
122 "/dev/dasdb2": {
123 "DEVLINKS": "/dev/disk/by-id/ccw-0X151F-part2 /dev/disk/by-id/ccw-IBM.750000000DXP71.1500.1f-part2 /dev/disk/by-uuid/07c44238-17da-4548-8f94-046e5c1251d3 /dev/disk/by-path/ccw-0.0.151f-part2",
124 "DEVNAME": "/dev/dasdb2",
125 "DEVPATH": "/devices/css0/0.0.017f/0.0.151f/block/dasdb/dasdb2",
126 "DEVTYPE": "partition",
127 "ID_BUS": "ccw",
128 "ID_FS_TYPE": "crypto_LUKS",
129 "ID_FS_USAGE": "crypto",
130 "ID_FS_UUID": "07c44238-17da-4548-8f94-046e5c1251d3",
131 "ID_FS_UUID_ENC": "07c44238-17da-4548-8f94-046e5c1251d3",
132 "ID_FS_VERSION": "2",
133 "ID_PATH": "ccw-0.0.151f",
134 "ID_PATH_TAG": "ccw-0_0_151f",
135 "ID_SCSI": "1",
136 "ID_SERIAL": "0X151F",
137 "ID_TYPE": "disk",
138 "ID_UID": "IBM.750000000DXP71.1500.1f",
139 "ID_XUID": "IBM.750000000DXP71.1500.1f",
140 "MAJOR": "94",
141 "MINOR": "6",
142 "PARTN": "2",
143 "SUBSYSTEM": "block",
144 "TAGS": ":systemd:",
145 "USEC_INITIALIZED": "1279563871011",
146 "attrs": {
147 "alignment_offset": "0",
148 "dev": "94:6",
149 "discard_alignment": "0",
150 "inflight": " 0 0",
151 "partition": "2",
152 "ro": "0",
153 "size": "52937490432",
154 "start": "1500192",
155 "stat": " 113 0 1832 200 0 0 0 0 0 230 320",
156 "subsystem": "block",
157 "uevent": "MAJOR=94\nMINOR=6\nDEVNAME=dasdb2\nDEVTYPE=partition\nPARTN=2"
158 }
159 },
160 "/dev/dasdc": {
161 "DEVLINKS": "/dev/disk/by-path/ccw-0.0.1522 /dev/disk/by-id/ccw-IBM.750000000DXP71.1500.22 /dev/disk/by-id/ccw-0X1522",
162 "DEVNAME": "/dev/dasdc",
163 "DEVPATH": "/devices/css0/0.0.0182/0.0.1522/block/dasdc",
164 "DEVTYPE": "disk",
165 "ID_BUS": "ccw",
166 "ID_PATH": "ccw-0.0.1522",
167 "ID_PATH_TAG": "ccw-0_0_1522",
168 "ID_SERIAL": "0X1522",
169 "ID_TYPE": "disk",
170 "ID_UID": "IBM.750000000DXP71.1500.22",
171 "ID_XUID": "IBM.750000000DXP71.1500.22",
172 "MAJOR": "94",
173 "MINOR": "8",
174 "MPATH_SBIN_PATH": "/sbin",
175 "SUBSYSTEM": "block",
176 "TAGS": ":systemd:",
177 "USEC_INITIALIZED": "9503072",
178 "attrs": {
179 "alignment_offset": "0",
180 "bdi": null,
181 "capability": "10",
182 "dev": "94:8",
183 "device": null,
184 "discard_alignment": "0",
185 "ext_range": "4",
186 "hidden": "0",
187 "inflight": " 0 0",
188 "range": "4",
189 "removable": "0",
190 "ro": "0",
191 "size": "59082670080",
192 "stat": " 46350 0 3209608 4010 55144 368331 13826720 190440 0 1083958950 1084285940",
193 "subsystem": "block",
194 "uevent": "MAJOR=94\nMINOR=8\nDEVNAME=dasdc\nDEVTYPE=disk"
195 }
196 },
197 "/dev/dasdc1": {
198 "DEVLINKS": "/dev/disk/by-id/ccw-IBM.750000000DXP71.1500.22-part1 /dev/disk/by-id/ccw-0X1522-part1 /dev/disk/by-path/ccw-0.0.1522-part1",
199 "DEVNAME": "/dev/dasdc1",
200 "DEVPATH": "/devices/css0/0.0.0182/0.0.1522/block/dasdc/dasdc1",
201 "DEVTYPE": "partition",
202 "ID_BUS": "ccw",
203 "ID_PATH": "ccw-0.0.1522",
204 "ID_PATH_TAG": "ccw-0_0_1522",
205 "ID_SCSI": "1",
206 "ID_SERIAL": "0X1522",
207 "ID_TYPE": "disk",
208 "ID_UID": "IBM.750000000DXP71.1500.22",
209 "ID_XUID": "IBM.750000000DXP71.1500.22",
210 "MAJOR": "94",
211 "MINOR": "9",
212 "PARTN": "1",
213 "SUBSYSTEM": "block",
214 "TAGS": ":systemd:",
215 "USEC_INITIALIZED": "1279589828313",
216 "attrs": {
217 "alignment_offset": "0",
218 "dev": "94:9",
219 "discard_alignment": "0",
220 "inflight": " 0 0",
221 "partition": "1",
222 "ro": "0",
223 "size": "17180786688",
224 "start": "192",
225 "stat": " 102 0 5328 140 0 0 0 0 0 210 210",
226 "subsystem": "block",
227 "uevent": "MAJOR=94\nMINOR=9\nDEVNAME=dasdc1\nDEVTYPE=partition\nPARTN=1"
228 }
229 },
230 "/dev/dasdc2": {
231 "DEVLINKS": "/dev/disk/by-id/ccw-IBM.750000000DXP71.1500.22-part2 /dev/disk/by-path/ccw-0.0.1522-part2 /dev/disk/by-id/ccw-0X1522-part2",
232 "DEVNAME": "/dev/dasdc2",
233 "DEVPATH": "/devices/css0/0.0.0182/0.0.1522/block/dasdc/dasdc2",
234 "DEVTYPE": "partition",
235 "ID_BUS": "ccw",
236 "ID_PATH": "ccw-0.0.1522",
237 "ID_PATH_TAG": "ccw-0_0_1522",
238 "ID_SCSI": "1",
239 "ID_SERIAL": "0X1522",
240 "ID_TYPE": "disk",
241 "ID_UID": "IBM.750000000DXP71.1500.22",
242 "ID_XUID": "IBM.750000000DXP71.1500.22",
243 "MAJOR": "94",
244 "MINOR": "10",
245 "PARTN": "2",
246 "SUBSYSTEM": "block",
247 "TAGS": ":systemd:",
248 "USEC_INITIALIZED": "1279589824184",
249 "attrs": {
250 "alignment_offset": "0",
251 "dev": "94:10",
252 "discard_alignment": "0",
253 "inflight": " 0 0",
254 "partition": "2",
255 "ro": "0",
256 "size": "17180786688",
257 "start": "4194720",
258 "stat": " 94 0 4528 120 0 0 0 0 0 200 210",
259 "subsystem": "block",
260 "uevent": "MAJOR=94\nMINOR=10\nDEVNAME=dasdc2\nDEVTYPE=partition\nPARTN=2"
261 }
262 },
263 "/dev/dasdc3": {
264 "DEVLINKS": "/dev/disk/by-path/ccw-0.0.1522-part3 /dev/disk/by-id/ccw-0X1522-part3 /dev/disk/by-id/ccw-IBM.750000000DXP71.1500.22-part3",
265 "DEVNAME": "/dev/dasdc3",
266 "DEVPATH": "/devices/css0/0.0.0182/0.0.1522/block/dasdc/dasdc3",
267 "DEVTYPE": "partition",
268 "ID_BUS": "ccw",
269 "ID_PATH": "ccw-0.0.1522",
270 "ID_PATH_TAG": "ccw-0_0_1522",
271 "ID_SCSI": "1",
272 "ID_SERIAL": "0X1522",
273 "ID_TYPE": "disk",
274 "ID_UID": "IBM.750000000DXP71.1500.22",
275 "ID_XUID": "IBM.750000000DXP71.1500.22",
276 "MAJOR": "94",
277 "MINOR": "11",
278 "PARTN": "3",
279 "SUBSYSTEM": "block",
280 "TAGS": ":systemd:",
281 "USEC_INITIALIZED": "1279589831397",
282 "attrs": {
283 "alignment_offset": "0",
284 "dev": "94:11",
285 "discard_alignment": "0",
286 "inflight": " 0 0",
287 "partition": "3",
288 "ro": "0",
289 "size": "17180786688",
290 "start": "8389248",
291 "stat": " 94 0 4528 90 0 0 0 0 0 140 150",
292 "subsystem": "block",
293 "uevent": "MAJOR=94\nMINOR=11\nDEVNAME=dasdc3\nDEVTYPE=partition\nPARTN=3"
294 }
295 },
296 "/dev/dasdd": {
297 "DEVLINKS": "/dev/disk/by-path/ccw-0.0.1544",
298 "DEVNAME": "/dev/dasdd",
299 "DEVPATH": "/devices/css0/0.0.01a4/0.0.1544/block/dasdd",
300 "DEVTYPE": "disk",
301 "ID_PATH": "ccw-0.0.1544",
302 "ID_PATH_TAG": "ccw-0_0_1544",
303 "MAJOR": "94",
304 "MINOR": "12",
305 "MPATH_SBIN_PATH": "/sbin",
306 "SUBSYSTEM": "block",
307 "TAGS": ":systemd:",
308 "USEC_INITIALIZED": "9547551",
309 "attrs": {
310 "alignment_offset": "0",
311 "bdi": null,
312 "capability": "10",
313 "dev": "94:12",
314 "device": null,
315 "discard_alignment": "0",
316 "ext_range": "4",
317 "hidden": "0",
318 "inflight": " 0 0",
319 "range": "4",
320 "removable": "0",
321 "ro": "0",
322 "size": "177248010240",
323 "stat": " 17638 7942 928408 83980 256956 87209 13098840 251560 0 1876199440 1884679730",
324 "subsystem": "block",
325 "uevent": "MAJOR=94\nMINOR=12\nDEVNAME=dasdd\nDEVTYPE=disk"
326 }
327 },
328 "/dev/dasdd1": {
329 "DEVLINKS": "/dev/disk/by-path/ccw-0.0.1544-part1 /dev/disk/by-uuid/0ef8a516-dcab-43d4-84d5-b3fd9d355ca8",
330 "DEVNAME": "/dev/dasdd1",
331 "DEVPATH": "/devices/css0/0.0.01a4/0.0.1544/block/dasdd/dasdd1",
332 "DEVTYPE": "partition",
333 "ID_FS_TYPE": "ext4",
334 "ID_FS_USAGE": "filesystem",
335 "ID_FS_UUID": "0ef8a516-dcab-43d4-84d5-b3fd9d355ca8",
336 "ID_FS_UUID_ENC": "0ef8a516-dcab-43d4-84d5-b3fd9d355ca8",
337 "ID_FS_VERSION": "1.0",
338 "ID_PATH": "ccw-0.0.1544",
339 "ID_PATH_TAG": "ccw-0_0_1544",
340 "ID_SCSI": "1",
341 "MAJOR": "94",
342 "MINOR": "13",
343 "PARTN": "1",
344 "SUBSYSTEM": "block",
345 "TAGS": ":systemd:",
346 "USEC_INITIALIZED": "9576626",
347 "attrs": {
348 "alignment_offset": "0",
349 "dev": "94:13",
350 "discard_alignment": "0",
351 "inflight": " 0 0",
352 "partition": "1",
353 "ro": "0",
354 "size": "177246437376",
355 "start": "192",
356 "stat": " 17433 7942 926616 83910 256956 87209 13098840 251560 0 113880 479170",
357 "subsystem": "block",
358 "uevent": "MAJOR=94\nMINOR=13\nDEVNAME=dasdd1\nDEVTYPE=partition\nPARTN=1"
359 }
360 },
361 "/dev/dasde": {
362 "DEVLINKS": "/dev/disk/by-path/ccw-0.0.2520",
363 "DEVNAME": "/dev/dasde",
364 "DEVPATH": "/devices/css0/0.0.05e0/0.0.2520/block/dasde",
365 "DEVTYPE": "disk",
366 "ID_PATH": "ccw-0.0.2520",
367 "ID_PATH_TAG": "ccw-0_0_2520",
368 "MAJOR": "94",
369 "MINOR": "16",
370 "MPATH_SBIN_PATH": "/sbin",
371 "SUBSYSTEM": "block",
372 "TAGS": ":systemd:",
373 "USEC_INITIALIZED": "9583304",
374 "attrs": {
375 "alignment_offset": "0",
376 "bdi": null,
377 "capability": "10",
378 "dev": "94:16",
379 "device": null,
380 "discard_alignment": "0",
381 "ext_range": "4",
382 "hidden": "0",
383 "inflight": " 0 0",
384 "range": "4",
385 "removable": "0",
386 "ro": "0",
387 "size": "0",
388 "stat": " 0 0 0 0 0 0 0 0 0 0 0",
389 "subsystem": "block",
390 "uevent": "MAJOR=94\nMINOR=16\nDEVNAME=dasde\nDEVTYPE=disk"
391 }
392 },
393 "/dev/dm-0": {
394 "DEVLINKS": "/dev/disk/by-id/dm-name-36005076306ffd6b60000000000002409 /dev/disk/by-id/dm-uuid-mpath-36005076306ffd6b60000000000002409 /dev/disk/by-id/scsi-36005076306ffd6b60000000000002409 /dev/mapper/36005076306ffd6b60000000000002409 /dev/disk/by-id/wwn-0x6005076306ffd6b60000000000002409",
395 "DEVNAME": "/dev/dm-0",
396 "DEVPATH": "/devices/virtual/block/dm-0",
397 "DEVTYPE": "disk",
398 "DM_NAME": "36005076306ffd6b60000000000002409",
399 "DM_STATE": "ACTIVE",
400 "DM_SUSPENDED": "0",
401 "DM_TABLE_STATE": "LIVE",
402 "DM_TYPE": "scsi",
403 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
404 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
405 "DM_UDEV_RULES": "1",
406 "DM_UDEV_RULES_VSN": "2",
407 "DM_UUID": "mpath-36005076306ffd6b60000000000002409",
408 "DM_WWN": "0x6005076306ffd6b60000000000002409",
409 "ID_FS_LABEL": "s1lp6:raid5-2406-2407-2408-2409",
410 "ID_FS_LABEL_ENC": "s1lp6:raid5-2406-2407-2408-2409",
411 "ID_FS_TYPE": "linux_raid_member",
412 "ID_FS_USAGE": "raid",
413 "ID_FS_UUID": "7967c3f6-b6bb-2523-f515-9792ff8ac0f3",
414 "ID_FS_UUID_ENC": "7967c3f6-b6bb-2523-f515-9792ff8ac0f3",
415 "ID_FS_UUID_SUB": "a18d1237-26f5-d9b4-73dc-6530195cd76a",
416 "ID_FS_UUID_SUB_ENC": "a18d1237-26f5-d9b4-73dc-6530195cd76a",
417 "ID_FS_VERSION": "1.2",
418 "MAJOR": "253",
419 "MINOR": "0",
420 "MPATH_DEVICE_READY": "1",
421 "MPATH_SBIN_PATH": "/sbin",
422 "SUBSYSTEM": "block",
423 "TAGS": ":systemd:",
424 "USEC_INITIALIZED": "52574971799",
425 "attrs": {
426 "alignment_offset": "0",
427 "bdi": null,
428 "capability": "10",
429 "dev": "253:0",
430 "discard_alignment": "0",
431 "ext_range": "1",
432 "hidden": "0",
433 "inflight": " 0 0",
434 "range": "1",
435 "removable": "0",
436 "ro": "0",
437 "size": "10737418240",
438 "stat": " 1367 0 9532 310 1 0 1 0 0 680 680",
439 "subsystem": "block",
440 "uevent": "MAJOR=253\nMINOR=0\nDEVNAME=dm-0\nDEVTYPE=disk"
441 }
442 },
443 "/dev/dm-1": {
444 "DEVLINKS": "/dev/disk/by-id/dm-uuid-mpath-36005076306ffd6b60000000000002408 /dev/mapper/36005076306ffd6b60000000000002408 /dev/disk/by-id/wwn-0x6005076306ffd6b60000000000002408 /dev/disk/by-id/dm-name-36005076306ffd6b60000000000002408 /dev/disk/by-id/scsi-36005076306ffd6b60000000000002408",
445 "DEVNAME": "/dev/dm-1",
446 "DEVPATH": "/devices/virtual/block/dm-1",
447 "DEVTYPE": "disk",
448 "DM_NAME": "36005076306ffd6b60000000000002408",
449 "DM_STATE": "ACTIVE",
450 "DM_SUSPENDED": "0",
451 "DM_TABLE_STATE": "LIVE",
452 "DM_TYPE": "scsi",
453 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
454 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
455 "DM_UDEV_RULES": "1",
456 "DM_UDEV_RULES_VSN": "2",
457 "DM_UUID": "mpath-36005076306ffd6b60000000000002408",
458 "DM_WWN": "0x6005076306ffd6b60000000000002408",
459 "ID_FS_LABEL": "s1lp6:raid5-2406-2407-2408-2409",
460 "ID_FS_LABEL_ENC": "s1lp6:raid5-2406-2407-2408-2409",
461 "ID_FS_TYPE": "linux_raid_member",
462 "ID_FS_USAGE": "raid",
463 "ID_FS_UUID": "7967c3f6-b6bb-2523-f515-9792ff8ac0f3",
464 "ID_FS_UUID_ENC": "7967c3f6-b6bb-2523-f515-9792ff8ac0f3",
465 "ID_FS_UUID_SUB": "e96ca63b-c454-c133-2bcf-db53103a44f7",
466 "ID_FS_UUID_SUB_ENC": "e96ca63b-c454-c133-2bcf-db53103a44f7",
467 "ID_FS_VERSION": "1.2",
468 "MAJOR": "253",
469 "MINOR": "1",
470 "MPATH_DEVICE_READY": "1",
471 "MPATH_SBIN_PATH": "/sbin",
472 "SUBSYSTEM": "block",
473 "TAGS": ":systemd:",
474 "USEC_INITIALIZED": "52578275554",
475 "attrs": {
476 "alignment_offset": "0",
477 "bdi": null,
478 "capability": "10",
479 "dev": "253:1",
480 "discard_alignment": "0",
481 "ext_range": "1",
482 "hidden": "0",
483 "inflight": " 0 0",
484 "range": "1",
485 "removable": "0",
486 "ro": "0",
487 "size": "10737418240",
488 "stat": " 2442 213 25630 1230 1 0 1 0 0 1320 2110",
489 "subsystem": "block",
490 "uevent": "MAJOR=253\nMINOR=1\nDEVNAME=dm-1\nDEVTYPE=disk"
491 }
492 },
493 "/dev/dm-10": {
494 "DEVLINKS": "/dev/disk/by-uuid/6b920893-062d-4b24-bafd-7237e7eea19d /dev/mapper/storage_vg_242x-lv_tmp /dev/storage_vg_242x/lv_tmp /dev/disk/by-id/dm-name-storage_vg_242x-lv_tmp /dev/disk/by-id/dm-uuid-LVM-vK8pAtBwlyrZxQgOcgVSlj81LvyUnvq4OF1H7mF23XJIHlznOzyw9TFKGuD2g0ta",
495 "DEVNAME": "/dev/dm-10",
496 "DEVPATH": "/devices/virtual/block/dm-10",
497 "DEVTYPE": "disk",
498 "DM_ACTIVATION": "1",
499 "DM_LV_NAME": "lv_tmp",
500 "DM_NAME": "storage_vg_242x-lv_tmp",
501 "DM_STATE": "ACTIVE",
502 "DM_SUSPENDED": "0",
503 "DM_TABLE_STATE": "LIVE",
504 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
505 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
506 "DM_UDEV_RULES": "1",
507 "DM_UDEV_RULES_VSN": "2",
508 "DM_UUID": "LVM-vK8pAtBwlyrZxQgOcgVSlj81LvyUnvq4OF1H7mF23XJIHlznOzyw9TFKGuD2g0ta",
509 "DM_VG_NAME": "storage_vg_242x",
510 "ID_FS_TYPE": "ext4",
511 "ID_FS_USAGE": "filesystem",
512 "ID_FS_UUID": "6b920893-062d-4b24-bafd-7237e7eea19d",
513 "ID_FS_UUID_ENC": "6b920893-062d-4b24-bafd-7237e7eea19d",
514 "ID_FS_VERSION": "1.0",
515 "MAJOR": "253",
516 "MINOR": "10",
517 "SUBSYSTEM": "block",
518 "TAGS": ":systemd:",
519 "USEC_INITIALIZED": "52580163360",
520 "attrs": {
521 "alignment_offset": "0",
522 "bdi": null,
523 "capability": "10",
524 "dev": "253:10",
525 "discard_alignment": "0",
526 "ext_range": "1",
527 "hidden": "0",
528 "inflight": " 0 0",
529 "range": "1",
530 "removable": "0",
531 "ro": "0",
532 "size": "103066632192",
533 "stat": " 1918 0 63050 980 46606 0 381088 330 0 3947610 3948030",
534 "subsystem": "block",
535 "uevent": "MAJOR=253\nMINOR=10\nDEVNAME=dm-10\nDEVTYPE=disk"
536 }
537 },
538 "/dev/dm-2": {
539 "DEVLINKS": "/dev/disk/by-id/wwn-0x6005076306ffd6b60000000000002406 /dev/disk/by-id/dm-uuid-mpath-36005076306ffd6b60000000000002406 /dev/disk/by-id/dm-name-36005076306ffd6b60000000000002406 /dev/disk/by-id/scsi-36005076306ffd6b60000000000002406 /dev/disk/by-uuid/308b3159-5497-48e7-84d7-cac358c4e228 /dev/mapper/36005076306ffd6b60000000000002406",
540 "DEVNAME": "/dev/dm-2",
541 "DEVPATH": "/devices/virtual/block/dm-2",
542 "DEVTYPE": "disk",
543 "DM_NAME": "36005076306ffd6b60000000000002406",
544 "DM_STATE": "ACTIVE",
545 "DM_SUSPENDED": "0",
546 "DM_TABLE_STATE": "LIVE",
547 "DM_TYPE": "scsi",
548 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
549 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
550 "DM_UDEV_RULES": "1",
551 "DM_UDEV_RULES_VSN": "2",
552 "DM_UUID": "mpath-36005076306ffd6b60000000000002406",
553 "DM_WWN": "0x6005076306ffd6b60000000000002406",
554 "ID_FS_TYPE": "bcache",
555 "ID_FS_UUID": "308b3159-5497-48e7-84d7-cac358c4e228",
556 "ID_FS_UUID_ENC": "308b3159-5497-48e7-84d7-cac358c4e228",
557 "MAJOR": "253",
558 "MINOR": "2",
559 "MPATH_DEVICE_READY": "1",
560 "MPATH_SBIN_PATH": "/sbin",
561 "SUBSYSTEM": "block",
562 "TAGS": ":systemd:",
563 "USEC_INITIALIZED": "52578383687",
564 "attrs": {
565 "alignment_offset": "0",
566 "bdi": null,
567 "capability": "10",
568 "dev": "253:2",
569 "discard_alignment": "0",
570 "ext_range": "1",
571 "hidden": "0",
572 "inflight": " 0 0",
573 "range": "1",
574 "removable": "0",
575 "ro": "0",
576 "size": "10737418240",
577 "stat": " 1747 0 28036 270 5 1 25 0 0 650 650",
578 "subsystem": "block",
579 "uevent": "MAJOR=253\nMINOR=2\nDEVNAME=dm-2\nDEVTYPE=disk"
580 }
581 },
582 "/dev/dm-3": {
583 "DEVLINKS": "/dev/disk/by-id/lvm-pv-uuid-c9yFym-fhMk-BHHc-nXDt-uxYY-xmQV-oWg69m /dev/mapper/36005076306ffd6b60000000000002422 /dev/disk/by-id/dm-uuid-mpath-36005076306ffd6b60000000000002422 /dev/disk/by-id/scsi-36005076306ffd6b60000000000002422 /dev/disk/by-id/dm-name-36005076306ffd6b60000000000002422 /dev/disk/by-id/wwn-0x6005076306ffd6b60000000000002422",
584 "DEVNAME": "/dev/dm-3",
585 "DEVPATH": "/devices/virtual/block/dm-3",
586 "DEVTYPE": "disk",
587 "DM_ACTIVATION": "0",
588 "DM_NAME": "36005076306ffd6b60000000000002422",
589 "DM_STATE": "ACTIVE",
590 "DM_SUBSYSTEM_UDEV_FLAG0": "1",
591 "DM_SUSPENDED": "0",
592 "DM_TABLE_STATE": "LIVE",
593 "DM_TYPE": "scsi",
594 "DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG": "1",
595 "DM_UDEV_PRIMARY_SOURCE_FLAG": "1",
596 "DM_UDEV_RULES": "1",
597 "DM_UDEV_RULES_VSN": "2",
598 "DM_UUID": "mpath-36005076306ffd6b60000000000002422",
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches