Linux에는 /dev/root
장치 노드가 있습니다. 예를 들어 /dev/sdaX
, 이는 다른 장치 노드와 동일한 블록 장치입니다. 이 경우 /dev/root
합리적인 장치 이름이 사용자에게 표시되도록 "실제" 장치 노드를 어떻게 구문 분석합니까?
예를 들어, 나는 /proc/mounts
.
쉘/파이썬 스크립트를 통해 작동하지만 C를 통해서는 작동하지 않는 솔루션을 찾고 있습니다.
답변1
root=
에서 매개변수를 구문 분석합니다 /proc/cmdline
.
답변2
여기에 제공된 많은 정보가 오해의 소지가 있고 실제로는 완전히 정확하지 않을 수 있으므로 아마도 업데이트되어야 할 것입니다.
https://bootlin.com/blog/find-root-device/
/ 마운트 지점은 단지 /dev/root에 해당한다는 것을 알려줄 뿐이며, 이는 찾고 있는 실제 장치가 아닙니다.
물론, 커널 명령줄을 보고 어떤 초기 루트 파일 시스템이 Linux를 부팅하도록 지시되었는지 확인할 수 있습니다(root 매개변수).
$ cat /proc/cmdline mem=512M console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait
그러나 이것이 현재 루팅된 기기를 보고 있다는 의미는 아닙니다. 많은 Linux 시스템은 마지막 루트 파일 시스템에 액세스하는 데만 사용되는 initramdisks 및 initramfs와 같은 중간 루트 파일 시스템에서 부팅됩니다.
여기서 한 가지 지적해야 할 점은 /proc/cmdline의 내용이 실제로 존재하는 실제 최종 장치 루트일 필요는 없다는 것입니다.
이것은 비지박스(Busybox) 직원이 보낸 것이며 부팅 상황에서 그들이 말하는 내용이 무엇인지 알고 있다고 생각합니다.
https://www.linuxquestions.org/questions/slackware-14/slackware-current-dev-root-688189/page2.html
내가 찾은 두 번째 유용한 리소스는 /dev/root 문제에 관한 아주 오래된 Slackware 스레드였습니다. 해당 스레드가 나온 시점부터 모든 변형이 항상 존재했음을 알 수 있지만 "대부분의" 배포판은 둘 다 기호 링크 방법을 사용한다고 생각합니다. 하지만 그것은 단순한 커널 컴파일 스위치이고 포스터를 올바르게 이해하면 하나를 만들거나 만들지 않을 수 있습니다. 즉, 한 방향으로 전환합니다. readlink /dev/root 실제 장치 이름을 보고하고 다른 장치 이름으로 전환하지만 그렇지 않습니다.
이 스레드의 주요 주제는 /dev/root를 제거하는 방법이므로 실제로 무엇인지, 구성 요소 등을 이해해야 합니다. 즉, 제거하려면 이를 이해해야 한다는 의미입니다.
이를 악물고 설명하면 다음과 같습니다.
/dev/root는 fstab에서 사용할 수 있는 일반 장치입니다. "rootfs"를 사용할 수도 있습니다. 이렇게 하면 덜 구체적으로 지정할 수 있으므로 몇 가지 이점이 있습니다. 내 말은 루트 파티션이 외부 드라이브에 있는 경우 항상 동일한 장치로 표시되지 않을 수 있으며 성공적으로 마운트하려면 올바른 장치와 일치하도록 fstab을 변경해야 한다는 것입니다. /dev/root를 사용하면 lilo 또는 grub의 커널 부팅 매개변수에 지정된 모든 장치와 항상 일치합니다.
/dev/root는 표시되지 않더라도 항상 가상 마운트 지점으로 존재합니다. rootfs의 경우에도 마찬가지입니다(앞에 /dev가 없는 proc 및 tmpfs와 같은 특수 가상 장치와 비교).
/dev/root는 "proc" 또는 "/dev/tcp"와 같은 가상 장치입니다. /dev에는 이러한 장치 노드가 없습니다. 이미 커널에 가상 장치로 존재합니다.
이는 심볼릭 링크가 반드시 존재하지 않는 이유를 설명합니다. 놀랍게도 나는 이 정보를 알아야 하는 몇 가지 프로그램을 유지 관리하기 때문에 이전에는 이 문제를 겪어본 적이 없지만, 안 하는 것보다는 늦는 것이 낫습니다.
나는 여기에 제공된 솔루션 중 일부가 "보통" 작동하고 아마도 내가 할 것이라고 생각하지만 문제에 대한 실제 솔루션은 아니며 busybox 작성자가 지적한 것처럼 매우 복잡한 상황에서 구현하기가 더 복잡합니다. . 견고한 방법.
[업데이트:} 일부 사용자 테스트 데이터를 얻은 후 마운트 방법을 사용할 예정인데, 적어도 어떤 경우에는 괜찮은 것 같습니다. /proc/cmdline은 변형이 너무 많기 때문에 쓸모가 없습니다. 첫 번째 예에서는 이전 접근 방식을 볼 수 있습니다. 이러한 경로는 동적으로 변경(디스크 순서 교체, 새 디스크 삽입 등)되고 갑자기 /dev /sda1로 변경될 수 있으므로 사용(원래 /dev/sdx[0-9] 유형 구문)을 사용하지 않는 것이 좋습니다. /dev/sdb1)이 됩니다.
root=/dev/sda1
root=UUID=5a25cf4a-9772-40cd-b527-62848d4bdfda
root=LABEL=random string
root=PARTUUID=a2079bfb-02
VS는 매우 깨끗하고 구문 분석하기 쉽습니다.
mount
/dev/sda1 on / type ext4 (rw,noatime,data=ordered)
cmdline의 경우 이론적으로 올바른 "답변"의 유일한 변형은 더 이상 사용되지 않는 첫 번째 변형이라는 것을 알 수 있습니다. /dev/sdxy와 같은 모바일 대상에 루트를 참조하면 안 되기 때문입니다.
다음 두 가지에는 /dev/disk/by-uuid 또는 /dev/disk/by-label의 해당 문자열에서 심볼릭 링크를 얻으려면 추가 작업이 필요합니다.
내가 믿는 마지막 요구 사항은 parted -l을 사용하여 parted ID가 가리키는 것이 무엇인지 찾는 것입니다.
이것은 제가 알고 본 변형일 뿐이며 GPTID와 같은 다른 변형도 있을 수 있습니다.
그래서 제가 사용한 해결책은 다음과 같습니다.
먼저 /dev/root가 심볼릭 링크인지 확인하세요. 그렇다면 /dev/disk/by-uuid 또는 by-label이 아닌지 확인하십시오. 그렇다면 최종 실제 경로를 얻기 위해 처리의 두 번째 단계를 수행해야 합니다. 사용하는 도구에 따라 다릅니다.
아무것도 없으면 마운트로 가서 무슨 일이 일어나는지 확인하십시오. 마지막 대체 사례로, 이에 대한 주장이 문제의 실제 파티션이나 장치일 필요도 없고 내 프로그램에 대한 해당 솔루션을 거부하기에 충분하기 때문에 이를 사용하지 않습니다. mount는 완전히 강력한 솔루션은 아니며, 충분한 샘플을 사용하면 이것이 사실이 아닌 경우를 쉽게 찾을 수 있을 것이라고 확신합니다. 하지만 저는 이 두 사례가 "대부분의" 사용자에게 적용된다고 믿으며 이것이 제가 필요한 전부입니다.
가장 좋고, 가장 깨끗하고, 가장 신뢰할 수 있는 해결책은 커널이 항상 심볼릭 링크를 만드는 것인데, 이는 어떤 것이나 누구에게도 해를 끼치지 않고 좋다고 부르지만 현실 세계에서는 그렇게 작동하지 않습니다. .
나는 이것이 모두 "좋거나 강력한" 솔루션이라고 생각하지 않지만 마운트 옵션은 "충분히 좋은" 요구 사항을 충족하는 것으로 보이며 정말 강력한 솔루션이 필요한 경우 busybox가 권장하는 것을 사용하십시오.
답변3
내가 살펴본 시스템에서는 /dev/root
실제 장치에 대한 심볼릭 링크가 있으므로 readlink /dev/root
(또는 readlink -f /dev/root
전체 경로를 원하는 경우) 그렇게 할 것입니다.
답변4
어쩌면 내가 뭔가를 놓친 것일 수도 있지만 다음은 어떻습니까?
mount|grep ' / '|cut -d' ' -f 1