2

As a precondition for starting my Syncthing service, I wish to mount an external USB drive (label MyBook). The action must be synchronous, so putting it anywhere else besides the service's ExecStartPre will not be sufficient. The mount must be a hard dependency of successful service startup. Rule: if the mount fails for any reason, the service doesn't start.

I should note that I had this working on another RPi3B+, running the same OS version. The problem here, though, comes when the script called by the service attempts to mount the drive. Here's that script:

#!/bin/bash

# Check if /dev/sda1 is already mounted
if ! grep -qs '/dev/sda1' /proc/mounts; then
    # Mount /dev/sda1 to /media/pi/MyBook
    echo "Mounting /dev/sda1 to /media/pi/MyBook"
    sudo mount /dev/sda1 /media/pi/MyBook
fi

I've added the user running the service (admin) to the sudoers file using visudo and rebooted for good measure:

admin ALL=(ALL) NOPASSWD: /bin/mount

Here's my error at service startup (journalctl doesn't reveal anything further than this):

pi@RPI:~ $ sudo systemctl status [email protected][email protected] - Syncthing - Open Source Continuous File Synchronization for admin
     Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/[email protected]
             └─override.conf
     Active: failed (Result: exit-code) since Tue 2023-02-21 17:23:14 AKST; 33s ago
       Docs: man:syncthing(1)
    Process: 959 ExecStartPre=/usr/local/bin/mount-sync-drive.sh (code=exited, status=1/FAILURE)
        CPU: 53ms

Feb 21 17:23:14 RPI systemd[1]: [email protected]: Scheduled restart job, restart counter is at 4.
Feb 21 17:23:14 RPI systemd[1]: Stopped Syncthing - Open Source Continuous File Synchronization for admin.
Feb 21 17:23:14 RPI systemd[1]: [email protected]: Start request repeated too quickly.
Feb 21 17:23:14 RPI systemd[1]: [email protected]: Failed with result 'exit-code'.
Feb 21 17:23:14 RPI systemd[1]: Failed to start Syncthing - Open Source Continuous File Synchronization for admin.

Note that when I mount the drive manually and comment out the line of code that performs the mount, the service starts successfully. I can also run the script manually (when logged in as admin) without any problem.

I considered the possibility of a permissions error during mounting, but that theory went by the wayside when I compared permissions against the Pi on which this was working. All is the same:

pi@RPI:~ $ sudo ls -lahR /media/pi/MyBook/
/media/pi/MyBook/:
total 16K
drwxrwxrwx  4 admin admin 4.0K Feb 21 15:00 .
drwxrwxrwx+ 3 root  root  4.0K Feb 20 16:17 ..
drwx------  3 admin admin 4.0K Feb 21 15:00 .config

/media/pi/MyBook/.config:
total 12K
drwx------ 3 admin admin 4.0K Feb 21 15:00 .
drwxrwxrwx 4 admin admin 4.0K Feb 21 15:00 ..
drwx------ 3 admin admin 4.0K Feb 21 15:00 syncthing

/media/pi/MyBook/.config/syncthing:
total 52K
drwx------ 3 admin admin 4.0K Feb 21 15:00 .
drwx------ 3 admin admin 4.0K Feb 21 15:00 ..
-rw-r--r-- 1 admin admin  794 Feb 21 15:00 cert.pem
-rw------- 1 admin admin 6.5K Feb 21 15:00 config.xml
-rw------- 1 admin admin 4.8K Feb 21 15:00 config.xml.v0
-rw------- 1 admin admin 3.8K Feb 21 15:00 config.xml.v32
-rw------- 1 admin admin  231 Feb 21 15:00 csrftokens.txt
-rw-r--r-- 1 admin admin  769 Feb 21 15:00 https-cert.pem
-rw------- 1 admin admin  288 Feb 21 15:00 https-key.pem
drwxr-xr-x 2 admin admin 4.0K Feb 21 17:21 index-v0.14.0.db
-rw------- 1 admin admin  288 Feb 21 15:00 key.pem

/media/pi/MyBook/.config/syncthing/index-v0.14.0.db:
total 300K
drwxr-xr-x 2 admin admin 4.0K Feb 21 17:21 .
drwx------ 3 admin admin 4.0K Feb 21 15:00 ..
-rw-r--r-- 1 admin admin  623 Feb 21 15:00 001319.ldb
-rw-r--r-- 1 admin admin  293 Feb 21 16:48 001332.ldb
-rw-r--r-- 1 admin admin  260 Feb 21 16:49 001333.ldb
-rw-r--r-- 1 admin admin  279 Feb 21 16:59 001336.ldb
-rw-r--r-- 1 admin admin  356 Feb 21 17:21 001339.ldb
-rw-r--r-- 1 admin admin  546 Feb 21 17:22 001340.log
-rw-r--r-- 1 admin admin   16 Feb 21 17:21 CURRENT
-rw-r--r-- 1 admin admin   16 Feb 21 17:21 CURRENT.bak
-rw-r--r-- 1 admin admin    0 Feb 21 15:00 LOCK
-rw-r--r-- 1 admin admin 253K Feb 21 17:22 LOG
-rw-r--r-- 1 admin admin 1.1K Feb 21 17:21 MANIFEST-001341

