1

Linux プラットフォームの ctypes Python モジュールを介して C 共有オブジェクト ライブラリにアクセスする Python アプリケーションがボトル Web サーバーにあります。C so-lib は、デバイス ノード ( ) を開き、/dev/myhwdevデバイスのファイル記述子に対して IOCTL 関数をアサートします。これは複雑なスタックですが、次のように Python の python-daemon コンテキストでボトル アプリをラップするまではうまく機能します。

# -*- coding: utf-8 -*-
import daemon
import bottle
from bottle import run, route, request

from userlib_via_ctypes_module import *
userlib_grab_device_file_descriptor()

@route('/regread')
def show_regread():
    address = request.query.address or request.forms.address
    length = request.query.length or request.forms.length
    return {'results':assert_ioctl_via_userlib(address, length)}

daemonContext = daemon.DaemonContext(
    detach_process = False
    )
with daemonContext:
    try:
        run(host = '0.0.0.0', port = '80', debug = True)
    except:
        print "(E) Bottle web-service was stopped.\n";

行をコメントアウトwith daemonContext(およびインデントを修正) するだけで、このコードは正しく機能します (つまり、正しい JSON 結果を提供します)。ただし、daemonContext 内で、userlib の print ステートメントは、デバイス ノードのファイル記述子が正しく開かれていることを示していますが、ioctl 関数はエラー コード -1 でサイレントに失敗します。

デバイスのファイル記述子を閉じて、(userlib コードまたは上記のルート ハンドラのいずれかで) 再度開くと、コマンドが正しく動作するようになります。しかし、デーモンとボトル サーバーがロックし、それ以降のすべての Web リクエストを無視します。

提案?現在、すべてが正常に機能するため、デーモン モジュールをあきらめる準備ができています。

ありがとう!

4

1 に答える 1

1

この質問を準備する中で、答えが明らかになりました。

このuserlib_grab_device_file_descriptor()関数は、userlib ioctl 関数に渡されたハードウェア デバイス ノードのファイル記述子を開く C レベルの SO-lib 関数を呼び出しました。

python-daemon は、コンテキストに入るとすべてのファイルハンドルを閉じます - ハードウェアデバイスの継承されたファイル記述子を含みます。userlib は、まだファイル記述子が有効であると考えていました。少なくとも、デバッグ メッセージに FD が 2 より大きい整数として出力されます。ただし、ユーザー ライブラリには知られていないため、ファイル ハンドルが実際に閉じられているため、IOCTL は黙って失敗します。uclib またはカーネルによって提供されるより良いエラー メッセージがあればよかったのにと思います。:(

とにかく、答えは次のように、ファイルハンドルの開始をデーモンコンテキストの内部に移動することでした:

...
with daemonContext:
    try:
        userlib_grab_device_file_descriptor()   # open fd here
        run(host = '0.0.0.0', port = '80', debug = True)
    except:
        print "(E) Bottle web-service was stopped.\n";

python-daemon のfiles_preserve属性を使用してみましたが、ファイル名ではなくファイル記述子番号で機能します。したがって、fd を開いた後、userlib は fd 番号をデーモンに渡す必要があるため、デーモンに入る前に fd を除外できます。...デーモンのファイル記述子を開く方が簡単であることがわかりました。:)

これが他の誰かに役立つことを願っています。:)

于 2012-06-28T22:18:19.037 に答える