Automatically start zram swap device on boot with systemd zram-generator under CentOS Stream 9

zram-generator package will install necessary tools to automate the creation on boot the compressed RAM devices. This article focuses on compressed swap devices.

main menu
install

As of writing this article, the latest version in the package system under CentOS Stream 9 is 0.32. The the latest version on the original page of the software is much higher number 1.1.2 and many of the following configuration options are marked as OBSOLETE, but they work in the 0.32 version included in CentOS Stream 9 (and the new configuration options does not!). That’s why it is important to check the included sample configuration file.
The package installs no configuration file, just a sample configuration file – /usr/share/doc/zram-generator/zram-generator.conf.example.
zram in the kernel space – https://docs.kernel.org/admin-guide/blockdev/zram.html

STEP 1) Install the zram-generator

It is easy and straightforward, just a single package:

[root@srv) ~]# dnf install -y zram-generator
Last metadata expiration check: 3:42:20 ago on Fri 20 Oct 2023 05:18:32 AM UTC.
Dependencies resolved.
==============================================================================================================
 Package                      Architecture         Version                      Repository               Size
==============================================================================================================
Installing:
 zram-generator               x86_64               0.3.2-7.el9                  appstream               409 k

Transaction Summary
==============================================================================================================
Install  1 Package

Total download size: 409 k
Installed size: 983 k
Downloading Packages:
zram-generator-0.3.2-7.el9.x86_64.rpm                                         2.1 MB/s | 409 kB     00:00    
--------------------------------------------------------------------------------------------------------------
Total                                                                         1.3 MB/s | 409 kB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                      1/1 
  Installing       : zram-generator-0.3.2-7.el9.x86_64                                                    1/1 
  Running scriptlet: zram-generator-0.3.2-7.el9.x86_64                                                    1/1 
  Verifying        : zram-generator-0.3.2-7.el9.x86_64                                                    1/1 

Installed:
  zram-generator-0.3.2-7.el9.x86_64                                                                           

Complete!

STEP 2) Create a configuration and start the service

By default, there is no configuration file. The best place for it is /etc/systemd/zram-generator.conf.
Here is an example, which will fulfill the following:

  • Set the maximum RAM of the system, because it is a hard-coded 9G, by default. And if not redefined the device will be with 9G max memory no matter how much is tuned by the other options.
  • Set the RAM of the compressed device.
  • Set the fraction of the ram, which may be used by the device. Again as with the above configuration option, it is important, because it limits the maximum available memory to allocate for the compressed device.
  • Set the type of the device – filesystem or swap device.

There is the real world example configuration – /etc/systemd/zram-generator.conf

[root@srv ~]# cat /etc/systemd/zram-generator.conf
[zram0]
host-memory-limit = none
max-zram-size = 32768
zram-fraction = 1.0
compression-algorithm = zstd
swap-priority = 100
fs-type = swap


This configuration file sets:

  • host-memory-limit – no limit to the maximum amount of memory
  • max-zram-size – 32G ram compressed device
  • zram-fraction – use 1:1 the memory set for the device, so use the whole memory from max-zram-size, not a fraction below 1.0
  • compression-algorithm – use zstd for better compression ratio (note, there are more algorithms)
  • fs-type – make a compressed swap device and activate it.

To start using the swap device, just start the systemd service:

[root@srv ~]# systemctl start systemd-zram-setup@zram0.service
[root@srv ~]# systemctl status systemd-zram-setup@zram0.service
● systemd-zram-setup@zram0.service - Create swap on /dev/zram0
     Loaded: loaded (/usr/lib/systemd/system/systemd-zram-setup@.service; static)
    Drop-In: /run/systemd/generator/systemd-zram-setup@zram0.service.d
             └─bindsto-swap.conf
     Active: active (exited) since Fri 2023-10-20 10:42:22 UTC; 1min 50s ago
       Docs: man:zram-generator(8)
             man:zram-generator.conf(5)
   Main PID: 277688 (code=exited, status=0/SUCCESS)
        CPU: 34ms

Oct 20 10:42:22 srv systemd[1]: Starting Create swap on /dev/zram0...
Oct 20 10:42:22 srv zram-generator[277690]: Setting up swapspace version 1, size = 3.5 GiB (3738169344 bytes)
Oct 20 10:42:22 srv zram-generator[277690]: LABEL=zram0, UUID=b8e44c25-97f0-4389-8534-414b2acc4866
Oct 20 10:42:22 srv systemd-makefs[277689]: /dev/zram0 successfully formatted as swap (label "zram0", uuid b8e44c25-97f0-4389-8534-414b2acc4866)
Oct 20 10:42:22 srv systemd[1]: Finished Create swap on /dev/zram0.
[root@srv ~]# zramctl 
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd          3.5G   4K   64B    4K       2 [SWAP]