Besides, all of that works fine when the drive is pre-mounted and the script's if condition is never satisfied.

And finally, here's my ExecStartPre:

[Service]
ExecStartPre=/usr/local/bin/mount-sync-drive.sh

All of the troubleshooting steps shown here are the results of a full day's research on the problem. I've now reached a dead end, I'm afraid.

How can I find out why this script won't mount my drive at service startup?

--EDIT--

Here's some error logging, captured via advice in the answer by @goldilocks:

Wed 22 Feb 15:57:43 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:44 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:45 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:46 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

That error message seems a bit mysterious to me. sudo appears to be OK on my system:

pi@RPI:/usr/local/bin $ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 178432 Jan 14 04:29 /usr/bin/sudo

And the mount seems OK (even when I run the script manually as admin):

pi@RPI:~ $ mount -v | grep sda1
pi@RPI:~ $ sudo -u admin /usr/local/bin/mount-sync-drive.sh
mount: /dev/sda1 mounted on /media/pi/MyBook.
pi@RPI:~ $ mount -v | grep sda1
/dev/sda1 on /media/pi/MyBook type ext4 (rw,relatime)

These outputs are exactly the same as the outputs on the Pi (again: same model, same OS, installed new within the hour on the same day using the same configuration, excepting the hostname) where the scripted mount is working. Also, sudo visudo shows both files to be the same on both systems.

The error message appears to be an important clue, but I'm unable to decipher its exact meaning. Search results aren't turning up anything meaningful (or specific to this situation).

My first guess was that the service somehow isn't running the script as admin, but that can't be the case since the status under service failure shows that it did indeed run under admin:

Feb 22 15:57:47 RPI systemd[1]: Failed to start Syncthing - Open Source Continuous File Synchronization for admin. <-- username substitution for %I here

How to understand what the error means? Further, how to identify and fix the actual problem that it's pointing to?

1 Answer 1

1

How can I find out why this script won't mount my drive at service startup?

You have an echo in there but don't mention whether this output is captured when run as a service at boot. If it isn't, mount is probably emitting an error that you never see.

journalctl -u [service_name] may or may not help you out there. The best way to do this, however, is to either add this at the beginning of the script:

exec &> /some/log/path

Where /some/log/path must be writable by the admin user, or (not and) add to the service file in the [Service] section:

StandardOutput=file:/some/log/path
StandardError=inherit  # Paranoid since this is the default.

You'll need to systemctl daemon-reload if you want to test that without rebooting. Again, the path should be writable for admin.

You can also make mount more verbose by using -v. Both of the above methods will overwrite anything from any previous run unless you rotate the log first.1 If you want to keep and append to the log instead, use exec &>> (vs. &>) or StandardOutput=append:/path. If you do this, a nice command to add at the top of the script (after exec &>>, if used), is date.

The systemd output options are explained in greater detail in man systemd.exec.


  1. More specifically what systemd file: will do is overwrite from the beginning of the file without clobbering (truncating) it first, which can get confusing. To clobber properly, use truncate: instead.
12
  • Thanks, I'll work on this today and get back to you asap.
    – InteXX
    Feb 22, 2023 at 19:11
  • I preferred the exec &>> approach, as it allows for inserting timestamps in the log file. Nice trick. The plot thickens—see my edit—but the solution still eludes me. What does the error indicate to you? I've managed to eliminate the possibilities described in the message itself, so what else could it be? The script works fine when run manually under the context of admin, but not when run by the service. And it's only on this system, which is 90% identical to the one where it's working. Maddening!
    – InteXX
    Feb 23, 2023 at 2:13
  • A timestamp in the script will be the same regardless of which method you use. WRT nosuid, you should ask that in a new question, probably at Unix & Linux. You could try adding mount | grep nosuid (no need for sudo) to the script to see which filesystems have this set at the time; try it normally and you will see a lot of virtual/in mem fs mounts with that set, including on /dev.
    – goldilocks
    Feb 23, 2023 at 14:15
  • ...The fact that the script works when run admin after boot possibly implies the root fs is mounted that way at the time (it gets re-mounted at least once); if so you could try local-fs.target as a dependency.
    – goldilocks
    Feb 23, 2023 at 14:15
  • +1, thanks for pointing me in the right direction. Guess I ought not to go trying to move the goalposts, eh...? 😉 "you should ask that in a new question" Yes, I've done exactly that.
    – InteXX
    Feb 23, 2023 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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