Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/disk
diff options
context:
space:
mode:
authorAnton Hvornum <anton@hvornum.se>2021-11-11 18:11:38 +0000
committerGitHub <noreply@github.com>2021-11-11 18:11:38 +0000
commitca52c796a55fd34cc1309f26bab86e15da722182 (patch)
tree6dd56f60f5445920788fc1a94d1e93f34c78aea7 /archinstall/lib/disk
parent9b944b90b151a616e36f7361c7cf3c6951e61970 (diff)
parentc0bf44e0ae82bf2e379e57965c0e21694b61cd3c (diff)
Merged PR #711 - Fixing disk "ghosting" issues using partprobe
* Adding partprobe at strategic places. * Swapped `for partition in blockdevice` to `for uuid, partition in blockdevice.partitions.items()` instead as `__iter__` for debugging purposes. * `get_mount_info()` now causes a exception rather than returning nothing if there is nothing to be shown. This to avoid issues where in places this is crucial information and it went by unnoticeable. Using exception handlers where it doesn't matter if there's any information or not.
Diffstat (limited to 'archinstall/lib/disk')
-rw-r--r--archinstall/lib/disk/blockdevice.py10
-rw-r--r--archinstall/lib/disk/filesystem.py35
-rw-r--r--archinstall/lib/disk/helpers.py7
-rw-r--r--archinstall/lib/disk/partition.py12
4 files changed, 36 insertions, 28 deletions
diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py
index 5204f09b..307c5983 100644
--- a/archinstall/lib/disk/blockdevice.py
+++ b/archinstall/lib/disk/blockdevice.py
@@ -112,8 +112,8 @@ class BlockDevice:
@property
def partitions(self):
from .filesystem import Partition
- SysCommand(['partprobe', self.path])
+ self.partprobe()
result = SysCommand(['/usr/bin/lsblk', '-J', self.path])
if b'not a block device' in result:
@@ -202,6 +202,9 @@ class BlockDevice:
info = space_info
return info
+ def partprobe(self):
+ SysCommand(['partprobe', self.path])
+
def has_partitions(self):
return len(self.partitions)
@@ -217,7 +220,7 @@ class BlockDevice:
def get_partition(self, uuid):
count = 0
while count < 5:
- for partition in self:
+ for partition_uuid, partition in self.partitions.items():
if partition.uuid == uuid:
return partition
else:
@@ -226,4 +229,7 @@ class BlockDevice:
count += 1
else:
log(f"Could not find {uuid} in disk after 5 retries",level=logging.INFO)
+ print(f"Cache: {self.part_cache}")
+ print(f"Partitions: {self.partitions.items()}")
+ print(f"UUID: {[uuid]}")
raise DiskError(f"New partition {uuid} never showed up after adding new partition on {self}")
diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py
index 84b11c05..cf2a286e 100644
--- a/archinstall/lib/disk/filesystem.py
+++ b/archinstall/lib/disk/filesystem.py
@@ -20,24 +20,8 @@ class Filesystem:
self.mode = mode
def __enter__(self, *args, **kwargs):
- if self.blockdevice.keep_partitions is False:
- log(f'Wiping {self.blockdevice} by using partition format {self.mode}', level=logging.DEBUG)
- if self.mode == GPT:
- if self.parted_mklabel(self.blockdevice.device, "gpt"):
- self.blockdevice.flush_cache()
- return self
- else:
- raise DiskError('Problem setting the disk label type to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel gpt')
- elif self.mode == MBR:
- if self.parted_mklabel(self.blockdevice.device, "msdos"):
- return self
- else:
- raise DiskError('Problem setting the disk label type to msdos:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos')
- else:
- raise DiskError(f'Unknown mode selected to format in: {self.mode}')
-
# TODO: partition_table_type is hardcoded to GPT at the moment. This has to be changed.
- elif self.mode == self.blockdevice.partition_table_type:
+ if self.mode == self.blockdevice.partition_table_type:
log(f'Kept partition format {self.mode} for {self.blockdevice}', level=logging.DEBUG)
else:
raise DiskError(f'The selected partition table format {self.mode} does not match that of {self.blockdevice}.')
@@ -74,6 +58,8 @@ class Filesystem:
if not self.parted_mklabel(self.blockdevice.device, "msdos"):
raise KeyError(f"Could not create a MSDOS label on {self}")
+ self.blockdevice.flush_cache()
+
# We then iterate the partitions in order
for partition in layout.get('partitions', []):
# We don't want to re-add an existing partition (those containing a UUID already)
@@ -132,6 +118,9 @@ class Filesystem:
if partition.target_mountpoint == mountpoint or partition.mountpoint == mountpoint:
return partition
+ def partprobe(self):
+ SysCommand(f'bash -c "partprobe"')
+
def raw_parted(self, string: str):
if (cmd_handle := SysCommand(f'/usr/bin/parted -s {string}')).exit_code != 0:
log(f"Parted ended with a bad exit code: {cmd_handle}", level=logging.ERROR, fg="red")
@@ -146,6 +135,7 @@ class Filesystem:
:type string: str
"""
if (parted_handle := self.raw_parted(string)).exit_code == 0:
+ self.partprobe()
return True
else:
raise DiskError(f"Parted failed to add a partition: {parted_handle}")
@@ -176,7 +166,15 @@ class Filesystem:
if len(new_uuid_set) > 0:
new_uuid = new_uuid_set.pop()
if new_uuid:
- return self.blockdevice.get_partition(new_uuid)
+ try:
+ return self.blockdevice.get_partition(new_uuid)
+ except Exception as err:
+ print('Blockdevice:', self.blockdevice)
+ print('Partitions:', self.blockdevice.partitions)
+ print('Partition set:', new_uuid_set)
+ print('New UUID:', [new_uuid])
+ print('get_partition():', self.blockdevice.get_partition)
+ raise err
else:
count += 1
log(f"Could not get uuid for partition. Waiting for the {count} time",level=logging.DEBUG)
@@ -199,4 +197,5 @@ class Filesystem:
SysCommand(f'bash -c "umount {device}?"')
except:
pass
+ self.partprobe()
return self.raw_parted(f'{device} mklabel {disk_label}').exit_code == 0
diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py
index 8e044ce3..e15e69b2 100644
--- a/archinstall/lib/disk/helpers.py
+++ b/archinstall/lib/disk/helpers.py
@@ -121,7 +121,7 @@ def harddrive(size=None, model=None, fuzzy=False):
def get_mount_info(path :Union[pathlib.Path, str], traverse=False, return_real_path=False) -> dict:
for traversal in list(map(str, [str(path)] + list(pathlib.Path(str(path)).parents))):
try:
- log(f"Getting mount information at location {traversal}", level=logging.INFO)
+ log(f"Getting mount information for device path {traversal}", level=logging.INFO)
output = SysCommand(f'/usr/bin/findmnt --json {traversal}').decode('UTF-8')
if output:
break
@@ -132,10 +132,7 @@ def get_mount_info(path :Union[pathlib.Path, str], traverse=False, return_real_p
break
if not output:
- if return_real_path:
- return {}, None
- else:
- return {}
+ raise DiskError(f"Could not get mount information for device path {path}")
output = json.loads(output)
if 'filesystems' in output:
diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py
index e9688965..3630a6f4 100644
--- a/archinstall/lib/disk/partition.py
+++ b/archinstall/lib/disk/partition.py
@@ -32,7 +32,10 @@ class Partition:
if mountpoint:
self.mount(mountpoint)
- mount_information = get_mount_info(self.path)
+ try:
+ mount_information = get_mount_info(self.path)
+ except DiskError:
+ mount_information = {}
if self.mountpoint != mount_information.get('target', None) and mountpoint:
raise DiskError(f"{self} was given a mountpoint but the actual mountpoint differs: {mount_information.get('target', None)}")
@@ -145,8 +148,11 @@ class Partition:
it doesn't seam to be able to detect md raid partitions.
"""
- lsblk = json.loads(SysCommand(f'lsblk -J -o+PARTUUID {self.path}').decode('UTF-8'))
- for partition in lsblk['blockdevices']:
+ partuuid_struct = SysCommand(f'lsblk -J -o+PARTUUID {self.path}')
+ if not partuuid_struct.exit_code == 0:
+ raise DiskError(f"Could not get PARTUUID for {self.path}: {partuuid_struct}")
+
+ for partition in json.loads(partuuid_struct.decode('UTF-8'))['blockdevices']:
return partition.get('partuuid', None)
return None