[PATCH] zRAM swap for Anaconda

Vratislav Podzimek vpodzime at redhat.com
Tue Jul 15 09:46:23 UTC 2014


zRAM is a standard block device like tmpfs with one nice difference -- its
content is compressed. One clever usage of such device is using it as a swap
device which effectively means one can have compressed RAM. Some experiments
show that by using zRAM as a swap device in the installation process anaconda
can install to machines with lower amount of RAM (succeeded with 320 MB) and
installations on low-RAM systems (< 1 GB) run faster due to usage of zRAM swap
instead/together with the standard swap we create and use for package
installation.

Specific limits, numbers and way of implementation may be changed in the future,
but this commit introduces the basic idea and straightforward approach.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 data/systemd/Makefile.am     |  3 +-
 data/systemd/anaconda.target |  1 +
 data/systemd/zram.service    | 11 ++++++++
 pyanaconda/ui/lib/disks.py   |  3 +-
 scripts/Makefile.am          |  2 +-
 scripts/makeupdates          |  2 +-
 scripts/zramswapoff          | 38 +++++++++++++++++++++++++
 scripts/zramswapon           | 66 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 122 insertions(+), 4 deletions(-)
 create mode 100644 data/systemd/zram.service
 create mode 100755 scripts/zramswapoff
 create mode 100755 scripts/zramswapon

diff --git a/data/systemd/Makefile.am b/data/systemd/Makefile.am
index d27ba2f..ababe99 100644
--- a/data/systemd/Makefile.am
+++ b/data/systemd/Makefile.am
@@ -27,7 +27,8 @@ dist_systemd_DATA = anaconda.service \
 		    anaconda-tmux at .service \
 		    anaconda-shell at .service \
 		    instperf.service \
-		    anaconda-sshd.service
+		    anaconda-sshd.service \
+		    zram.service
 
 dist_generator_SCRIPTS = anaconda-generator
 
diff --git a/data/systemd/anaconda.target b/data/systemd/anaconda.target
index bafad64..e160da6 100644
--- a/data/systemd/anaconda.target
+++ b/data/systemd/anaconda.target
@@ -10,3 +10,4 @@ Wants=NetworkManager.service
 Wants=plymouth-quit.service plymouth-quit-wait.service
 Wants=anaconda-direct.service anaconda.service
 Wants=anaconda-sshd.service
+Wants=zram.service
diff --git a/data/systemd/zram.service b/data/systemd/zram.service
new file mode 100644
index 0000000..d2cd96c
--- /dev/null
+++ b/data/systemd/zram.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Service enabling compressing RAM with zRam
+ConditionKernelCommandLine=!inst.zram=off
+ConditionKernelCommandLine=!inst.zram=0
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/anaconda/zramswapon
+ExecStop=/usr/libexec/anaconda/zramswapoff
+RemainAfterExit=yes
+
diff --git a/pyanaconda/ui/lib/disks.py b/pyanaconda/ui/lib/disks.py
index 7c4b1ff..ce0d4f5 100644
--- a/pyanaconda/ui/lib/disks.py
+++ b/pyanaconda/ui/lib/disks.py
@@ -58,7 +58,8 @@ def getDisks(devicetree, fake=False):
 
         disks = []
         for d in devices:
-            if d.isDisk and not d.format.hidden and not (d.protected and d.removable):
+            if d.isDisk and not d.format.hidden and not (d.protected and d.removable) \
+               and "zram" not in d.name:
                 # unformatted DASDs are detected with a size of 0, but they should
                 # still show up as valid disks if this function is called, since we
                 # can still use them; anaconda will know how to handle them, so they
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 0035373..c9105a1 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -18,7 +18,7 @@
 # Author: David Cantrell <dcantrell at redhat.com>
 
 scriptsdir = $(libexecdir)/$(PACKAGE_NAME)
