diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index d73a19653a7f..38625d26173a 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 <literal>output</literal>, job output is written to + the console. If it's <literal>owner</literal>, additionally + the job becomes owner of the console. It it's empty (the + default), output is written to + <filename>/var/log/upstart/<replaceable>jobname</replaceable></filename> + ''; + }; + }; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index b60dd8c27c40..7808bac12743 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 <<EOF [1;31m<<< Emergency shell >>>[0m