diff --git a/system/options.nix b/system/options.nix index 6b167d82c1a1..039f8b72403a 100644 --- a/system/options.nix +++ b/system/options.nix @@ -420,6 +420,8 @@ in (import ../upstart-jobs/swraid.nix) # Activate software RAID arrays. + (import ../upstart-jobs/filesystems.nix) # Mount file systems. + # security (import ../system/sudo.nix) diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix index 6f14800d2967..ca90d8bb8d3f 100644 --- a/upstart-jobs/default.nix +++ b/upstart-jobs/default.nix @@ -71,13 +71,6 @@ let jobs = map makeJob ([ - # Mount file systems. - (import ../upstart-jobs/filesystems.nix { - inherit mount; - inherit (pkgs) utillinux e2fsprogs; - fileSystems = config.fileSystems; - }) - # Swapping. (import ../upstart-jobs/swap.nix { inherit (pkgs) utillinux lib; diff --git a/upstart-jobs/filesystems.nix b/upstart-jobs/filesystems.nix index 24569db11b48..10673cce5f30 100644 --- a/upstart-jobs/filesystems.nix +++ b/upstart-jobs/filesystems.nix @@ -1,120 +1,126 @@ -{utillinux, e2fsprogs, fileSystems, mount}: +{pkgs, config, ...}: + +###### implementation let - - # !!! use XML + inherit (pkgs) e2fsprogs; mountPoints = map (fs: fs.mountPoint) fileSystems; + fileSystems = config.fileSystems; devices = map (fs: if fs ? device then fs.device else "LABEL=" + fs.label) fileSystems; fsTypes = map (fs: if fs ? fsType then fs.fsType else "auto") fileSystems; optionss = map (fs: if fs ? options then fs.options else "defaults") fileSystems; autocreates = map (fs: if fs ? autocreate then fs.autocreate else "0") fileSystems; + mount = config.system.sbin.mount; -in - -{ - name = "filesystems"; + job = '' + start on startup + start on new-devices + start on ip-up - job = " -start on startup -start on new-devices -start on ip-up - -script + script PATH=${e2fsprogs}/sbin:$PATH - + mountPoints=(${toString mountPoints}) devices=(${toString devices}) fsTypes=(${toString fsTypes}) optionss=(${toString optionss}) autocreates=(${toString autocreates}) - + 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= - - for ((n = 0; n < \${#mountPoints[*]}; n++)); do - mountPoint=\${mountPoints[$n]} - device=\${devices[$n]} - fsType=\${fsTypes[$n]} - options=\${optionss[$n]} - autocreate=\${autocreates[$n]} - - isLabel= - if echo \"$device\" | grep -q '^LABEL='; then isLabel=1; fi - - isPseudo= - if test \"$fsType\" = \"nfs\" || test \"$fsType\" = \"tmpfs\" || - test \"$fsType\" = \"ext3cow\"; then isPseudo=1; fi - - if ! test -n \"$isLabel\" -o -n \"$isPseudo\" -o -e \"$device\"; then - echo \"skipping $device, doesn't exist (yet)\" - continue - fi - - # !!! quick hack: if mount point already exists, try a - # remount to change the options but nothing else. - if cat /proc/mounts | grep -F -q \" $mountPoint \"; then - echo \"remounting $device on $mountPoint\" - ${mount}/bin/mount -t \"$fsType\" \\ - -o remount,\"$options\" \\ - \"$device\" \"$mountPoint\" || true - 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. - - # !!! not very smart about labels yet; should resolve the label somehow. - if test -z \"$isLabel\" -a -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,\"$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 - - if test \"\$autocreate\" = 1; then mkdir -p \"\$mountPoint\"; fi - - if ${mount}/bin/mount -t \"$fsType\" -o \"$options\" \"$device\" \"$mountPoint\"; then - newDevices=1 - fi - - done - + + while test -n "$newDevices"; do + + newDevices= + + for ((n = 0; n < ''${#mountPoints[*]}; n++)); do + mountPoint=''${mountPoints[$n]} + device=''${devices[$n]} + fsType=''${fsTypes[$n]} + options=''${optionss[$n]} + autocreate=''${autocreates[$n]} + + isLabel= + if echo "$device" | grep -q '^LABEL='; then isLabel=1; fi + + isPseudo= + if test "$fsType" = "nfs" || test "$fsType" = "tmpfs" || + test "$fsType" = "ext3cow"; then isPseudo=1; fi + + if ! test -n "$isLabel" -o -n "$isPseudo" -o -e "$device"; then + echo "skipping $device, doesn't exist (yet)" + continue + fi + + # !!! quick hack: if mount point already exists, try a + # remount to change the options but nothing else. + if cat /proc/mounts | grep -F -q " $mountPoint "; then + echo "remounting $device on $mountPoint" + ${mount}/bin/mount -t "$fsType" \ + -o remount,"$options" \ + "$device" "$mountPoint" || true + 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. + + # !!! not very smart about labels yet; should resolve the label somehow. + if test -z "$isLabel" -a -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,"$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 + + if test "$autocreate" = 1; then mkdir -p "$mountPoint"; fi + + if ${mount}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint"; then + newDevices=1 + fi + + done + done + + end script + ''; +in -end script - "; - +{ + services = { + extraJobs = [{ + name = "filesystems"; + inherit job; + }]; + }; }