Results 1 to 8 of 8

Thread: Script run from udev rule gets killed shortly after start

  1. #1
    Join Date
    Jun 2012
    Location
    Naoussa, Imathia, Greece
    Posts
    6

    Default Script run from udev rule gets killed shortly after start

    Hi everyone.
    I've written a udev rule to backup data in a usb stick when plugged in (that is backup data FROM usb to HDD).
    Before updating to 12.3 the script worked fine. I can't recall if something else came in the way, but after updating the script gets killed shortly after starting. The device mounts, rsync starts and the detached script gets killed killing rsync and leaving the device mounted.

    Any pointers as to what might be going wrong?

    The rule is:
    Code:
    KERNEL=="sd?1", ACTION=="add", SUBSYSTEMS=="scsi", ATTRS{vendor}=="JetFlash", ATTRS{model}=="Transcend 4GB   ", RUN+="/usr/local/bin/backupUSB.sh %k"
    The script is:
    Code:
    #!/bin/bash
    {
        # Log beggining of backup
        /usr/bin/logger USB Backup - Beginning at `date`
        # if needed, create the mount directory
        if [ ! -d /mnt/backup ] ; then mkdir /mnt/backup ; fi
    
    
        /bin/mount -t vfat -o shortname=mixed,iocharset=utf8 /dev/$1 /mnt/backup
    
    
        # Backup command using RSync
        rsync -avh --progress --modify-window=2 /mnt/backup/** /home/diggy/backups/TrancendBackup/ > /tmp/usblog.txt
    
    
        # force sync of files to disk before unmounting
        /bin/sync
    
    
        # unmount the backup disk
        /bin/umount /mnt/backup
    
    
        # Log end of backup
        /usr/bin/logger USB Backup - End at `date`
    } &

  2. #2
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    15,254

    Default Re: Script run from udev rule gets killed shortly after start

    Does the log file contain any useful errors? I note that you mount the device, then rsync immediately afterwards. I wonder if a small delay is required to guarantee the operation?

  3. #3

    Default Re: Script run from udev rule gets killed shortly after start

    That won't work. RUN is for short program invocations only and udev enforces this. Also, it would have been killed by systemd anyway when parent udev exits.

    The clean way to do it using modern systemd/udev infrastructure.

    1. Create systemd service that starts you backup script on request. Do not put it in background! I.e. remove { ... } & wrapper. Otherwise system will believe your script finished as soon as it is started:
    Code:
    bor@opensuse:~> cat > /etc/systemd/system/backup\@.service << EOF
    [Unit]
    Description=Backup to USB Flash Disk
    BindsTo=dev-%i.device
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/backupUSB.sh %I
    EOF
    bor@opensuse:~> systemctl daemon-reload
    This is template unit (it has "@" in its name). Later you will dynamically instantiate template by calling it with device name. You refer to device name using %i and %I placeholders (latter is capital "i" not small "L"). BindsTo ensure service is stopped when device in unplugged.

    2. Create udev rule to start service when device in plugged in.
    Code:
    bor@opensuse:~> cat > /etc/udev/rules.d/99-backup.rules << EOF
    KERNEL=="sd?1", ACTION=="add", SUBSYSTEMS=="scsi", ATTRS{vendor}=="JetFlash", ATTRS{model}=="Transcend 4GB   ", RUN+="/usr/bin/systemctl --no-block start backup@%k.service"
    EOF
    bor@opensuse:~> udevadm control --reload
    Now when you plug in USB stick service backup@sdX1.service should be started. You can check status using "systemctl status backup@sdX1.service".

  4. #4
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    15,254

    Default Re: Script run from udev rule gets killed shortly after start

    Quote Originally Posted by arvidjaar View Post
    That won't work. RUN is for short program invocations only and udev enforces this. Also, it would have been killed by systemd anyway when parent udev exits.

    The clean way to do it using modern systemd/udev infrastructure.

    1. Create systemd service that starts you backup script on request. Do not put it in background! I.e. remove { ... } & wrapper. Otherwise system will believe your script finished as soon as it is started:
    Code:
    bor@opensuse:~> cat > /etc/systemd/system/backup\@.service << EOF
    [Unit]
    Description=Backup to USB Flash Disk
    BindsTo=dev-%i.device
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/backupUSB.sh %I
    EOF
    bor@opensuse:~> systemctl daemon-reload
    This is template unit (it has "@" in its name). Later you will dynamically instantiate template by calling it with device name. You refer to device name using %i and %I placeholders (latter is capital "i" not small "L"). BindsTo ensure service is stopped when device in unplugged.

    2. Create udev rule to start service when device in plugged in.
    Code:
    bor@opensuse:~> cat > /etc/udev/rules.d/99-backup.rules << EOF
    KERNEL=="sd?1", ACTION=="add", SUBSYSTEMS=="scsi", ATTRS{vendor}=="JetFlash", ATTRS{model}=="Transcend 4GB   ", RUN+="/usr/bin/systemctl --no-block start backup@%k.service"
    EOF
    bor@opensuse:~> udevadm control --reload
    Now when you plug in USB stick service backup@sdX1.service should be started. You can check status using "systemctl status backup@sdX1.service".
    Nice answer arvidjaar. Many backup methods rely on the former udev/script strategy, so others are bound to fall into this trap too. I will remember this post for future reference.

  5. #5
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    20,833

    Default Re: Script run from udev rule gets killed shortly after start

    Yes, very illuminating example on how to use systemd/udev.
    Henk van Velden

  6. #6
    Join Date
    Jun 2012
    Location
    Naoussa, Imathia, Greece
    Posts
    6

    Default Re: Script run from udev rule gets killed shortly after start

    First of all thank you all for your prompt replies.

    @deano_ferrari

    Thanks for the interest. No errors or info in the log whatsoever.

    @arvidjaar
    SOOO elegant solution. I didn't have any idea I could make it work with systemd.
    Works as promised!
    Two questions though:
    1) When plugging in the device, it mounted instantly in KDE and unmounted before I the service starts. No major issue here. In the other hand the device still is available for mount in KDE. Haven't tried it but I'm assuming that trying to mount while the backup service runs will fail, right?

    2) I want to have a visual indication as to when the backup starts (so as not to try to mount it) and ends (so that I can mount and use it). I found someone used notify-send setting the missing DBUS_SESSION_BUS_ADDRESS env here: Ubuntu: backup to USB drive on mount | Ninetynine.be

    Would you say this is a lean way to do it or should I find some other way?

    Thank you in advance.

  7. #7

    Default Re: Script run from udev rule gets killed shortly after start

    Quote Originally Posted by diggy128 View Post

    1) When plugging in the device, it mounted instantly in KDE and unmounted before I the service starts.

    I understand that it is mounted, but I'm surprised it is unmounted, I do not know who does it.
    No major issue here. In the other hand the device still is available for mount in KDE. Haven't tried it but I'm assuming that trying to mount while the backup service runs will fail, right?


    As your script mounts device, I expect udisks (and user session disk managers using it) will notice that fact and won't offer to mount partition again. You can also prevent automount by setting ENV{UDISKS_AUTO}="0" or set it to be completely ignored by setting ENV{UDISKS_IGNORE}="1" device property in udev rule. I assume KDE in 12.3 finally switched to using udisks2.


    2) I want to have a visual indication as to when the backup starts (so as not to try to mount it) and ends (so that I can mount and use it). I found someone used notify-send setting the missing DBUS_SESSION_BUS_ADDRESS env here: Ubuntu: backup to USB drive on mount | Ninetynine.be

    Would you say this is a lean way to do it or should I find some other way?

    I guess it will work. Unfortunately this is the same problem as with running X11 program outside of user context - you need to know DBUS session address (X11 DISPLAY number) before you can try to communicate. The clean way is to have some small program started in user session and listening on system bus for signals and forwarding them to local session notification manager. Signals are broadcast to all users so sending program does not really need to know how many listeners there are nor their address. But solution described in the link will do as well as long as you need to notify only one and the same user always.

  8. #8
    Join Date
    Jun 2012
    Location
    Naoussa, Imathia, Greece
    Posts
    6

    Default Re: Script run from udev rule gets killed shortly after start

    Worked like a charm.
    Now I have my rsync based backup working fine and with KDE notifications in place.

    Thank you!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •