From: Karol Lewandowski Date: Wed, 22 May 2024 12:57:56 +0000 (+0200) Subject: sd_fusing.py: Invoke ioctl to reread partitions directly X-Git-Tag: accepted/tizen/unified/20240603.161029~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5a7f3c8dead1caf68e44e7a08449671dffb43385;p=platform%2Fkernel%2Fu-boot.git sd_fusing.py: Invoke ioctl to reread partitions directly This commit drops blockdev(8) in favor for invoking ioctl(2) directly, to be able to catch EBUSY errors that happen to occur due to not yet known kernel/udev timinig issue. This commit also drops sfdisk --no-reread flag, which affects issuing ioctl to reread partition table _before_ actual repartitioning. ioctl to reread partition table after writing changes is invoked unconditionally and can't be disabled. Change-Id: I105c445f9fdb3d1d2eee7ffd2de3f7ad04920f13 Signed-off-by: Karol Lewandowski --- diff --git a/scripts/tizen/sd_fusing.py b/scripts/tizen/sd_fusing.py index a564c2fe16..8aafc8aef3 100755 --- a/scripts/tizen/sd_fusing.py +++ b/scripts/tizen/sd_fusing.py @@ -5,6 +5,7 @@ from functools import reduce import argparse import atexit import errno +import fcntl import logging import os import re @@ -14,6 +15,7 @@ import subprocess import sys import tarfile import tempfile +import time __version__ = "1.0.4" @@ -24,6 +26,7 @@ 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): @@ -780,7 +783,7 @@ def mkpart(args, target): sys.exit(1) logging.debug("New partition table:\n" + str(target.label)) - argv = ['sfdisk', '--no-reread', '--wipe-partitions', 'always', Device] + argv = ['sfdisk', '--wipe-partitions', 'always', Device] logging.debug(" ".join(argv)) proc = subprocess.run(argv, stdout=None, @@ -791,15 +794,29 @@ 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)) - argv = ['blockdev', '--rereadpt', Device] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=None, - stderr=None) - if proc.returncode != 0: - logging.error(f"Failed to request kernel to reread partition table on {Device}. (Insufficient permissions?)") + 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) + else: + logging.notice(f"Successfully re-read partition table on {Device}") if target.bootcode: logging.debug("Writing bootcode\n")