{ config, pkgs, ... }: with pkgs.lib; let # Packages that provide fsck backends. fsPackages = [ pkgs.e2fsprogs pkgs.reiserfsprogs ]; in { ###### interface options = { fileSystems = mkOption { example = [ { mountPoint = "/"; device = "/dev/hda1"; } { mountPoint = "/data"; device = "/dev/hda2"; fsType = "ext3"; options = "data=journal"; } { mountPoint = "/bigdisk"; label = "bigdisk"; } ]; description = " The file systems to be mounted. It must include an entry for the root directory (mountPoint = \"/\"). Each entry in the list is an attribute set with the following fields: mountPoint, device, fsType (a file system type recognised by mount; defaults to \"auto\"), and options (the mount options passed to mount using the flag; defaults to \"defaults\"). Instead of specifying device, you can also specify a volume label (label) for file systems that support it, such as ext2/ext3 (see mke2fs -L). autocreate forces mountPoint to be created with mkdir -p . "; type = types.nullOr (types.list types.optionSet); options = { mountPoint = mkOption { example = "/mnt/usb"; type = types.uniq types.string; description = " Location of the mounted the file system. "; }; device = mkOption { default = null; example = "/dev/sda"; type = types.uniq (types.nullOr types.string); description = " Location of the device. "; }; label = mkOption { default = null; example = "root-partition"; type = types.uniq (types.nullOr types.string); description = " Label of the device (if any). "; }; fsType = mkOption { default = "auto"; example = "ext3"; type = types.uniq types.string; description = " Type of the file system. "; }; options = mkOption { default = "defaults,relatime"; example = "data=journal"; type = types.string; merge = pkgs.lib.concatStringsSep ","; description = " Option used to mount the file system. "; }; autocreate = mkOption { default = false; type = types.bool; description = " Automatically create the mount point defined in . "; }; }; }; system.sbin.mount = mkOption { internal = true; default = pkgs.utillinuxng; description = " Package containing mount and umount. "; }; }; ###### implementation config = { # Add the mount helpers to the system path so that `mount' can find them. environment.systemPackages = [ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ] ++ fsPackages; environment.etc = singleton { source = pkgs.writeText "fstab" '' # This is a generated file. Do not edit! # Filesystems. ${flip concatMapStrings config.fileSystems (fs: (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") + " " + fs.mountPoint + " " + fs.fsType + " " + fs.options + " 0" + " " + (if fs.mountPoint == "/" then "1" else "2") + "\n" )} # Swap devices. ${flip concatMapStrings config.swapDevices (sw: "${sw.device} none swap\n" )} ''; target = "fstab"; }; jobs.mountall = { startOn = "started udev"; script = '' exec > /dev/console 2>&1 export PATH=${config.system.sbin.mount}/bin:${makeSearchPath "sbin" ([pkgs.utillinux] ++ fsPackages)}:$PATH ${pkgs.mountall}/sbin/mountall --verbose --debug echo DONE ''; extraConfig = "console owner"; task = true; }; }; }