[PATCH 1/2] zRAM swap for Anaconda

Vratislav Podzimek vpodzime at redhat.com
Tue Jul 8 13:56:52 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    |  8 ++++++
 pyanaconda/ui/lib/disks.py   |  3 +-
 scripts/Makefile.am          |  2 +-
 scripts/makeupdates          |  2 +-
 scripts/zramswapoff          | 38 +++++++++++++++++++++++++
 scripts/zramswapon           | 66 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 119 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..bd5fe3d 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
\ No newline at end of file
diff --git a/data/systemd/zram.service b/data/systemd/zram.service
new file mode 100644
index 0000000..af894cf
--- /dev/null
+++ b/data/systemd/zram.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Service enabling compressing RAM with zRam
+
+[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 77abf5b..f84c8ef 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 1de193a..0f2a44e 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..49a468e
--- /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>
+#
+
+# 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))
+
+if [ $mem_total_kb -gt "1048576" ]; then
+    # more than 1 GB or RAM, 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
+# Determine module parm
+mod_parm=$(modinfo zram |grep parm |tr -s " " |cut -f2 -d ":")
+modprobe zram $mod_parm=$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