Linux 디스크의 경우 기본 정보를 얻기 위해 hdparm
또는 와 같은 명령을 사용할 수 있다는 것을 알고 있습니다. smartctl
하지만 이러한 명령의 구현을 위해서는 Linux에서 디스크에 있는 해당 파일을 읽어서 모두 구현한다고 생각합니다. 예를 들어, 장치의 크기를 얻으려면/dev/sdacat /sys/block/sda/size
, 대신 or 같은 명령을 사용할 수 있습니다 . 그렇다면 문제는 디스크에 해당하는 파일을 직접 읽어 디스크의 일련번호를 알아내는 방법이다.hdparm
smartctl
답변1
나는 단지 그것을 시도하고 있습니다. ioctl을 통해 일련번호를 얻습니다. 다음은 strace의 일부 출력입니다.
open("/dev/sda", O_RDONLY|O_NONBLOCK) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=20000, flags=0, data[36]=["\0\0\5\2[\0\0\0ATA WDC WD5000LPVX-0"...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[16]=[85, 08, 0e, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, ec, 00], mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=20000, flags=0, data[512]=["zB\377?7\310\20\0\0\0\0\0?\0\0\0\0\0\0\0 W -DXW11"...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[16]=[85, 08, 0e, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, ec, 00], mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=20000, flags=0, data[512]=["zB\377?7\310\20\0\0\0\0\0?\0\0\0\0\0\0\0 W -DXW11"...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
답변2
적어도 내 시스템에서는 가능합니다. 이 솔루션은 /run/udev/data
데이터 덤프에 의존합니다.
다음은 bash 스크립트의 예입니다.
#!/bin/bash
IFS=$'\n' read -d '' -r -a DRIVES <<< "$(ls /dev/sd*[0-9] 2>/dev/null)"
IFS=$'\n' read -d '' -r -a NVME_DRIVES <<< "$(ls /dev/nvme*[0-9]n[0-9] 2>/dev/null)"
DRIVES+=("${NVME_DRIVES[@]}")
for drive in "${DRIVES[@]}"; do
drive=${drive##*/}
IFS=$'\n' read -d '' -r -a _uevent <<< "$(grep -e "MAJOR" -e "MINOR" "/sys/class/block/${drive}/uevent"| sort | awk -F "=" '{print $2}')"
_serial=$(grep "ID_SERIAL=" "/run/udev/data/b${_uevent[0]}:${_uevent[1]}" | awk -F "=" '{print $2}')
echo "[${drive}] serial: ${_serial} short: ${_serial##*_}"
done
스크립트의 논리는 다음과 같습니다.
- 시스템의 드라이브 목록 가져오기
- 각 드라이브 장치의 블록 주소를 읽습니다.
- udev 메타데이터에서 데이터 가져오기
단계는 strace에서 공제됩니다.lsblk --nodeps -no serial /dev/sda
답변3
strace를 사용하여 smartctl이 디스크의 일련 번호를 얻는 방법을 확인할 수 있습니다. CMD 라인은 다음과 같습니다: strace smartctl -a /dev/sda. 어쩌면 ioctl을 통해 일련 번호를 얻는 것일 수도 있습니다.
답변4
Linux의 디스크 sda:
egrep '^E:ID_SERIAL' /run/udev/data/b$(basename $(readlink --canonicalize /sys/block/sda/bdi)) E:ID_SERIAL=삼성_SSD_850_EVO_500GB_S3R3NF0JA99600T E:ID_SERIAL_SHORT=S3R3NF0JA99600T
날짜&& uname --kernel-release 2021년 11월 2일 화요일 오전 11:50:37 PDT 5.13.0-20-일반