diff --git a/modules/services/hardware/hal.nix b/modules/services/hardware/hal.nix index 56bcf1fb4d8..be51968317f 100644 --- a/modules/services/hardware/hal.nix +++ b/modules/services/hardware/hal.nix @@ -99,21 +99,14 @@ in mkdir -m 0755 -p /var/run/hald rm -f /var/cache/hald/fdi-cache - - # !!! Hack: start the daemon here to make sure it's - # running when the Upstart job reaches the "running" - # state. Should be fixable in Upstart 0.6. - # The `PATH=' works around a bug in HAL: it concatenates - # its libexec directory to $PATH, but using a 512-byte - # buffer. So if $PATH is too long it fails. - PATH= ${hal}/sbin/hald --use-syslog # --verbose=yes ''; - postStop = - '' - pid=$(cat /var/run/hald/pid || true) - test -n "$pid" && kill "$pid" - ''; + daemonType = "fork"; + + # The `PATH=' works around a bug in HAL: it concatenates + # its libexec directory to $PATH, but using a 512-byte + # buffer. So if $PATH is too long it fails. + script = "PATH= exec ${hal}/sbin/hald --use-syslog"; }; services.udev.packages = [hal]; diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index 105f8a2b54f..2baa87e9547 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -169,9 +169,6 @@ in mkdir -p /var/lib/udev/rules.d - # Get rid of possible old udev processes. - ${procps}/bin/pkill -u root "^udevd$" || true - # Do the loading of additional stage 2 kernel modules. # Maybe this isn't the best place... for i in ${toString config.boot.kernelModules}; do @@ -179,32 +176,24 @@ in ${modprobe}/sbin/modprobe $i || true done - # Start udev. mkdir -p /dev/.udev # !!! bug in udev? - ${udev}/sbin/udevd --daemon + ''; + daemonType = "fork"; + + exec = "${udev}/sbin/udevd --daemon"; + + postStart = + '' # Let udev create device nodes for all modules that have already # been loaded into the kernel (or for which support is built into # the kernel). ${udev}/sbin/udevadm trigger ${udev}/sbin/udevadm settle # wait for udev to finish - # Kill udev, let Upstart restart and monitor it. (This is nasty, - # but we have to run `udevadm trigger' first. Maybe we can use - # Upstart's `binary' keyword, but it isn't implemented yet.) - if ! ${procps}/bin/pkill -u root "^udevd$"; then - echo "couldn't stop udevd" - fi - - while ${procps}/bin/pgrep -u root "^udevd$"; do - sleep 1 - done - initctl emit new-devices ''; - - exec = "${udev}/sbin/udevd"; - + }; }; diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix index d91be4eb88b..b0c8dc66ae5 100644 --- a/modules/services/system/dbus.nix +++ b/modules/services/system/dbus.nix @@ -124,24 +124,19 @@ in ${dbus.tools}/bin/dbus-uuidgen --ensure rm -f ${homeDir}/pid - # !!! hack - dbus should be running once this job is - # considered "running"; should be fixable once we have - # Upstart 0.6. - ${dbus}/bin/dbus-daemon --config-file=${configDir}/system.conf ''; + daemonType = "fork"; + + exec = "${dbus}/bin/dbus-daemon --config-file=${configDir}/system.conf"; + postStop = '' - pid=$(cat ${homeDir}/pid) - if test -n "$pid"; then - kill $pid - fi - # !!! Hack: doesn't belong here. - pid=$(cat /var/run/ConsoleKit/pid) + pid=$(cat /var/run/ConsoleKit/pid || true) if test -n "$pid"; then - kill $pid - rm /var/run/ConsoleKit/pid + kill $pid || true + rm -f /var/run/ConsoleKit/pid fi ''; }; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 0919fc0d75f..fea8f9e880c 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -38,16 +38,16 @@ let else "" } - ${if job.stopOn != "" then "stop on ${job.stopOn}" else ""} + ${optionalString (job.stopOn != "") "stop on ${job.stopOn}"} env PATH=${makeSearchPath "bin" upstartPath}:${makeSearchPath "sbin" upstartPath} ${concatMapStrings (n: "env ${n}=${getAttr n job.environment}\n") (attrNames job.environment)} - ${if job.preStart != "" then '' + ${optionalString (job.preStart != "") '' pre-start script ${job.preStart} end script - '' else ""} + ''} ${if job.script != "" && job.exec != "" then abort "Job ${job.name} has both a `script' and `exec' attribute." @@ -64,13 +64,28 @@ let else "" } - ${if job.respawn && !job.task then "respawn" else ""} + ${optionalString (job.postStart != "") '' + post-start script + ${job.postStart} + end script + ''} + + ${optionalString job.task "task"} + ${optionalString job.respawn "respawn"} - ${if job.postStop != "" then '' + ${optionalString (job.postStop != "") '' post-stop script ${job.postStop} end script - '' else ""} + ''} + + ${optionalString (!job.task) ( + if job.daemonType == "fork" then "expect fork" else + if job.daemonType == "daemon" then "expect daemon" else + if job.daemonType == "stop" then "expect stop" else + if job.daemonType == "none" then "" else + throw "invalid daemon type `${job.daemonType}'" + )} ${job.extraConfig} ''; @@ -141,6 +156,16 @@ let ''; }; + postStart = mkOption { + type = types.string; + default = ""; + description = '' + Shell commands executed after the job is started (i.e. after + the job's main process is started), but before the job is + considered “running”. + ''; + }; + postStop = mkOption { type = types.string; default = ""; @@ -156,7 +181,7 @@ let description = '' Command to start the job's main process. If empty, the job has no main process, but can still have pre/post-start - and pre/post-stop scripts, and is considered "running" + and pre/post-stop scripts, and is considered “running” until it is stopped. ''; }; @@ -198,6 +223,20 @@ let ''; }; + daemonType = mkOption { + type = types.string; + default = "none"; + description = '' + Determines how Upstart detects when a daemon should be + considered “running”. The value none means + that the daemon is considered ready immediately. The value + fork means that the daemon will fork once. + The value daemon means that the daemon will + fork twice. The value stop means that the + daemon will raise the SIGSTOP signal to indicate readiness. + ''; + }; + extraConfig = mkOption { type = types.string; default = "";