Merge branch 'systemd' of github.com:NixOS/nixos into systemd
This commit is contained in:
commit
30586846ce
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
|
mkdir -p $dst/images/callouts
|
||||||
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
||||||
|
|
||||||
cp ${./style.css} $dst/style.css
|
cp ${./style.css} $dst/style.css
|
||||||
|
|
||||||
ensureDir $out/nix-support
|
ensureDir $out/nix-support
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
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:
|
<listitem><para>For partitioning:
|
||||||
<command>fdisk</command>.</para></listitem>
|
<command>fdisk</command>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>For initialising Ext4 partitions:
|
<listitem><para>For initialising Ext4 partitions:
|
||||||
<command>mkfs.ext4</command>. It is recommended that you assign a
|
<command>mkfs.ext4</command>. It is recommended that you assign a
|
||||||
unique symbolic label to the file system using the option
|
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
|
<command>mkswap</command>. Again it’s recommended to assign a
|
||||||
label to the swap partition: <option>-L
|
label to the swap partition: <option>-L
|
||||||
<replaceable>label</replaceable></option>.</para></listitem>
|
<replaceable>label</replaceable></option>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
<listitem><para>For creating LVM volumes, the LVM commands, e.g.,
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ pvcreate /dev/sda1 /dev/sdb1
|
$ pvcreate /dev/sda1 /dev/sdb1
|
||||||
$ vgcreate MyVolGroup /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>
|
$ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
||||||
|
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
@ -87,7 +87,7 @@ $ lvcreate --size 1G --name smalldisk MyVolGroup</screen>
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Mount the target file system on which NixOS should
|
<listitem><para>Mount the target file system on which NixOS should
|
||||||
be installed on <filename>/mnt</filename>.</para></listitem>
|
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>
|
xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>.</para>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem><para>If your machine has a limited amount of memory, you
|
<listitem><para>If your machine has a limited amount of memory, you
|
||||||
may want to activate swap devices now (<command>swapon
|
may want to activate swap devices now (<command>swapon
|
||||||
<replaceable>device</replaceable></command>). The installer (or
|
<replaceable>device</replaceable></command>). The installer (or
|
||||||
@ -234,7 +234,7 @@ $ reboot</screen>
|
|||||||
|
|
||||||
swapDevices =
|
swapDevices =
|
||||||
[ { device = "/dev/disk/by-label/swap"; } ];
|
[ { device = "/dev/disk/by-label/swap"; } ];
|
||||||
|
|
||||||
services.sshd.enable = true;
|
services.sshd.enable = true;
|
||||||
}</screen>
|
}</screen>
|
||||||
</example>
|
</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
|
booting, and try to realise the configuration in the running system
|
||||||
(e.g., by restarting system services).</para>
|
(e.g., by restarting system services).</para>
|
||||||
|
|
||||||
<para>You can also do
|
<para>You can also do
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nixos-rebuild test</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
|
locks up your machine, you can just reboot to get back to a working
|
||||||
configuration.</para>
|
configuration.</para>
|
||||||
|
|
||||||
<para>There is also
|
<para>There is also
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nixos-rebuild boot</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
|
switch to it now (so it will only take effect after the next
|
||||||
reboot).</para>
|
reboot).</para>
|
||||||
|
|
||||||
<para>Finally, you can do
|
<para>Finally, you can do
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nixos-rebuild build</screen>
|
$ nixos-rebuild build</screen>
|
||||||
@ -329,7 +329,7 @@ You can then upgrade NixOS to the latest version in the channel by
|
|||||||
running
|
running
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-channel --update
|
$ nix-channel --update nixos
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
and running the <command>nixos-rebuild</command> command as described
|
and running the <command>nixos-rebuild</command> command as described
|
||||||
|
@ -24,16 +24,16 @@
|
|||||||
<year>2007-2012</year>
|
<year>2007-2012</year>
|
||||||
<holder>Eelco Dolstra</holder>
|
<holder>Eelco Dolstra</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
</info>
|
</info>
|
||||||
|
|
||||||
|
|
||||||
<preface>
|
<preface>
|
||||||
<title>Preface</title>
|
<title>Preface</title>
|
||||||
|
|
||||||
<para>This manual describes NixOS, a Linux distribution based on
|
<para>This manual describes NixOS, a Linux distribution based on
|
||||||
the purely functional package management system Nix.</para>
|
the purely functional package management system Nix.</para>
|
||||||
|
|
||||||
<para>NixOS is rather bleeding edge, and this manual is
|
<para>NixOS is rather bleeding edge, and this manual is
|
||||||
correspondingly sketchy and quite possibly out of date. It gives
|
correspondingly sketchy and quite possibly out of date. It gives
|
||||||
basic information on how to get NixOS up and running, but since
|
basic information on how to get NixOS up and running, but since
|
||||||
@ -45,11 +45,13 @@
|
|||||||
mailing list or on <link
|
mailing list or on <link
|
||||||
xlink:href="irc://irc.freenode.net/#nixos">the
|
xlink:href="irc://irc.freenode.net/#nixos">the
|
||||||
<literal>#nixos</literal> channel on Freenode.</link>.</para>
|
<literal>#nixos</literal> channel on Freenode.</link>.</para>
|
||||||
|
|
||||||
</preface>
|
</preface>
|
||||||
|
|
||||||
|
|
||||||
<xi:include href="installation.xml" />
|
<xi:include href="installation.xml" />
|
||||||
|
<xi:include href="configuration.xml" />
|
||||||
|
<xi:include href="running.xml" />
|
||||||
<!-- <xi:include href="userconfiguration.xml" /> -->
|
<!-- <xi:include href="userconfiguration.xml" /> -->
|
||||||
<xi:include href="troubleshooting.xml" />
|
<xi:include href="troubleshooting.xml" />
|
||||||
<xi:include href="development.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>
|
<title>Troubleshooting</title>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section><title>Boot problems</title>
|
||||||
|
|
||||||
<title>Debugging the boot process</title>
|
|
||||||
|
|
||||||
<para>To get a Stage 1 shell (i.e., a shell in the initial ramdisk),
|
<para>If NixOS fails to boot, there are a number of kernel command
|
||||||
add <literal>debug1</literal> to the kernel command line. The shell
|
line parameters that may help you to identify or fix the issue. You
|
||||||
gets started before anything useful has been done. That is, no
|
can add these parameters in the GRUB boot menu by pressing “e” to
|
||||||
modules have been loaded and no file systems have been mounted, except
|
modify the selected boot entry and editing the line starting with
|
||||||
for <filename>/proc</filename> and <filename>/sys</filename>.</para>
|
<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
|
<variablelist>
|
||||||
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>
|
|
||||||
|
|
||||||
</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>
|
<varlistentry><term><literal>single</literal></term>
|
||||||
|
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
|
||||||
<title>Safe mode</title>
|
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
|
<varlistentry><term><literal>systemd.log_level=debug systemd.log_target=console</literal></term>
|
||||||
<filename>upstart-jobs/hardware-scan</filename>) causes problems, add
|
<listitem><para>Make systemd very verbose and send log messages to
|
||||||
<literal>safemode</literal> to the kernel command line. This will
|
the console instead of the journal.</para></listitem>
|
||||||
disable auto-loading of modules for your PCI devices. However, you
|
</varlistentry>
|
||||||
will probably need to explicitly add modules to
|
|
||||||
<option>boot.kernelModules</option> to get network support etc.</para>
|
</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>
|
||||||
|
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|
||||||
<title>Maintenance mode</title>
|
<title>Maintenance mode</title>
|
||||||
|
|
||||||
<para>You can go to maintenance mode by doing
|
<para>You can enter rescue mode by running:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ shutdown now</screen>
|
$ systemctl rescue</screen>
|
||||||
|
|
||||||
This will eventually give you a single-user root shell.
|
This will eventually give you a single-user root shell. Systemd will
|
||||||
|
stop (almost) all system services. To get out of maintenance mode,
|
||||||
To get out of maintenance mode, do
|
just exit from the rescue shell.</para>
|
||||||
|
|
||||||
<screen>
|
|
||||||
$ initctl emit startup</screen>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -100,6 +100,7 @@
|
|||||||
./services/misc/rogue.nix
|
./services/misc/rogue.nix
|
||||||
./services/misc/svnserve.nix
|
./services/misc/svnserve.nix
|
||||||
./services/misc/synergy.nix
|
./services/misc/synergy.nix
|
||||||
|
./services/monitoring/dd-agent.nix
|
||||||
./services/monitoring/monit.nix
|
./services/monitoring/monit.nix
|
||||||
./services/monitoring/nagios/default.nix
|
./services/monitoring/nagios/default.nix
|
||||||
./services/monitoring/smartd.nix
|
./services/monitoring/smartd.nix
|
||||||
|
@ -16,5 +16,5 @@ with pkgs.lib;
|
|||||||
boot.systemd.services."serial-getty@hvc0".enable = false;
|
boot.systemd.services."serial-getty@hvc0".enable = false;
|
||||||
|
|
||||||
# Since we can't manually respond to a panic, just reboot.
|
# 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;
|
environment = cfg.envVars;
|
||||||
|
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
{ ExecStart = "${nix}/bin/nix-worker --daemon";
|
{ ExecStart = "@${nix}/bin/nix-daemon nix-daemon";
|
||||||
KillMode = "process";
|
KillMode = "process";
|
||||||
Nice = cfg.daemonNiceLevel;
|
Nice = cfg.daemonNiceLevel;
|
||||||
IOSchedulingPriority = cfg.daemonIONiceLevel;
|
IOSchedulingPriority = cfg.daemonIONiceLevel;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
nix = config.environment.nix;
|
|
||||||
cfg = config.nix.gc;
|
cfg = config.nix.gc;
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ in
|
|||||||
|
|
||||||
automatic = mkOption {
|
automatic = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
type = types.bool;
|
||||||
description = "
|
description = "
|
||||||
Automatically run the garbage collector at specified dates.
|
Automatically run the garbage collector at specified dates.
|
||||||
";
|
";
|
||||||
@ -24,6 +23,7 @@ in
|
|||||||
|
|
||||||
dates = mkOption {
|
dates = mkOption {
|
||||||
default = "15 03 * * *";
|
default = "15 03 * * *";
|
||||||
|
type = types.string;
|
||||||
description = "
|
description = "
|
||||||
Run the garbage collector at specified dates to avoid full
|
Run the garbage collector at specified dates to avoid full
|
||||||
hard-drives.
|
hard-drives.
|
||||||
@ -33,6 +33,7 @@ in
|
|||||||
options = mkOption {
|
options = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example = "--max-freed $((64 * 1024**3))";
|
example = "--max-freed $((64 * 1024**3))";
|
||||||
|
type = types.string;
|
||||||
description = "
|
description = "
|
||||||
Options given to <filename>nix-collect-garbage</filename> when the
|
Options given to <filename>nix-collect-garbage</filename> when the
|
||||||
garbage collector is run automatically.
|
garbage collector is run automatically.
|
||||||
@ -45,10 +46,17 @@ in
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf cfg.automatic {
|
config = {
|
||||||
services.cron.systemCronJobs = [
|
|
||||||
"${cfg.dates} root ${nix}/bin/nix-collect-garbage ${cfg.options} > /var/log/gc.log 2>&1"
|
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;
|
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
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -69,7 +80,7 @@ in
|
|||||||
|
|
||||||
system.build.manual = manual;
|
system.build.manual = manual;
|
||||||
|
|
||||||
environment.systemPackages = [ manual.manpages ];
|
environment.systemPackages = [ manual.manpages help ];
|
||||||
|
|
||||||
boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
|
boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
|
||||||
|
|
||||||
@ -78,7 +89,7 @@ in
|
|||||||
{ description = "NixOS Manual";
|
{ description = "NixOS Manual";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
{ ExecStart = "${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html";
|
{ ExecStart = "${cfg.browser} ${entry}";
|
||||||
StandardInput = "tty";
|
StandardInput = "tty";
|
||||||
StandardOutput = "tty";
|
StandardOutput = "tty";
|
||||||
TTYPath = "/dev/tty${cfg.ttyNumber}";
|
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;
|
environment.TZ = config.time.timeZone;
|
||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
partOf = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
|
serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
|
||||||
};
|
};
|
||||||
|
@ -97,6 +97,11 @@ in
|
|||||||
|
|
||||||
wantedBy = [ "network.target" ];
|
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 ];
|
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
|
||||||
|
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
|
@ -29,6 +29,8 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
check = mkAssert (!(config.services.rpcbind.enable && config.services.portmap.enable))
|
||||||
|
"Portmap and rpcbind cannot both be enabled.";
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ in
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf config.services.rpcbind.enable {
|
config = mkIf config.services.rpcbind.enable (check {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.rpcbind ];
|
environment.systemPackages = [ pkgs.rpcbind ];
|
||||||
|
|
||||||
@ -77,6 +79,6 @@ in
|
|||||||
serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind";
|
serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,8 @@ in
|
|||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
stopIfChanged = false;
|
||||||
|
|
||||||
path = [ pkgs.openssh ];
|
path = [ pkgs.openssh ];
|
||||||
|
|
||||||
environment.LD_LIBRARY_PATH = nssModulesPath;
|
environment.LD_LIBRARY_PATH = nssModulesPath;
|
||||||
|
@ -389,7 +389,7 @@ in
|
|||||||
boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target";
|
boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target";
|
||||||
|
|
||||||
boot.systemd.services."display-manager" =
|
boot.systemd.services."display-manager" =
|
||||||
{ after = [ "systemd-udev-settle.service" ];
|
{ after = [ "systemd-udev-settle.service" "local-fs.target" ];
|
||||||
|
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ use File::Basename;
|
|||||||
use File::Slurp;
|
use File::Slurp;
|
||||||
use Cwd 'abs_path';
|
use Cwd 'abs_path';
|
||||||
|
|
||||||
|
my $startListFile = "/run/systemd/start-list";
|
||||||
my $restartListFile = "/run/systemd/restart-list";
|
my $restartListFile = "/run/systemd/restart-list";
|
||||||
my $reloadListFile = "/run/systemd/reload-list";
|
my $reloadListFile = "/run/systemd/reload-list";
|
||||||
|
|
||||||
@ -116,6 +117,8 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
elsif ($unit =~ /\.target$/) {
|
elsif ($unit =~ /\.target$/) {
|
||||||
|
my $unitInfo = parseUnit($newUnitFile);
|
||||||
|
|
||||||
# Cause all active target units to be restarted below.
|
# Cause all active target units to be restarted below.
|
||||||
# This should start most changed units we stop here as
|
# This should start most changed units we stop here as
|
||||||
# well as any new dependencies (including new mounts and
|
# 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
|
# active after the system has resumed, which probably
|
||||||
# should not be the case. Just ignore it.
|
# should not be the case. Just ignore it.
|
||||||
if ($unit ne "suspend.target" && $unit ne "hibernate.target") {
|
if ($unit ne "suspend.target" && $unit ne "hibernate.target") {
|
||||||
my $unitInfo = parseUnit($newUnitFile);
|
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no")) {
|
||||||
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) {
|
write_file($startListFile, { append => 1 }, "$unit\n");
|
||||||
write_file($restartListFile, { 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)) {
|
elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
|
||||||
@ -140,10 +157,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||||||
# FIXME: do something?
|
# FIXME: do something?
|
||||||
} else {
|
} else {
|
||||||
my $unitInfo = parseUnit($newUnitFile);
|
my $unitInfo = parseUnit($newUnitFile);
|
||||||
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")
|
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) {
|
||||||
|| $unit eq "systemd-user-sessions.service"
|
|
||||||
|| $unit eq "systemd-journald.service")
|
|
||||||
{
|
|
||||||
push @unitsToSkip, $unit;
|
push @unitsToSkip, $unit;
|
||||||
} else {
|
} else {
|
||||||
# If this unit is socket-activated, then stop the
|
# If this unit is socket-activated, then stop the
|
||||||
@ -158,21 +172,31 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||||||
foreach my $socket (@sockets) {
|
foreach my $socket (@sockets) {
|
||||||
if (defined $activePrev->{$socket}) {
|
if (defined $activePrev->{$socket}) {
|
||||||
push @unitsToStop, $socket;
|
push @unitsToStop, $socket;
|
||||||
write_file($restartListFile, { append => 1 }, "$socket\n");
|
write_file($startListFile, { append => 1 }, "$socket\n");
|
||||||
$socketActivated = 1;
|
$socketActivated = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Otherwise, record that this unit needs to be
|
if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) {
|
||||||
# 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
push @unitsToStop, $unit;
|
||||||
} elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
|
} elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
|
||||||
# Filesystem type or device changed, so unmount and mount it.
|
# 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;
|
push @unitsToStop, $unit;
|
||||||
} elsif ($prev->{options} ne $new->{options}) {
|
} elsif ($prev->{options} ne $new->{options}) {
|
||||||
# Mount options changes, so remount it.
|
# Mount options changes, so remount it.
|
||||||
@ -266,16 +290,25 @@ system("@systemd@/bin/systemctl", "reset-failed");
|
|||||||
# Make systemd reload its units.
|
# Make systemd reload its units.
|
||||||
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
|
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.
|
# Start all active targets, as well as changed units we stopped above.
|
||||||
# The latter is necessary because some may not be dependencies of the
|
# The latter is necessary because some may not be dependencies of the
|
||||||
# targets (i.e., they were manually started). FIXME: detect units
|
# targets (i.e., they were manually started). FIXME: detect units
|
||||||
# that are symlinks to other units. We shouldn't start both at the
|
# 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
|
# same time because we'll get a "Failed to add path to set" error from
|
||||||
# systemd.
|
# 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";
|
print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
|
||||||
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
||||||
unlink($restartListFile);
|
unlink($startListFile);
|
||||||
|
|
||||||
# Reload units that need it. This includes remounting changed mount
|
# Reload units that need it. This includes remounting changed mount
|
||||||
# units.
|
# units.
|
||||||
|
@ -50,7 +50,7 @@ in
|
|||||||
|
|
||||||
boot.extraKernelParams = mkOption {
|
boot.extraKernelParams = mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
example = [ "debugtrace" ];
|
example = [ "boot.trace" ];
|
||||||
description = "Additional user-defined kernel parameters.";
|
description = "Additional user-defined kernel parameters.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
let
|
let
|
||||||
isEnabled = config.boot.loader.grub.memtest86;
|
isEnabled = config.boot.loader.grub.memtest86;
|
||||||
memtest86 = pkgs.memtest86;
|
memtest86 = pkgs.memtest86plus;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#! @shell@
|
#! @shell@
|
||||||
|
|
||||||
targetRoot=/mnt-root
|
targetRoot=/mnt-root
|
||||||
|
console=tty1
|
||||||
|
|
||||||
export LD_LIBRARY_PATH=@extraUtils@/lib
|
export LD_LIBRARY_PATH=@extraUtils@/lib
|
||||||
export PATH=@extraUtils@/bin:@extraUtils@/sbin
|
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
|
root filesystem on \`$targetRoot' and then start stage 2. Press one
|
||||||
of the following keys:
|
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
|
f) to start an interactive shell having pid 1 (needed if you want to
|
||||||
start stage 2's init manually); or
|
start stage 2's init manually)
|
||||||
*) to ignore the error and continue.
|
EOF
|
||||||
|
fi
|
||||||
|
cat <<EOF
|
||||||
|
r) to reboot immediately
|
||||||
|
*) to ignore the error and continue
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
read reply
|
read reply
|
||||||
|
|
||||||
# Get the console from the kernel cmdline
|
if [ -n "$allowShell" -a "$reply" = f ]; then
|
||||||
console=tty1
|
exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console"
|
||||||
for o in $(cat /proc/cmdline); do
|
elif [ -n "$allowShell" -a "$reply" = i ]; then
|
||||||
case $o in
|
echo "Starting interactive shell..."
|
||||||
console=*)
|
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
|
||||||
set -- $(IFS==; echo $o)
|
elif [ "$reply" = r ]; then
|
||||||
params=$2
|
echo "Rebooting..."
|
||||||
set -- $(IFS=,; echo $params)
|
reboot -f
|
||||||
console=$1
|
else
|
||||||
;;
|
echo "Continuing..."
|
||||||
esac
|
fi
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trap 'fail' 0
|
trap 'fail' 0
|
||||||
@ -76,24 +71,36 @@ mount -t securityfs none /sys/kernel/security
|
|||||||
export stage2Init=/init
|
export stage2Init=/init
|
||||||
for o in $(cat /proc/cmdline); do
|
for o in $(cat /proc/cmdline); do
|
||||||
case $o in
|
case $o in
|
||||||
|
console=*)
|
||||||
|
set -- $(IFS==; echo $o)
|
||||||
|
params=$2
|
||||||
|
set -- $(IFS=,; echo $params)
|
||||||
|
console=$1
|
||||||
|
;;
|
||||||
init=*)
|
init=*)
|
||||||
set -- $(IFS==; echo $o)
|
set -- $(IFS==; echo $o)
|
||||||
stage2Init=$2
|
stage2Init=$2
|
||||||
;;
|
;;
|
||||||
debugtrace)
|
boot.trace|debugtrace)
|
||||||
# Show each command.
|
# Show each command.
|
||||||
set -x
|
set -x
|
||||||
;;
|
;;
|
||||||
debug1) # stop right away
|
boot.shell_on_fail)
|
||||||
|
allowShell=1
|
||||||
|
;;
|
||||||
|
boot.debug1|debug1) # stop right away
|
||||||
|
allowShell=1
|
||||||
fail
|
fail
|
||||||
;;
|
;;
|
||||||
debug1devices) # stop after loading modules and creating device nodes
|
boot.debug1devices) # stop after loading modules and creating device nodes
|
||||||
|
allowShell=1
|
||||||
debug1devices=1
|
debug1devices=1
|
||||||
;;
|
;;
|
||||||
debug1mounts) # stop after mounting file systems
|
boot.debug1mounts) # stop after mounting file systems
|
||||||
|
allowShell=1
|
||||||
debug1mounts=1
|
debug1mounts=1
|
||||||
;;
|
;;
|
||||||
stage1panic=1)
|
boot.panic_on_fail|stage1panic=1)
|
||||||
panicOnFail=1
|
panicOnFail=1
|
||||||
;;
|
;;
|
||||||
root=*)
|
root=*)
|
||||||
@ -180,7 +187,7 @@ onACPower() {
|
|||||||
checkFS() {
|
checkFS() {
|
||||||
local device="$1"
|
local device="$1"
|
||||||
local fsType="$2"
|
local fsType="$2"
|
||||||
|
|
||||||
# Only check block devices.
|
# Only check block devices.
|
||||||
if [ ! -b "$device" ]; then return 0; fi
|
if [ ! -b "$device" ]; then return 0; fi
|
||||||
|
|
||||||
@ -219,7 +226,7 @@ checkFS() {
|
|||||||
if test $(($fsckResult | 2)) = $fsckResult; then
|
if test $(($fsckResult | 2)) = $fsckResult; then
|
||||||
echo "fsck finished, rebooting..."
|
echo "fsck finished, rebooting..."
|
||||||
sleep 3
|
sleep 3
|
||||||
reboot
|
reboot -f
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $(($fsckResult | 4)) = $fsckResult; then
|
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/dmsetup $out/bin/dmsetup
|
||||||
cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm
|
cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm
|
||||||
cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib
|
cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib
|
||||||
|
cp -v ${pkgs.systemd}/lib/libsystemd-daemon.so.* $out/lib
|
||||||
|
|
||||||
# Add RAID mdadm tool.
|
# Add RAID mdadm tool.
|
||||||
cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm
|
cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm
|
||||||
|
@ -62,20 +62,12 @@ ln -s /proc/mounts /etc/mtab
|
|||||||
|
|
||||||
|
|
||||||
# Process the kernel command line.
|
# Process the kernel command line.
|
||||||
debug2=
|
|
||||||
for o in $(cat /proc/cmdline); do
|
for o in $(cat /proc/cmdline); do
|
||||||
case $o in
|
case $o in
|
||||||
debugtrace)
|
boot.debugtrace)
|
||||||
# Show each command.
|
# Show each command.
|
||||||
set -x
|
set -x
|
||||||
;;
|
;;
|
||||||
debug2)
|
|
||||||
debug2=1
|
|
||||||
;;
|
|
||||||
S|s|single)
|
|
||||||
# !!! argh, can't pass a startup event to Upstart yet.
|
|
||||||
exec @shell@
|
|
||||||
;;
|
|
||||||
resume=*)
|
resume=*)
|
||||||
set -- $(IFS==; echo $o)
|
set -- $(IFS==; echo $o)
|
||||||
resumeDevice=$2
|
resumeDevice=$2
|
||||||
@ -168,26 +160,6 @@ ln -sfn /run/booted-system /nix/var/nix/gcroots/booted-system
|
|||||||
@shell@ @postBootCommands@
|
@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.
|
# Start systemd.
|
||||||
echo "starting systemd..."
|
echo "starting systemd..."
|
||||||
PATH=/run/current-system/systemd/lib/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 =
|
upstreamUnits =
|
||||||
[ # Targets.
|
[ # Targets.
|
||||||
"basic.target"
|
"basic.target"
|
||||||
#"sysinit.target"
|
"sysinit.target"
|
||||||
"sockets.target"
|
"sockets.target"
|
||||||
"graphical.target"
|
"graphical.target"
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
"getty.target"
|
"getty.target"
|
||||||
"rescue.target"
|
|
||||||
"network.target"
|
"network.target"
|
||||||
"nss-lookup.target"
|
"nss-lookup.target"
|
||||||
"nss-user-lookup.target"
|
"nss-user-lookup.target"
|
||||||
@ -37,6 +36,12 @@ let
|
|||||||
#"cryptsetup.target"
|
#"cryptsetup.target"
|
||||||
"sigpwr.target"
|
"sigpwr.target"
|
||||||
|
|
||||||
|
# Rescue/emergency.
|
||||||
|
"rescue.target"
|
||||||
|
"rescue.service"
|
||||||
|
"emergency.target"
|
||||||
|
"emergency.service"
|
||||||
|
|
||||||
# Udev.
|
# Udev.
|
||||||
"systemd-udevd-control.socket"
|
"systemd-udevd-control.socket"
|
||||||
"systemd-udevd-kernel.socket"
|
"systemd-udevd-kernel.socket"
|
||||||
@ -139,33 +144,6 @@ let
|
|||||||
"shutdown.target.wants"
|
"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:
|
makeJobScript = name: text:
|
||||||
let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${name}"; inherit text; };
|
let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${name}"; inherit text; };
|
||||||
in "${x}/bin/${name}";
|
in "${x}/bin/${name}";
|
||||||
@ -246,6 +224,7 @@ let
|
|||||||
${let env = cfg.globalEnvironment // def.environment;
|
${let env = cfg.globalEnvironment // def.environment;
|
||||||
in concatMapStrings (n: "Environment=${n}=${getAttr n env}\n") (attrNames env)}
|
in concatMapStrings (n: "Environment=${n}=${getAttr n env}\n") (attrNames env)}
|
||||||
${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"}
|
${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"}
|
||||||
|
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
|
||||||
|
|
||||||
${optionalString (def.preStart != "") ''
|
${optionalString (def.preStart != "") ''
|
||||||
ExecStartPre=${makeJobScript "${name}-pre-start" ''
|
ExecStartPre=${makeJobScript "${name}-pre-start" ''
|
||||||
@ -346,6 +325,8 @@ let
|
|||||||
|
|
||||||
ln -s ${cfg.defaultUnit} $out/default.target
|
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 ../getty@tty1.service $out/multi-user.target.wants/
|
||||||
ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \
|
ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \
|
||||||
../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
|
../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
|
||||||
@ -523,20 +504,8 @@ in
|
|||||||
{ description = "Security Keys";
|
{ 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 =
|
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}.service" (serviceToUnit n v)) cfg.services
|
||||||
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets
|
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets
|
||||||
// listToAttrs (map
|
// 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 {
|
networking.nameservers = mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
example = ["130.161.158.4" "130.161.33.17"];
|
example = ["130.161.158.4" "130.161.33.17"];
|
||||||
@ -245,6 +255,7 @@ in
|
|||||||
boot.systemd.targets."network-interfaces" =
|
boot.systemd.targets."network-interfaces" =
|
||||||
{ description = "All Network Interfaces";
|
{ description = "All Network Interfaces";
|
||||||
wantedBy = [ "network.target" ];
|
wantedBy = [ "network.target" ];
|
||||||
|
unitConfig.X-StopOnReconfiguration = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.systemd.services =
|
boot.systemd.services =
|
||||||
@ -282,7 +293,9 @@ in
|
|||||||
# Set the default gateway.
|
# Set the default gateway.
|
||||||
${optionalString (cfg.defaultGateway != "") ''
|
${optionalString (cfg.defaultGateway != "") ''
|
||||||
# FIXME: get rid of "|| true" (necessary to make it idempotent).
|
# 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.
|
# Turn on forwarding if any interface has enabled proxy_arp.
|
||||||
@ -335,6 +348,9 @@ in
|
|||||||
echo "configuring interface..."
|
echo "configuring interface..."
|
||||||
ip -4 addr flush dev "${i.name}"
|
ip -4 addr flush dev "${i.name}"
|
||||||
ip -4 addr add "${i.ipAddress}/${mask}" 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
|
else
|
||||||
echo "skipping configuring interface"
|
echo "skipping configuring interface"
|
||||||
fi
|
fi
|
||||||
|
@ -65,7 +65,7 @@ let kernel = config.boot.kernelPackages.kernel; in
|
|||||||
# Panic if an error occurs in stage 1 (rather than waiting for
|
# Panic if an error occurs in stage 1 (rather than waiting for
|
||||||
# user intervention).
|
# user intervention).
|
||||||
boot.kernelParams =
|
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.
|
# `xwininfo' is used by the test driver to query open windows.
|
||||||
environment.systemPackages = [ pkgs.xorg.xwininfo ];
|
environment.systemPackages = [ pkgs.xorg.xwininfo ];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user