CherryPy找不到/dev/urandom(或等效文件)--错误。

5

我正在运行一个基于Cherrypy 3.2.0和Python 2.5.1的服务器,但是每隔几天UI会给出如下错误提示,并且需要重启才能继续使用:

[29/Mar/2012:06:37:57] HTTP Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/_cprequest.py", line 636, in respond
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/_cprequest.py", line 97, in run
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/_cprequest.py", line 57, in __call__
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/lib/sessions.py", line 757, in init
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/lib/sessions.py", line 162, in __init__
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/lib/sessions.py", line 190, in _regenerate
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/lib/sessions.py", line 204, in generate_id
File "/usr/lib/python2.5/site-packages/CherryPy-3.2.0-py2.5.egg/cherrypy/_cpcompat.py", line 264, in random20
File "/usr/lib/python2.5/os.py", line 733, in urandom
NotImplementedError: /dev/urandom (or equivalent) not found

`_cpcompat.py`中的以下代码段表明,如果cherrypy无法读取`/dev/urandom`,则会回退到`random.random`,但似乎没有回退。
```html

_cpcompat.py有以下代码,表明如果cherrypy无法读取/dev/urandom,则会回退到random.random,但似乎没有回退。

```
try:
    os.urandom(20)
    import binascii
    def random20():
        return binascii.hexlify(os.urandom(20)).decode('ascii')

except (AttributeError, NotImplementedError):
    import random
    # os.urandom not available until Python 2.4. Fall back to random.random.
    def random20(): 
        return sha('%s' % random.random()).hexdigest()

以下是与上下文相关的来自os.py的代码片段: 如果没有“urandom”:
    def urandom(n):
        """urandom(n) -> str

        Return a string of n random bytes suitable for cryptographic use.

        """
        try:
            _urandomfd = open("/dev/urandom", O_RDONLY)
        except (OSError, IOError):
            raise NotImplementedError("/dev/urandom (or equivalent) not found")
        bytes = ""
        while len(bytes) < n:
            bytes += read(_urandomfd, n - len(bytes))
        close(_urandomfd)
        return bytes

当cherrypy无法读取/dev/urandom时,以下代码片段可以正常工作:

python -c "import os;fd = open('/dev/urandom', 'r');print fd.read(5);fd.close()"

我有两个问题:

  1. 为什么cherrypy会抛出未实现的错误,而我能够从/dev/urandom读取随机位?
  2. 为什么_cpcompact.pyos.py引发NotImplementedError时没有执行except部分?

python -c "import os; print os.urandom(5)" 运行正常吗? - tMC
遗憾的是,它确实会出现这种情况,而CherryPy则表示/dev/urandom未实现! - haltTm
也许权限出了问题? - Sam Dolan
@haltTm:我不知道,我只是随便说了一些东西。 - Sam Dolan
1
我敢打赌,如果你在 os.py 中加入一些调试代码来将异常信息写入系统日志(或其他文件),那将会非常有帮助。 - tMC
3个回答

4

这也不是一个答案,但根据我的经验,当“打开的文件过多”错误在multiprocessing进程开始抛出未捕获异常时,NotImplementedError是错误的,但仍然会出现在子线程或子进程中并悬而未决。

我会从堆栈的更高层次开始调试,并查看是否有由进程引发的 buried 或 silent 异常。

以下是当我开始看到此错误时的堆栈跟踪示例:

Exception in thread Plotter:
Traceback (most recent call last):
  File "threading.pyc", line 532, in __bootstrap_inner
  File "plotters/edge.pyc", line 459, in run
  AttributeError: 'error' object has no attribute 'error'

OSError: [Errno 24] Too many open files
  File "multiprocessing/connection.pyc", line 150, in Client
  File "multiprocessing/connection.pyc", line 370, in deliver_challenge
    None
  File "os.pyc", line 756, in urandom
NotImplementedError: /dev/urandom (or equivalent) not found

我的AttributeError错误最终产生了.../urandom未找到的imlp错误。


1

这不是一个答案,但也许你可以在os.py中加入一些调试代码(我想象不出它会影响任何使用import os的其他程序,但值得记住它是定制的)。

if not _exists("urandom"):
    def urandom(n):
        """urandom(n) -> str

        Return a string of n random bytes suitable for cryptographic use.

        """
        try:
            _urandomfd = open("/dev/urandom", O_RDONLY)
        # debug changes
        except (OSError, IOError) as Err:
            import syslog
            syslog.syslog(repr(Err))
        # /debug
            raise NotImplementedError("/dev/urandom (or equivalent) not found")
        bytes = ""
        while len(bytes) < n:
            bytes += read(_urandomfd, n - len(bytes))
        close(_urandomfd)
        return bytes

希望这能准确地告诉您错误的原因。(当然,您可以将syslog替换为写入文件等操作)


我们可以得出的一个结论是,这是OSErrorIOError。这能对错误类型有所启示吗?当下次发生错误时,我会与您分享结果。 另一个重要问题是,为什么_cpcompat.py没有执行except部分,也就是import random ... - haltTm
OSErrorIOError异常可用于表示任何一种系统错误。引发的异常对象包含了具体的errno,这将非常有用(如权限被拒绝、文件未找到、句柄未打开以供读取等等)。需要捕获这些信息以更好地理解发生了什么。 - tMC
你能帮我处理 Python 2.5 版本的 except(OSError,IOError) as Err 吗?目前,我使用的是 except Exception,e:,虽然我猜测这应该可以达到相同的目的。 - haltTm
错误:(24,“打开的文件太多”)。/proc/cherrypy_pid/fd/ 显示有1049个文件处于打开状态。这是由于我的日志模块中存在一些错误导致的。顺便说一下,对我来说 ulimit -n 返回10240。我想知道是否有进程范围内的限制,限制了它可以打开的文件数量? - haltTm
1
@haltTm 这可能会有所帮助:http://docs.python.org/library/resource.html。否则,您可以在“/etc/security/limits.conf”中系统范围内提高限制。但请记住,如果软件打开但从未关闭句柄,则这只会延长其运行时间,直到耗尽句柄。 - tMC

0
如果您的系统尚未创建/dev/random和/dev/urandom,则可以使用以下命令创建它们:
mknod -m 644 /dev/random c 1 8
mknod -m 644 /dev/urandom c 1 9
chown root:root /dev/random /dev/urandom

在我的系统上,该模块的权限为666。 - Chris Wesseling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接