]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: check if device is OPAL locked on I/O error
authorLuca Boccassi <bluca@debian.org>
Wed, 22 Feb 2023 01:33:36 +0000 (01:33 +0000)
committerLuca Boccassi <bluca@debian.org>
Wed, 22 Feb 2023 02:02:03 +0000 (02:02 +0000)
Use the appropriate ioctl, if available, to check if a device is locked
when we get an I/O error. Save the information so that we don't have to
repeat the ioctl.

Before:

LIBBLKID_DEBUG=all blkid -p /dev/sdd2
206326: libblkid:     INIT: library debug mask: 0xffff
206326: libblkid:     INIT: library version: 2.38.1 [04-Aug-2022]
Available "LIBBLKID_DEBUG=<name>[,...]|<mask>" debug masks:
   all      [0xffff] : info about all subsystems
   cache    [0x0004] : blkid tags cache
   config   [0x0008] : config file utils
   dev      [0x0010] : device utils
   devname  [0x0020] : /proc/partitions evaluation
   devno    [0x0040] : conversions to device name
   evaluate [0x0080] : tags resolving
   help     [0x0001] : this help
   lowprobe [0x0100] : superblock/raids/partitions probing
   buffer   [0x2000] : low-probing buffers
   probe    [0x0200] : devices verification
   read     [0x0400] : cache parsing
   save     [0x0800] : cache writing
   tag      [0x1000] : tags utils
206326: libblkid: LOWPROBE: allocate a new probe
206326: libblkid: LOWPROBE: zeroize wiper
206326: libblkid: LOWPROBE: ready for low-probing, offset=0, size=234584276992, zonesize=0
206326: libblkid: LOWPROBE: whole-disk: NO, regfile: NO
206326: libblkid: LOWPROBE: start probe
206326: libblkid: LOWPROBE: zeroize wiper
206326: libblkid: LOWPROBE: chain safeprobe superblocks ENABLED
206326: libblkid: LOWPROBE: --> starting probing loop [SUBLKS idx=-1]
206326: libblkid: LOWPROBE: [0] linux_raid_member:
206326: libblkid: LOWPROBE:  call probefunc()
206326: libblkid: LOWPROBE:  read: off=234584211456 len=64
206326: libblkid: LOWPROBE:  read failed: Input/output error
206326: libblkid: LOWPROBE: <-- leaving probing loop (failed=-5) [SUBLKS idx=0]
206326: libblkid: LOWPROBE: freeing values list
206326: libblkid: LOWPROBE: end probe
206326: libblkid: LOWPROBE: zeroize wiper
206326: libblkid: LOWPROBE: free probe

After:

LIBBLKID_DEBUG=all blkid -p /dev/sdd2
206221: libblkid:     INIT: library debug mask: 0xffff
206221: libblkid:     INIT: library version: 2.38.1119 [28-Mar-2022]
Available "LIBBLKID_DEBUG=<name>[,...]|<mask>" debug masks:
   all      [0x00ffff] : info about all subsystems
   cache    [0x000004] : blkid tags cache
   config   [0x000008] : config file utils
   dev      [0x000010] : device utils
   devname  [0x000020] : /proc/partitions evaluation
   devno    [0x000040] : conversions to device name
   evaluate [0x000080] : tags resolving
   help     [0x000001] : this help
   lowprobe [0x000100] : superblock/raids/partitions probing
   buffer   [0x002000] : low-probing buffers
   probe    [0x000200] : devices verification
   read     [0x000400] : cache parsing
   save     [0x000800] : cache writing
   tag      [0x001000] : tags utils
