やるきなし

2020/09/11 19:13 / /dev/md126 が Linux 5.8.8 で認識されない

Kernel を Linux 5.7.X から Linux 5.8.8 に上げたら /dev/md126 や /dev/md127 が見えなくなった.Kernel の問題なのか,udev の問題なのか,あるいは mdadm の問題か,という感じで順番に探っていったのだけど,Kernel と mdadm の問題だった.

Linux 5.8.8 の block: fix locking in bdev_del_partition の修正で,BLKPG_DEL_PARTITION ioctl の仕様が微妙に変更になっていて,mdadm がこの ioctl を使ってブロックデバイスが partition か否かをチェックしていて,そこで挙動がおかしくなっていた.

mdadm の該当箇所 util.cは以下のとおりで,errno が ENXIO か ENOTTY の場合は partition ではないと判断している.Linux 5.7.19 では partition ではない場合 ENXIO (No such device or address)が返される.これが,Linux 5.8.8 では ENOMEM (Cannot allocate memory)が返される.うーん.

int test_partition(int fd)
{
    /* Check if fd is a whole-disk or a partition.
     * BLKPG will return EINVAL on a partition, and BLKPG_DEL_PARTITION
     * will return ENXIO on an invalid partition number.
     */
    struct blkpg_ioctl_arg a;
    struct blkpg_partition p;
    a.op = BLKPG_DEL_PARTITION;
    a.data = (void*)&p;
    a.datalen = sizeof(p);
    a.flags = 0;
    memset(a.data, 0, a.datalen);
    p.pno = 1<<30;
    if (ioctl(fd, BLKPG, &a) == 0)
        /* Very unlikely, but not a partition */
        return 0;
    if (errno == ENXIO || errno == ENOTTY)
        /* not a partition */
        return 0;

    return 1;
}

sudo mdadm --detail-platform は 5.7.19 と 5.8.8 で出力は同じ.一方 sudo mdadm --examine /dev/sda (sda は RAID メンバの1つ)の出力が両者で異なっていたので,そこから探っていって問題箇所を見つけた.

Linux 5.7.19 での sudo mdadm --examine /dev/sda は以下で,

/dev/sda:
          Magic : Intel Raid ISM Cfg Sig.
        Version : 1.3.00
    Orig Family : 231b061f
         Family : 231b061f
     Generation : 00e7c753
     Attributes : All supported
           UUID : (snip)
       Checksum : (snip)
    MPB Sectors : 2
          Disks : 4
   RAID Devices : 1

  Disk01 Serial : (snip)
          State : active
             Id : 00000001
    Usable Size : (snip)

[Volume0]:
           UUID : (snip)
     RAID Level : 5
        Members : 4
          Slots : [UUUU]
(snip)

Linux 5.8.8 の sudo mdadm --examine /dev/sda は以下.

/dev/sda:
   MBR Magic : aa55
Partition[0] :   (snip) sectors at            1 (type ee)

ということで,mdadm 側に以下のパッチをあてると解決する.

--- mdadm-4.1/util.c    2018-10-02 03:26:06.000000000 +0900
+++ mdadm-4.1/util.c    2020-09-11 18:59:17.924356095 +0900
@@ -524,7 +524,7 @@
    if (ioctl(fd, BLKPG, &a) == 0)
        /* Very unlikely, but not a partition */
        return 0;
-   if (errno == ENXIO || errno == ENOTTY)
+   if (errno == ENXIO || errno == ENOTTY || errno == ENOMEM)
        /* not a partition */
        return 0;
 

手元環境 Debian なので上記 patch をあてた mdadm のパッケージを作って,dpkg -i で突っ込んで,mdadm は initrd にも含まれることになるので initrd が更新されていなければ sudo update-initramfs -k all -u で作り直す.

追記 (2020/9/18)

ENOMEM が返される問題,Linux 5.8.10 で仕様がもとにもどされて(block: restore a specific error code in bdev_del_partition),今は ENXIO を返すようになっている.

Related articles