cdrecord(cdda2wav)のデバッグをしていて、
SCSI pass-throughのioctl() が途中で SIGTERMされると色々腐るので
作者にパッチ送ったんですが、
「まともなOSならioctl()は割り込み不可だ」と
なんか相手にしてもらえません。
割り込み不可ならioctl(2)にEINTRへの言及は
ないと思うんですがあ、実際どうなんでしょ。
えらい人の意見聞いてから反論したいんで。
当方:Sun Ultra1, Solaris2.6 105181-33
個人的にはioctl()も止まってくれないと困る(と思う)
#根本的な問題はシグナルハンドラからioctl()を
#呼んでることのような気が
別件
俺パッチはクリティカルセクションでsigprocmask()使ってSIGTERMなんかを
無視(遅延)するようにしましたが、当然sigprocmask()に移植性はないので、
cdrecordの作者を満足させられそうな割り込み禁止法は
どんな感じでしょうかね(SunOS4あたりでも動く程度の移植性かいな…)
--
kabe
<ka...@sra-tohoku.co.jp> writes:
> 「まともなOSならioctl()は割り込み不可だ」と
> なんか相手にしてもらえません。
>
> 割り込み不可ならioctl(2)にEINTRへの言及は
> ないと思うんですがあ、実際どうなんでしょ。
> えらい人の意見聞いてから反論したいんで。
> 当方:Sun Ultra1, Solaris2.6 105181-33
Linuxのman pageにはEINTRへの言及はないですね(RedHat 7.2)。
(BSD Man Pageとか23 July 1993とか書いてあって、例によって全く信頼でき
ない感じですけど...)
POSIX.1-2001にはERRORSに、
[EINTR]
A signal was caught during the ioctl() operation.
とあります。
(http://www.opengroup.org/onlinepubs/007904975/functions/ioctl.html)
> #根本的な問題はシグナルハンドラからioctl()を
> #呼んでることのような気が
シグナルハンドラからioctl()を呼ぶとどうなるかに関しては、
All functions not in the above table are considered to be unsafe with
respect to signals. ... when a signal interrupts an unsafe function
and the signal-catching function calls an unsafe function, the
behavior is undefined.
(http://www.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_04.html)
とあります。(ioctlはtableに無く、したがってunsafe functionです。)
> 別件
> 俺パッチはクリティカルセクションでsigprocmask()使ってSIGTERMなんかを
> 無視(遅延)するようにしましたが、当然sigprocmask()に移植性はないので、
> cdrecordの作者を満足させられそうな割り込み禁止法は
> どんな感じでしょうかね(SunOS4あたりでも動く程度の移植性かいな…)
sigprocmask()はPOSIX.1-2001には入ってますよ...ってのは移植性があること
にならないかな? SunOS4にはないでしょうけど。
(http://www.opengroup.org/onlinepubs/007904975/functions/sigprocmask.html)
前田敦司
In article <225841420030...@sra-tohoku.co.jp>, <ka...@sra-tohoku.co.jp>
writes
> 「まともなOSならioctl()は割り込み不可だ」と
> なんか相手にしてもらえません。
Linux って割りとシステムコールに割り込まないOSかも知れないで
すね。mt みたいに殺せないプロセスがたくさんあってこまるんだが...
システムコールをソース上でトレースしていっても、なかなか ei
してくれない。ロックかスケジューラにぶつからない限り割り込み
許可しないんじゃないかと思っているんですけど、どうなんでしょう?
> #根本的な問題はシグナルハンドラからioctl()を
> #呼んでることのような気が
これは、また別な問題だよな。でも、そのシグナルハンドラは、
そのシグナルからは保護されているはずですよね。そうではない
「まともでないOS」ってのは、かつてあったわけだけど。
In article <m3n0kzt...@maedapc.cc.tsukuba.ac.jp>, MAEDA Atusi <ma...@cc.tsuk
uba.ac.jp> writes
> 実際のOSの実装でどうなのかは良く知らんので、説得材料になるかどうかは不
> 明ですが...
なんだよね...
> シグナルハンドラからioctl()を呼ぶとどうなるかに関しては、
> All functions not in the above table are considered to be unsafe with
> respect to signals. ... when a signal interrupts an unsafe function
> and the signal-catching function calls an unsafe function, the
> behavior is undefined.
まぁ、そうでしょうね。シグナルハンドラと割り込まれたルーチンを
どう同期させるかは頭がいたい問題ですよね。結局、同期用の変数を
変更するシグナルを自分で発行したりして... これは情けない。
スレッド中心でAPIを考えるなら、
シグナルごとにスレッドを持つようにして、同期はセマフォを使う
ってのがきれいだと思う。
---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)
橋本(つ)です.
NetNews 記事を post できない環境で,google で見たので,メールにて.^^;
>From:ka...@sra-tohoku.co.jp (ka...@sra-tohoku.co.jp)
>Subject:ioctl() は signalで止まらないのか?
>Newsgroups:fj.unix,fj.sys.sun
>Date:2003-02-13 10:09:22 PST
> cdrecord(cdda2wav)のデバッグをしていて、
> SCSI pass-throughのioctl() が途中で SIGTERMされると色々腐るので
確認しますが,上記(↑)は uscsi(7I) の事までは良いとして,これが
次のどちらか,確認されているなら,どちらか教えて下さい.(NetNews 上
「状況説明の補足」として出されても構いません).
(1) SIGTERM に signal handler を設定していて,ioctl(2) の errno が
EINTR になる事を truss(1) ないし,当該 ioctl(2) が -1 を返した直後
perror(3c) を実行した等の手段で確認した.
(2) そうではない? i.e. ioctl() 自体は正常終了しているかも知れない?
あるいは,他の errno で終了しているかも知れない? handler も設定
しておらず,単に process が終了した後,装置の状態がおかしくなった?
という事までしか確認していない?
# (2) なら,EINTR とか ioctl() の割込み云々は,あるいは関係ない話?
#この場合は,作者へのパッチ内容の説明を変更すれば,受け入れられる?
> 作者にパッチ送ったんですが、
> 「まともなOSならioctl()は割り込み不可だ」と
> なんか相手にしてもらえません。
> 割り込み不可ならioctl(2)にEINTRへの言及は
> ないと思うんですがあ、実際どうなんでしょ。
ioctl(2) に限らず,system call が EINTR で終了するのは,それが "slow
system call" i.e.「処理の途中で context switch しうる」場合で,"fast
system call" i.e. この場合,sd(7d) driver 内の関数に渡るまでのどこも
context switch が起りえない処理しかしていない場合,EINTR で復帰する
事はありません.Unix の初期の実装の頃から,disk 上のファイルに対する
アクセス時には read/write/ioctl が fast system call になり,端末及び
network へのアクセスでは slow system call になるといった違いが存在する
事がよくありました.「まともなOSならioctl() は割り込み不可だ」との発言
の真意は「SCSI device への read/write/ioctl は fast system call になる
はず」という意味合いと思います.
さらに「ioctl(2) に EINTR がある」事は,「この特定の場合に EINTR で
エラーになる」事を正当化するとは限りません.
> 当方:Sun Ultra1, Solaris2.6 105181-33
という事であれば,man ioctl すると ERRORS の項目に次のように書いてある
はずで,これは前述のように driver 毎の違いがある事を想定しての注意です.
ioctl() also fails if the device driver detects an error.
In this case, the error is passed through ioctl() without
change to the caller. A particular driver might not have
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
all of the following error cases. Under the following con-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ditions, requests to device drivers may fail and set errno
to:
以上の他,(どう「いろいろ腐る」のか分からないので)下記の最新 sd
driver patch が当たっているかも,多少気になりました.
http://jp.sunsolve.sun.com/pub-cgi/findPatch.pl?patchId=105356&rev=20
橋本 剛 (HASHIMOTO, Tsuyoshi)
P.S. この記事は,全文引用を含め,内容を NetNews 上に引用して構いません.
>> 確認しますが,上記(↑)は uscsi(7I) の事までは良いとして,これが
>> 次のどちらか,確認されているなら,どちらか教えて下さい.(NetNews 上
>> 「状況説明の補足」として出されても構いません).
>>
>> (1) SIGTERM に signal handler を設定していて,ioctl(2) の errno が
>> EINTR になる事を truss(1) ないし,当該 ioctl(2) が -1 を返した直後
>> perror(3c) を実行した等の手段で確認した.
>>
>> (2) そうではない? i.e. ioctl() 自体は正常終了しているかも知れない?
どっちでもなく、gdbで追っかけると
ioctl()の途中で抜け出してシグナルハンドラに飛んでいます。
(ioctlは終了して*いない*)
本来最終的にはioctl()はEINTRで戻ると思われますが、
cdda2wav/libscgがハンドラの最中でabort()で内臓ぶちまけて死ぬので、
くだんのioctl()は結局終了しないまま。
#SCSI直叩きしてるのでデバイスが変な状態のまま放置されてしまう
まあそんなことはどうでもよい。
>> ioctl(2) に限らず,system call が EINTR で終了するのは,それが "slow
>> system call" i.e.「処理の途中で context switch しうる」場合で,"fast
ハードディスクならそーかもしれませんが
スピンアップに数秒かかるような CDROM に対するioctlは
まともなドライバならプリエンプタブルに作るでしょうから、
途中でシグナル受ければEINTRで戻るんじゃないかと踏んでいます。
SCSIなら途中でdisconnectすることもあるし。
>> 最新 sd driver patch が当たっているかも,多少気になりました.
>> http://jp.sunsolve.sun.com/pub-cgi/findPatch.pl?patchId=105356&rev=20
最新cluster当ててます。あまり意味はないようですが
% showrev -p |grep 105356
Patch: 105356-20 Obsoletes: 105797-07 Requires: Incompatibles: Packages: SUNWcsu, SUNWcsr, SUNWhea
#むしろ105486-xx 4141713 system crashes when reading from ISO9660 Joliet cdrom
#のほうが重要だったりして(ハマり経験あり)
--
kabe