2009-10-12 18:36:19 +02:00
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
|
|
with pkgs.lib;
|
2006-12-21 15:22:40 +01:00
|
|
|
|
|
2010-06-04 17:35:32 +02:00
|
|
|
|
let
|
|
|
|
|
|
|
|
|
|
# Packages that provide fsck backends.
|
2011-08-30 20:25:54 +02:00
|
|
|
|
fsPackages = [ pkgs.e2fsprogs pkgs.reiserfsprogs pkgs.dosfstools ];
|
2010-06-04 17:35:32 +02:00
|
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
2009-10-12 18:36:19 +02:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
###### interface
|
2009-05-28 01:14:38 +02:00
|
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
|
2009-06-11 18:03:57 +02:00
|
|
|
|
fileSystems = mkOption {
|
2009-05-28 01:14:38 +02:00
|
|
|
|
example = [
|
|
|
|
|
{ mountPoint = "/";
|
|
|
|
|
device = "/dev/hda1";
|
|
|
|
|
}
|
|
|
|
|
{ mountPoint = "/data";
|
|
|
|
|
device = "/dev/hda2";
|
|
|
|
|
fsType = "ext3";
|
|
|
|
|
options = "data=journal";
|
|
|
|
|
}
|
|
|
|
|
{ mountPoint = "/bigdisk";
|
|
|
|
|
label = "bigdisk";
|
|
|
|
|
}
|
|
|
|
|
];
|
2009-10-12 18:36:19 +02:00
|
|
|
|
|
2009-05-28 01:14:38 +02:00
|
|
|
|
description = "
|
|
|
|
|
The file systems to be mounted. It must include an entry for
|
|
|
|
|
the root directory (<literal>mountPoint = \"/\"</literal>). Each
|
|
|
|
|
entry in the list is an attribute set with the following fields:
|
|
|
|
|
<literal>mountPoint</literal>, <literal>device</literal>,
|
|
|
|
|
<literal>fsType</literal> (a file system type recognised by
|
|
|
|
|
<command>mount</command>; defaults to
|
|
|
|
|
<literal>\"auto\"</literal>), and <literal>options</literal>
|
|
|
|
|
(the mount options passed to <command>mount</command> using the
|
|
|
|
|
<option>-o</option> flag; defaults to <literal>\"defaults\"</literal>).
|
|
|
|
|
|
|
|
|
|
Instead of specifying <literal>device</literal>, you can also
|
|
|
|
|
specify a volume label (<literal>label</literal>) for file
|
|
|
|
|
systems that support it, such as ext2/ext3 (see <command>mke2fs
|
|
|
|
|
-L</command>).
|
|
|
|
|
|
|
|
|
|
<literal>autocreate</literal> forces <literal>mountPoint</literal> to be created with
|
|
|
|
|
<command>mkdir -p</command> .
|
|
|
|
|
";
|
2009-10-12 18:36:19 +02:00
|
|
|
|
|
2011-07-27 22:55:35 +02:00
|
|
|
|
type = types.nullOr (types.loaOf types.optionSet);
|
|
|
|
|
apply = x: attrValues x;
|
2009-06-11 18:03:57 +02:00
|
|
|
|
|
2009-07-15 15:41:00 +02:00
|
|
|
|
options = {
|
2009-06-11 18:03:57 +02:00
|
|
|
|
|
|
|
|
|
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 {
|
2009-07-14 14:07:17 +02:00
|
|
|
|
default = "defaults,relatime";
|
2009-06-11 18:03:57 +02:00
|
|
|
|
example = "data=journal";
|
|
|
|
|
type = types.string;
|
|
|
|
|
merge = pkgs.lib.concatStringsSep ",";
|
2010-09-13 13:46:35 +02:00
|
|
|
|
description = "Options used to mount the file system.";
|
2009-06-11 18:03:57 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
autocreate = mkOption {
|
2009-06-14 13:07:44 +02:00
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
2009-06-11 18:03:57 +02:00
|
|
|
|
description = "
|
|
|
|
|
Automatically create the mount point defined in
|
|
|
|
|
<option>fileSystems.*.mountPoint</option>.
|
|
|
|
|
";
|
|
|
|
|
};
|
2010-09-13 13:46:35 +02:00
|
|
|
|
|
|
|
|
|
noCheck = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = "Disable running fsck on this filesystem.";
|
|
|
|
|
};
|
2009-06-11 18:03:57 +02:00
|
|
|
|
};
|
2009-05-28 01:14:38 +02:00
|
|
|
|
};
|
|
|
|
|
|
2009-06-11 18:03:57 +02:00
|
|
|
|
system.sbin.mount = mkOption {
|
2009-05-28 01:14:38 +02:00
|
|
|
|
internal = true;
|
2009-08-11 23:10:33 +02:00
|
|
|
|
default = pkgs.utillinuxng;
|
2009-05-28 01:14:38 +02:00
|
|
|
|
description = "
|
2009-08-11 23:10:33 +02:00
|
|
|
|
Package containing mount and umount.
|
2009-05-28 01:14:38 +02:00
|
|
|
|
";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-10-12 18:36:19 +02:00
|
|
|
|
###### implementation
|
2009-05-28 01:14:38 +02:00
|
|
|
|
|
2009-10-12 18:36:19 +02:00
|
|
|
|
config = {
|
2009-05-28 01:14:38 +02:00
|
|
|
|
|
2009-10-12 18:36:19 +02:00
|
|
|
|
# Add the mount helpers to the system path so that `mount' can find them.
|
2010-06-04 17:35:32 +02:00
|
|
|
|
environment.systemPackages =
|
|
|
|
|
[ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ]
|
|
|
|
|
++ fsPackages;
|
2009-10-12 18:36:19 +02:00
|
|
|
|
|
2010-06-04 16:22:11 +02:00
|
|
|
|
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"
|
2010-09-13 13:46:35 +02:00
|
|
|
|
+ " " + (if fs.fsType == "none" || fs.noCheck then "0" else
|
|
|
|
|
if fs.mountPoint == "/" then "1" else "2")
|
2010-06-04 16:22:11 +02:00
|
|
|
|
+ "\n"
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
# Swap devices.
|
|
|
|
|
${flip concatMapStrings config.swapDevices (sw:
|
|
|
|
|
"${sw.device} none swap\n"
|
|
|
|
|
)}
|
|
|
|
|
'';
|
|
|
|
|
target = "fstab";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
jobs.mountall =
|
2010-07-07 14:11:29 +02:00
|
|
|
|
{ startOn = "started udev"
|
|
|
|
|
# !!! The `started nfs-kernel-statd' condition shouldn't be
|
|
|
|
|
# here. The `nfs-kernel-statd' job should have a `starting
|
|
|
|
|
# mountall' condition. However, that doesn't work if
|
|
|
|
|
# `mountall' is restarted due to an apparent bug in Upstart:
|
|
|
|
|
# `mountall' hangs forever in the `start/starting' state.
|
|
|
|
|
+ optionalString config.services.nfsKernel.client.enable " and started nfs-kernel-statd";
|
2010-06-04 16:22:11 +02:00
|
|
|
|
|
2010-06-07 14:15:55 +02:00
|
|
|
|
task = true;
|
|
|
|
|
|
2010-06-04 16:22:11 +02:00
|
|
|
|
script =
|
|
|
|
|
''
|
|
|
|
|
exec > /dev/console 2>&1
|
2010-06-07 14:15:55 +02:00
|
|
|
|
echo "mounting filesystems..."
|
2010-06-04 17:35:32 +02:00
|
|
|
|
export PATH=${config.system.sbin.mount}/bin:${makeSearchPath "sbin" ([pkgs.utillinux] ++ fsPackages)}:$PATH
|
2010-06-07 14:15:55 +02:00
|
|
|
|
${pkgs.mountall}/sbin/mountall
|
2010-06-04 16:22:11 +02:00
|
|
|
|
'';
|
2010-06-07 14:15:55 +02:00
|
|
|
|
};
|
2009-05-28 01:14:38 +02:00
|
|
|
|
|
2010-06-07 14:15:55 +02:00
|
|
|
|
# The `mount-failed' event is emitted synchronously, but we don't
|
|
|
|
|
# want `mountall' to wait for the emergency shell. So use this
|
|
|
|
|
# intermediate job to make the event asynchronous.
|
2010-07-12 18:07:26 +02:00
|
|
|
|
jobs.mount_failed =
|
2010-06-07 14:15:55 +02:00
|
|
|
|
{ name = "mount-failed";
|
|
|
|
|
task = true;
|
|
|
|
|
startOn = "mount-failed";
|
|
|
|
|
script =
|
|
|
|
|
''
|
2010-07-05 11:28:22 +02:00
|
|
|
|
[ -n "$MOUNTPOINT" ] || exit 0
|
2010-06-07 14:15:55 +02:00
|
|
|
|
start --no-wait emergency-shell \
|
|
|
|
|
DEVICE="$DEVICE" MOUNTPOINT="$MOUNTPOINT"
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2010-07-12 18:07:26 +02:00
|
|
|
|
# On an `ip-up' event, notify mountall so that it retries mounting
|
|
|
|
|
# remote filesystems.
|
|
|
|
|
jobs.mountall_ip_up =
|
|
|
|
|
{
|
|
|
|
|
name = "mountall-ip-up";
|
|
|
|
|
task = true;
|
|
|
|
|
startOn = "ip-up";
|
|
|
|
|
script =
|
|
|
|
|
''
|
|
|
|
|
${pkgs.procps}/bin/pkill -USR1 -u root mountall || true
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
jobs.emergency_shell =
|
2010-06-07 14:15:55 +02:00
|
|
|
|
{ name = "emergency-shell";
|
2009-05-28 01:14:38 +02:00
|
|
|
|
|
2009-10-12 18:36:19 +02:00
|
|
|
|
task = true;
|
2010-06-07 14:15:55 +02:00
|
|
|
|
|
|
|
|
|
extraConfig = "console owner";
|
|
|
|
|
|
|
|
|
|
script =
|
|
|
|
|
''
|
2010-07-05 11:28:22 +02:00
|
|
|
|
[ -n "$MOUNTPOINT" ] || exit 0
|
|
|
|
|
|
2010-06-07 14:15:55 +02:00
|
|
|
|
exec < /dev/console > /dev/console 2>&1
|
|
|
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
|
|
|
|
|
|
[1;31m<<< Emergency shell >>>[0m
|
|
|
|
|
|
|
|
|
|
The filesystem \`$DEVICE' could not be mounted on \`$MOUNTPOINT'.
|
|
|
|
|
|
|
|
|
|
Please do one of the following:
|
|
|
|
|
|
|
|
|
|
- Repair the filesystem (\`fsck $DEVICE') and exit the emergency
|
|
|
|
|
shell to resume booting.
|
|
|
|
|
|
|
|
|
|
- Ignore any failed filesystems and continue booting by running
|
|
|
|
|
\`initctl emit filesystem'.
|
|
|
|
|
|
|
|
|
|
- Remove the failed filesystem from the system configuration in
|
|
|
|
|
/etc/nixos/configuration.nix and run \`nixos-rebuild switch'.
|
|
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
${pkgs.shadow}/bin/login root || false
|
|
|
|
|
|
|
|
|
|
initctl start --no-wait mountall
|
|
|
|
|
'';
|
2009-10-12 18:36:19 +02:00
|
|
|
|
};
|
2006-12-21 15:22:40 +01:00
|
|
|
|
|
2009-03-06 13:27:33 +01:00
|
|
|
|
};
|
2009-08-11 23:10:33 +02:00
|
|
|
|
|
2006-12-21 15:22:40 +01:00
|
|
|
|
}
|