I'm having an issue with a script that seems really weird; it appears to stop executing prematurely when run from udev, but not when I run it manually from the command line. I've tried troubleshooting it with the set -x and when I run it from the command line everything gets executed as expected. However, when it gets run from udev, it stops prematurely after a certain point.

Part of the issue, I think, is that it's hard to debug the script when it's run by udev. I've tried putting in logger statements, but they basically just tell me the same thing (it stops prematurely).

Do you see anything that pops out that would be causing this issue?

The script(s) can be found here. One note about them, they are intended for an embedded system. When run manually from the command line, the command I run is:

./product.sh -b update /dev/sda1

The udev rule that runs the script is:

ACTION=="add", KERNEL=="sd?1", RUN+="/usr/sbin/product.sh -b update /dev/%k"

The script appears to stop at lines 195 or 197 in product.sh. I've noticed that if I comment out lines 22 and 28 in product-manifest.sh everything runs as expected when run by udev and manually on command line.

  • You need to use full, explicit paths for the executables - and to verify that the find, xargs and md5sum commands are definitely available to you at the time you run the script. – mikeserv Apr 29 '15 at 17:05
  • I changed the find, xargs, md5sum, and the other commands (for safe measure) to their absolute paths, but it didn't change anything. – E-rich Apr 29 '15 at 17:56
  • And did you verify that they're definitely available? Like for c in find xargs md5sum; do [ -x /sbin/"$c" ] || ! break; done && /sbin/find ... | /sbin/xargs /sbin/md5sum? Also, udev typically runs in a different mount context than what you may be used to. umount anything is usually a bad idea in a script run by udev especially because many udev rules are applied concurrently. If find searches a path which disappears while it does it will be a problem. Instead you should be calling up another udev rule. – mikeserv Apr 29 '15 at 18:10
  • Oh wait, I get it: mount /dev/mmcblk0p1 /mnt/boot; find /mnt -type f | xargs md5sum. That's your problem - you want an && between them, I think. Are you quite certain that you're not actually working from the partition you're mounting when you do? You need to explore the mount state at the time the script runs - is it run from initramfs (as I assume)? And is there - at the time it runs - actually a dev called mmcwhatever available to mount? Is the /mnt/boot path possibly the one into which the initramfs might actually try to switch_root into eventually? – mikeserv Apr 29 '15 at 18:28
  • The system is not running from an initramfs. There is always a dev called mmcblk0p1 (there's also a mmcblk0p2) because it's specified in my kernel config; it's an on-board SD card. The /mnt/boot path is just a temporary mount point I can mount the partition that contains the boot files. The only purpose of mounting the boot partition is to list the files in the manifest. – E-rich Apr 29 '15 at 18:43

Ok, I think I figured out the issue. I think the issue is the result of line 157 where I'm redirecting the output to a file; that file happens to be a mounted USB drive. I'm guessing the redirecting is done concurrently, and when product-manifest.sh is complete the script continues, eventually leading to umounting the USB drive before the concurrent write to the USB drive is complete. And when the umount occurs concurrently some error occurs which ends up prematurely terminating the script.

The fix was to redirect the output to the SD card and then us cp to copy it to the USB drive:

product-manifest.sh > "/tmp/MANIFEST"
cp "/tmp/MANIFEST" "$1"

Thanks to @mikeserv for pointing me in the right direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.