一部のLinux環境で複数ユーザがIDLを同時起動できない問題点とその回避策について
米国本社のフォーラムにて確認されたLinux環境でのIDLの起動不具合を本ブログにて周知します。
発生する現象について
1つのマシンでIDLを起動できるのが1ユーザまでにOS側で制限されます。
2ユーザ目からは起動時に以下のエラーとなり、IDLのライセンスが取得できません。
(null): [1,7e1,8,0[74100008,1,1202014d]]
Internal. : Internal. (code : 1947205640)
(cll_internal.cpp : 498) (code : 1947205640) (CLLFloatingLicenseThread.cpp : 473)
CLLFloatingLicenseInitialize failed to start the license thread.
Unable to obtain an IDL license.
本現象の対象となる可能性のあるお客様
以下のすべての条件を満たすお客様はこの問題が発生する可能性があります。
- Linux環境でIDLを使用している
- OSのkernelバージョンが 4.19 以上である[1]
- systemd (システムデーモン) のバージョンが 241 以上である[2]
[1] 使用しているKernelのバージョンは以下のコマンドで確認してください。
# uname -r
[2] 使用しているsystemdのバージョンは以下のコマンドで確認してください。
# journalctl --version
この問題の回避策
以下のコマンドを実行することで、デフォルトのファイル保護機能の設定を更新してください。
# sysctl fs.protected_regular=0
回避策に関する技術的な詳細
Linux4.19以降ではFIFO/regular fileの保護機能が強化されており、systemd-241以降ではこの保護機能がデフォルトで有効になっています。
参考: Systemd 241 Paired With Linux 4.19+ To Enable New Regular File & FIFO Protection
# sysctl fs.protected_regular = 1
通常の動作として、IDLを実行した最初のユーザー(ここではuser11)が/tmpディレクトリの下にfne.XXXXファイルを作成します。
# ls -al /tmp
drwxrwxrwt 27 root root 860 Mar 21 15:07 .
drwxr-xr-x 25 root root 301 Mar 14 10:49 ..
-rwxrwxrwx 1 user11 grp11 0 Mar 21 14:16 /tmp/fne.erkueytuierytierutyertiuertyeriuteyriuteryituyer
★fne*のユーザ権限がuser11
次に、2番目のユーザーがIDLを起動すると、次のメッセージが表示されます。
(null): [1,7e1,8,0[74100008,1,1202014d]]
Internal. : Internal. (code : 1947205640)
(cll_internal.cpp : 498) (code : 1947205640) (CLLFloatingLicenseThread.cpp : 473)
CLLFloatingLicenseInitialize failed to start the license thread.
Unable to obtain an IDL license.
このエラーについてstraceを確認すると、openat(O_CREAT)システムコールが失敗したことが示されています。
(2行目でpermissionによるエラーが発生していることが確認できます)
1578 stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=880, ...}) = 0
1578 openat(AT_FDCWD, "/tmp/fne.erkueytuierytierutyertiuertyeriuteyriuteryituyer", O_WRONLY|O_CREAT, 0777) = -1 EACCES (Permission denied)
1578 futex(0x7fd6798101a0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
1578 munmap(0x7fd678288000, 12925792) = 0
1578 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2696, ...}) = 0
1578 write(2, "(null): [1,7e1,8,0[74100008,1,1202014d]] Internal. : Internal. (code : 1947205640) (cll_internal.cpp : 498) (code: 1947205640) (CLLFloatingLicenseThread.cpp : 473)", 164) = 164
1578 write(2, "\n", 1) = 1
1578 write(2, "CLLFloatingLicenseInitialize", 28) = 28
1578 write(2, " failed to start the license thread.", 36) = 36
これを回避したい場合、次の方法でデフォルトの保護設定を更新・無効にします。
これによって2ユーザ目以降もIDLを起動できるようになります。
# sysctl fs.protected_regular=0