Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swapspace: dynamically manage swapspace on NixOS #88093

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@
<link linkend="opt-services.prosody-filer.enable">services.prosody-filer</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/Tookmund/Swapspace">Swapspace</link>,
dynamic swap management via swapfiles. Avaliable at
<link linkend="opt-services.swapspace.enable">services.swapspace</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://timetagger.app">timetagger</link>,
Expand Down
11 changes: 7 additions & 4 deletions nixos/doc/manual/release-notes/rl-2205.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ In addition to numerous new and upgraded packages, this release has the followin

- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).

- [Swapspace](https://github.com/Tookmund/Swapspace), dynamic swap management via swapfiles. Avaliable at [services.swapspace](#opt-services.swapspace.enable).

- [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).

- [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
Expand All @@ -58,7 +60,7 @@ In addition to numerous new and upgraded packages, this release has the followin
## Backward Incompatibilities {#sec-release-22.05-incompatibilities}

- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
This *only* makes a difference if you are cross-compiling and will
This _only_ makes a difference if you are cross-compiling and will
ensure that `pkgs.ghc` always runs on the host platform and compiles
for the target platform (similar to `pkgs.gcc` for example).
`haskellPackages.ghc` still behaves as before, running on the build
Expand Down Expand Up @@ -158,7 +160,7 @@ In addition to numerous new and upgraded packages, this release has the followin
to allow users to make changes to the `nixos-rebuild build-vm` configuration
that do not apply to their normal system.

The `config.system.build.vm` attribute now always exists and defaults to the
The `config.system.build.vm` attribute now always exists and defaults to the
value from `vmVariant`. Configurations that import the `virtualisation/qemu-vm.nix`
module themselves will override this value, such that `vmVariant` is not used.

Expand Down Expand Up @@ -207,8 +209,9 @@ In addition to numerous new and upgraded packages, this release has the followin
Plugins are automatically repackaged using autoPatchelf.

- The `zrepl` package has been updated from 0.4.0 to 0.5:
* The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
* A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.

- The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
- A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.

- Renamed option `services.openssh.challengeResponseAuthentication` to `services.openssh.kbdInteractiveAuthentication`.
Reason is that the old name has been deprecated upstream.
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,7 @@
./services/system/nscd.nix
./services/system/saslauthd.nix
./services/system/self-deploy.nix
./services/system/swapspace.nix
./services/system/uptimed.nix
./services/torrent/deluge.nix
./services/torrent/flexget.nix
Expand Down
87 changes: 87 additions & 0 deletions nixos/modules/services/system/swapspace.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{ config, lib, pkgs, ... }:

with lib;

let cfg = config.services.swapspace;
in {
###### interface

options = {

services.swapspace = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to create swapfiles dynamically using the SwapSpace manager.
Files will be added and removed based on current memory usage.
'';
};

path = mkOption {
type = types.path;
default = "/var/lib/swap";
description = ''
Location of the swap files. This directory will be restricted to root.
'';
};

cooldown = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
Cooldown period between changes.
SwapSpace will wait at least this many seconds before an action,
like removing a swapfile after adding one.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is null then the same as 0 or how does it interact?

'';
};

minSwapSize = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
Minimum size of a swapfile.
'';
};

maxSwapSize = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
Maximum size of a swapfile.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be great to explain what happens when this is set to null. Same for minSwapSize.

'';
};

extraArgs = mkOption {
type = types.str;
default = "";
description = ''
Any extra arguments to pass to SwapSpace.
'';
example = "-P -v -u 5";
};
};
};

###### implementation

config = mkIf cfg.enable {
systemd.tmpfiles.rules = [ "d '${cfg.path}' 0700 - - - - " ];
systemd.services.swapspace = with pkgs; {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
systemd.services.swapspace = with pkgs; {
systemd.services.swapspace = {

you don't refer to things inside pkgs anywhere.

description = "SwapSpace Daemon";
serviceConfig = {
Type = "simple";
ExecStart = ''${pkgs.swapspace}/bin/swapspace --swappath="${cfg.path}"''
+ optionalString (cfg.cooldown != null)
" --cooldown=${toString cfg.cooldown}"
+ optionalString (cfg.minSwapSize != null)
" --min_swapsize=${toString cfg.minSwapSize}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the documentation:

Never bother to allocate any swapfiles smaller than size bytes. There should be no need to change this variable except for testing.

I suggest removing this argument and the option. For testing, one can just use extraArgs.

+ optionalString (cfg.maxSwapSize != null)
" --max_swapsize=${toString cfg.maxSwapSize}" + " ${cfg.extraArgs}";
Restart = "always";
RestartSec = 30;
};
wantedBy = [ "multi-user.target" ];
};
};
}
42 changes: 42 additions & 0 deletions pkgs/os-specific/linux/swapspace/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{ stdenv, lib, fetchFromGitHub, autoreconfHook, utillinux }:

stdenv.mkDerivation rec {
pname = "swapspace";
version = "1.17";

src = fetchFromGitHub {
owner = "Tookmund";
repo = "Swapspace";
rev = "v${version}";
sha256 = "06xvmyy1fp94h00k9nn929j00ca3w12fiz07wf9az6srxa8i4ndz";
};

nativeBuildInputs = [ autoreconfHook ];

patchPhase = ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
patchPhase = ''
postPatch = ''

sed -e 's@"mkswap"@"${utillinux}/bin/mkswap"@' \
-e 's@"/sbin/swapon"@"${utillinux}/bin/swapon"@' \
-e 's@"/sbin/swapoff"@"${utillinux}/bin/swapoff"@' \
-i src/support.c src/swaps.c
'';

postInstall = ''
mkdir $out/bin
mv $out/sbin/swapspace $out/bin/swapspace
# This should be an empty directory, fail if not
rmdir $out/sbin
rm -r $out/var
'';

enableParallelBuilding = true;

nativeBuildInputs = [ autoreconfHook ];

Comment on lines +33 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nativeBuildInputs = [ autoreconfHook ];

duped with line 14

meta = with lib; {
homepage = "https://github.com/Tookmund/Swapspace";
description = "Dynamically add and remove swapfiles based on memory pressure";
license = licenses.gpl2;
maintainers = with maintainers; [ wmertens ];
platforms = platforms.linux;
};
}