Hello all,

this is my first post on this mailing list and, first of all, I'd like to thank 
you and appreciate your work on systemd in general. I admire the logic, the 
completeness of the manpages and in general how beautifully things are 
engineered. I'm no unix graybeard and systemd saved me from having to learn all 
that legacy stuff systemd replaces. Compared to fstab, /etc/network/interfaces 
and init.d, systemd is a piece of art.

---

I'm working on an embedded device which should access and scan connected usb 
drives for certain files. I seem to witness a race condition with my current 
solution. I would ask for advice on how to implement this functionality in a 
better way.

When a device /dev/sdb1 is connected, the udev rule below starts BOTH
* a systemd-service "start-standalone-mender-deployment@media-sdb1.service"
* `systemd-mount --no-block --automount=no --options=ro --collect /dev/sdb1 
/media/sdb1`

The service then starts a shell script accessing the usb drive. Occasionally, 
it says the directory the usb drive is mounted at is empty. When checking 
manually, I see it's not. I strongly suspect the script accessed the directory 
before the usb drive got mounted there.

Here's the udev rule:
```
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", KERNEL=="*[0-9]*", 
ENV{ID_FS_USAGE}=="filesystem", TAG+="systemd", 
ENV{SYSTEMD_WANTS}+="start-standalone-mender-deployment@media-$name.service", 
RUN{program}+="/usr/bin/systemd-mount --no-block --automount=no --options=ro 
--collect $devnode /media/$name"
```

And here's the systemd service:
It is templated and gets instantiated with "media-sdb1". It therefore has an 
"After=media-sdb1.mount". I suspect Systemd-udevd executes the 
ENV{SYSTEMD_WANTS} part before the RUN{program} part. Hence, "media-sdb1.mount" 
doesn't yet exist when the service gets started, as it gets created a tad later 
by systemd-mount.

```
[Unit]
Description=Start standalone Mender deployment (%i)
After=%i.mount

[Service]
Type=oneshot
Restart=no
ExecStart=/bin/sh /usr/bin/start-standalone-mender-deployment.sh /%I
```

Can you confirm my theory?

The only alternative I see is to invoke systemd-mount without --no-block from 
the shell script itself. Instead of communicating the mount point (media-sdb1) 
via unit template parameter, I would communicate the device path (/dev/sdb1) to 
the template unit and pass it on to the shell script, which would determine 
mount point based on that.

I'm all ears if you have comments or advice on that. I guess I'm not the first 
one implementing something like this.


Regards,
Manuel

P.S.: I won't be able to respond until Sunday Aug 29th.

Reply via email to