やるきなし

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は以下のとおりで,errnoENXIOENOTTY の場合は 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 で突っ込んで,mdadminitrd にも含まれることになるので 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