mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-16 23:03:40 +01:00
Merge branch 'systemd' of github.com:NixOS/nixos into systemd
This commit is contained in:
commit
30586846ce
27 changed files with 776 additions and 193 deletions
173
doc/manual/configuration.xml
Normal file
173
doc/manual/configuration.xml
Normal file
|
@ -0,0 +1,173 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="ch-configuration">
|
||||
|
||||
<title>Configuring NixOS</title>
|
||||
|
||||
<para>This chapter describes how to configure various aspects of a
|
||||
NixOS machine through the configuration file
|
||||
<filename>/etc/nixos/configuration.nix</filename>. As described in
|
||||
<xref linkend="sec-changing-config" />, changes to that file only take
|
||||
effect after you run <command>nixos-rebuild</command>.</para>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Networking</title>
|
||||
|
||||
<section><title>Secure shell access</title>
|
||||
|
||||
<para>Secure shell (SSH) access to your machine can be enabled by
|
||||
setting:
|
||||
|
||||
<programlisting>
|
||||
services.openssh.enable = true;
|
||||
</programlisting>
|
||||
|
||||
By default, root logins using a password are disallowed. They can be
|
||||
disabled entirely by setting
|
||||
<literal>services.openssh.permitRootLogin</literal> to
|
||||
<literal>"no"</literal>.</para>
|
||||
|
||||
<para>You can declaratively specify authorised RSA/DSA public keys for
|
||||
a user as follows:
|
||||
|
||||
<!-- FIXME: this might not work if the user is unmanaged. -->
|
||||
<programlisting>
|
||||
users.extraUsers.alice.openssh.authorizedKeys.keys =
|
||||
[ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>IPv4 configuration</title>
|
||||
|
||||
<para>By default, NixOS uses DHCP (specifically,
|
||||
(<command>dhcpcd</command>)) to automatically configure network
|
||||
interfaces. However, you can configure an interface manually as
|
||||
follows:
|
||||
|
||||
<programlisting>
|
||||
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
|
||||
</programlisting>
|
||||
|
||||
(The network prefix can also be specified using the option
|
||||
<literal>subnetMask</literal>,
|
||||
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
|
||||
Typically you’ll also want to set a default gateway and set of name
|
||||
servers:
|
||||
|
||||
<programlisting>
|
||||
networking.defaultGateway = "192.168.1.1";
|
||||
networking.nameservers = [ "8.8.8.8" ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<note><para>Statically configured interfaces are set up by the systemd
|
||||
service
|
||||
<replaceable>interface-name</replaceable><literal>-cfg.service</literal>.
|
||||
The default gateway and name server configuration is performed by
|
||||
<literal>network-setup.service</literal>.</para></note>
|
||||
|
||||
<para>The host name is set using <option>networking.hostName</option>:
|
||||
|
||||
<programlisting>
|
||||
networking.hostName = "cartman";
|
||||
</programlisting>
|
||||
|
||||
The default host name is <literal>nixos</literal>. Set it to the
|
||||
empty string (<literal>""</literal>) to allow the DHCP server to
|
||||
provide the host name.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>IPv6 configuration</title>
|
||||
|
||||
<para>IPv6 is enabled by default. Stateless address autoconfiguration
|
||||
is used to automatically assign IPv6 addresses to all interfaces. You
|
||||
can disable IPv6 support globally by setting:
|
||||
|
||||
<programlisting>
|
||||
networking.enableIPv6 = false;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Firewall</title>
|
||||
|
||||
<para>NixOS has a simple stateful firewall that blocks incoming
|
||||
connections and other unexpected packets. The firewall applies to
|
||||
both IPv4 and IPv6 traffic. It can be enabled as follows:
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.enable = true;
|
||||
</programlisting>
|
||||
|
||||
You can open specific TCP ports to the outside world:
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
</programlisting>
|
||||
|
||||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
|
||||
is enabled (<option>services.openssh.enable = true</option>). UDP
|
||||
ports can be opened through
|
||||
<option>networking.firewall.allowedUDPPorts</option>. Also of
|
||||
interest is
|
||||
|
||||
<programlisting>
|
||||
networking.firewall.allowPing = true;
|
||||
</programlisting>
|
||||
|
||||
to allow the machine to respond to ping requests. (ICMPv6 pings are
|
||||
always allowed.)</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Wireless networks</title>
|
||||
|
||||
<para>TODO</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section><title>Ad-hoc configuration</title>
|
||||
|
||||
<para>You can use <option>networking.localCommands</option> to specify
|
||||
shell commands to be run at the end of
|
||||
<literal>network-setup.service</literal>. This is useful for doing
|
||||
network configuration not covered by the existing NixOS modules. For
|
||||
instance, to statically configure an IPv6 address:
|
||||
|
||||
<programlisting>
|
||||
networking.localCommands =
|
||||
''
|
||||
ip -6 addr add 2001:610:685:1::1/64 dev eth0
|
||||
'';
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- TODO: OpenVPN, NAT -->
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- TODO: declarative package installation; X11; user management;
|
||||
Apache; libvirtd virtualisation -->
|
||||
|
||||
|
||||
</chapter>
|
|
@ -59,7 +59,7 @@ in rec {
|
|||
|
||||
mkdir -p $dst/images/callouts
|
||||
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
||||
|
||||
|
||||
cp ${./style.css} $dst/style.css
|
||||
|
||||
ensureDir $out/nix-support
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<title>Installation</title>
|
||||
<title>Installing NixOS</title>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
@ -58,7 +58,7 @@ Wiki</link>.</para>
|
|||
|
||||
<listitem><para>For partitioning:
|
||||
<command>fdisk</command>.</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>For initialising Ext4 partitions:
|
||||
<command>mkfs.ext4</command>. It is recommended that you assign a
|
||||
unique symbolic label to the file system using the option
|
||||
|
@ -70,13 +70,13 @@ Wiki</link>.</para>
|
|||
<command>mkswap</command>. Again it’s recommended to assign a
|
||||
label to the swap partition: <option>-L
|
||||
<replaceable>label</replaceable></option>.</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||
|
||||
<screen>
|
||||
$ pvcreate /dev/sda1 /dev/sdb1
|
||||
$ vgcreate MyVolGroup /dev/sda1 /dev/sdb1
|
||||
$ lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
$ lvcreate --size 2G --name bigdisk MyVolGroup
|
||||
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||
|
||||
</para></listitem>
|
||||
|
@ -87,7 +87,7 @@ $ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
|||
</itemizedlist>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
|
||||
<listitem><para>Mount the target file system on which NixOS should
|
||||
be installed on <filename>/mnt</filename>.</para></listitem>
|
||||
|
||||
|
@ -138,7 +138,7 @@ $ nixos-option --install</screen>
|
|||
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
|
||||
<listitem><para>If your machine has a limited amount of memory, you
|
||||
may want to activate swap devices now (<command>swapon
|
||||
<replaceable>device</replaceable></command>). The installer (or
|
||||
|
@ -234,7 +234,7 @@ $ reboot</screen>
|
|||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-label/swap"; } ];
|
||||
|
||||
|
||||
services.sshd.enable = true;
|
||||
}</screen>
|
||||
</example>
|
||||
|
@ -260,7 +260,7 @@ to build the new configuration, make it the default configuration for
|
|||
booting, and try to realise the configuration in the running system
|
||||
(e.g., by restarting system services).</para>
|
||||
|
||||
<para>You can also do
|
||||
<para>You can also do
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild test</screen>
|
||||
|
@ -270,7 +270,7 @@ without making it the boot default. So if (say) the configuration
|
|||
locks up your machine, you can just reboot to get back to a working
|
||||
configuration.</para>
|
||||
|
||||
<para>There is also
|
||||
<para>There is also
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild boot</screen>
|
||||
|
@ -279,7 +279,7 @@ to build the configuration and make it the boot default, but not
|
|||
switch to it now (so it will only take effect after the next
|
||||
reboot).</para>
|
||||
|
||||
<para>Finally, you can do
|
||||
<para>Finally, you can do
|
||||
|
||||
<screen>
|
||||
$ nixos-rebuild build</screen>
|
||||
|
@ -329,7 +329,7 @@ You can then upgrade NixOS to the latest version in the channel by
|
|||
running
|
||||
|
||||
<screen>
|
||||
$ nix-channel --update
|
||||
$ nix-channel --update nixos
|
||||
</screen>
|
||||
|
||||
and running the <command>nixos-rebuild</command> command as described
|
||||
|
|
|
@ -24,16 +24,16 @@
|
|||
<year>2007-2012</year>
|
||||
<holder>Eelco Dolstra</holder>
|
||||
</copyright>
|
||||
|
||||
|
||||
</info>
|
||||
|
||||
|
||||
|
||||
<preface>
|
||||
<title>Preface</title>
|
||||
|
||||
<para>This manual describes NixOS, a Linux distribution based on
|
||||
the purely functional package management system Nix.</para>
|
||||
|
||||
|
||||
<para>NixOS is rather bleeding edge, and this manual is
|
||||
correspondingly sketchy and quite possibly out of date. It gives
|
||||
basic information on how to get NixOS up and running, but since
|
||||
|
@ -45,11 +45,13 @@
|
|||
mailing list or on <link
|
||||
xlink:href="irc://irc.freenode.net/#nixos">the
|
||||
<literal>#nixos</literal> channel on Freenode.</link>.</para>
|
||||
|
||||
|
||||
</preface>
|
||||
|
||||
|
||||
|
||||
<xi:include href="installation.xml" />
|
||||
<xi:include href="configuration.xml" />
|
||||
<xi:include href="running.xml" />
|
||||
<!-- <xi:include href="userconfiguration.xml" /> -->
|
||||
<xi:include href="troubleshooting.xml" />
|
||||
<xi:include href="development.xml" />
|
||||
|
|
288
doc/manual/running.xml
Normal file
288
doc/manual/running.xml
Normal file
|
@ -0,0 +1,288 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="ch-running">
|
||||
|
||||
<title>Running NixOS</title>
|
||||
|
||||
<para>This chapter describes various aspects of managing a running
|
||||
NixOS system, such as how to use the <command>systemd</command>
|
||||
service manager.</para>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Service management</title>
|
||||
|
||||
<para>In NixOS, all system services are started and monitored using
|
||||
the systemd program. Systemd is the “init” process of the system
|
||||
(i.e. PID 1), the parent of all other processes. It manages a set of
|
||||
so-called “units”, which can be things like system services
|
||||
(programs), but also mount points, swap files, devices, targets
|
||||
(groups of units) and more. Units can have complex dependencies; for
|
||||
instance, one unit can require that another unit must be succesfully
|
||||
started before the first unit can be started. When the system boots,
|
||||
it starts a unit named <literal>default.target</literal>; the
|
||||
dependencies of this unit cause all system services to be started,
|
||||
filesystems to be mounted, swap files to be activated, and so
|
||||
on.</para>
|
||||
|
||||
<para>The command <command>systemctl</command> is the main way to
|
||||
interact with <command>systemd</command>. Without any arguments, it
|
||||
shows the status of active units:
|
||||
|
||||
<screen>
|
||||
$ systemctl
|
||||
-.mount loaded active mounted /
|
||||
swapfile.swap loaded active active /swapfile
|
||||
sshd.service loaded active running SSH Daemon
|
||||
graphical.target loaded active active Graphical Interface
|
||||
<replaceable>...</replaceable>
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
<para>You can ask for detailed status information about a unit, for
|
||||
instance, the PostgreSQL database service:
|
||||
|
||||
<screen>
|
||||
$ systemctl status postgresql.service
|
||||
postgresql.service - PostgreSQL Server
|
||||
Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service)
|
||||
Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago
|
||||
Main PID: 2390 (postgres)
|
||||
CGroup: name=systemd:/system/postgresql.service
|
||||
├─2390 postgres
|
||||
├─2418 postgres: writer process
|
||||
├─2419 postgres: wal writer process
|
||||
├─2420 postgres: autovacuum launcher process
|
||||
├─2421 postgres: stats collector process
|
||||
└─2498 postgres: zabbix zabbix [local] idle
|
||||
|
||||
Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET
|
||||
Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections
|
||||
Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started
|
||||
Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server.
|
||||
</screen>
|
||||
|
||||
Note that this shows the status of the unit (active and running), all
|
||||
the processes belonging to the service, as well as the most recent log
|
||||
messages from the service.
|
||||
|
||||
</para>
|
||||
|
||||
<para>Units can be stopped, started or restarted:
|
||||
|
||||
<screen>
|
||||
$ systemctl stop postgresql.service
|
||||
$ systemctl start postgresql.service
|
||||
$ systemctl restart postgresql.service
|
||||
</screen>
|
||||
|
||||
These operations are synchronous: they wait until the service has
|
||||
finished starting or stopping (or has failed). Starting a unit will
|
||||
cause the dependencies of that unit to be started as well (if
|
||||
necessary).</para>
|
||||
|
||||
<!-- - cgroups: each service and user session is a cgroup
|
||||
|
||||
- cgroup resource management -->
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Rebooting and shutting down</title>
|
||||
|
||||
<para>The system can be shut down (and automatically powered off) by
|
||||
doing:
|
||||
|
||||
<screen>
|
||||
$ shutdown
|
||||
</screen>
|
||||
|
||||
This is equivalent to running <command>systemctl poweroff</command>.
|
||||
Likewise, <command>reboot</command> (a.k.a. <command>systemctl
|
||||
reboot</command>) will reboot the system.</para>
|
||||
|
||||
<para>The machine can be suspended to RAM (if supported) using
|
||||
<command>systemctl suspend</command>, and suspended to disk using
|
||||
<command>systemctl hibernate</command>.</para>
|
||||
|
||||
<para>These commands can be run by any user who is logged in locally,
|
||||
i.e. on a virtual console or in X11; otherwise, the user is asked for
|
||||
authentication.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>User sessions</title>
|
||||
|
||||
<para>Systemd keeps track of all users who are logged into the system
|
||||
(e.g. on a virtual console or remotely via SSH). The command
|
||||
<command>loginctl</command> allows quering and manipulating user
|
||||
sessions. For instance, to list all user sessions:
|
||||
|
||||
<screen>
|
||||
$ loginctl
|
||||
SESSION UID USER SEAT
|
||||
c1 500 eelco seat0
|
||||
c3 0 root seat0
|
||||
c4 500 alice
|
||||
</screen>
|
||||
|
||||
This shows that two users are logged in locally, while another is
|
||||
logged in remotely. (“Seats” are essentially the combinations of
|
||||
displays and input devices attached to the system; usually, there is
|
||||
only one seat.) To get information about a session:
|
||||
|
||||
<screen>
|
||||
$ loginctl session-status c3
|
||||
c3 - root (0)
|
||||
Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago
|
||||
Leader: 2536 (login)
|
||||
Seat: seat0; vc3
|
||||
TTY: /dev/tty3
|
||||
Service: login; type tty; class user
|
||||
State: online
|
||||
CGroup: name=systemd:/user/root/c3
|
||||
├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login --
|
||||
├─10339 -bash
|
||||
└─10355 w3m nixos.org
|
||||
</screen>
|
||||
|
||||
This shows that the user is logged in on virtual console 3. It also
|
||||
lists the processes belonging to this session. Since systemd keeps
|
||||
track of this, you can terminate a session in a way that ensures that
|
||||
all the session’s processes are gone:
|
||||
|
||||
<screen>
|
||||
$ loginctl terminate-session c3
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Control groups</title>
|
||||
|
||||
<para>To keep track of the processes in a running system, systemd uses
|
||||
<emphasis>control groups</emphasis> (cgroups). A control group is a
|
||||
set of processes used to allocate resources such as CPU, memory or I/O
|
||||
bandwidth. There can be multiple control group hierarchies, allowing
|
||||
each kind of resource to be managed independently.</para>
|
||||
|
||||
<para>The command <command>systemd-cgls</command> lists all control
|
||||
groups in the <literal>systemd</literal> hierarchy, which is what
|
||||
systemd uses to keep track of the processes belonging to each service
|
||||
or user session:
|
||||
|
||||
<screen>
|
||||
$ systemd-cgls
|
||||
├─user
|
||||
│ └─eelco
|
||||
│ └─c1
|
||||
│ ├─ 2567 -:0
|
||||
│ ├─ 2682 kdeinit4: kdeinit4 Running...
|
||||
│ ├─ <replaceable>...</replaceable>
|
||||
│ └─10851 sh -c less -R
|
||||
└─system
|
||||
├─httpd.service
|
||||
│ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH
|
||||
│ └─<replaceable>...</replaceable>
|
||||
├─dhcpcd.service
|
||||
│ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf
|
||||
└─ <replaceable>...</replaceable>
|
||||
</screen>
|
||||
|
||||
Similarly, <command>systemd-cgls cpu</command> shows the cgroups in
|
||||
the CPU hierarchy, which allows per-cgroup CPU scheduling priorities.
|
||||
By default, every systemd service gets its own CPU cgroup, while all
|
||||
user sessions are in the top-level CPU cgroup. This ensures, for
|
||||
instance, that a thousand run-away processes in the
|
||||
<literal>httpd.service</literal> cgroup cannot starve the CPU for one
|
||||
process in the <literal>postgresql.service</literal> cgroup. (By
|
||||
contrast, it they were in the same cgroup, then the PostgreSQL process
|
||||
would get 1/1001 of the cgroup’s CPU time.) You can limit a service’s
|
||||
CPU share in <filename>configuration.nix</filename>:
|
||||
|
||||
<programlisting>
|
||||
boot.systemd.services.httpd.serviceConfig.CPUShares = 512;
|
||||
</programlisting>
|
||||
|
||||
By default, every cgroup has 1024 CPU shares, so this will halve the
|
||||
CPU allocation of the <literal>httpd.service</literal> cgroup.</para>
|
||||
|
||||
<para>There also is a <literal>memory</literal> hierarchy that
|
||||
controls memory allocation limits; by default, all processes are in
|
||||
the top-level cgroup, so any service or session can exhaust all
|
||||
available memory. Per-cgroup memory limits can be specified in
|
||||
<filename>configuration.nix</filename>; for instance, to limit
|
||||
<literal>httpd.service</literal> to 512 MiB of RAM (excluding swap)
|
||||
and 640 MiB of RAM (including swap):
|
||||
|
||||
<programlisting>
|
||||
boot.systemd.services.httpd.serviceConfig.MemoryLimit = "512M";
|
||||
boot.systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ];
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The command <command>systemd-cgtop</command> shows a
|
||||
continuously updated list of all cgroups with their CPU and memory
|
||||
usage.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!--===============================================================-->
|
||||
|
||||
<section><title>Logging</title>
|
||||
|
||||
<para>System-wide logging is provided by systemd’s
|
||||
<emphasis>journal</emphasis>, which subsumes traditional logging
|
||||
daemons such as syslogd and klogd. Log entries are kept in binary
|
||||
files in <filename>/var/log/journal/</filename>. The command
|
||||
<literal>journalctl</literal> allows you to see the contents of the
|
||||
journal. For example,
|
||||
|
||||
<screen>
|
||||
$ journalctl -b
|
||||
</screen>
|
||||
|
||||
shows all journal entries since the last reboot. (The output of
|
||||
<command>journalctl</command> is piped into <command>less</command> by
|
||||
default.) You can use various options and match operators to restrict
|
||||
output to messages of interest. For instance, to get all messages
|
||||
from PostgreSQL:
|
||||
|
||||
<screen>
|
||||
$ journalctl _SYSTEMD_UNIT=postgresql.service
|
||||
-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. --
|
||||
...
|
||||
Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down
|
||||
-- Reboot --
|
||||
Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET
|
||||
Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections
|
||||
</screen>
|
||||
|
||||
Or to get all messages since the last reboot that have at least a
|
||||
“critical” severity level:
|
||||
|
||||
<screen>
|
||||
$ journalctl -b -p crit
|
||||
Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice]
|
||||
Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1)
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</chapter>
|
|
@ -4,60 +4,81 @@
|
|||
<title>Troubleshooting</title>
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<title>Debugging the boot process</title>
|
||||
<section><title>Boot problems</title>
|
||||
|
||||
<para>To get a Stage 1 shell (i.e., a shell in the initial ramdisk),
|
||||
add <literal>debug1</literal> to the kernel command line. The shell
|
||||
gets started before anything useful has been done. That is, no
|
||||
modules have been loaded and no file systems have been mounted, except
|
||||
for <filename>/proc</filename> and <filename>/sys</filename>.</para>
|
||||
<para>If NixOS fails to boot, there are a number of kernel command
|
||||
line parameters that may help you to identify or fix the issue. You
|
||||
can add these parameters in the GRUB boot menu by pressing “e” to
|
||||
modify the selected boot entry and editing the line starting with
|
||||
<literal>linux</literal>. The following are some useful kernel command
|
||||
line parameters that are recognised by the NixOS boot scripts or by
|
||||
systemd:
|
||||
|
||||
<para>To get a Stage 2 shell (i.e., a shell in the actual root file
|
||||
system), add <literal>debug2</literal> to the kernel command
|
||||
line. This shell is started right after stage 1 calls the stage 2
|
||||
<literal>init</literal> script, so the root file system is there but
|
||||
no services have been started.</para>
|
||||
<variablelist>
|
||||
|
||||
</section>
|
||||
<varlistentry><term><literal>boot.shell_on_fail</literal></term>
|
||||
<listitem><para>Start a root shell if something goes wrong in
|
||||
stage 1 of the boot process (the initial ramdisk). This is
|
||||
disabled by default because there is no authentication for the
|
||||
root shell.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>boot.debug1</literal></term>
|
||||
<listitem><para>Start an interactive shell in stage 1 before
|
||||
anything useful has been done. That is, no modules have been
|
||||
loaded and no file systems have been mounted, except for
|
||||
<filename>/proc</filename> and
|
||||
<filename>/sys</filename>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>boot.trace</literal></term>
|
||||
<listitem><para>Print every shell command executed by the stage 1
|
||||
and 2 boot scripts.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<section>
|
||||
|
||||
<title>Safe mode</title>
|
||||
<varlistentry><term><literal>single</literal></term>
|
||||
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
|
||||
This will cause systemd to start nothing but the unit
|
||||
<literal>rescue.target</literal>, which runs
|
||||
<command>sulogin</command> to prompt for the root password and
|
||||
start a root login shell. Exiting the shell causes the system to
|
||||
continue with the normal boot process.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<para>If the hardware autodetection (in
|
||||
<filename>upstart-jobs/hardware-scan</filename>) causes problems, add
|
||||
<literal>safemode</literal> to the kernel command line. This will
|
||||
disable auto-loading of modules for your PCI devices. However, you
|
||||
will probably need to explicitly add modules to
|
||||
<option>boot.kernelModules</option> to get network support etc.</para>
|
||||
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
|
||||
<listitem><para>Make systemd very verbose and send log messages to
|
||||
the console instead of the journal.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
For more parameters recognised by systemd, see
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
|
||||
|
||||
<para>If no login prompts or X11 login screens appear (e.g. due to
|
||||
hanging dependencies), you can press Alt+ArrowUp. If you’re lucky,
|
||||
this will start rescue mode (described above). (Also note that since
|
||||
most units have a 90-second timeout before systemd gives up on them,
|
||||
the <command>agetty</command> login prompts should appear eventually
|
||||
unless something is very wrong.)</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
|
||||
<title>Maintenance mode</title>
|
||||
|
||||
<para>You can go to maintenance mode by doing
|
||||
<para>You can enter rescue mode by running:
|
||||
|
||||
<screen>
|
||||
$ shutdown now</screen>
|
||||
$ systemctl rescue</screen>
|
||||
|
||||
This will eventually give you a single-user root shell.
|
||||
|
||||
To get out of maintenance mode, do
|
||||
|
||||
<screen>
|
||||
$ initctl emit startup</screen>
|
||||
|
||||
</para>
|
||||
This will eventually give you a single-user root shell. Systemd will
|
||||
stop (almost) all system services. To get out of maintenance mode,
|
||||
just exit from the rescue shell.</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</chapter>
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
./services/misc/rogue.nix
|
||||
./services/misc/svnserve.nix
|
||||
./services/misc/synergy.nix
|
||||
./services/monitoring/dd-agent.nix
|
||||
./services/monitoring/monit.nix
|
||||
./services/monitoring/nagios/default.nix
|
||||
./services/monitoring/smartd.nix
|
||||
|
|
|
@ -16,5 +16,5 @@ with pkgs.lib;
|
|||
boot.systemd.services."serial-getty@hvc0".enable = false;
|
||||
|
||||
# Since we can't manually respond to a panic, just reboot.
|
||||
boot.kernelParams = [ "panic=1" "stage1panic=1" ];
|
||||
boot.kernelParams = [ "panic=1" "boot.panic_on_fail" ];
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ in
|
|||
environment = cfg.envVars;
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart = "${nix}/bin/nix-worker --daemon";
|
||||
{ ExecStart = "@${nix}/bin/nix-daemon nix-daemon";
|
||||
KillMode = "process";
|
||||
Nice = cfg.daemonNiceLevel;
|
||||
IOSchedulingPriority = cfg.daemonIONiceLevel;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
with pkgs.lib;
|
||||
|
||||
let
|
||||
nix = config.environment.nix;
|
||||
cfg = config.nix.gc;
|
||||
in
|
||||
|
||||
|
@ -16,7 +15,7 @@ in
|
|||
|
||||
automatic = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = types.bool;
|
||||
description = "
|
||||
Automatically run the garbage collector at specified dates.
|
||||
";
|
||||
|
@ -24,6 +23,7 @@ in
|
|||
|
||||
dates = mkOption {
|
||||
default = "15 03 * * *";
|
||||
type = types.string;
|
||||
description = "
|
||||
Run the garbage collector at specified dates to avoid full
|
||||
hard-drives.
|
||||
|
@ -33,6 +33,7 @@ in
|
|||
options = mkOption {
|
||||
default = "";
|
||||
example = "--max-freed $((64 * 1024**3))";
|
||||
type = types.string;
|
||||
description = "
|
||||
Options given to <filename>nix-collect-garbage</filename> when the
|
||||
garbage collector is run automatically.
|
||||
|
@ -45,10 +46,17 @@ in
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.automatic {
|
||||
services.cron.systemCronJobs = [
|
||||
"${cfg.dates} root ${nix}/bin/nix-collect-garbage ${cfg.options} > /var/log/gc.log 2>&1"
|
||||
];
|
||||
config = {
|
||||
|
||||
services.cron.systemCronJobs = mkIf cfg.automatic (singleton
|
||||
"${cfg.dates} root ${config.system.build.systemd}/bin/systemctl start nix-gc.service");
|
||||
|
||||
boot.systemd.services."nix-gc" =
|
||||
{ description = "Nix Garbage Collector";
|
||||
path = [ config.environment.nix ];
|
||||
script = "exec nix-collect-garbage ${cfg.options}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,17 @@ let
|
|||
inherit pkgs options;
|
||||
};
|
||||
|
||||
entry = "${manual.manual}/share/doc/nixos/manual.html";
|
||||
|
||||
help = pkgs.writeScriptBin "nixos-help"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
if ! ''${BROWSER:-w3m} ${entry}; then
|
||||
echo "$0: unable to start a web browser; please set \$BROWSER or install ‘w3m’"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -69,7 +80,7 @@ in
|
|||
|
||||
system.build.manual = manual;
|
||||
|
||||
environment.systemPackages = [ manual.manpages ];
|
||||
environment.systemPackages = [ manual.manpages help ];
|
||||
|
||||
boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
|
||||
|
||||
|
@ -78,7 +89,7 @@ in
|
|||
{ description = "NixOS Manual";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig =
|
||||
{ ExecStart = "${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html";
|
||||
{ ExecStart = "${cfg.browser} ${entry}";
|
||||
StandardInput = "tty";
|
||||
StandardOutput = "tty";
|
||||
TTYPath = "/dev/tty${cfg.ttyNumber}";
|
||||
|
|
58
modules/services/monitoring/dd-agent.nix
Normal file
58
modules/services/monitoring/dd-agent.nix
Normal file
|
@ -0,0 +1,58 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
cfg = config.services.dd-agent;
|
||||
|
||||
datadog-conf = pkgs.runCommand "datadog.conf" {} ''
|
||||
sed -e 's|^api_key:|api_key: ${cfg.api_key}|' ${optionalString (cfg.hostname != null)
|
||||
"-e 's|^#hostname: mymachine.mydomain|hostname: ${cfg.hostname}|'"
|
||||
} ${pkgs.dd-agent}/etc/dd-agent/datadog.conf.example > $out
|
||||
'';
|
||||
in {
|
||||
options.services.dd-agent = {
|
||||
enable = mkOption {
|
||||
description = "Whether to enable the dd-agent montioring service";
|
||||
|
||||
default = false;
|
||||
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
# !!! This gets stored in the store (world-readable), wish we had https://github.com/NixOS/nix/issues/8
|
||||
api_key = mkOption {
|
||||
description = "The Datadog API key to associate the agent with your account";
|
||||
|
||||
example = "ae0aa6a8f08efa988ba0a17578f009ab";
|
||||
|
||||
type = types.uniq types.string;
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
description = "The hostname to show in the Datadog dashboard (optional)";
|
||||
|
||||
default = null;
|
||||
|
||||
example = "mymachine.mydomain";
|
||||
|
||||
type = types.uniq (types.nullOr types.string);
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.etc = [ { source = datadog-conf; target = "dd-agent/datadog.conf"; } ];
|
||||
|
||||
boot.systemd.services.dd-agent = {
|
||||
description = "Datadog agent monitor";
|
||||
|
||||
path = [ pkgs.sysstat pkgs.procps ];
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
|
||||
|
||||
restartTriggers = [ pkgs.dd-agent ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -87,7 +87,6 @@ in
|
|||
environment.TZ = config.time.timeZone;
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
partOf = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
|
||||
};
|
||||
|
|
|
@ -97,6 +97,11 @@ in
|
|||
|
||||
wantedBy = [ "network.target" ];
|
||||
|
||||
# Stopping dhcpcd during a reconfiguration is undesirable
|
||||
# because it brings down the network interfaces configured by
|
||||
# dhcpcd. So do a "systemctl restart" instead.
|
||||
stopIfChanged = false;
|
||||
|
||||
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
|
||||
|
||||
serviceConfig =
|
||||
|
|
|
@ -29,6 +29,8 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
check = mkAssert (!(config.services.rpcbind.enable && config.services.portmap.enable))
|
||||
"Portmap and rpcbind cannot both be enabled.";
|
||||
|
||||
in
|
||||
|
||||
|
@ -57,7 +59,7 @@ in
|
|||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.rpcbind.enable {
|
||||
config = mkIf config.services.rpcbind.enable (check {
|
||||
|
||||
environment.systemPackages = [ pkgs.rpcbind ];
|
||||
|
||||
|
@ -77,6 +79,6 @@ in
|
|||
serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind";
|
||||
};
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -267,6 +267,8 @@ in
|
|||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
stopIfChanged = false;
|
||||
|
||||
path = [ pkgs.openssh ];
|
||||
|
||||
environment.LD_LIBRARY_PATH = nssModulesPath;
|
||||
|
|
|
@ -389,7 +389,7 @@ in
|
|||
boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target";
|
||||
|
||||
boot.systemd.services."display-manager" =
|
||||
{ after = [ "systemd-udev-settle.service" ];
|
||||
{ after = [ "systemd-udev-settle.service" "local-fs.target" ];
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ use File::Basename;
|
|||
use File::Slurp;
|
||||
use Cwd 'abs_path';
|
||||
|
||||
my $startListFile = "/run/systemd/start-list";
|
||||
my $restartListFile = "/run/systemd/restart-list";
|
||||
my $reloadListFile = "/run/systemd/reload-list";
|
||||
|
||||
|
@ -116,6 +117,8 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
}
|
||||
|
||||
elsif ($unit =~ /\.target$/) {
|
||||
my $unitInfo = parseUnit($newUnitFile);
|
||||
|
||||
# Cause all active target units to be restarted below.
|
||||
# This should start most changed units we stop here as
|
||||
# well as any new dependencies (including new mounts and
|
||||
|
@ -123,11 +126,25 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
# active after the system has resumed, which probably
|
||||
# should not be the case. Just ignore it.
|
||||
if ($unit ne "suspend.target" && $unit ne "hibernate.target") {
|
||||
my $unitInfo = parseUnit($newUnitFile);
|
||||
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) {
|
||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no")) {
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
}
|
||||
|
||||
# Stop targets that have X-StopOnReconfiguration set.
|
||||
# This is necessary to respect dependency orderings
|
||||
# involving targets: if unit X starts after target Y and
|
||||
# target Y starts after unit Z, then if X and Z have both
|
||||
# changed, then X should be restarted after Z. However,
|
||||
# if target Y is in the "active" state, X and Z will be
|
||||
# restarted at the same time because X's dependency on Y
|
||||
# is already satisfied. Thus, we need to stop Y first.
|
||||
# Stopping a target generally has no effect on other units
|
||||
# (unless there is a PartOf dependency), so this is just a
|
||||
# bookkeeping thing to get systemd to do the right thing.
|
||||
if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "no")) {
|
||||
push @unitsToStop, $unit;
|
||||
}
|
||||
}
|
||||
|
||||
elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
|
||||
|
@ -140,10 +157,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
# FIXME: do something?
|
||||
} else {
|
||||
my $unitInfo = parseUnit($newUnitFile);
|
||||
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")
|
||||
|| $unit eq "systemd-user-sessions.service"
|
||||
|| $unit eq "systemd-journald.service")
|
||||
{
|
||||
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) {
|
||||
push @unitsToSkip, $unit;
|
||||
} else {
|
||||
# If this unit is socket-activated, then stop the
|
||||
|
@ -158,21 +172,31 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||
foreach my $socket (@sockets) {
|
||||
if (defined $activePrev->{$socket}) {
|
||||
push @unitsToStop, $socket;
|
||||
write_file($restartListFile, { append => 1 }, "$socket\n");
|
||||
write_file($startListFile, { append => 1 }, "$socket\n");
|
||||
$socketActivated = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Otherwise, record that this unit needs to be
|
||||
# started below. We write this to a file to
|
||||
# ensure that the service gets restarted if we're
|
||||
# interrupted.
|
||||
if (!$socketActivated) {
|
||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) {
|
||||
|
||||
push @unitsToStop, $unit;
|
||||
# This unit should be restarted instead of
|
||||
# stopped and started.
|
||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||
|
||||
} else {
|
||||
|
||||
# If the unit is not socket-activated, record
|
||||
# that this unit needs to be started below.
|
||||
# We write this to a file to ensure that the
|
||||
# service gets restarted if we're interrupted.
|
||||
if (!$socketActivated) {
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
}
|
||||
|
||||
push @unitsToStop, $unit;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +240,7 @@ foreach my $mountPoint (keys %$prevFss) {
|
|||
push @unitsToStop, $unit;
|
||||
} elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
|
||||
# Filesystem type or device changed, so unmount and mount it.
|
||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||
push @unitsToStop, $unit;
|
||||
} elsif ($prev->{options} ne $new->{options}) {
|
||||
# Mount options changes, so remount it.
|
||||
|
@ -266,16 +290,25 @@ system("@systemd@/bin/systemctl", "reset-failed");
|
|||
# Make systemd reload its units.
|
||||
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
|
||||
|
||||
# Restart changed services (those that have to be restarted rather
|
||||
# than stopped and started).
|
||||
my @restart = unique(split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
|
||||
if (scalar @restart > 0) {
|
||||
print STDERR "restarting the following units: ", join(", ", sort(@restart)), "\n";
|
||||
system("@systemd@/bin/systemctl", "restart", "--", @restart) == 0 or $res = 4;
|
||||
unlink($restartListFile);
|
||||
}
|
||||
|
||||
# Start all active targets, as well as changed units we stopped above.
|
||||
# The latter is necessary because some may not be dependencies of the
|
||||
# targets (i.e., they were manually started). FIXME: detect units
|
||||
# that are symlinks to other units. We shouldn't start both at the
|
||||
# same time because we'll get a "Failed to add path to set" error from
|
||||
# systemd.
|
||||
my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
|
||||
my @start = unique("default.target", split('\n', read_file($startListFile, err_mode => 'quiet') // ""));
|
||||
print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
|
||||
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
||||
unlink($restartListFile);
|
||||
unlink($startListFile);
|
||||
|
||||
# Reload units that need it. This includes remounting changed mount
|
||||
# units.
|
||||
|
|
|
@ -50,7 +50,7 @@ in
|
|||
|
||||
boot.extraKernelParams = mkOption {
|
||||
default = [ ];
|
||||
example = [ "debugtrace" ];
|
||||
example = [ "boot.trace" ];
|
||||
description = "Additional user-defined kernel parameters.";
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
with pkgs.lib;
|
||||
let
|
||||
isEnabled = config.boot.loader.grub.memtest86;
|
||||
memtest86 = pkgs.memtest86;
|
||||
memtest86 = pkgs.memtest86plus;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#! @shell@
|
||||
|
||||
targetRoot=/mnt-root
|
||||
console=tty1
|
||||
|
||||
export LD_LIBRARY_PATH=@extraUtils@/lib
|
||||
export PATH=@extraUtils@/bin:@extraUtils@/sbin
|
||||
|
@ -17,37 +18,31 @@ An error occured in stage 1 of the boot process, which must mount the
|
|||
root filesystem on \`$targetRoot' and then start stage 2. Press one
|
||||
of the following keys:
|
||||
|
||||
i) to launch an interactive shell;
|
||||
EOF
|
||||
if [ -n "$allowShell" ]; then cat <<EOF
|
||||
i) to launch an interactive shell
|
||||
f) to start an interactive shell having pid 1 (needed if you want to
|
||||
start stage 2's init manually); or
|
||||
*) to ignore the error and continue.
|
||||
start stage 2's init manually)
|
||||
EOF
|
||||
fi
|
||||
cat <<EOF
|
||||
r) to reboot immediately
|
||||
*) to ignore the error and continue
|
||||
EOF
|
||||
|
||||
read reply
|
||||
|
||||
# Get the console from the kernel cmdline
|
||||
console=tty1
|
||||
for o in $(cat /proc/cmdline); do
|
||||
case $o in
|
||||
console=*)
|
||||
set -- $(IFS==; echo $o)
|
||||
params=$2
|
||||
set -- $(IFS=,; echo $params)
|
||||
console=$1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case $reply in
|
||||
f)
|
||||
exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" ;;
|
||||
i)
|
||||
echo "Starting interactive shell..."
|
||||
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
|
||||
;;
|
||||
*)
|
||||
echo "Continuing...";;
|
||||
esac
|
||||
if [ -n "$allowShell" -a "$reply" = f ]; then
|
||||
exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console"
|
||||
elif [ -n "$allowShell" -a "$reply" = i ]; then
|
||||
echo "Starting interactive shell..."
|
||||
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
|
||||
elif [ "$reply" = r ]; then
|
||||
echo "Rebooting..."
|
||||
reboot -f
|
||||
else
|
||||
echo "Continuing..."
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'fail' 0
|
||||
|
@ -76,24 +71,36 @@ mount -t securityfs none /sys/kernel/security
|
|||
export stage2Init=/init
|
||||
for o in $(cat /proc/cmdline); do
|
||||
case $o in
|
||||
console=*)
|
||||
set -- $(IFS==; echo $o)
|
||||
params=$2
|
||||
set -- $(IFS=,; echo $params)
|
||||
console=$1
|
||||
;;
|
||||
init=*)
|
||||
set -- $(IFS==; echo $o)
|
||||
stage2Init=$2
|
||||
;;
|
||||
debugtrace)
|
||||
boot.trace|debugtrace)
|
||||
# Show each command.
|
||||
set -x
|
||||
;;
|
||||
debug1) # stop right away
|
||||
boot.shell_on_fail)
|
||||
allowShell=1
|
||||
;;
|
||||
boot.debug1|debug1) # stop right away
|
||||
allowShell=1
|
||||
fail
|
||||
;;
|
||||
debug1devices) # stop after loading modules and creating device nodes
|
||||
boot.debug1devices) # stop after loading modules and creating device nodes
|
||||
allowShell=1
|
||||
debug1devices=1
|
||||
;;
|
||||
debug1mounts) # stop after mounting file systems
|
||||
boot.debug1mounts) # stop after mounting file systems
|
||||
allowShell=1
|
||||
debug1mounts=1
|
||||
;;
|
||||
stage1panic=1)
|
||||
boot.panic_on_fail|stage1panic=1)
|
||||
panicOnFail=1
|
||||
;;
|
||||
root=*)
|
||||
|
@ -180,7 +187,7 @@ onACPower() {
|
|||
checkFS() {
|
||||
local device="$1"
|
||||
local fsType="$2"
|
||||
|
||||
|
||||
# Only check block devices.
|
||||
if [ ! -b "$device" ]; then return 0; fi
|
||||
|
||||
|
@ -219,7 +226,7 @@ checkFS() {
|
|||
if test $(($fsckResult | 2)) = $fsckResult; then
|
||||
echo "fsck finished, rebooting..."
|
||||
sleep 3
|
||||
reboot
|
||||
reboot -f
|
||||
fi
|
||||
|
||||
if test $(($fsckResult | 4)) = $fsckResult; then
|
||||
|
|
|
@ -177,6 +177,7 @@ let
|
|||
cp -v ${pkgs.lvm2}/sbin/dmsetup $out/bin/dmsetup
|
||||
cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm
|
||||
cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib
|
||||
cp -v ${pkgs.systemd}/lib/libsystemd-daemon.so.* $out/lib
|
||||
|
||||
# Add RAID mdadm tool.
|
||||
cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm
|
||||
|
|
|
@ -62,20 +62,12 @@ ln -s /proc/mounts /etc/mtab
|
|||
|
||||
|
||||
# Process the kernel command line.
|
||||
debug2=
|
||||
for o in $(cat /proc/cmdline); do
|
||||
case $o in
|
||||
debugtrace)
|
||||
boot.debugtrace)
|
||||
# Show each command.
|
||||
set -x
|
||||
;;
|
||||
debug2)
|
||||
debug2=1
|
||||
;;
|
||||
S|s|single)
|
||||
# !!! argh, can't pass a startup event to Upstart yet.
|
||||
exec @shell@
|
||||
;;
|
||||
resume=*)
|
||||
set -- $(IFS==; echo $o)
|
||||
resumeDevice=$2
|
||||
|
@ -168,26 +160,6 @@ ln -sfn /run/booted-system /nix/var/nix/gcroots/booted-system
|
|||
@shell@ @postBootCommands@
|
||||
|
||||
|
||||
# For debugging Upstart.
|
||||
if [ -n "$debug2" ]; then
|
||||
# Get the console from the kernel cmdline
|
||||
console=tty1
|
||||
for o in $(cat /proc/cmdline); do
|
||||
case $o in
|
||||
console=*)
|
||||
set -- $(IFS==; echo $o)
|
||||
params=$2
|
||||
set -- $(IFS=,; echo $params)
|
||||
console=$1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Debug shell called from @out@"
|
||||
setsid @shellDebug@ < /dev/$console >/dev/$console 2>/dev/$console
|
||||
fi
|
||||
|
||||
|
||||
# Start systemd.
|
||||
echo "starting systemd..."
|
||||
PATH=/run/current-system/systemd/lib/systemd \
|
||||
|
|
|
@ -183,6 +183,21 @@ rec {
|
|||
'';
|
||||
};
|
||||
|
||||
stopIfChanged = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
If set, a changed unit is restarted by calling
|
||||
<command>systemctl stop</command> in the old configuration,
|
||||
then <command>systemctl start</command> in the new one.
|
||||
Otherwise, it is restarted in a single step using
|
||||
<command>systemctl restart</command> in the new configuration.
|
||||
The latter is less correct because it runs the
|
||||
<literal>ExecStop</literal> commands from the new
|
||||
configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,12 +23,11 @@ let
|
|||
upstreamUnits =
|
||||
[ # Targets.
|
||||
"basic.target"
|
||||
#"sysinit.target"
|
||||
"sysinit.target"
|
||||
"sockets.target"
|
||||
"graphical.target"
|
||||
"multi-user.target"
|
||||
"getty.target"
|
||||
"rescue.target"
|
||||
"network.target"
|
||||
"nss-lookup.target"
|
||||
"nss-user-lookup.target"
|
||||
|
@ -37,6 +36,12 @@ let
|
|||
#"cryptsetup.target"
|
||||
"sigpwr.target"
|
||||
|
||||
# Rescue/emergency.
|
||||
"rescue.target"
|
||||
"rescue.service"
|
||||
"emergency.target"
|
||||
"emergency.service"
|
||||
|
||||
# Udev.
|
||||
"systemd-udevd-control.socket"
|
||||
"systemd-udevd-kernel.socket"
|
||||
|
@ -139,33 +144,6 @@ let
|
|||
"shutdown.target.wants"
|
||||
];
|
||||
|
||||
rescueService =
|
||||
''
|
||||
[Unit]
|
||||
Description=Rescue Shell
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
After=sysinit.target
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Environment=HOME=/root
|
||||
WorkingDirectory=/root
|
||||
ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.'
|
||||
#ExecStart=-/sbin/sulogin
|
||||
ExecStart=-${pkgs.bashInteractive}/bin/bash --login
|
||||
ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default
|
||||
Type=idle
|
||||
StandardInput=tty-force
|
||||
StandardOutput=inherit
|
||||
StandardError=inherit
|
||||
KillMode=process
|
||||
|
||||
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
|
||||
# terminates cleanly.
|
||||
KillSignal=SIGHUP
|
||||
'';
|
||||
|
||||
makeJobScript = name: text:
|
||||
let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${name}"; inherit text; };
|
||||
in "${x}/bin/${name}";
|
||||
|
@ -246,6 +224,7 @@ let
|
|||
${let env = cfg.globalEnvironment // def.environment;
|
||||
in concatMapStrings (n: "Environment=${n}=${getAttr n env}\n") (attrNames env)}
|
||||
${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"}
|
||||
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
|
||||
|
||||
${optionalString (def.preStart != "") ''
|
||||
ExecStartPre=${makeJobScript "${name}-pre-start" ''
|
||||
|
@ -346,6 +325,8 @@ let
|
|||
|
||||
ln -s ${cfg.defaultUnit} $out/default.target
|
||||
|
||||
ln -s rescue.target $out/kbrequest.target
|
||||
|
||||
#ln -s ../getty@tty1.service $out/multi-user.target.wants/
|
||||
ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \
|
||||
../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
|
||||
|
@ -523,20 +504,8 @@ in
|
|||
{ description = "Security Keys";
|
||||
};
|
||||
|
||||
# This is like the upstream sysinit.target, except that it doesn't
|
||||
# depend on local-fs.target and swap.target. If services need to
|
||||
# be started after some filesystem (local or otherwise) has been
|
||||
# mounted, they should use the RequiresMountsFor option.
|
||||
boot.systemd.targets.sysinit =
|
||||
{ description = "System Initialization";
|
||||
after = [ "emergency.service" "emergency.target" ];
|
||||
unitConfig.Conflicts = "emergency.service emergency.target";
|
||||
unitConfig.RefuseManualStart = true;
|
||||
};
|
||||
|
||||
boot.systemd.units =
|
||||
{ "rescue.service".text = rescueService; }
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
|
||||
mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
|
||||
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets
|
||||
// listToAttrs (map
|
||||
|
|
|
@ -135,6 +135,16 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
networking.defaultGatewayWindowSize = mkOption {
|
||||
default = null;
|
||||
example = 524288;
|
||||
type = types.nullOr types.int;
|
||||
description = ''
|
||||
The window size of the default gateway. It limits maximal data bursts that TCP peers
|
||||
are allowed to send to us.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.nameservers = mkOption {
|
||||
default = [];
|
||||
example = ["130.161.158.4" "130.161.33.17"];
|
||||
|
@ -245,6 +255,7 @@ in
|
|||
boot.systemd.targets."network-interfaces" =
|
||||
{ description = "All Network Interfaces";
|
||||
wantedBy = [ "network.target" ];
|
||||
unitConfig.X-StopOnReconfiguration = true;
|
||||
};
|
||||
|
||||
boot.systemd.services =
|
||||
|
@ -282,7 +293,9 @@ in
|
|||
# Set the default gateway.
|
||||
${optionalString (cfg.defaultGateway != "") ''
|
||||
# FIXME: get rid of "|| true" (necessary to make it idempotent).
|
||||
ip route add default via "${cfg.defaultGateway}" || true
|
||||
ip route add default via "${cfg.defaultGateway}" ${
|
||||
optionalString (cfg.defaultGatewayWindowSize != null)
|
||||
"window ${cfg.defaultGatewayWindowSize}"} || true
|
||||
''}
|
||||
|
||||
# Turn on forwarding if any interface has enabled proxy_arp.
|
||||
|
@ -335,6 +348,9 @@ in
|
|||
echo "configuring interface..."
|
||||
ip -4 addr flush dev "${i.name}"
|
||||
ip -4 addr add "${i.ipAddress}/${mask}" dev "${i.name}"
|
||||
# Ensure that the default gateway remains set.
|
||||
# (Flushing this interface may have removed it.)
|
||||
${config.system.build.systemd}/bin/systemctl try-restart --no-block network-setup.service
|
||||
else
|
||||
echo "skipping configuring interface"
|
||||
fi
|
||||
|
|
|
@ -65,7 +65,7 @@ let kernel = config.boot.kernelPackages.kernel; in
|
|||
# Panic if an error occurs in stage 1 (rather than waiting for
|
||||
# user intervention).
|
||||
boot.kernelParams =
|
||||
[ "console=tty1" "console=ttyS0" "panic=1" "stage1panic=1" ];
|
||||
[ "console=tty1" "console=ttyS0" "panic=1" "boot.panic_on_fail" ];
|
||||
|
||||
# `xwininfo' is used by the test driver to query open windows.
|
||||
environment.systemPackages = [ pkgs.xorg.xwininfo ];
|
||||
|
|
Loading…
Reference in a new issue