mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-01 15:11:25 +00:00
* Use mountall to mount all filesystems and activate all swap devices
during boot. Mountall ensures that these are done in the right order. It's informed by udev about devices becoming available. It emits some Upstart events upon reaching certain states, in particular ‘local-filesystems’ after all local filesystems have been mounted successfully, ‘remote-filesystems’ after all network filesystems have been mounted, and ‘filesystem’ (sic) when all filesystems have been mounted. Currently, if a filesystem fails to mount or doesn't exist, then the mingettys won't start and the boot will appear to hang. This is because mountall doesn't emit an event for failing filesystems and waits indefinitely for the filesystems to become available. * The ‘filesystems’ and ‘swap’ Upstart jobs are gone. (Support for encrypted swap devices is temporarily gone.) * Generate a proper /etc/fstab from the ‘fileSystems’ and ‘swapDevices’ options. svn path=/nixos/branches/boot-order/; revision=22148
This commit is contained in:
parent
5316059442
commit
dbadf6e9c2
@ -55,7 +55,7 @@ with pkgs.lib;
|
||||
# Generate a separate job for each tty.
|
||||
jobs = listToAttrs (map (tty: nameValuePair tty {
|
||||
|
||||
startOn = "started udev";
|
||||
startOn = "started udev and local-filesystems";
|
||||
|
||||
exec = "${pkgs.mingetty}/sbin/mingetty --loginprog=${pkgs.shadow}/bin/login --noclear ${tty}";
|
||||
|
||||
|
@ -2,108 +2,6 @@
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
fileSystems = config.fileSystems;
|
||||
mount = config.system.sbin.mount;
|
||||
|
||||
task =
|
||||
''
|
||||
PATH=${pkgs.e2fsprogs}/sbin:${pkgs.utillinuxng}/sbin:$PATH
|
||||
|
||||
newDevices=1
|
||||
|
||||
# If we mount any file system, we repeat this loop, because new
|
||||
# mount opportunities may have become available (such as images
|
||||
# for loopback mounts).
|
||||
|
||||
while test -n "$newDevices"; do
|
||||
newDevices=
|
||||
|
||||
${flip concatMapStrings fileSystems (fs: ''
|
||||
for dummy in x; do # make `continue' work
|
||||
mountPoint='${fs.mountPoint}'
|
||||
device='${if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}"}'
|
||||
fsType='${fs.fsType}'
|
||||
|
||||
# A device is a pseudo-device (i.e. not an actual device
|
||||
# node) if it's not an absolute path (e.g. an NFS server
|
||||
# such as machine:/path), if it starts with // (a CIFS FS),
|
||||
# a known pseudo filesystem (such as tmpfs), or the device
|
||||
# is a directory (e.g. a bind mount).
|
||||
isPseudo=
|
||||
test "''${device:0:1}" != / -o "''${device:0:2}" = // -o "$fsType" = "tmpfs" \
|
||||
-o -d "$device" && isPseudo=1
|
||||
|
||||
if ! test -n "$isPseudo" -o -e "$device"; then
|
||||
echo "skipping $device, doesn't exist (yet)"
|
||||
continue
|
||||
fi
|
||||
|
||||
# !!! quick hack: if the mount point is already mounted, try
|
||||
# a remount to change the options but nothing else.
|
||||
if cat /proc/mounts | grep -F -q " $mountPoint "; then
|
||||
if test "''${device:0:2}" != //; then
|
||||
echo "remounting $device on $mountPoint"
|
||||
${mount}/bin/mount -t "$fsType" \
|
||||
-o remount,"${fs.options}" \
|
||||
"$device" "$mountPoint" || true
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# If $device is already mounted somewhere else, unmount it first.
|
||||
# !!! Note: we use /etc/mtab, not /proc/mounts, because mtab
|
||||
# contains more accurate info when using loop devices.
|
||||
|
||||
if test -z "$isPseudo"; then
|
||||
|
||||
device=$(readlink -f "$device")
|
||||
|
||||
prevMountPoint=$(
|
||||
cat /etc/mtab \
|
||||
| grep "^$device " \
|
||||
| sed 's|^[^ ]\+ \+\([^ ]\+\).*|\1|' \
|
||||
)
|
||||
|
||||
if test "$prevMountPoint" = "$mountPoint"; then
|
||||
echo "remounting $device on $mountPoint"
|
||||
${mount}/bin/mount -t "$fsType" \
|
||||
-o remount,"${fs.options}" \
|
||||
"$device" "$mountPoint" || true
|
||||
continue
|
||||
fi
|
||||
|
||||
if test -n "$prevMountPoint"; then
|
||||
echo "unmount $device from $prevMountPoint"
|
||||
${mount}/bin/umount "$prevMountPoint" || true
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo "mounting $device on $mountPoint"
|
||||
|
||||
# !!! should do something with the result; also prevent repeated fscks.
|
||||
if test -z "$isPseudo"; then
|
||||
fsck -a "$device" || true
|
||||
fi
|
||||
|
||||
${optionalString fs.autocreate
|
||||
''
|
||||
mkdir -p "$mountPoint"
|
||||
''
|
||||
}
|
||||
|
||||
if ${mount}/bin/mount -t "$fsType" -o "${fs.options}" "$device" "$mountPoint"; then
|
||||
newDevices=1
|
||||
fi
|
||||
done
|
||||
'')}
|
||||
done
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
@ -221,12 +119,44 @@ in
|
||||
config = {
|
||||
|
||||
# Add the mount helpers to the system path so that `mount' can find them.
|
||||
environment.systemPackages = [pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils];
|
||||
environment.systemPackages = [ pkgs.ntfs3g pkgs.cifs_utils pkgs.nfsUtils pkgs.mountall ];
|
||||
|
||||
jobs.filesystems =
|
||||
{ startOn = [ "new-devices" "ip-up" ];
|
||||
environment.etc = singleton
|
||||
{ source = pkgs.writeText "fstab"
|
||||
''
|
||||
# This is a generated file. Do not edit!
|
||||
|
||||
script = task;
|
||||
# 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:${pkgs.utillinux}/sbin:$PATH
|
||||
${pkgs.mountall}/sbin/mountall --verbose --debug
|
||||
echo DONE
|
||||
'';
|
||||
|
||||
extraConfig = "console owner";
|
||||
|
||||
task = true;
|
||||
};
|
||||
|
@ -2,12 +2,6 @@
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
inherit (pkgs) cryptsetup utillinux;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
@ -36,37 +30,31 @@ in
|
||||
options = {config, options, ...}: {
|
||||
|
||||
options = {
|
||||
|
||||
device = mkOption {
|
||||
example = "/dev/sda3";
|
||||
type = types.string;
|
||||
description = ''
|
||||
Path of the device.
|
||||
'';
|
||||
description = "Path of the device.";
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
example = "swap";
|
||||
type = types.string;
|
||||
description = "
|
||||
description = ''
|
||||
Label of the device. Can be used instead of <varname>device</varname>.
|
||||
";
|
||||
'';
|
||||
};
|
||||
|
||||
cipher = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = types.bool;
|
||||
description = "
|
||||
Cipher the swap device to protect swapped data. This option
|
||||
description = ''
|
||||
Encrypt the swap device to protect swapped data. This option
|
||||
does not work with labels.
|
||||
";
|
||||
'';
|
||||
};
|
||||
|
||||
command = mkOption {
|
||||
description = "
|
||||
Command used to activate the swap device.
|
||||
";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
@ -75,59 +63,12 @@ in
|
||||
"/dev/disk/by-label/${config.label}"
|
||||
else
|
||||
mkNotdef;
|
||||
|
||||
command = ''
|
||||
if test -e "${config.device}"; then
|
||||
${if config.cipher then ''
|
||||
plainDevice="${config.device}"
|
||||
name="crypt$(echo "$plainDevice" | sed -e 's,/,.,g')"
|
||||
device="/dev/mapper/$name"
|
||||
if ! test -e "$device"; then
|
||||
${cryptsetup}/sbin/cryptsetup -c aes -s 128 -d /dev/urandom create "$name" "$plainDevice"
|
||||
${utillinux}/sbin/mkswap -f "$device" || true
|
||||
fi
|
||||
''
|
||||
else ''
|
||||
device="${config.device}"
|
||||
''
|
||||
}
|
||||
device=$(readlink -f "$device")
|
||||
# Add new swap devices.
|
||||
if echo $unused | grep -q "^$device\$"; then
|
||||
unused="$(echo $unused | grep -v "^$device\$" || true)"
|
||||
else
|
||||
${utillinux}/sbin/swapon "$device" || true
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
|
||||
jobs.swap =
|
||||
{ task = true;
|
||||
|
||||
startOn = ["startup" "new-devices"];
|
||||
|
||||
script =
|
||||
''
|
||||
unused="$(sed '1d; s/ .*//' /proc/swaps)"
|
||||
|
||||
${toString (map (x: x.command) config.swapDevices)}
|
||||
|
||||
# Remove remaining swap devices.
|
||||
test -n "$unused" && ${utillinux}/sbin/swapoff $unused || true
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user