프로그래밍 방식으로 실행할 때 mdadm이 일관성이 없습니다.

프로그래밍 방식으로 실행할 때 mdadm이 일관성이 없습니다.

업데이트 #1:

방금 추가 테스트를 수행하고 셸 스크립트(.sh, #!/bin/bash)와 php의 cli에 의해 실행되는 php 스크립트를 작성했습니다.

배쉬가 작동합니다.

문제를 일으키는 것은 Apache의 HTTP 컨텍스트가 아니라 PHP 자체인 것 같습니다. php raider.php단순히 루트 셸에서 실행하면 원래 언급된 것과 동일한 두 가지 문제가 발생하기 때문입니다 .


WebOS로 장치를 만들고 있습니다. WebOS는 운영 체제(루트)에 대한 액세스가 필요하므로 Apache에서 호스팅됩니다 http:http. sudoers는 NOPASSWD를 사용하여 ALL을 허용하도록 설정됩니다 http.

루트로 실행되는 프로세스를 교육하지 마십시오. 환경이 제어되고 2년 동안 40개 이상의 장치가 배송되었으며 문제가 보고되지 않았습니다.

phpproc_open명령은 HTTP 요청 컨텍스트를 통해 (Apache의 경우 mod_php5)에 의해 실행됩니다 .

을 제외한 모든 명령이 제대로 작동하는 것 같습니다 mdadm --create. 배열을 만들려고 하면 만들려고 선택한 RAID 수준에 따라 임의의 결과가 나타납니다.

전에도 하나 있었는데네임스페이스 문제, 그러나 더 이상 그렇지 않습니다. 일부 OS 업데이트 후 문제가 나타나기 시작했습니다(정확히 언제인지는 알 수 없습니다. 이전 버전의 WebOS가 작동하지 않았으며 최근에 문제가 제기되어 분명히 수정이 필요했을 것입니다. 최신 버전도 있습니다. 잘 작동합니다(명령 실행 주기가 다릅니다).

mdadm_udev부팅 시 RAID를 어셈블하기 위해 initramfs 후크를 사용하고 있습니다 . RAID의 메타데이터를 기준으로 올바르게 조립한 것 같아서 /etc/mdadm.conf비워 두었습니다 . mdadm_udev그러나 유일한 문제는 그것들을 조립할 때 <hostname>:<raidname>.

위의 문제로 인해 를 사용하고 있는데 mdadm --create /dev/md/<hostname>:stoneshare ...사용자가 누구인지에 관계없이(루트가 아닌 사용자가 sudo로 실행하고 성공) CLI에서 제대로 실행되는 것처럼 보이지만 HTTP 컨텍스트를 통해 실행할 때 문제가 있습니다.

시나리오 #1, RAID0:

<?php

$command = sprintf('sudo mdadm --create /dev/md/%s:stoneshare --level 0 --raid-devices 2 /dev/sdb1 /dev/sdc1');
proc_open($command, /* ... */, /* ... */);

/dev/md127그러나 RAID를 활성화 하고 다음과 같은 심볼릭 링크를 사용하여 CLI를 사용하여 /dev/md/<hostname>:<sharename>위 스크립트를 실행하면 RAID가 생성됩니다 /dev/md127.

[root@stone ~]# mdadm --detail --scan
ARRAY /dev/md127 metadata=1.2 name=stone:stoneshare UUID=7329e458:96be442a:84f616d8:fd4ba42e

[root@stone ~]# ls -la /dev/md*
brw-rw---- 1 root disk 9, 127 Jul 30 11:48 /dev/md127

시나리오 #2, RAID1:

<?php

$command = sprintf('sudo mdadm --create /dev/md/%s:stoneshare --level 1 --assume-clean --raid-devices 2 /dev/sdb1 /dev/sdc1');
proc_open($command, /* ... */, /* ... */);

확인하다:

[root@stone ~]# mdadm --detail --scan
ARRAY /dev/md/stone:stoneshare metadata=1.2 name=stone:stoneshare UUID=7329e458:96be442a:84f616d8:fd4ba42e

[root@stone ~]# ls -la /dev/md*
brw-rw---- 1 root disk 9, 127 Jul 30 11:48 /dev/md127

/dev/md:
total 0
drwxr-xr-x  2 root root   60 Jul 30 12:17 .
drwxr-xr-x 19 root root 3080 Jul 30 12:17 ..
lrwxrwxrwx  1 root root   10 Jul 30 12:17 stone:stoneshare -> /dev/md127

이상하게도 심볼릭 링크는 생성되었으나 다른 문제가 있습니다. 즉, RAID 생성 시 무작위 /dev/sdb1또는 자동으로 오류로 표시된다는 것입니다. /dev/sdc1RAID가 생성되어 시작되었지만 1개의 드라이브로 실행 중입니다. 때로는 두 드라이브 모두 결함으로 표시되지 않고 RAID가 전혀 문제 없이 생성되는 경우도 있습니다.

내가 발견한 장비 고장에 대한 정보를 선별했습니다.

[root@stone ~]# journalctl -xb
Jul 30 11:39:43 stone kernel: md: bind<sdb1>
Jul 30 11:39:43 stone kernel: md: bind<sdc1>
Jul 30 11:39:43 stone kernel: md/raid1:md127: active with 2 out of 2 mirrors
Jul 30 11:39:43 stone kernel: created bitmap (8 pages) for device md127
Jul 30 11:39:43 stone kernel: md127: bitmap initialized from disk: read 1 pages, set 14903 of 14903 bits
Jul 30 11:39:43 stone kernel: md127: detected capacity change from 0 to 1000068874240
Jul 30 11:39:43 stone kernel:  md127: unknown partition table
Jul 30 11:39:43 stone systemd[1]: Starting MD array monitor...
Jul 30 11:39:43 stone systemd[1]: About to execute: /usr/lib/systemd/scripts/mdadm_env.sh
Jul 30 11:39:43 stone systemd[1]: Forked /usr/lib/systemd/scripts/mdadm_env.sh as 457
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service changed failed -> start-pre
Jul 30 11:39:43 stone systemd[457]: Executing: /usr/lib/systemd/scripts/mdadm_env.sh
Jul 30 11:39:43 stone systemd[457]: Failed at step EXEC spawning /usr/lib/systemd/scripts/mdadm_env.sh: No such file or directory
Jul 30 11:39:43 stone systemd[1]: Received SIGCHLD from PID 457 ((m_env.sh)).
Jul 30 11:39:43 stone systemd[1]: Child 457 ((m_env.sh)) died (code=exited, status=203/EXEC)
Jul 30 11:39:43 stone systemd[1]: Child 457 belongs to mdmonitor.service
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service: control process exited, code=exited status=203
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service got final SIGCHLD for state start-pre
Jul 30 11:39:43 stone systemd[1]: About to execute: /sbin/mdadm --monitor $MDADM_MONITOR_ARGS
Jul 30 11:39:43 stone systemd[1]: Forked /sbin/mdadm as 460
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service changed start-pre -> running
Jul 30 11:39:43 stone systemd[1]: Job mdmonitor.service/start finished, result=done
Jul 30 11:39:43 stone systemd[1]: Started MD array monitor.
Jul 30 11:39:43 stone kernel: md: md127 still in use.
Jul 30 11:39:43 stone kernel: md/raid1:md127: Disk failure on sdb1, disabling device.
                              md/raid1:md127: Operation continuing on 1 devices.
Jul 30 11:39:43 stone mdadm[460]: mdadm: No mail address or alert command - not monitoring.
Jul 30 11:39:43 stone systemd[460]: Executing: /sbin/mdadm --monitor --scan
Jul 30 11:39:43 stone systemd[1]: Received SIGCHLD from PID 460 (mdadm).
Jul 30 11:39:43 stone systemd[1]: Child 460 (mdadm) died (code=exited, status=1/FAILURE)
Jul 30 11:39:43 stone systemd[1]: Child 460 belongs to mdmonitor.service
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service: main process exited, code=exited, status=1/FAILURE
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service changed running -> failed
Jul 30 11:39:43 stone systemd[1]: Unit mdmonitor.service entered failed state.
Jul 30 11:39:43 stone systemd[1]: mdmonitor.service: cgroup is empty
Jul 30 11:39:43 stone kernel: RAID1 conf printout:
Jul 30 11:39:43 stone kernel:  --- wd:1 rd:2
Jul 30 11:39:43 stone kernel:  disk 0, wo:1, o:0, dev:sdb1
Jul 30 11:39:43 stone kernel:  disk 1, wo:0, o:1, dev:sdc1
Jul 30 11:39:43 stone systemd[1]: Got disconnect on private connection.
Jul 30 11:39:43 stone kernel: RAID1 conf printout:
Jul 30 11:39:43 stone kernel:  --- wd:1 rd:2
Jul 30 11:39:43 stone kernel:  disk 1, wo:0, o:1, dev:sdc1
Jul 30 11:39:43 stone kernel: md: unbind<sdb1>
Jul 30 11:39:43 stone kernel: md: export_rdev(sdb1)

내 생각에 이것이 mdmonitorRAID를 만드는 데 중요한지 의심됩니다.


CLI에서 실행할 때 두 RAID가 모두 완벽하게 조립되었으며 문제가 발생하지 않았습니다.

SMART 데이터에 따르면 드라이브는 정상입니다.

실제로 UUID는 동일하지 않습니다. 단일 RAID를 기반으로 예제를 만들었습니다.


이 불일치를 일으키는 내가 여기서 뭘 잘못하고 있습니까?

답변1

TL;박사

문제가 무엇인지 알아냈습니다! sleep일부 파티션 작업 사이에 약간의 시간이 필요합니다 . 분명히 동시성 문제를 우연히 발견했습니다.

더 자세히 알아보기:

프로세스가 완료된다고 해서 커널이 프로세스에서 자신의 역할을 완료했다는 의미는 아닌 것 같습니다(커널이 특정 프로세스 이후에 작업을 수행해야 하는 경우). 내 경우에는 파티셔닝이 문제였습니다. mdadm --create너무 일찍 시작했고 커널이 아직 일부 파티셔닝 변경 사항으로 업데이트되지 않은 것 같습니다. 예, 그 사이에 뭔가가 있지만 partprobe변경 사항을 인식하지 못하는 것 같습니다.

나는 우연히 발견할 때까지 쉘 스크립트, cli php 스크립트, 웹 스크립트를 사용하여 디버깅을 시작했습니다.

[root@stone /] parted -s /dev/sdb mklabel gpt unit GB mkpart primary 0 100%
[root@stone /] parted -s /dev/sdc mklabel gpt unit GB mkpart primary 0 100%

[root@stone /] partprobe

[root@stone /] lsblk
sda      8:0    0  55.9G  0 disk
├─sda1   8:1    0     1M  0 part
├─sda2   8:2    0   500M  0 part /boot/efi
├─sda3   8:3    0   500M  0 part [SWAP]
└─sda4   8:4    0  54.9G  0 part /
sdb      8:16   0 931.5G  0 disk
└─sdb1   8:17   0 931.5G  0 part
sdc      8:32   0 931.5G  0 disk

명령이 실행될 때 간격이 없으므로 CPU가 가능한 한 빨리 명령을 처리할 수 있습니다. /dev/sdc파티션 테이블이 아직 업데이트되지 않은 것으로 나타났습니다.

분명히 그 다음 명령은 파티션 테이블을 변경하지 않고 시작되어 이상한 동작을 일으켰습니다 partprobe.mdadm --create

내 관찰과 가정이 완전히 틀렸을 수도 있지만, 적어도 이것이 상황을 나 자신에게 논리적으로 설명할 수 있는 방법입니다.

예, 수정 사항은 sleep통화 사이에 다음을 추가하는 것입니다.

[root@stone /] parted -s /dev/sdb mklabel gpt unit GB mkpart primary 0 100%
[root@stone /] parted -s /dev/sdc mklabel gpt unit GB mkpart primary 0 100%

[root@stone /] sleep 1

[root@stone /] partprobe

[root@stone /] sleep 1

[root@stone /] lsblk
sda      8:0    0  55.9G  0 disk
├─sda1   8:1    0     1M  0 part
├─sda2   8:2    0   500M  0 part /boot/efi
├─sda3   8:3    0   500M  0 part [SWAP]
└─sda4   8:4    0  54.9G  0 part /
sdb      8:16   0 931.5G  0 disk
└─sdb1   8:17   0 931.5G  0 part
sdc      8:32   0 931.5G  0 disk

이로써 문제가 해결되었습니다.

하지만 결국 RAID0의 경우에는 심볼릭 링크가 생성되지 않지만 RAID1의 경우에는 생성되는 논리적 설명을 여전히 찾을 수 없습니다. 심볼릭 링크 생성을 방지하기 위해 준비를 푸시하는 방법을 이해할 수 없습니다 ...

관련 정보