Linux에서 해당 파일을 통해 디스크의 일련 번호를 얻는 방법은 무엇입니까?

Linux에서 해당 파일을 통해 디스크의 일련 번호를 얻는 방법은 무엇입니까?

Linux 디스크의 경우 기본 정보를 얻기 위해 hdparm또는 와 같은 명령을 사용할 수 있다는 것을 알고 있습니다. smartctl하지만 이러한 명령의 구현을 위해서는 Linux에서 디스크에 있는 해당 파일을 읽어서 모두 구현한다고 생각합니다. 예를 들어, 장치의 크기를 얻으려면/dev/sdacat /sys/block/sda/size, 대신 or 같은 명령을 사용할 수 있습니다 . 그렇다면 문제는 디스크에 해당하는 파일을 직접 읽어 디스크의 일련번호를 알아내는 방법이다.hdparmsmartctl

답변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-일반

관련 정보