루트 사용자가 "장치 또는 리소스 사용 중" 응답을 받지 못하는 이유는 무엇입니까?

루트 사용자가 "장치 또는 리소스 사용 중" 응답을 받지 못하는 이유는 무엇입니까?

저는 GSM 모뎀을 사용하고 있으며 /dev/ttyUSB2해당 장치를 사용하고 있습니다.

장치에는 다음과 같은 적절한 권한이 있습니다.

$ ls -alh /dev/ttyUSB2
crw-rw---- 1 root dialout 188, 2 May 25 19:44 /dev/ttyUSB2

나는 dialout그룹에 속해 있으며 이 모뎀에 AT 명령을 한 번만 보낼 수 있습니다. "ATD" 명령( )을 보낸 echo -e -n "ATD ...;\r" > /dev/ttyUSB2lsof /dev/ttyUSB2프로세스 에 따라 이 파일을 열려면 ModemManager다른 AT 명령을 보내면 다음 메시지가 나타납니다.

bash: /dev/ttyUSB2: Device or resource busy

좋아, 어떤 이유로 ModemManager는 파일을 사용 중으로 유지하지만 그런 일이 발생하면 여전히 동일한 방식으로 명령을 보낼 수 있지만 root사용자로부터는 가능합니다.

두 가지 질문이 있습니다.

  1. 루트 사용자가 이 "장치 또는 리소스 사용 중" 잠금을 무시할 수 있는 이유는 무엇입니까?
  2. 일반 사용자가 루트 사용자처럼 우회해야 하는 권한/기타 설정은 무엇입니까?

답변1

최근에 Gentoo로 작업하는 동안 유사한 오류가 발생했습니다 wvdial(올바르게 구성된 커널 사용, usb_modeswitch설정 사용, wvdial 설정이 다른 시스템에서 작동하는지 확인 등). 설명하신 대로 루트는 쉽게 모뎀을 초기화하고 인터넷에 연결할 수 있지만 dialout그룹의 사용자는 귀하와 매우 유사한 오류 메시지를 받게 됩니다. 관련 장치 파일은 다음과 같습니다.

$ ls -l /dev/ttyUSB2
crw-rw---- 1 root dialout 188, 2 Apr  6 01:43 /dev/ttyUSB2

문제는 wvdial이 내 시스템에 있는 /run/lock잠금 파일 아래에 필요한 잠금 파일을 생성 할 수 없다는 것으로 밝혀졌습니다. root:uucp일반 사용자를 에 추가한 후 uucp잠금 파일을 만들 수 있습니다.

$ ls -la /run/lock
drwxrwxr-x  2 root uucp  80 Apr  6 01:43 .
drwxr-xr-x 10 root root 520 Apr  6 01:44 ..
-rw-r--r--  1 foo  foo   11 Apr  6 01:43 LCK..ttyUSB2
[...]

그리고 사용자는 루트처럼 성공적으로 연결할 수 있습니다. (궁금하신 경우 find / -group uucp해당 폴더 외에는 아무것도 반환되지 않습니다.)

저는 ModemManager장치 파일을 직접 쓰거나 읽는 데 익숙하지 않지만(그리고 장치 파일을 직접 쓰거나 읽는 데 익숙하지 않습니다) 설명이 유사하다는 점을 고려하면 일반 사용자를 다른 보충 그룹에 추가해야 할 수도 있다고 생각합니다. 루트로 연결하여 ModemManager에 관련된 다른 파일이 무엇인지 확인하십시오. 그 중 하나(또는 상위 디렉토리)가 문제의 원인일 수 있습니다.

답변2

코드를 보면tty_reopen()Linux 커널 소스 코드의 기능, tty_open_current_tty()자체적으로 호출되고 tty 파일 작업을 위한 함수 tty_open()로 등록됩니다 .open

    if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
        return -EBUSY;

EBUSYTTY_EXCLUSIVEtty가 ( a를 통해 ) 표시되어 프로세스를 실행할 수 없는 경우 ioctl(TIOCEXCL)반환됩니다 CAP_SYS_ADMIN.

tty_ioctl매뉴얼 페이지 에 문서화되어 있습니다 .

독점 모드

TIOCEXCL void
터미널을 독점 모드로 전환합니다. open터미널에서 더 이상 (2) 작업이 허용되지 않습니다. ( EBUSY해당 기능을 갖춘 프로세스를 제외하고는 모두 실패합니다 CAP_SYS_ADMIN .)

TIOCGEXCL int *argp
(Linux 3.8부터) 터미널이 현재 배타적 모드에 있으면 argp가 가리키는 위치에 0이 아닌 값을 배치하고, 그렇지 않으면 *argp에 0을 배치합니다.

TIOCNXCL void
독점 모드를 비활성화합니다.

따라서 여기에서는 실행 중인 (또는 가능한 ) 프로세스를 제외한 다른 프로세스가 장치를 열 수 없도록 장치 ModemManager를 열고 호출할 수 있습니다 .ioctl(TIOCEXCL)rootCAP_SYS_ADMIN

너는 볼 수있어코드의 함수 ioctl()에서 이 작업을 수행합니다.port_connected()이 댓글로:

    /* When the port is connected, drop the serial port lock so PPP can do
     * something with the port.  When the port is disconnected, grab the lock
     * again.
     */

관련 정보