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-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ef7d174dc6e472c6a0bee2462c0b49ffe4ff7b67;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. Change-Id: I105c445f9fdb3d1d2eee7ffd2de3f7ad04920f13 Signed-off-by: Karol Lewandowski --- diff --git a/scripts/tizen/sd_fusing.py b/scripts/tizen/sd_fusing.py index 3b58d74890..e7f580dad0 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" @@ -23,6 +25,7 @@ File = "" Yes = False LOGGING_NOTICE = int((logging.INFO + logging.WARNING) / 2) +BLKRRPART = 4703 # from linux/fs.h class DebugFormatter(logging.Formatter): def format(self, record): @@ -790,15 +793,32 @@ 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 = 2 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(2): + try: + with os.open(Device, os.O_RDWR) as fd: + fcntl.ioctl(fd, BLKRRPART) + rereadpt_ok = True + except OSError as e: + if e.errno == errno.EBUSY: + logging.error(f"{rereadpt_err}: {e.strerror}. Retrying after {wait_secs}") + time.sleep(wait_secs) + continue + 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}") + + # Wait a bit to ensure new layout has propagated to userspace + time.sleep(wait_secs) if target.bootcode: logging.debug("Writing bootcode\n")