38

If I use this command :

mount -t xfs -o noatime,nodiratime,logbufs=8 -L d1 /srv/node/d1

all works correctly. But if I try to mount through the systemd mount it fails.

I've created a file /etc/systemd/system/mnt-d1.mount with the following content:

[Unit]
Description = Disk 1

[Mount]
What = LABEL=d1
Where = /srv/node/d1
Type = xfs
Options = noatime,nodiratime,logbufs=8

[Install]
WantedBy = multi-user.target

After that I run these commands:

systemctl daemon-reload
systemctl start mnt-d1.mount

The last one showed me:

Failed to start mnt-d1.mount: Unit mnt-d1.mount failed to load: Invalid argument.  
See system logs and 'systemctl status mnt-d1.mount' for details.

systemctl status mnt-d1.mount showed me:

May 16 18:13:52 object1 systemd[1]: Cannot add dependency job for unit mnt-d1.mount, ignoring: Unit mnt-d1.mount failed to ...ectory.
May 16 18:24:05 object1 systemd[1]: mnt-d1.mount's Where= setting doesn't match unit name. Refusing.

Please help me to mount a disk via a systemd mount unit.

0

4 Answers 4

58

The error message explains the cause:

Where= setting doesn't match unit name. Refusing.

though understanding that message requires reading several man pages.
Per systemd.mount man page (emphasize mine):

Where=

Takes an absolute path of a directory of the mount point. If the mount point does not exist at the time of mounting, it is created. This string must be reflected in the unit filename. (See above.) This option is mandatory.

The "see above" part is:

Mount units must be named after the mount point directories they control. Example: the mount point /home/lennart must be configured in a unit file home-lennart.mount. For details about the escaping logic used to convert a file system path to a unit name, see systemd.unit(5).

OK, systemd.unit man page states that:

Properly escaped paths can be generated using the systemd-escape(1) command.

pointing to systemd-escape man page which explains how to do it:

To generate the mount unit for a path:

$ systemd-escape -p --suffix=mount "/tmp//waldi/foobar/"
tmp-waldi-foobar.mount

So, in your case, /srv/node/d1 translates to srv-node-d1.mount


Note that IF PATHS CONTAIN CHARACTERS OTHER THAN [[:alnum:]._:] e.g. punctuation (except the three mentioned before), spaces etc, those characters will be replaced by their ASCII hex code (e.g \x20 for space) so the resulting escaped path might contain backslashes:

systemd-escape -p --suffix=mount '/media/offline@server/<user>'

outputs

media-offline\x40server-\x3cuser\x3e.mount

Now that might need an additional level of escaping when used in terminal or scripts. I recommend single-quoting the whole string and be done with it:

touch '/etc/systemd/system/media-offline\x40server-\x3cuser\x3e.mount'

but you can also escape all backslashes if you so wish, see mrhhug's post below.

6
  • 8
    It's important to note that the "path escaping" system can get a bit complex even dealing with non-A-Z names. Even some dashes in the path will need to be converted to the C-style \x2d escape, which when used to create the unit file may (depending on your shell/editor) need to again escape the slash character - so the unit file fit mounting /some-path may require running edit some\\x2dpath.mount
    – Guss
    Feb 16, 2017 at 19:22
  • 2
    I ended up here trying to figure out why I couldn't mount share-name. Renaming it share_name solved the problem.
    – Brian Z
    Mar 17, 2019 at 17:35
  • 1
    I'd give a double upvote if I could!
    – John Mee
    Nov 15, 2019 at 1:43
  • 8
    Why is it so ridiculously hard to have a unit file for mounting a path with a - character? I generated the mount with systemd-escape -p --suffix=mount "/storage/media-server" and it output storage-media\x2dserver.mount and that filename still produces the same error.. Jan 16, 2020 at 22:05
  • How are spaces escaped in the Where=? Neither \x20 nor quotes seemed to work for me.
    – coolaj86
    Mar 25, 2023 at 1:34
5

If anyone is seeing this error when trying to mount in a local directory that contains a hyphen, be careful when you address that file on your shell, my shell (bash 4) needed the slash escaped, so we are escaping the escape.
Example:

#/etc/systemd/system/mnt-my\x2dlocal\x2ddir.mount
[Unit]
Description=My mount

[Mount]
What=//some/remote/share
Where=/mnt/my-local-dir
Type=cifs
Options=user=nonrootuser

[Install]
WantedBy=multi-user.target

The absolute file path in this example is : /etc/systemd/system/mnt-my\x2dlocal\x2ddir.mount

but to rename your file you need to do this :

mv /my/original/file /etc/systemd/system/mnt-my\\x2dlocal\\x2ddir.mount

and when you call systemd you need to

systemctl status /etc/systemd/system/mnt-my\\x2dlocal\\x2ddir.mount

Now you can mount remote shares at boot as a non-root user.

0

Keys to success

In addition to what others have said, here's a few things that may not have been clear enough:

  1. Keys like What= and Where= have literal values - no escapes
  2. Paths on the filesystem must be systemd-escaped
    • the shell will interpret \, so SINGLE quote it to escape: 'my\x20'
  3. You MUST run sudo systemctl daemon-reload between name/content changes
  4. sudo journalctl -xe ESCAPEME.mount will give better logs that status

Example: /etc/systemd/system/ESCAPEME.mount

/etc/systemd/system/mnt-TrueNAS-TV\x20Shows.mount:

[Unit]
  Description=My CIFs Media Mounter
  Requires=network-online.target
  After=network-online.service

[Mount]
  What=//192.168.1.200/TV Shows
  Where=/mnt/TrueNAS/TV Shows
  Options=username=my-user,password=my-secret
  Type=cifs

[Install]
  WantedBy=multi-user.target

Example: /etc/systemd/system/ESCAPEME.automount

/etc/systemd/system/mnt-TrueNAS-TV\x20Shows.automount:

[Unit]
  Description=My CIFs Media Automount

[Automount]
  Where=/mnt/TrueNAS/TV Shows

[Install]
  WantedBy=multi-user.target
0

This may not apply to the example in this question, but this may help others who get the same error:

You CANNOT add a comment on the same line as an assignment (that will be part of the variable).

So, if your file says

Where=/here # Mount it there

it will try to mount "/here # Mount it there" ... and not /here.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .