Systemd.mounts.*. and systemd.automounts.*. - options causing an error

Wish you all a nice day.

Currently I’m struggling wit the systemd.mounts. options.

I used this how to:

to fill the options in the mounts.nix file (see below).

I used these parameters on arch linux and debian to mount my server shares.

I’ve written a file called: mounts.nix which is imported in the imports section of configuration.nix.

{ config, ... }:
let
 netonline = "network-online.target";
 wanted = "multi-user.target";

in
 {
  systemd.mounts.server-[servername]-[share].description = "Mount for server ...";
  systemd.mounts.server-[servername]-[share].requires = [ netonline ];
  systemd.mounts.server-[servername]-[share].what = "//[servername]/[share]";
  systemd.mounts.server-[servername]-[share].where = "/server/[Server]/[share]";
  systemd.mounts.server-[servername]-[share].type = "cifs";
  systemd.mounts.server-[servername]-[share].options = "username=[MYUSER],password=[MySecretPassword],rw";
  systemd.mounts.server-[servername]-[share].wantedBy = [wanted];
  systemd.mounts.server-[servername]-[share].enable = true;

  systemd.automounts.server-[servername]-[share].description = "Automount for server...";
  systemd.automounts.server-[servername]-[share].requires = ["network-online.target"];
  systemd.automounts.server-[servername]-[share].after = ["network-online.target"];
  systemd.automounts.server-[servername]-[share].where = "/server/[servername]/[share]";
  systemd.automounts.server-[servername]-[share].wantedBy = ["multi-user.target"];
  systemd.automounts.server-[servername]-[share].enable = true;
 }

I tried it without using the Variables on top of that file but ended in the same result.

When I start:
nixos-rebuild test

it results in:

A definition for option `systemd.mounts' is not of type `list of submodules'.

with different outputs when I comment out single lines to determine which one could be wrong.

is here a “module” missing?

{ config, ... }:

Can someone point me where I’m wrong? I don’t see it.

Would it be possible to replace the [servername] by a variable? This would make it easier to change a share location with editing a single variable, since I would mount several shares from a single server.

Nix is a quiet powerful technique. I just started digging around and have some machines replaced with nixos. One Laptop, a workstation and a pi400. This is a good way to unifi the configuration across these machines. I think this is great.

Thanks in advance.
Steffan

1 Like

Hey, @realloki,

I had to setup some systemd mounts and automounts and stumbled upon your question. The issue with your suggested configuration is actually simple, NixOS options dictate the following for systemd.mounts:

Definition of systemd mount units. This is a list instead of an attrSet, because systemd mandates the names to be derived from the ‘where’ attribute.

As such, the following code should work for you:

{ config, ... }:

{
  boot.supportedFilesystems = [ "cifs" ];

  systemd.mounts = [{
    description = "Mount for server ...";
    what = "//[servername]/[share]";
    where = "/server/[servername]/[share]";
    type = "cifs";
    options = "username=[MYUSER],password=[MySecretPassword],rw";
  }];

  systemd.automounts = [{
    description = "Automount for server...";
    where = "/server/[servername]/[share]";
    wantedBy = [ "multi-user.target" ];
  }];
}

So, besides the list thing I have 3 more tips to give you:

  • No need to define any requirement for the network target. According to the man page of systemd.mount:

Network mount units automatically acquire After= dependencies on remote-fs-pre.target, network.target and network-online.target, and gain a Before= dependency on remote-fs.target unless nofail mount option is set. Towards the latter a Wants= unit is added as well.

  • If you intend to use automount, then you should not set wantedBy = [ "multi-user.target" ]; to the mount, as this should take over any work of automount and mount the share permanently.

  • You need to explicitly set boot.supportedFilesystems = [ "cifs" ];, so that mount.cifs is available to systemd.

Hope this helps you!

2 Likes

Hi @joko thanks very much, this worked for me.

I think you meant “should set”, right?

