From 0f670829a33cdbe7d63624dd0af3dc8febc76a86 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Fri, 28 Jan 2022 17:01:55 +0000 Subject: [PATCH] util/linux: fix BLK_IOC_FLSBUF on ppc64le ioctl contants are platform dependent. It should be the same on x86, aarch64 and s390x but it is indeed different on ppc64le. This lead to the call to `ioctl_blockdev_flushbuf` actually raising an exception of `OSError: [Errno 22] Invalid argument`. The constant was calculated with a little python snippet that in theory could also go directly into the code, but for now the simpler condition in this patch is enough. The snippet is a port of the defines from the Linux kernel, specifically /usr/include/asm-generic/ioctl.h. class IOConstants: """IO Commands for Linux""" if platform.machine() == "ppc64le": NRBITS = 8 TYPEBITS = 8 SIZEBITS = 13 DIR_NONE = 1 else: NRBITS = 8 TYPEBITS = 8 SIZEBITS = 14 DIR_NONE = 0 NRSHIFT = 0 TYPESHIFT = NRSHIFT+NRBITS SIZESHIFT = TYPESHIFT+TYPEBITS DIRSHIFT = SIZESHIFT+SIZEBITS @classmethod def make(cls, directory, iotype, nr, size): return ((directory << cls.DIRSHIFT) | (iotype << cls.TYPESHIFT) | (nr << cls.NRSHIFT) | (size << cls.SIZESHIFT)) @classmethod def make_dir_none(cls, iotype, nr): return cls.make(cls.DIR_NONE, iotype, nr, 0) This is used to get the value for `BLKFLSBUF` taken from the include `/usr/include/linux/fs.h`: #define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ The value is then obtained via: print("0x%x" % IOConstants.make_dir_none(0x12,97)) 0x20001261 --- osbuild/util/linux.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osbuild/util/linux.py b/osbuild/util/linux.py index 2ccbfc61..8308a7e1 100644 --- a/osbuild/util/linux.py +++ b/osbuild/util/linux.py @@ -14,6 +14,7 @@ reasonable manner. import array import fcntl +import platform __all__ = [ @@ -32,7 +33,11 @@ FS_IOC_SETFLAGS = 0x40086602 FS_IMMUTABLE_FL = 0x00000010 -BLK_IOC_FLSBUF = 0x00001261 + +if platform.machine() == "ppc64le": + BLK_IOC_FLSBUF = 0x20001261 +else: + BLK_IOC_FLSBUF = 0x00001261 def ioctl_get_immutable(fd: int):