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.