Skip to content

Commit 1ac04df

Browse files
Stefan Wiehlera3f
authored andcommitted
driver/usbstoragedriver: have write_image wait for partition to appear
write_image currently waits for only the block device to appear, even if the image should be written to a partition. Improve this a bit by polling for the partition itself to appear with a non-zero size. While at it, we refactor the code a bit to improve code reuse when we add the write_files method in the follow-up commit. Signed-off-by: Stefan Wiehler <stefan.wiehler@missinglinkelectronics.com> Co-authored-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
1 parent 6c8c6e5 commit 1ac04df

1 file changed

Lines changed: 37 additions & 18 deletions

File tree

labgrid/driver/usbstoragedriver.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class USBStorageDriver(Driver):
4040
default=None,
4141
validator=attr.validators.optional(attr.validators.instance_of(str))
4242
)
43+
WAIT_FOR_MEDIUM_TIMEOUT = 10.0 # s
44+
WAIT_FOR_MEDIUM_SLEEP = 0.5 # s
4345

4446
def on_activate(self):
4547
pass
@@ -68,22 +70,10 @@ def write_image(self, filename=None, mode=Mode.DD, partition=None, skip=0, seek=
6870
mf = ManagedFile(filename, self.storage)
6971
mf.sync_to_resource()
7072

71-
# wait for medium
72-
timeout = Timeout(10.0)
73-
while not timeout.expired:
74-
try:
75-
if self.get_size() > 0:
76-
break
77-
time.sleep(0.5)
78-
except ValueError:
79-
# when the medium gets ready the sysfs attribute is empty for a short time span
80-
continue
81-
else:
82-
raise ExecutionError("Timeout while waiting for medium")
73+
self._wait_for_medium(partition)
8374

84-
partition = "" if partition is None else partition
75+
target = self._get_devpath(partition)
8576
remote_path = mf.get_remote_path()
86-
target = f"{self.storage.path}{partition}"
8777

8878
if mode == Mode.DD:
8979
self.logger.info('Writing %s to %s using dd.', remote_path, target)
@@ -139,12 +129,41 @@ def write_image(self, filename=None, mode=Mode.DD, partition=None, skip=0, seek=
139129
print_on_silent_log=True
140130
)
141131

132+
def _get_devpath(self, partition):
133+
partition = "" if partition is None else partition
134+
# simple concatenation is sufficient for USB mass storage
135+
return f"{self.storage.path}{partition}"
136+
142137
@Driver.check_active
143-
@step(result=True)
144-
def get_size(self):
145-
args = ["cat", f"/sys/class/block/{self.storage.path[5:]}/size"]
138+
def _wait_for_medium(self, partition):
139+
timeout = Timeout(self.WAIT_FOR_MEDIUM_TIMEOUT)
140+
while not timeout.expired:
141+
if self.get_size(partition) > 0:
142+
break
143+
time.sleep(self.WAIT_FOR_MEDIUM_SLEEP)
144+
else:
145+
raise ExecutionError("Timeout while waiting for medium")
146+
147+
@Driver.check_active
148+
@step(args=['partition'], result=True)
149+
def get_size(self, partition=None):
150+
"""
151+
Get the size of the bound USB storage root device or partition.
152+
153+
Args:
154+
partition (int or None): optional, get size of the specified partition or None for
155+
getting the size of the root device (defaults to None)
156+
157+
Returns:
158+
int: size in bytes
159+
"""
160+
args = ["cat", f"/sys/class/block/{self._get_devpath(partition)[5:]}/size"]
146161
size = subprocess.check_output(self.storage.command_prefix + args)
147-
return int(size)*512
162+
try:
163+
return int(size) * 512
164+
except ValueError:
165+
# when the medium gets ready the sysfs attribute is empty for a short time span
166+
return 0
148167

149168

150169
@target_factory.reg_driver

0 commit comments

Comments
 (0)