diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix
index d73a19653a7..38625d26173 100644
--- a/modules/system/upstart/upstart.nix
+++ b/modules/system/upstart/upstart.nix
@@ -42,8 +42,12 @@ let
${concatMapStrings (n: "env ${n}=\"${getAttr n env}\"\n") (attrNames env)}
+ ${optionalString (job.console != "") "console ${job.console}"}
+
pre-start script
- exec >> ${log} 2>&1
+ ${optionalString (job.console == "") ''
+ exec >> ${log} 2>&1
+ ''}
ln -sfn "$(readlink -f "/etc/init/${job.name}.conf")" /var/run/upstart-jobs/${job.name}
${optionalString (job.preStart != "") ''
source ${jobHelpers}
@@ -56,24 +60,32 @@ let
else if job.script != "" then
''
script
- exec >> ${log} 2>&1
+ ${optionalString (job.console == "") ''
+ exec >> ${log} 2>&1
+ ''}
source ${jobHelpers}
${job.script}
end script
''
- else if job.exec != "" then
+ else if job.exec != "" && job.console == "" then
''
script
exec >> ${log} 2>&1
exec ${job.exec}
end script
''
+ else if job.exec != "" then
+ ''
+ exec ${job.exec}
+ ''
else ""
}
${optionalString (job.postStart != "") ''
post-start script
- exec >> ${log} 2>&1
+ ${optionalString (job.console == "") ''
+ exec >> ${log} 2>&1
+ ''}
source ${jobHelpers}
${job.postStart}
end script
@@ -88,7 +100,9 @@ let
# (upstart 0.6.5, job.c:562)
optionalString (job.preStop != "") (assert hasMain; ''
pre-stop script
- exec >> ${log} 2>&1
+ ${optionalString (job.console == "") ''
+ exec >> ${log} 2>&1
+ ''}
source ${jobHelpers}
${job.preStop}
end script
@@ -96,7 +110,9 @@ let
${optionalString (job.postStop != "") ''
post-stop script
- exec >> ${log} 2>&1
+ ${optionalString (job.console == "") ''
+ exec >> ${log} 2>&1
+ ''}
source ${jobHelpers}
${job.postStop}
end script
@@ -364,6 +380,18 @@ let
'';
};
+ console = mkOption {
+ default = "";
+ example = "console";
+ description = ''
+ If set to output, job output is written to
+ the console. If it's owner, additionally
+ the job becomes owner of the console. It it's empty (the
+ default), output is written to
+ /var/log/upstart/jobname
+ '';
+ };
+
};
diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix
index b60dd8c27c4..7808bac1274 100644
--- a/modules/tasks/filesystems.nix
+++ b/modules/tasks/filesystems.nix
@@ -178,7 +178,9 @@ in
path = [ pkgs.utillinux pkgs.mountall ] ++ config.system.fsPackages;
- script =
+ console = "output";
+
+ preStart =
''
# Ensure that this job is restarted when fstab changed:
# ${fstab}
@@ -186,11 +188,13 @@ in
${optionalString config.services.nfs.client.enable ''
ensure statd || true
''}
-
- exec > /dev/console 2>&1
+
echo "mounting filesystems..."
- exec mountall
'';
+
+ daemonType = "daemon";
+
+ exec = "mountall --daemon";
};
# The `mount-failed' event is emitted synchronously, but we don't
@@ -223,19 +227,26 @@ in
startOn = "ip-up";
script =
''
- ${pkgs.procps}/bin/pkill -USR1 -u root mountall || true
+ # Send USR1 to the mountall process. Can't use "pkill
+ # mountall" here because that has a race condition: we may
+ # accidentally send USR1 to children of mountall (such as
+ # fsck) just before they do execve().
+ status="$(status mountall)"
+ if [[ "$status" =~ "start/running, process "([0-9]+) ]]; then
+ pid=''${BASH_REMATCH[1]}
+ echo "sending USR1 to $pid..."
+ kill -USR1 "$pid"
+ fi
'';
};
jobs."emergency-shell" =
{ task = true;
- extraConfig = "console owner";
+ console = "owner";
script =
''
- exec < /dev/console > /dev/console 2>&1
-
cat <>>[0m