* mountall: make the "console output" Upstart stanza do its work. We
were redirecting output to /var/log/upstart/<job>, so it didn't work properly. * mountall-ip-up: send the USR1 signal to the mountall process by looking up its PID, rather than doing "pkill -USR1 mountall". This prevents a very subtle race condition where USR1 is delivered to a child process of mountall (such as fsck), if pkill sees the child just before its execve(). There is actually still a race condition because mountall installs its USR1 handler *after* daemonising, so mountall-ip-up could accidentally kill mountall. Should report this to upstream. svn path=/nixos/trunk/; revision=33236
This commit is contained in:
parent
b82c253b24
commit
362d1389d3
2 changed files with 53 additions and 14 deletions
|
@ -42,8 +42,12 @@ let
|
||||||
|
|
||||||
${concatMapStrings (n: "env ${n}=\"${getAttr n env}\"\n") (attrNames env)}
|
${concatMapStrings (n: "env ${n}=\"${getAttr n env}\"\n") (attrNames env)}
|
||||||
|
|
||||||
|
${optionalString (job.console != "") "console ${job.console}"}
|
||||||
|
|
||||||
pre-start script
|
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}
|
ln -sfn "$(readlink -f "/etc/init/${job.name}.conf")" /var/run/upstart-jobs/${job.name}
|
||||||
${optionalString (job.preStart != "") ''
|
${optionalString (job.preStart != "") ''
|
||||||
source ${jobHelpers}
|
source ${jobHelpers}
|
||||||
|
@ -56,24 +60,32 @@ let
|
||||||
else if job.script != "" then
|
else if job.script != "" then
|
||||||
''
|
''
|
||||||
script
|
script
|
||||||
exec >> ${log} 2>&1
|
${optionalString (job.console == "") ''
|
||||||
|
exec >> ${log} 2>&1
|
||||||
|
''}
|
||||||
source ${jobHelpers}
|
source ${jobHelpers}
|
||||||
${job.script}
|
${job.script}
|
||||||
end script
|
end script
|
||||||
''
|
''
|
||||||
else if job.exec != "" then
|
else if job.exec != "" && job.console == "" then
|
||||||
''
|
''
|
||||||
script
|
script
|
||||||
exec >> ${log} 2>&1
|
exec >> ${log} 2>&1
|
||||||
exec ${job.exec}
|
exec ${job.exec}
|
||||||
end script
|
end script
|
||||||
''
|
''
|
||||||
|
else if job.exec != "" then
|
||||||
|
''
|
||||||
|
exec ${job.exec}
|
||||||
|
''
|
||||||
else ""
|
else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
${optionalString (job.postStart != "") ''
|
${optionalString (job.postStart != "") ''
|
||||||
post-start script
|
post-start script
|
||||||
exec >> ${log} 2>&1
|
${optionalString (job.console == "") ''
|
||||||
|
exec >> ${log} 2>&1
|
||||||
|
''}
|
||||||
source ${jobHelpers}
|
source ${jobHelpers}
|
||||||
${job.postStart}
|
${job.postStart}
|
||||||
end script
|
end script
|
||||||
|
@ -88,7 +100,9 @@ let
|
||||||
# (upstart 0.6.5, job.c:562)
|
# (upstart 0.6.5, job.c:562)
|
||||||
optionalString (job.preStop != "") (assert hasMain; ''
|
optionalString (job.preStop != "") (assert hasMain; ''
|
||||||
pre-stop script
|
pre-stop script
|
||||||
exec >> ${log} 2>&1
|
${optionalString (job.console == "") ''
|
||||||
|
exec >> ${log} 2>&1
|
||||||
|
''}
|
||||||
source ${jobHelpers}
|
source ${jobHelpers}
|
||||||
${job.preStop}
|
${job.preStop}
|
||||||
end script
|
end script
|
||||||
|
@ -96,7 +110,9 @@ let
|
||||||
|
|
||||||
${optionalString (job.postStop != "") ''
|
${optionalString (job.postStop != "") ''
|
||||||
post-stop script
|
post-stop script
|
||||||
exec >> ${log} 2>&1
|
${optionalString (job.console == "") ''
|
||||||
|
exec >> ${log} 2>&1
|
||||||
|
''}
|
||||||
source ${jobHelpers}
|
source ${jobHelpers}
|
||||||
${job.postStop}
|
${job.postStop}
|
||||||
end script
|
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>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,9 @@ in
|
||||||
|
|
||||||
path = [ pkgs.utillinux pkgs.mountall ] ++ config.system.fsPackages;
|
path = [ pkgs.utillinux pkgs.mountall ] ++ config.system.fsPackages;
|
||||||
|
|
||||||
script =
|
console = "output";
|
||||||
|
|
||||||
|
preStart =
|
||||||
''
|
''
|
||||||
# Ensure that this job is restarted when fstab changed:
|
# Ensure that this job is restarted when fstab changed:
|
||||||
# ${fstab}
|
# ${fstab}
|
||||||
|
@ -186,11 +188,13 @@ in
|
||||||
${optionalString config.services.nfs.client.enable ''
|
${optionalString config.services.nfs.client.enable ''
|
||||||
ensure statd || true
|
ensure statd || true
|
||||||
''}
|
''}
|
||||||
|
|
||||||
exec > /dev/console 2>&1
|
|
||||||
echo "mounting filesystems..."
|
echo "mounting filesystems..."
|
||||||
exec mountall
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
daemonType = "daemon";
|
||||||
|
|
||||||
|
exec = "mountall --daemon";
|
||||||
};
|
};
|
||||||
|
|
||||||
# The `mount-failed' event is emitted synchronously, but we don't
|
# The `mount-failed' event is emitted synchronously, but we don't
|
||||||
|
@ -223,19 +227,26 @@ in
|
||||||
startOn = "ip-up";
|
startOn = "ip-up";
|
||||||
script =
|
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" =
|
jobs."emergency-shell" =
|
||||||
{ task = true;
|
{ task = true;
|
||||||
|
|
||||||
extraConfig = "console owner";
|
console = "owner";
|
||||||
|
|
||||||
script =
|
script =
|
||||||
''
|
''
|
||||||
exec < /dev/console > /dev/console 2>&1
|
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
[1;31m<<< Emergency shell >>>[0m
|
[1;31m<<< Emergency shell >>>[0m
|
||||||
|
|
Loading…
Reference in a new issue