FWIW this is how I configured automounting two shares, one needing login and another having anonymous access:

  boot.supportedFilesystems = [ "cifs" ];
  systemd.mounts = [
  { description = "Mount for /home on NAS";
    what = "//192.168.1.99/home";
    where = "/run/mount/NAS/home";
    type = "cifs";
    options = "username=myself,password=myself,rw";
    }
  { description = "Mount for /public on NAS";
    what = "//192.168.1.99/public";
    where = "/run/mount/NAS/public";
    type = "cifs";
    options = "rw";
    }
  ];
  systemd.automounts = [
  { description = "Automount for /home on NAS";
    where = "/run/mount/NAS/home";
    wantedBy = [ "multi-user.target" ];
    }
  { description = "Automount for /public on NAS";
    where = "/run/mount/NAS/public";
    wantedBy = [ "multi-user.target" ];
    }
  ];
1 Like

Hello @rahim123,

I did mean to write not, it was intentional. Let me refine this:

If the mount unit (not to be confused with the automount one) has the specific WantedBy attribute, then what is defined can get mounted by that unit. multi-user.target means that the mount should happen once systemd considers the system ready for multi-user use (source).

This is not something I want, though, for CIFS shares, I want them to be available on-demand, i.e., in case I try to access data from those specific mounts. For that reason, I define the automount units and set them available (wantedBy) on the multi-user.target.

@realloki’s example had wantedBy defined in both mount and automount units and I considered important to distinguish their use in my response.

Hello @joko.

After that long time I’m back trying/using NixOS.

Your help did work for me very fine.

Instead of using “multi-user.target” “default.target” can be used. This worked for me. In automounts of course, like you mentioned without setting this in mount.

I also replaced the options username and password with a credentials option with a file for the credentials. This way the credentials are only placed once in this file and must not be repeated for each share in mounts.

Thanks a lot for your help.
Steffan

Note that you usually don’t need to make custom mount and automount units. You should usually just set your file systems normally and use the x-systemd.automount option. e.g.

fileSystems."/run/mount/NAS/home" = {
  device = "//192.168.1.99/home";
  fsType = "cifs";
  options = [
    "username=myself"
    "password=myself"
    "rw"
    "x-systemd.automount"
  ];
};

systemd will correctly handle the unit dependencies and ordering on its own, including ordering around network targets for networked fsTypes. See the details in the systemd.mount(5) and systemd.automount(5) man pages.

I mention this partly because if changing multi-user.target to default.target works, you’re in the realm of strange magic because that shouldn’t make a difference. But systemd’s fstab parser will definitely get it right

1 Like

@realloki Feels good to see that you managed to configure this. :slight_smile:

As @ElvishJerricco pointed out, one could use the fileSystems options as well. AFAIK, this involves yet another systemd component, systemd-fstab-generator, which transforms the /etc/fstab file to systemd unit files. Since it is not hard to write those unit files on my own, I prefer the systemd units approach.

@ElvishJerricco as aforementioned, I think both approaches are almost identical, so service ordering should take place in both.

Regarding default.target and multi-user.target, please check systemd.special(7) - Linux manual page. My proposal is to keep using multi-user.target since this will not try to mount your network filesystems if you try to boot on single-user or rescue mode. But then again, how often are we using those modes? :grinning_face_with_smiling_eyes:

@joko
between fstab and automount is one diffrence. automount mounts and unmounts automatically and when needed. Where fstab mounts are always mounted or must be manually mounted.

or am I wrong? Ohh, I see… combined with the automount… yes it’s an other way.

If I’m on single user mode I could imagine that it would be nice to be able to save some data off that machine?!? So it could be helpful to have a server share mounted.

@ElvishJerricco For (mostly) permanently USB attached disks, which should be remounted on spurious failures, is fileSystem still the way to go, or is systemd.mounts more appropriate for that situation?

There’s nearly zero reasons to ever write custom systemd.mounts units. Unless there’s something you actually cannot do with fstab / fileSystems, you should use it.

1 Like