Script launched from rule udev stays zombie when launching a new process

4

I'm trying to use a udev rule to launch a dbus client from a script.

The udev rule will jump when a pendrive is connected, and execute the script usbdevinserted.sh , which will copy the identifier of the pendrive to a file and launch the dbus client

The udev rule is this:

 KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", RUN+="/usr/bin/pendrive-reminder/usbdevinserted.sh"

The code of usbdevinserted.sh this:

set 2>&1 | grep DEVPATH | cut -d "=" -f 2 >> /tmp/usbdevinfo

#Get list of users with graphic session started, and their active display 
userdisplay=$(who | gawk '/\(:[[:digit:]](\.[[:digit:]])?\)/ { print $1 ";" substr($NF, 2, length($NF)-2) }' | uniq)

#for each user, show notification and (only in polkit >= 106) launch dbus client 
for element in $userdisplay
do          
    #get username       
    user=$(echo $element | cut -d ";" -f 1)

    #get display active of this user        
    export DISPLAY=$(echo $element | cut -d ";" -f 2)

    #Send notification to user
    su $user -c 'notify-send "Pendrive Reminder" "Shutdown lock enabled. The shutdown will be unlocked when pendrive is disconnected"'
    #if polkit version >=106, also launch dbus client
    if test $polkit_version -ge 106
    then
        su $user -c 'python /usr/bin/pendrive-reminder/client.py' &
    fi
done

And the dbus client ( client.py ) is this:

#!/usr/bin/python3
from gi.repository import GLib
from gi.repository import Notify
import dbus
from dbus.mainloop.glib import DBusGMainLoop

dbus_loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus(mainloop=dbus_loop)
loop = GLib.MainLoop()

def msg_handler(*args,**keywords):
    try:
        #show notification to desktop
        Notify.init('Pendrive Reminder')
        notify = Notify.Notification.new('Pendrive Reminder', 'Shutdown lock enabled. Disconnect pendrive to enable shutdown')
        notify.show()
    except:
        pass

bus.add_signal_receiver(handler_function=msg_handler, dbus_interface='org.preminder', path_keyword='path')
loop.run()

The idea is that the script ( usbdevinserted.sh ) ends, leaving the dbus client running. I have tried launching it manually from the terminal, and it works fine: the script ends and leaves the dbus client running.

But, when I launch the script from the udev rule, the script, even after executing its sequence of instructions, stays zombie and does not die until after a few minutes, time in which it leaves udev blocked.

And, if I launch the script from udev, removing the part where the dbus client is launched ( client.py ), the script ends correctly without being zombie.

Do you know where the problem may be?

UPDATE

As I have indicated in the comments, I have tried with:

su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & | at now

But now the dbus client does not get launched (or dies next to the script) I've also tried with:

su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & - batch

But the script does not end (not even as a zombie)

And with:

su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & - at

the script becomes zombie again until a few minutes later

    
asked by AlmuHS 31.03.2018 в 22:42
source

1 answer

3

Solved:

I have created a file, with the commands that I have to launch, and I have launched it with at -f fichero

The script looks like this:

set 2>&1 | grep DEVPATH | cut -d "=" -f 2 >> /tmp/usbdevinfo

#Get list of users with graphic session started, and their active display 
userdisplay=$(who | gawk '/\(:[[:digit:]](\.[[:digit:]])?\)/ { print $1 ";" substr($NF, 2, length($NF)-2) }' | uniq) 


#Get polkit version
polkit_version=$(pkaction --version | cut -d " " -f 3 | cut -d "." -f 2)

#for each user, show notification and (only in polkit >= 106) launch dbus client 
for element in $userdisplay
do          
    #get username       
    user=$(echo $element | cut -d ";" -f 1)

    #get display active of this user        
    export DISPLAY=$(echo $element | cut -d ";" -f 2)

    #Send notification to user
    su $user -c 'notify-send "Pendrive Reminder" "Shutdown lock enabled. The shutdown will be unlocked when pendrive is disconnected"'

    #if polkit version >=106, also launch dbus client
    if test $polkit_version -ge 106
    then
        #To avoid udev lock after launch dbus client, launch client as task

        #Creates a temporally file, with commands to launch in the task 
        echo "export DISPLAY=$DISPLAY" > at_task        
        echo "/usr/bin/pendrive-reminder/client.py" >> at_task                      

        #Launch task with at command
        su $user -c 'at -f at_task now'
    fi
done

Thanks @aloMalbarez !!

    
answered by 31.03.2018 / 23:59
source