开发者

iotop script does not work via custom script execution

开发者 https://www.devze.com 2023-04-08 00:03 出处:网络
I have CSF installed (configure safe firewall), it has a function to allow you to have custom scripts executed on load average events.

I have CSF installed (configure safe firewall), it has a function to allow you to have custom scripts executed on load average events.

My script:

##!/usr/bin/env bash
iotop -bto --iter=1 2>&1 | mail -s "$HOSTNAME iotop output" incidents@

It works fine via bash shell but when executed by lfd (the monitoring process of CSF), I get the following output:

Traceback (most recent call last):
  File "/usr/bin/iotop", line 9, in <module>
    from iotop.ui import main
  File "/usr/lib/p开发者_JS百科ython2.6/site-packages/iotop/ui.py", line 13, in
<module>
    from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats
  File "/usr/lib/python2.6/site-packages/iotop/data.py", line 36, in
<module>
    from iotop import ioprio, vmstat
  File "/usr/lib/python2.6/site-packages/iotop/ioprio.py", line 52, in
<module>
    __NR_ioprio_get = find_ioprio_syscall_number(IOPRIO_GET_ARCH_SYSCALL)
  File "/usr/lib/python2.6/site-packages/iotop/ioprio.py", line 38, in
find_ioprio_syscall_number
    bits = platform.architecture()[0]
  File "/usr/lib64/python2.6/platform.py", line 1073, in architecture
    output = _syscmd_file(executable, '')
  File "/usr/lib64/python2.6/platform.py", line 1021, in _syscmd_file
    rc = f.close()
IOError: [Errno 10] No child processes

Can anyone shed some light on this?


Internally it calls an equivalent of:

import os
import sys

f = os.popen('file -b "%s" 2> %s' % (sys.executable, os.devnull))
f.read()
f.close()

For popen() to work it has to be able to get the SIGCHLD signal telling it that a child process exited. It seems that the environment that executes iotop has a custom reaper process that intercepts SIGCHLD and prevents python from getting notified about the process exiting. Thus when the function calls .close(), python tries to kill the process that is already dead and gets an error from the operating system.

If you cannot reconfigure the environment to let SIGCHLD pass, I think you'll have ro resort to ugly hacking.

Wrapping iotop in a script that monkey-patches platform.architecture() with a function that always returns the same tuple (something like ('64bit', 'ELF')—consult the output of real architecture()) should let you progress.

Alternatively, you can just make a local copy of the platform.py file and edit that directly, setting PYTHONPATH for the cron job to point to that new file.


Normally when you have problems automating commands, it's because the thing that's running the command automatically does not have the same environment variables defined (because there's no login). I don't think that's the case here, though. I would sooner suspect the user that the script is running as doesn't have the same rights.

I would try to su to the user CSF is running the script as, and try running it manually as that user.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号