Page 1 of 3 123 LastLast
Results 1 to 10 of 27

Thread: Writing udev Rules

  1. #1
    Join Date
    Mar 2009
    Beans
    927
    Distro
    Ubuntu 12.04 Precise Pangolin

    Post Writing udev Rules

    Problem: Looks like the drive is mounted after the script has finished. If anyone knows a fix for this, please post a message here.

    Detect the USB
    Firstly you'll need to set up a system to detect when your USB drive is plugged in, and run a script when it is. We will use udev to achieve this.

    Create the file /etc/udev/rules.d/91-local.rules and copy this into it:
    Code:
    SUBSYSTEMS=="usb", KERNEL=="sd??", ACTION=="add", RUN+="/usr/local/bin/USB %k"
    This will run a script located at /usr/local/bin/USB and pass it %k (the kernel name for the device detected).


    Now we'll need to test that this works - create a script at /usr/local/bin/USB and copy this into it:
    Code:
    #!/bin/bash
    echo 'Hello World!' >>"/home/<username>/Desktop/udev.out"
    exit
    (obviously replacing <username> with your username)
    Now add the execute bit (sudo chmod +x /usr/local/bin/USB), and finally test that everything works by plugging in a USB drive. If everything does work you should see a file called udev.out appear on your desktop, upon opening it you should see that it contains the text 'Hello World!' Do not continue until this part of the system works.


    Find Your USB Identifier
    We will need a way to identify your USB so that we can treat it differently to other USBs. If you do not plan to give your USB any special treatment, feel free to skip to the next section.
    We will use the disk identifier to identify your USB, you can find this by plugging in your USB and running sudo fdisk -l - if you're not sure which one in the list is yours then look at the amount of GBs and the number of partitions each disk has.


    Create the Backup Script
    Finally the actual backup script (/usr/local/bin/USB), you can write your own in a language of your choice, or use mine, written in bash. If you use mine you'll have to change the variables at the top and install rsync. Here it is:

    [BASH]
    PHP Code:
    #!/bin/bash
    exec &> /var/log/udev-USB

    MY_DRIVE_UUID
    ='????-????'  # My USB disk identifier
    OUT='/home/bob/USB-Backup'  # Where the backups are stored
    SIZE_LIMIT='1GB'  # Size gets rounded to nearest unit
    USERNAME='bob'  # Username to chown the backup to

    function error { echo "$@, aborting." >&2; exit 1; }

    drive_kernel="${1}"
    if [ -"${drive_kernel}]; then error "Could not detect drive kernel"fi
    echo "drive_kernel=${drive_kernel}"

    drive_uuid=$(blkid -/dev/null -o value -s UUID /dev/${drive_kernel})
    if [ -
    "${drive_uuid}]; then error "Could not detect drive UUID"fi
    echo "drive_uuid=${drive_uuid}"
    if [ "${drive_uuid}!= "${MY_DRIVE_UUID}]; then error "Not my drive"fi  # Only backup my drive

    drive_size=`df -B "${SIZE_LIMIT}" | grep "^/dev/${drive_kernel}" | awk '{print $3}'`
    if [ -
    "${drive_size}]; then error "Could not detect drive contents"fi
    echo "drive_size=${drive_kernel}"
    if [ "${drive_size}]; then error "Drive contents too big"fi

    drive_mountpoint
    =`df | grep "^/dev/${drive_kernel}" | awk '{print $6}'`
    if [ -
    "${drive_mountpoint}]; then error "Could not detect drive mountpoint"fi
    echo "drive_mountpoint=${drive_mountpoint}"

    if [ ! -"${OUT}]; then mkdir -"${OUT}"fi  # If $OUT does not exist, then make it

    if [ "${drive_uuid}== "${MY_DRIVE_UUID}]
    then
        rsync 
    -ac "${drive_mountpoint}/""${OUT}/My USB/" &&\
        
    chown -"${USERNAME}" "${OUT}/My USB/"
    else
        
    rsync -ac "${drive_mountpoint}/""$OUT/${drive_uuid}/" &&\
        
    chown -"${USERNAME}" "${OUT}/${drive_uuid}/"
    fi

    exit $? 

    P.S.
    If you have any trouble following this guide or want to offer a suggestion on how it could be improved, please just post here. If it helped you, add a few tags - it makes it easier for other people to find it that way.

    See Also: http://www.reactivated.net/writing_udev_rules.html.
    Thanks to flaconindy.
    Last edited by Penguin Guy; September 9th, 2010 at 07:50 PM.

  2. #2
    Join Date
    Sep 2006
    Location
    France.
    Beans
    Hidden!
    Distro
    Lubuntu Development Release

    Re: Writing udev Rules

    Sorry it took so long for the tutorial to be approved. Thanks for you patience

  3. #3
    Join Date
    Mar 2009
    Beans
    927
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Writing udev Rules

    Quote Originally Posted by bapoumba View Post
    Sorry it took so long for the tutorial to be approved. Thanks for you patience
    Oops, after waiting a month I figured something must have gone wrong so I re-posted it here. Sorry.

    Edit: Fixed, I got a mod to jail the duplicate.
    Last edited by Penguin Guy; November 7th, 2009 at 03:56 PM.

  4. #4
    Join Date
    Oct 2008
    Beans
    12

    Re: Writing udev Rules

    Hi,

    I am currently strugling with an udev rule that used to waork correctly under Jaunty (now I use Karmic).
    It is quite similar to the ones above, but it is for me impossible to get the mount point of the USB device. It seems that my USB device is only mounted in its final mountpoint (/media/whatever) only AFTER my programm has finished executing.
    So when I execute my programm, I can't retreive the mount point ! It does not exists ! If I wait x seconds, then try to obtain the mount point (by reading /etc/mtab or doint something like df | grep /dev/sdd1 | awk '{print $6}' ) I can't retreive it !
    Does anybody is in the same situation as me ? Anybody knows a way to get the final mountpoint in a script and access it ?

  5. #5
    Join Date
    Mar 2009
    Beans
    927
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Writing udev Rules

    @francois.marot

    Have you tried waiting a second or two to give the system time to mount the device correctly? Try using sleep 1s before you check the mountpoint - this worked for me.

  6. #6
    Join Date
    Oct 2008
    Beans
    12

    Re: Writing udev Rules

    That's the problem !
    Now (Karmic), the mtab or df command are only populated with the information AFTER my script is executed.
    This means that if I make my programm wait 5 seconds, then mtab and df contain the new info only after 5 seconds.
    If I wait 30seconds, it 's the same: for 30 seconds, if I type df on the command line or read mtab, the new info is not in it.
    So there is no way my programm can access the mount point.
    I must be missing something...
    The only solution I see is to create a cron job that will be run later (say 30s) and quit my script once the job is created in order to release UDEV, make it poppulate mtab. Than 30s later, I can read it. But this is kinda overkill !

  7. #7
    Join Date
    Mar 2009
    Beans
    927
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Writing udev Rules

    @francois.marot

    What directory is your script in, and what is it called? Things like this will have an effect on it's run-order which could mean it get's run before the mounter script. My script is in /etc/udev/rules.d/91-local.rules.

  8. #8
    Join Date
    Oct 2008
    Beans
    12

    Re: Writing udev Rules

    Hi Penguin Guy,

    I knew the rule and named my script (that used to work on Jaunty...) something like 99-myScript.rules. It should be executed last. But something seem to wait for it to finish before the USB drive is mounted in /media/USBDriveName

  9. #9
    Join Date
    Mar 2009
    Beans
    927
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Writing udev Rules

    @francois.marot

    I would suggest starting with a simple 'Hello World!' program before moving on to add the more advanced features - have you tried something like:
    Code:
    #!/bin/sh
    echo 'Hello World!' >>"/home/<username>/Desktop/udev.out"
    exit
    And if so, did it work?

  10. #10
    Join Date
    Oct 2008
    Beans
    12

    Re: Writing udev Rules

    I tried something like that and there was no problem... As I said, the problem is mtab and df command not containing the new mount point until my script has finished. But my script NEEDS this information ! Don't know what to do for the moment...

Page 1 of 3 123 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

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