Python程序可能导致文件系统错误?

Fut*_*oof 3 python linux sleep udev raspberry-pi

概述:

你好.我有一个python程序,在9-5小时之间控制一个运动传感器.该程序在树莓派上运行,存储在带有西方人v2.1 Debian OS的SD媒体上.该计划在很大程度上依赖于time.sleep方法在非工作时间睡觉,并在第二天上午9点恢复它的职责.如果传感器触发,它会通过网络摄像头自动拍摄一张小图片.

问题:

直到最近该程序工作正常,直到某天有人触发传感器并且take_picture()函数无法初始化/ dev/video0.似乎udev没有将设备映射到/ dev/video*,当我重新插入网络摄像头并用" dmesg | tail " 检查它的状态时,我收到一个错误:

[36725.201116] EXT4-fs error (device mmcblk0p2): udev 
Run Code Online (Sandbox Code Playgroud)

在研究了问题并得出文件系统损坏的结论后,我试图在SD媒体上运行文件系统检查.在该过程中解决了许多错误,但重新安装USB网络摄像头后再次出现相同的EXT4-fs错误消息.

修复尝试#1

此时我重新安装了操作系统并重新运行了我的传感器python程序; 两天它工作,发送图像,睡觉.我假设一切正常,所以我关闭设备将传感器放在更集中的位置.

启动设备并只是从ssh连接运行"python"命令后,我收到此错误:

Traceback (most recent call last):
  File "/usr/lib/python2.7/site.py", line 562, in <module>
    main()
  File "/usr/lib/python2.7/site.py", line 544, in main
    known_paths = addusersitepackages(known_paths)
  File "/usr/lib/python2.7/site.py", line 271, in addusersitepackages
    user_site = getusersitepackages()
  File "/usr/lib/python2.7/site.py", line 246, in getusersitepackages
    user_base = getuserbase() # this will also set USER_BASE
  File "/usr/lib/python2.7/site.py", line 235, in getuserbase
    from sysconfig import get_config_var
ImportError: cannot import name get_config_var
Run Code Online (Sandbox Code Playgroud)

在程序运行的时间和重新启动之间没有更改任何设置.我假设最坏的并再次检查"dmesg | tail"并收到更多的文件系统错误:

[36725.201116] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[36725.239030] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)
Run Code Online (Sandbox Code Playgroud)

在额外的文件系统检查并重新启动后,运行"python":

[  819.427780] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[  819.470874] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)
[  819.570893] EXT4-fs error (device mmcblk0p2): ext4_xattr_block_get:232: inode #21265: comm python: bad block 128
Run Code Online (Sandbox Code Playgroud)

在这一点上,我认为这些错误的原因可能与我的程序的核心有关,但实质上它很简单,只在创建图片时写入磁盘.以下是罪魁祸首代码:

潜在问题的代码:

def take_picture():
    cam = pygame.camera.Camera("/dev/video0",(320,240))  #1280x960 max but slow
    pygame.init()
    cam.start()
    print "Capturing Image..."
    image_output = cam.get_image()
    pygame.image.save(image_output,'img_' +str(get_timestamp)+'.jpg')
    cam.stop()

#activate PIR
def pir_init():
    while True:
        m = datetime.datetime.now().time().minute    #loop through for current time
        h = datetime.datetime.now().time().hour
        d = datetime.datetime.today().weekday()
        if d > 4:
            print("Sleeping...")
            print time_sleep
            time_sleep = (((7 - d) * 3600) * 24) - (h * 3600) + (9 * 3600)
            time.sleep(time_sleep)
        elif h < 9:                                         
            print("Sleeping...")
            time_sleep = (9 - h) * 3600
            time.sleep(time_sleep)
        elif h > 16:
            print("Sleeping...")
            time_sleep = ((24 - h) + 9) * 3600
            time.sleep(time_sleep)
        elif io.input(pir_pin):
            print("PIR ALARM")
            pygame.camera.init()
            time.sleep(1.5)
            take_picture()
            send_gmail()   
            time.sleep(10)      #cooldown to prevent email spew
        else:
            print "Waiting..."
            time.sleep(0.5)     #sleep and wait for movement
            print m
print "Wait"
Run Code Online (Sandbox Code Playgroud)

我上面可以看到的唯一潜在问题可能是生成图片或长时间睡眠.

任何洞察可能导致这些重复文件系统错误的内容都将受到赞赏.提前致谢!

ean*_*son 5

SD卡在Raspberry Pi上损坏是很常见的,这段代码不能直接导致这种情况.

我认为代码会导致我看到的问题的唯一原因是它是否经常尝试写入SD卡,这不太可能并且很可能是由潜在问题引起的.也许SD卡坏了,或来自坏的批次.

如果您只是将这些作为电子邮件发送,则可能是不将图片存储在硬盘驱动器上的替代方法.或者您可以添加USB硬盘驱动器或记忆棒,并使用它来存储图片.

您也可以缓存图片并一次写出一对,而不是直接写出每个图片以减少SD卡的负载.这就像在内存中存储5个图片一样简单,一旦你拍了5张图片就把它们写出来.

pictures = {}
pictures[get_timestamp] = image_output
Run Code Online (Sandbox Code Playgroud)

然后,一旦总共有五个条目循环遍历它们,使用该键生成文件名,而值包含实际图片.然后,将所有五个保存在硬盘上.

如果您有512MB版本,您可以增加存储在内存中的图片数量,但请记住,如果出现电源故障,您将丢失内存中的任何内容

  • **更新**:SD卡是罪魁祸首.我对新的(金士顿SDHC 8FB Class 10)卡进行了压力测试,以至于我的G-mail帐户收到了200多封电子邮件,因此将我锁定.到目前为止,没有发生文件系统错误.再次感谢. (2认同)