
私は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/ttyUSB2
後、lsof /dev/ttyUSB2
プロセスに従ってこのファイルを開くには、ModemManager
別のATコマンドを送信すると、次のメッセージが表示されます。
bash: /dev/ttyUSB2: Device or resource busy
さて、何らかの理由でModemManagerはファイルを使用していますが、そのようなことが起こった場合でも同じ方法でコマンドを送信できますが、root
ユーザーからは可能です。
2つの質問があります。
- ルートユーザーがこの「デバイスまたはリソースを使用している」ロックを無視できるのはなぜですか。
- 一般ユーザーがrootユーザーのようにバイパスする必要がある権限/その他の設定は何ですか?
答え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
[...]
そして、ユーザーはrootのように正常に接続できます。 (気になる場合は、find / -group uucp
そのフォルダ以外には何も返されません。)
私はModemManager
、デバイスファイルを直接書き込んだり読んだりするのに慣れていませんが(そして、デバイスファイルを直接書いたり読んだりするのに慣れていません)、説明が似ていることを考えると、一般ユーザーを別の補足グループに追加する必要があるかもしれません。ルートとして接続して、ModemManagerに関連する他のファイルが何であるかを確認します。そのうちの1つ(または親ディレクトリ)が問題の原因である可能性があります。
答え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;
EBUSY
TTY_EXCLUSIVE
ttyが(a経由で)表示され、プロセスを実行できない場合にioctl(TIOCEXCL)
返されますCAP_SYS_ADMIN
。
tty_ioctl
マニュアルページに文書化されています。
排他モード
TIOCEXCL
void
端末を排他モードに切り替えます。open
端末では、(2) 操作ができなくなりました。 (EBUSY
その機能を持つプロセスを除いてすべてが失敗しますCAP_SYS_ADMIN
。)
TIOCGEXCL
int *argp
(Linux 3.8以降)端末が現在排他モードにある場合は、argpが指す位置にゼロ以外の値を配置し、そうでない場合は* argpにゼロを配置します。
TIOCNXCL
void
排他モードを無効にします。
したがって、ここでは、実行中の(または可能な)プロセスを除く他のプロセスがデバイスを開けないようにデバイスを開いてModemManager
呼び出すことができます。ioctl(TIOCEXCL)
root
CAP_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.
*/