No need to issue “systemctl enable”, it will be started on boot. Use zramctl to see how much memory the device is using and how much is the the real uncompressed data on the device(s).

Bonus 1 – to check the available compressing algorithms

To show, which compressing algorithms are available on the system:

[root@srv ~]# cat /sys/devices/virtual/block/zram0/comp_algorithm
lzo lzo-rle [zstd]

The zstd is used in this example.

Bonus 2 – compressing algorithms comparison.

A quick notice what is he performance of each compressing algorithm (source – https://github.com/facebook/zstd)

Compressor Ratio Compression Decompression
zstd-1.3.4-1 2.877 470 MB/s 1380 MB/s
brotli 1.0.2 -0 2.701 410 MB/s 430 MB/s
quicklz 1.5.0 -1 2.238 550 MB/s 710 MB/s
lzo1x 2.09 -1 2.108 650 MB/s 830 MB/s
lz4 1.8.1 2.101 750 MB/s 3700 MB/s
snappy 1.1.4 2.091 530 MB/s 1800 MB/s
lzf 3.6 -1 2.077 400 MB/s 860 MB/s

Bonus 3 – Troubleshooting

On first run, there may be some glitches with the compression algorithms, especially if they are not used until now.
The service will time out with an error

[root@srv ~]# systemctl start systemd-zram-setup@zram0.service
A dependency job for systemd-zram-setup@zram0.service failed. See 'journalctl -xe' for details.
[root@srv ~]# journalctl -xe
Oct 20 10:22:07 srv systemd[1]: dev-zram0.device: Job dev-zram0.device/start timed out.
Oct 20 10:22:07 srv systemd[1]: Timed out waiting for device /dev/zram0.
░░ Subject: A start job for unit dev-zram0.device has failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ A start job for unit dev-zram0.device has finished with a failure.
░░ 
░░ The job identifier is 78708 and the job result is timeout.
Oct 20 10:22:07 srv systemd[1]: Dependency failed for Compressed Swap on /dev/zram0.
░░ Subject: A start job for unit dev-zram0.swap has failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ A start job for unit dev-zram0.swap has finished with a failure.
░░ 
░░ The job identifier is 78707 and the job result is dependency.
Oct 20 10:22:07 srv systemd[1]: Dependency failed for Create swap on /dev/zram0.
░░ Subject: A start job for unit systemd-zram-setup@zram0.service has failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ A start job for unit systemd-zram-setup@zram0.service has finished with a failure.
░░ 
░░ The job identifier is 78702 and the job result is dependency.
Oct 20 10:22:07 srv systemd[1]: systemd-zram-setup@zram0.service: Job systemd-zram-setup@zram0.service/start failed with result 'dependency'.
Oct 20 10:22:07 srv systemd[1]: dev-zram0.swap: Job dev-zram0.swap/start failed with result 'dependency'.
Oct 20 10:22:07 srv systemd[1]: dev-zram0.device: Job dev-zram0.device/start failed with result 'timeout'.

Or an error in the /var/log/messages:

Oct 20 08:48:18 srv systemd[1]: Starting Create swap on /dev/zram0...
Oct 20 08:48:18 srv kernel: zram: Cannot initialise zstd compressing backend
Oct 20 08:48:18 srv zram-generator[1828043]: Error: Failed to configure disk size into /sys/block/zram0/disksize
Oct 20 08:48:18 srv zram-generator[1828043]: Caused by:
Oct 20 08:48:18 srv zram-generator[1828043]:    Cannot allocate memory (os error 12)
Oct 20 08:48:18 srv systemd[1]: systemd-zram-setup@zram0.service: Main process exited, code=exited, status=1/FAILURE
Oct 20 08:48:18 srv systemd[1]: systemd-zram-setup@zram0.service: Failed with result 'exit-code'.
Oct 20 08:48:18 srv systemd[1]: Failed to start Create swap on /dev/zram0.
Oct 20 08:48:18 srv systemd[1]: Dependency failed for Compressed Swap on /dev/zram0.
Oct 20 08:48:18 srv systemd[1]: dev-zram0.swap: Job dev-zram0.swap/start failed with result 'dependency'.
Oct 20 08:48:28 srv systemd[1]: Starting Create swap on /dev/zram0...
Oct 20 08:48:28 srv kernel: zram: Cannot initialise zstd compressing backend
Oct 20 08:48:28 srv zram-generator[1828057]: Error: Failed to configure disk size into /sys/block/zram0/disksize
Oct 20 08:48:28 srv zram-generator[1828057]: Caused by:
Oct 20 08:48:28 srv zram-generator[1828057]:    Cannot allocate memory (os error 12)
Oct 20 08:48:28 srv systemd[1]: systemd-zram-setup@zram0.service: Main process exited, code=exited, status=1/FAILURE
Oct 20 08:48:28 srv systemd[1]: systemd-zram-setup@zram0.service: Failed with result 'exit-code'.
Oct 20 08:48:28 srv systemd[1]: Failed to start Create swap on /dev/zram0.
Oct 20 08:48:28 srv systemd[1]: Dependency failed for Compressed Swap on /dev/zram0.
Oct 20 08:48:28 srv systemd[1]: dev-zram0.swap: Job dev-zram0.swap/start failed with result 'dependency'.

The above two errors are because of not loaded zstd algorithm module. To solve it, just use modprobe:

modprobe zstd

zstd used here might be another algorithm name, so use it to load the module in the kernel. After first use, the next reboot of the server or restart of the service will not need to manually load the algorithm it will be auto-loaded properly.

There is another example with not properly cleaned old compressed device:

[root@srv ~]# systemctl start systemd-zram-setup@zram0.service
Job for systemd-zram-setup@zram0.service failed because the control process exited with error code.
See "systemctl status systemd-zram-setup@zram0.service" and "journalctl -xeu systemd-zram-setup@zram0.service" for details.
[root@srv ~]# journalctl -xeu systemd-zram-setup@zram0.service
Oct 20 11:43:31 srv systemd[1]: Starting Create swap on /dev/zram0...
░░ Subject: A start job for unit systemd-zram-setup@zram0.service has begun execution
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ A start job for unit systemd-zram-setup@zram0.service has begun execution.
░░ 
░░ The job identifier is 30660.
Oct 20 11:43:31 srv zram-generator[187504]: Error: Failed to configure compression algorithm into /sys/block/zram0/comp_algorithm
Oct 20 11:43:31 srv zram-generator[187504]: Caused by:
Oct 20 11:43:31 srv zram-generator[187504]:     Device or resource busy (os error 16)
Oct 20 11:43:31 srv systemd[1]: systemd-zram-setup@zram0.service: Main process exited, code=exited, status=1/FAILURE
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ An ExecStart= process belonging to unit systemd-zram-setup@zram0.service has exited.
░░ 
░░ The process' exit code is 'exited' and its exit status is 1.
Oct 20 11:43:31 srv systemd[1]: systemd-zram-setup@zram0.service: Failed with result 'exit-code'.
░░ Subject: Unit failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ The unit systemd-zram-setup@zram0.service has entered the 'failed' state with result 'exit-code'.
Oct 20 11:43:31 srv systemd[1]: Failed to start Create swap on /dev/zram0.
░░ Subject: A start job for unit systemd-zram-setup@zram0.service has failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░ 
░░ A start job for unit systemd-zram-setup@zram0.service has finished with a failure.
░░ 
░░ The job identifier is 30660 and the job result is failed.

In this case, just reset the device with the zramctl:

zramctl -r /dev/zram0

Or slightly more complex, just remove the kernel module and load it again:

[root@srv ~]# zramctl -r /dev/zram0
[root@srv ~]# rmmod zram
[root@srv ~]# modprobe zram
[root@srv ~]# modprobe zstd
[root@srv ~]# systemctl start systemd-zram-setup@zram0.service

Bonus 4 – The sample configuration file for version 0.32

Many of the following configuration options are obsolete in the newer 1.1 version of zram-generator.

[root@srv ~]# cat /usr/share/doc/zram-generator/zram-generator.conf.example
# This file is part of the zram-generator project
# https://github.com/systemd/zram-generator

[zram0]
# This section describes the settings for /dev/zram0.
#
# The maximum amount of memory (in MiB). If the machine has more RAM
# than this, zram device will not be created.
#
# "host-memory-limit = none" may be used to disable this limit. This
# is also the default.
host-memory-limit = 9048

# The fraction of memory to use as ZRAM. For example, if the machine
# has 1 GiB, and zram-fraction=0.25, then the zram device will have
# 256 MiB. Values in the range 0.10–0.50 are recommended.
#
# The default is 0.5.
zram-fraction = 0.10

# The maximum size of the zram device (in MiB).
#
# If host-memory times zram-fraction is greater than this,
# the size will be capped to this amount;
# for example, on a machine with 2 GiB of RAM and with zram-fraction=0.5,
# the device would still be 512 MiB in size due to the limit below.
#
# The default is 4096.
max-zram-size = 512

# The compression algorithm to use for the zram device,
# or leave unspecified to keep the kernel default.
compression-algorithm = lzo-rle

[zram1]
# This section describes the settings for /dev/zram1.
#
# host-memory-limit is not specifed, so this device will always be created.

# Size the device to a tenth of RAM.
zram-fraction = 0.1

# The file system to put on the device. If not specified, ext2 will be used.
fs-type = ext2

# Where to mount the file system. If a mount point is not specified,
# the device will be initialized, but will not be used for anything.
mount-point = /run/compressed-mount-point

More topics with CentOS Stream 9https://ahelpme.com/tag/centos-stream-9/

Leave a Reply

Your email address will not be published. Required fields are marked *