/dev/sda5
또는 와 같은 파일 시스템이 있는 경우 /dev/mmcblk0p5
문자열 조작 없이 파티션 번호( 5
) 및 블록 장치(예: )를 가져오는 것이 가능합니까 /dev/mmcblk0
, 아니면 파티션 번호( ) 및 블록 장치(예:)를 가져오는 데 필요한 문자열 구문 분석 양을 최소화하여 얻을 수 있습니까?
커널이 5.x라고 가정합니다. 아래 예는 5.10을 실행하는 장치에서 가져온 것입니다. 그러나 대답이 커널 또는 구성과 관련된 경우 대답에 이를 표시하십시오.
세부정보/예:
udevadm info
(v247에서) 속성을 포함하여 많은 중요한 정보를 반환합니다 PARTN
. 하지만나는 "속성 X의 값을 인쇄"하는 방법이 있다고 믿지 않습니다. v247(아마도 v251?)에서는 속성과 값을 찾기 위해 출력을 구문 분석해야 합니다. 예를 들면 다음과 같습니다.
udevadm info /dev/disk/by-label/rootfs | grep -e '^E: PARTN=' | awk -F '=' '{print $2}' # prints '2'
udevadm
major
나중에 도움이 될 수 있는 숫자 도 포함되어 있지만 "디스크" 속성이나 이와 유사한 것은 없습니다.
남은 것을 /sys/class/block/mmcblk0p2/partition
제거할 의향이 있다고 가정하고 sysfs 파일을 읽어 파티션 번호를 찾을 수도 있습니다 ./dev/
mmcblk0p2
$ cat /sys/class/block/mmcblk0p2/partition
2
major:minor
같은 방식으로 숫자도 얻을 수 있는 것 같습니다 (최소한의 문자열 토큰을 사용하여).
$ cat /sys/class/block/mmcblk0p2/dev
179:2
/sys/class/block/mmcblk0p2
불행하게도 아래의 어떤 것도 파티션이 있는 블록 장치를 직접 가리키는 것 같지 않습니다 . mmcblk0
이 경우입니다.
이 디스크를 얻으려면 아래의 모든 경로를 검색하여 /sys/block/
파티션이 있는 경로를 찾을 수 있습니다. 즉, /sys/block/mmcblk0/mmcblk0p2
이 경로가 존재합니까? 그렇다면 세 번째 경로 구성 요소, 즉 mmcblk0
디스크가 됩니다.
major
또는 다음과 같이 파티션( 179
이 경우) 의 숫자를 사용할 수 있습니다 .
$ realpath /dev/block/179\:0
/dev/mmcblk0
구문 분석도 가능합니다 /proc/partitions
(다시 문자열 구문 분석!).
$ cat /proc/partitions
major minor #blocks name
..snip..
179 0 7782400 mmcblk0
179 1 96632 mmcblk0p1
179 2 3145728 mmcblk0p2
일부 문자열 스푸핑이 필요하다고 가정할 때 "가장 쉬운"/가장 취약한 방법은 무엇입니까?
배경
여러 분할 구성표를 지원하는 일반 ARM 장치 이미지가 있습니다. 일부 ARM 장치에는 특정 파티션 구성표가 필요한 반면 다른 장치는 하나의 파티션만 사용할 수 있습니다. 디스크를 채우기 위해 rootfs를 확장하는 스크립트가 있습니다.
파티션 크기를 조정하려면 다음을 실행합니다.
sfdisk --no-reread "$DISK" -N "$PART" <<EOF
, $SIZE, L
EOF
그 중에는 예를 들어 DISK=/dev/mmcblk0
및 PART=2
. 그런 다음 우리는 그것을 사용합니다 resize2fs
.
답변1
/sys/block/ 아래의 모든 경로를 검색하여 파티션이 있는 경로를 찾을 수 있습니다.
모든 경로를 검색하는 대신 심볼릭 링크만 읽을 수 있습니다.
$ readlink /sys/class/block/sdb17
[…]/block/sdb/sdb17
$ basename "$(realpath /sys/class/block/sdb17/..)"
sdb
$ basename "$(realpath /sys/class/block/nvme0n1p2/..)"
nvme0n1
또는 다음과 같이 파티션의 주요 번호(이 경우 179)를 사용할 수 있습니다.
파티션 번호가 크면 실패합니다.
$ cat /sys/block/sdb/sdb17/dev
259:1
$ realpath /dev/block/259:0
/dev/sdb16
답변2
udev 규칙을 생성하는 경우 매개변수를 사용하여 규칙에서 스크립트로 환경 변수를 전달할 수 있습니다.
%n
장치의 커널 번호는 어디에 있습니까( 당신에게 주어진 %n
것 입니다 )./dev/sda1
1
%P
상위 장치의 노드 이름은 어디에 있습니까(예: 귀하에게 %P
제공됨 ). 따라서 스크립트에 like를 추가하여 작업을 수행할 수 있습니다 ./dev/sda1
sda
%P
/dev
/dev/%P
따라서 이 작업을 수행하는 간단한 예는 먼저 udev 규칙을 만드는 것입니다(아래 표시된 것보다 장치를 더 잘 식별해야 합니다).
KERNEL=="sd[a-z][0-9]", ACTION=="add", RUN+="/path/to/script.sh %P %n"
그런 다음 그에 따라 스크립트를 편집하십시오.
sfdisk --no-reread "/dev/$1" -N "$2" <<EOF
, $SIZE, L
EOF
$1
어디에 있을 것인가 %P
, $2
어디에 있을 것인가%n
이는 장치가 연결될 때마다 스크립트가 실행되기를 원한다고 가정하지만(이로 인해 ACTION=="add"
). 이는 실행하는 데 시간이 오래 걸리지 않는 스크립트에만 작동합니다(udev는 장기 실행 프로세스를 처리하지 않습니다).
이 문제를 해결하려면 환경 변수를 systemd 인스턴스 유닛에 전달한 다음 스크립트를 호출하면 됩니다.