-dist_scripts_SCRIPTS = upd-updates run-anaconda anaconda-yum
+dist_scripts_SCRIPTS = upd-updates run-anaconda anaconda-yum zramswapon zramswapoff
 dist_noinst_SCRIPTS  = upd-kernel makeupdates
 
 dist_bin_SCRIPTS = analog anaconda-cleanup instperf
diff --git a/scripts/makeupdates b/scripts/makeupdates
index f323f01..574694f 100755
--- a/scripts/makeupdates
+++ b/scripts/makeupdates
@@ -295,7 +295,7 @@ def copyUpdatedFiles(tag, updates, cwd):
             install_to_dir(gitfile, "usr/share/anaconda/ui")
         elif gitfile.startswith("data/post-scripts/"):
             install_to_dir(gitfile, "usr/share/anaconda/post-scripts")
-        elif gitfile.endswith("anaconda-yum"):
+        elif any(gitfile.endswith(libexec_script) for libexec_script in ("anaconda-yum", "zramswapon", "zramswapoff")):
             install_to_dir(gitfile, "usr/libexec/anaconda")
         elif gitfile.endswith("AnacondaWidgets.py"):
             import gi
diff --git a/scripts/zramswapoff b/scripts/zramswapoff
new file mode 100755
index 0000000..7dc4d55
--- /dev/null
+++ b/scripts/zramswapoff
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Copyright (C) 2014  Red Hat, Inc.
+#
+# Heavily inspired by zramswapoff script found in the Simone Sclavi's repository
+# at http://software.opensuse.org/package/systemd-zram-service
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.  You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Vratislav Podzimek <vpodzime at redhat.com>
+#
+
+# get the number of CPUs
+num_cpus=$(getconf _NPROCESSORS_ONLN)
+
+# set decremented number of CPUs
+decr_num_cpus=$((num_cpus - 1))
+
+# Switching off swap
+for i in $(seq 0 $decr_num_cpus); do
+    if [ "$(grep /dev/zram$i /proc/swaps)" ]; then
+        swapoff /dev/zram$i
+    fi
+done
+
+rmmod zram
diff --git a/scripts/zramswapon b/scripts/zramswapon
new file mode 100755
index 0000000..8747dd0
--- /dev/null
+++ b/scripts/zramswapon
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# Copyright (C) 2014  Red Hat, Inc.
+#
+# Heavily inspired by zramswapon script found in the Simone Sclavi's repository
+# at http://software.opensuse.org/package/systemd-zram-service
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.  You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Vratislav Podzimek <vpodzime at redhat.com>
+#
+
+set -e
+
+# get the amount of memory in the machine
+mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
+mem_total=$((mem_total_kb * 1024))
+
+grep -E 'inst\.zram=(on|1)' /proc/cmdline > /dev/null
+force=$?
+if [ \( $mem_total_kb -gt "1048576" \) -a \( ! $force \) ]; then
+    # more than 1 GB of RAM and not forced, do nothing
+    exit 0
+fi
+
+# get the number of CPUs
+num_cpus=$(getconf _NPROCESSORS_ONLN)
+
+# set decremented number of CPUs
+decr_num_cpus=$((num_cpus - 1))
+
+# load dependency modules
+modprobe zram num_devices=$num_cpus
+
+# initialize the devices
+for i in $(seq 0 $decr_num_cpus); do
+    echo $((mem_total / num_cpus)) > /sys/block/zram$i/disksize
+done
+
+# Creating swap filesystems
+for i in $(seq 0 $decr_num_cpus); do
+    mkswap /dev/zram$i
+done
+
+# Switch the swaps on
+for i in $(seq 0 $decr_num_cpus); do
+    swapon -p 100 /dev/zram$i
+done
+
+if [ $mem_total_kb -le "1048576" ]; then
+    # less than 1 GB or RAM -> less than 512 MB /tmp (tmpfs defaults to
+    # 0.5*RAM), bump up the /tmp's size, yum may need it
+    mount -o remount,size=512M /tmp
+fi
-- 
1.9.3



More information about the anaconda-patches mailing list