206221: libblkid: LOWPROBE: allocate a new probe
206221: libblkid: LOWPROBE: zeroize wiper
206221: libblkid: LOWPROBE: ready for low-probing, offset=0, size=234584276992, zonesize=0
206221: libblkid: LOWPROBE: whole-disk: NO, regfile: NO
206221: libblkid: LOWPROBE: start probe
206221: libblkid: LOWPROBE: zeroize wiper
206221: libblkid: LOWPROBE: chain safeprobe superblocks ENABLED
206221: libblkid: LOWPROBE: --> starting probing loop [SUBLKS idx=-1]
206221: libblkid: LOWPROBE: [0] linux_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE:  read: off=234584211456 len=64
206221: libblkid: LOWPROBE:  read failed: Input/output error
206221: libblkid: LOWPROBE:  read: off=234584268800 len=256
206221: libblkid: LOWPROBE:  read failed: Input/output error
206221: libblkid: LOWPROBE:  read: off=0 len=256
206221: libblkid: LOWPROBE:  read: off=4096 len=256
206221: libblkid: LOWPROBE: [1] ddf_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE:  read: off=234584276480 len=512
206221: libblkid: LOWPROBE:  read failed: Input/output error
206221: libblkid: LOWPROBE: [2] isw_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [3] lsi_mega_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [4] via_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [5] silicon_medley_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [6] nvidia_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [7] promise_fasttrack_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [8] hpt45x_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [9] hpt37x_raid_member:
206221: libblkid: LOWPROBE:  read: off=4096 len=1024
206221: libblkid:   BUFFER:  reuse: off=4096 len=1024 (for off=4096 len=1024)
206221: libblkid: LOWPROBE: [10] adaptec_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [11] jmicron_raid_member:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE: [12] bcache:
206221: libblkid:   BUFFER:  reuse: off=4096 len=1024 (for off=4096 len=1024)
206221: libblkid: LOWPROBE: [13] bcachefs:
206221: libblkid:   BUFFER:  reuse: off=4096 len=1024 (for off=4096 len=1024)
206221: libblkid:   BUFFER:  reuse: off=4096 len=1024 (for off=4096 len=1024)
206221: libblkid: LOWPROBE: [14] ceph_bluestore:
206221: libblkid: LOWPROBE:  read: off=0 len=1024
206221: libblkid: LOWPROBE: [15] drbd:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid: LOWPROBE:  read: off=234584272896 len=104
206221: libblkid: LOWPROBE:  read failed: Input/output error
206221: libblkid: LOWPROBE:  read: off=234584272896 len=1392
206221: libblkid: LOWPROBE:  read failed: Input/output error
206221: libblkid: LOWPROBE: [16] drbdmanage_control_volume:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [17] drbdproxy_datalog:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [18] LVM2_member:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE:  read: off=1024 len=1024
206221: libblkid:   BUFFER:  reuse: off=1024 len=1024 (for off=1024 len=1024)
206221: libblkid: LOWPROBE: [19] LVM1_member:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [20] DM_snapshot_cow:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [21] DM_verity_hash:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [22] DM_integrity:
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: [23] crypto_LUKS:
206221: libblkid: LOWPROBE:  call probefunc()
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=512)
206221: libblkid: LOWPROBE: assigning VERSION [superblocks]
206221: libblkid: LOWPROBE: assigning UUID [superblocks]
206221: libblkid: LOWPROBE: assigning LABEL [superblocks]
206221: libblkid: LOWPROBE:  free value LABEL
206221: libblkid: LOWPROBE: assigning SUBSYSTEM [superblocks]
206221: libblkid: LOWPROBE: assigning TYPE [superblocks]
206221: libblkid: LOWPROBE: assigning USAGE [superblocks]
206221: libblkid: LOWPROBE: <-- leaving probing loop (type=crypto_LUKS) [SUBLKS idx=23]
206221: libblkid: LOWPROBE: freeing values list
206221: libblkid: LOWPROBE: chain safeprobe topology DISABLED
206221: libblkid: LOWPROBE: chain safeprobe partitions ENABLED
206221: libblkid: LOWPROBE: Resetting partitions values
206221: libblkid: LOWPROBE: --> starting probing loop [PARTS idx=-1]
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: gpt: ---> call probefunc()
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=512)
206221: libblkid: LOWPROBE: gpt: <--- (rc = 1)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: ultrix: ---> call probefunc()
206221: libblkid: LOWPROBE:  read: off=15872 len=512
206221: libblkid: LOWPROBE: ultrix: <--- (rc = 1)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE:  read: off=28672 len=1024
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE: atari: ---> call probefunc()
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=512)
206221: libblkid: LOWPROBE: atari: <--- (rc = 1)
206221: libblkid: LOWPROBE: <-- leaving probing loop (failed=1) [PARTS idx=12]
206221: libblkid: LOWPROBE: parts: start probing for partition entry
206221: libblkid:    DEVNO: found devno 0x0830 as /dev/sdd
206221: libblkid: LOWPROBE: allocate a wholedisk probe
206221: libblkid: LOWPROBE: allocate a new probe
206221: libblkid: LOWPROBE: zeroize wiper
206221: libblkid: LOWPROBE: ready for low-probing, offset=0, size=256060514304, zonesize=0
206221: libblkid: LOWPROBE: whole-disk: YES, regfile: NO
206221: libblkid: LOWPROBE: partlist reset
206221: libblkid: LOWPROBE: parts: initialized partitions list (size=0)
206221: libblkid: LOWPROBE: --> starting probing loop [PARTS idx=-1]
206221: libblkid: LOWPROBE:  read: off=0 len=1024
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=1024)
206221: libblkid: LOWPROBE:  magic sboff=510, kboff=0
206221: libblkid: LOWPROBE: dos: ---> call probefunc()
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=512)
206221: libblkid: LOWPROBE: probably GPT -- ignore
206221: libblkid: LOWPROBE: dos: <--- (rc = 1)
206221: libblkid: LOWPROBE: gpt: ---> call probefunc()
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=0 len=512)
206221: libblkid: LOWPROBE:  #1 valid PMBR partition
206221: libblkid: LOWPROBE:  checking for GPT header at 1
206221: libblkid:   BUFFER:  reuse: off=0 len=1024 (for off=512 len=512)
206221: libblkid: LOWPROBE:  read: off=1024 len=16384
206221: libblkid: LOWPROBE: parts: create a new partition table (type=gpt, offset=512)
206221: libblkid: LOWPROBE: parts: add partition (start=2048, size=41943040)
206221: libblkid: LOWPROBE: parts: add partition (start=41945088, size=458172416)
206221: libblkid: LOWPROBE: gpt: <--- (rc = 0)
206221: libblkid: LOWPROBE: <-- leaving probing loop (type=gpt) [PARTS idx=4]
206221: libblkid: LOWPROBE: partitions probe done [rc=0]
206221: libblkid: LOWPROBE: returning partitions binary data
206221: libblkid: LOWPROBE: trying to convert devno 0x832 to partition
206221: libblkid: LOWPROBE: searching by offset/size
206221: libblkid: LOWPROBE: assigning PART_ENTRY_SCHEME [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_UUID [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_TYPE [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_NUMBER [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_OFFSET [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_SIZE [partitions]
206221: libblkid: LOWPROBE: assigning PART_ENTRY_DISK [partitions]
206221: libblkid: LOWPROBE: parts: end probing for partition entry [success]
206221: libblkid: LOWPROBE: partitions probe done [rc=0]
206221: libblkid: LOWPROBE: end probe
206221: libblkid: LOWPROBE: zeroize wiper
206221: libblkid: LOWPROBE: returning VERSION value
206221: libblkid: LOWPROBE: returning UUID value
206221: libblkid: LOWPROBE: returning SUBSYSTEM value
206221: libblkid: LOWPROBE: returning TYPE value
206221: libblkid: LOWPROBE: returning USAGE value
206221: libblkid: LOWPROBE: returning PART_ENTRY_SCHEME value
206221: libblkid: LOWPROBE: returning PART_ENTRY_UUID value
206221: libblkid: LOWPROBE: returning PART_ENTRY_TYPE value
206221: libblkid: LOWPROBE: returning PART_ENTRY_NUMBER value
206221: libblkid: LOWPROBE: returning PART_ENTRY_OFFSET value
206221: libblkid: LOWPROBE: returning PART_ENTRY_SIZE value
206221: libblkid: LOWPROBE: returning PART_ENTRY_DISK value
/dev/sdd2: VERSION="2" UUID="a918f1d0-f1de-44f5-9d93-ce9dc15cc2c7" SUBSYSTEM="HW-OPAL" TYPE="crypto_LUKS" USAGE="crypto" PART_ENTRY_SCHEME="gpt" PART_ENTRY_UUID="39ed5135-46e4-ca44-837e-da3c0781367b" PART_ENTRY_TYPE="0fc63daf-8483-4772-8e79-3d69d8477de4" PART_ENTRY_NUMBER="2" PART_ENTRY_OFFSET="41945088" PART_ENTRY_SIZE="458172416" PART_ENTRY_DISK="8:48"
206221: libblkid:   BUFFER: Resetting probing buffers
206221: libblkid:   BUFFER:  remove buffer: [off=0, len=256]
206221: libblkid:   BUFFER:  remove buffer: [off=4096, len=256]
206221: libblkid:   BUFFER:  remove buffer: [off=4096, len=1024]
206221: libblkid:   BUFFER:  remove buffer: [off=0, len=1024]
206221: libblkid:   BUFFER:  remove buffer: [off=1024, len=1024]
206221: libblkid:   BUFFER:  remove buffer: [off=15872, len=512]
206221: libblkid:   BUFFER:  remove buffer: [off=28672, len=1024]
206221: libblkid: LOWPROBE:  buffers summary: 5120 bytes by 7 read() calls
206221: libblkid: LOWPROBE: resetting results
206221: libblkid: LOWPROBE:  free value VERSION
206221: libblkid: LOWPROBE:  free value UUID
206221: libblkid: LOWPROBE:  free value SUBSYSTEM
206221: libblkid: LOWPROBE:  free value TYPE
206221: libblkid: LOWPROBE:  free value USAGE
206221: libblkid: LOWPROBE:  free value PART_ENTRY_SCHEME
206221: libblkid: LOWPROBE:  free value PART_ENTRY_UUID
206221: libblkid: LOWPROBE:  free value PART_ENTRY_TYPE
206221: libblkid: LOWPROBE:  free value PART_ENTRY_NUMBER
206221: libblkid: LOWPROBE:  free value PART_ENTRY_OFFSET
206221: libblkid: LOWPROBE:  free value PART_ENTRY_SIZE
206221: libblkid: LOWPROBE:  free value PART_ENTRY_DISK
206221: libblkid:   BUFFER: Resetting probing buffers
206221: libblkid:   BUFFER:  remove buffer: [off=0, len=1024]
206221: libblkid:   BUFFER:  remove buffer: [off=1024, len=16384]
206221: libblkid: LOWPROBE:  buffers summary: 17408 bytes by 2 read() calls
206221: libblkid: LOWPROBE: free probe
206221: libblkid: LOWPROBE: free probe

Signed-off-by: Luca Boccassi <bluca@debian.org>
configure.ac
libblkid/src/blkidP.h
libblkid/src/probe.c
meson.build

index 89ba867dfb352fa6d0401da468c9e0e44315b2e5..d631b062d280ee31cc05a69464d979641972480c 100644 (file)
@@ -751,6 +751,11 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([extern char *__progname;],
           AC_MSG_RESULT([yes]),
           AC_MSG_RESULT([no]))
 
+AC_CHECK_DECL([IOC_OPAL_GET_STATUS],
+       [AC_DEFINE([HAVE_OPAL_GET_STATUS], [1],
+               [Define to 1 if OPAL status ioctl is defined])],,
+             [#include <linux/sed-opal.h>])
+
 dnl Static compilation
 m4_define([UL_STATIC_PROGRAMS], [blkid, fdisk, losetup, mount, nsenter, sfdisk, umount, unshare])
 
index a9308068e66296af0284123931e8237d227d953b..5d2a02055dc812fa0c94204eb5cce183708df6c4 100644 (file)
@@ -237,6 +237,7 @@ struct blkid_struct_probe
 #define BLKID_FL_CDROM_DEV     (1 << 3)        /* is a CD/DVD drive */
 #define BLKID_FL_NOSCAN_DEV    (1 << 4)        /* do not scan this device */
 #define BLKID_FL_MODIF_BUFF    (1 << 5)        /* cached buffers has been modified */
+#define BLKID_FL_OPAL_LOCKED   (1 << 6)        /* OPAL device is locked (I/O errors) */
 
 /* private per-probing flags */
 #define BLKID_PROBE_FL_IGNORE_PT (1 << 1)      /* ignore partition table */
@@ -407,6 +408,9 @@ extern int blkid_probe_is_tiny(blkid_probe pr)
 extern int blkid_probe_is_cdrom(blkid_probe pr)
                        __attribute__((nonnull))
                        __attribute__((warn_unused_result));
+extern int blkdid_probe_is_opal_locked(blkid_probe pr)
+                       __attribute__((nonnull))
+                       __attribute__((warn_unused_result));
 
 extern unsigned char *blkid_probe_get_buffer(blkid_probe pr,
                                 uint64_t off, uint64_t len)
index 61c7a446802f62b66a4f7268e65d0d03e672f7ed..35de30334697c712a8b068d342d96f88a44321e1 100644 (file)
 #include <stdint.h>
 #include <stdarg.h>
 #include <limits.h>
+#ifdef HAVE_OPAL_GET_STATUS
+#include <linux/sed-opal.h>
+#endif
 
 #include "blkidP.h"
 #include "all-io.h"
@@ -578,8 +581,23 @@ static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint
 
                /* I/O errors on CDROMs are non-fatal to work with hybrid
                 * audio+data disks */
-               if (ret >= 0 || blkid_probe_is_cdrom(pr))
+               if (ret >= 0 || blkid_probe_is_cdrom(pr) || blkdid_probe_is_opal_locked(pr))
                        errno = 0;
+#ifdef HAVE_OPAL_GET_STATUS
+               else {
+                       struct opal_status st = { };
+
+                       /* If the device is locked with OPAL, we'll fail to read with I/O
+                        * errors when probing deep into the block device. Do not return
+                        * an error, so that we can move on to different types of checks.*/
+                       ret = ioctl(pr->fd, IOC_OPAL_GET_STATUS, &st);
+                       if (ret == 0 && (st.flags & OPAL_FL_LOCKED)) {
+                               pr->flags |= BLKID_FL_OPAL_LOCKED;
+                               errno = 0;
+                       }
+               }
+#endif
+
                return NULL;
        }
 
@@ -815,6 +833,11 @@ int blkid_probe_is_cdrom(blkid_probe pr)
        return (pr->flags & BLKID_FL_CDROM_DEV);
 }
 
+int blkdid_probe_is_opal_locked(blkid_probe pr)
+{
+       return (pr->flags & BLKID_FL_OPAL_LOCKED);
+}
+
 #ifdef CDROM_GET_CAPABILITY
 
 static int is_sector_readable(int fd, uint64_t sector)
index 5139a3fd0593f82e05b4cca7d72262adf30c3e62..f0ebe074144e96624aa0e519ce2ac0d287a59593 100644 (file)
@@ -692,6 +692,9 @@ int main(void) {
 have = cc.compiles(code, name : 'using __progname')
 conf.set('HAVE___PROGNAME', have ? 1 : false)
 
+have_opal_get_status= cc.has_header_symbol('linux/sed-opal.h', 'IOC_OPAL_GET_STATUS')
+conf.set('HAVE_OPAL_GET_STATUS', have_opal_get_status ? 1 : false)
+
 build_plymouth_support = get_option('build-plymouth-support')
 have_tiocglcktrmios = cc.has_header_symbol(
   'sys/ioctl.h', 'TIOCGLCKTRMIOS',