scripts: sd_fusing: wait for udev after sfdisk 41/312441/5
authorJacek Kryszyn <j.kryszyn@samsung.com>
Mon, 10 Jun 2024 06:45:41 +0000 (08:45 +0200)
committerJaehoon Chung <jh80.chung@samsung.com>
Thu, 13 Jun 2024 04:22:43 +0000 (13:22 +0900)
It was observed that errors related to wrong partition table
were thrown from time to time after repartitoning the device
with sfdisk. It seems that this was due to udev trying to
automatically rescan devices after being notified that some
changes were made.

This commit adds execution of udevadm settle after sfdisk.
The added command exits only after the udev event queue is
empty (or the timeout occured).

This commit reverts changes made by commit 5a7f3c8 (Invoke
ioctl to reread partitions directly) which are not needed
anymore. Running blockdev after sfdisk is also unnecessary
since sfdisk rereads the partition table anyway.

Change-Id: Ic89ea65846b4e064c85a316fdf6c07be42eb51e7
Signed-off-by: Jacek Kryszyn <j.kryszyn@samsung.com>
scripts/tizen/sd_fusing.py

index b875105..f2f2fb9 100755 (executable)
@@ -5,7 +5,6 @@ from functools import reduce
 import argparse
 import atexit
 import errno
-import fcntl
 import logging
 import os
 import re
@@ -15,7 +14,6 @@ import subprocess
 import sys
 import tarfile
 import tempfile
-import time
 
 __version__ = "1.1.1"
 
@@ -26,7 +24,6 @@ Yes = False
 SuperDelivered = False
 
 LOGGING_NOTICE = int((logging.INFO + logging.WARNING) / 2)
-BLKRRPART = 4703 # from linux/fs.h
 
 class DebugFormatter(logging.Formatter):
     def format(self, record):
@@ -802,29 +799,17 @@ def mkpart(args, target):
         logging.error(f"New partition table:\n" + str(target.label))
         sys.exit(1)
 
-    # Invoke ioctl directly as blockdev sometimes fails with EBUSY for no known reason (udev/kernel timing issue?)
-    wait_secs = 3
-    logging.debug("Requesting kernel to re-read partition table:\n" + str(target.label))
-    rereadpt_ok = False
-    rereadpt_err = f"Failed to request kernel to re-read partition table on {Device}"
-    for i in range(5):
-        try:
-            with open(Device, "wb") as f:
-                fcntl.ioctl(f.fileno(), BLKRRPART)
-                rereadpt_ok = True
-                break
-        except OSError as e:
-            if e.errno == errno.EBUSY:
-                logging.error(f"{rereadpt_err}: {e.strerror}. Retrying after {wait_secs} seconds")
-                time.sleep(wait_secs)
-            else:
-                logging.error(f"{rereadpt_err}: {e.strerror}")
-                sys.exit(1)
-    if not rereadpt_ok:
-        logging.error(f"{rereadpt_err}")
-        sys.exit(1)
+    # Run `udevadm settle` to ensure that partition change made by `sfdisk` is completely reflected in userspace.
+    logging.info("Waiting for the udev event queue to empty...")
+    argv = ['udevadm', 'settle']
+    logging.debug(" ".join(argv))
+    proc = subprocess.run(argv,
+                          stdout=None,
+                          stderr=None)
+    if proc.returncode != 0:
+        logging.warning("udevadm settle exited without clearing the udev event queue.")
     else:
-        logging.notice(f"Successfully re-read partition table on {Device}")
+        logging.info("The udev event queue is empty.")
 
     if target.bootcode:
         logging.debug("Writing bootcode\n")