动态交换文件程序 dphys-swapfile(可从 apt 获得)在更改配置时不会重新配置/etc/dphys-swapfile
。
基本上,我删除了注释“#”并将值更改为 8GB。
# restrict size (computed and absolute!) to maximally this limit
# can be set to empty for no limit, but beware of filled partitions!
# this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
# but is also sensible on 64bit to prevent filling /var or even / partition
CONF_MAXSWAP=8192
然后我跑
sudo dphys-swapfile setup
但是新的配置没有计算出来,我得到了这个作为输出
computing size, username@ubuntu:~$
停止 dphys-swapfile 并运行设置然后启动没有任何反应,并且交换文件大小仍然为 2GB。
删除交换文件/var/swap
,然后重新运行安装程序会产生上述相同的输出,然后尝试启动它,但由于交换文件丢失而出错。
username@ubuntu:~$ sudo dphys-swapfile swapon
/sbin/dphys-swapfile: ERROR: swap file /var/swap missing! you need to first run /sbin/dphys-swapfile setup to generate one
答案1
看来在 Ubuntu 18.04 上正确sudo apt install dphys-swapfile
运行脚本/bin/sh
然而,重新使用时/sbin/dphys-swapfile
算术/bin/sh
计算失败。
在echo
对代码进行调试并检查后,我注意到使用参数时重新计算应该会回显更多文本setup/install
。经过更多调试后,我注意到是包含算术计算的行退出/出错了。
所以我所做的是将内容从 改为/bin/sh
并/bin/bash
在let
所有行前面添加计算内容。
这解决了问题,现在可以动态调整交换文件的大小!
下面是我修复的 dphys-swapfile 脚本的副本,/sbin/dphys-swapfile
您需要使用 sudo 来编辑它。
#! /bin/bash
# /sbin/dphys-swapfile - automatically set up an swapfile
# author Neil Franklin, last modification 2010.05.05
# This script is copyright ETH Zuerich Physics Departement,
# use under either BSD or GPL license
# this script is intended to be run as root user, usually while booting
# 2018/10/01 - DanglingPointer - Changed shebang line from /bin/sh to /bin/bash; then added 'let' to all arithmetic calculations to fix bug wherein "setup/install" parameter would not work in Ubuntu.
### ------ configuration for this site
# --- CONF_* various site dependant user config variables
# where we want the swapfile to be, this is the default
CONF_SWAPFILE=/var/swap
# set size to absolute value, leaving empty (default) then uses computed value
# you most likely don't want this, unless you have an special disk situation
CONF_SWAPSIZE=
# set size to computed value, this times RAM size, dynamically adapts,
# guarantees that there is enough swap without wasting disk space on excess
CONF_SWAPFACTOR=2
# restrict size (computed and absolute!) to maximally this limit
# can be set to empty for no limit, but beware of filled partitions!
# this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
# but is also sensible on 64bit to prevent filling /var or even / partition
CONF_MAXSWAP=2048
### ------ actual implementation from here on
# no user settings any more below this point
set -e
# sanitise this place, else some commands may fail
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
# what we are
NAME=dphys-swapfile
PNAME=dphys-swapfile
# check user config file, let user override settings
# swap file place/filename and size
if [ -f /etc/"${PNAME}" ] ; then
. /etc/"${PNAME}"
fi
case "$1" in
setup)
# (re-)size/-generate, fast if no memory size change
if [ "${CONF_SWAPSIZE}" = "" ] ; then
# no absolute size given, so automatically compute optimal size
echo -n "computing size, "
echo
# this seems to be the nearest to physical RAM size, lacks about 60k
# but it actually then fails from AMD64 kernel 2.6.32 onwards
#KCORESIZE="`ls -l /proc/kcore | awk '{ print $5 }'`"
## make MBytes which rounded down will be exactly 1 too few, so add 1
#MEMSIZE="`echo "${KCORESIZE} 1048576 / 1 + p q" | dc`"
# so second attempt at finding out physical RAM size, lacks about 10M
# see how long this variant stays usable :-)
MEMTOTAL="`grep '^MemTotal:' /proc/meminfo | awk '{ print $2 }'`"
echo "Current MEMTOTAL = $MEMTOTAL "
echo
# make MBytes which rounded down will be about 10 too few, so add 10
let MEMSIZE="`echo "${MEMTOTAL} 1024 / 10 + p q" | dc`"
echo "Computed MEMSIZE = $MEMSIZE "
echo
# compute desired swap size, as factor * RAM
let CONF_SWAPSIZE="`echo "${MEMSIZE} ${CONF_SWAPFACTOR} * p q" | dc`"
# remove any fractional MBytes
CONF_SWAPSIZE="`echo "${CONF_SWAPSIZE}" | cut -f 1 -d '.'`"
fi
# announce end resulting config
echo -n "want ${CONF_SWAPFILE}=${CONF_SWAPSIZE}MByte"
if [ "${CONF_MAXSWAP}" != "" ] ; then
# check for swap size limit and restrict to it
if [ "${CONF_SWAPSIZE}" -gt "${CONF_MAXSWAP}" ] ; then
echo -n ", restricting to config limit: ${CONF_MAXSWAP}MBytes"
CONF_SWAPSIZE="${CONF_MAXSWAP}"
fi
fi
# we will be later starting, and in between possible deleting/rebuilding
# so deactivate any already running swapfile, to avoid errors
"$0" swapoff
# compare existing swapfile (if one exists) to see if it needs replacing
if [ -f "${CONF_SWAPFILE}" ] ; then
echo -n ", checking existing"
# we need bytes for comparing with existing swap file
let SWAPBYTES="`echo "${CONF_SWAPSIZE} 1048576 * p q" | dc`"
FILEBYTES="`ls -l "${CONF_SWAPFILE}" | awk '{ print $5 }'`"
# wrong size, get rid of existing swapfile, after remake
if [ "${FILEBYTES}" != "${SWAPBYTES}" ] ; then
echo -n ": deleting wrong size file (${FILEBYTES})"
# deactivate and delete existing file, before remaking for new size
"$0" uninstall
else
echo -n ": keeping it"
fi
fi
# if no swapfile (or possibly old one got deleted) make one
if [ ! -f "${CONF_SWAPFILE}" ] ; then
echo -n ", generating swapfile ..."
# first deleting existing mount lines, if any there (same code as above)
grep -v "^${CONF_SWAPFILE}" /etc/fstab > /etc/.fstab
mv /etc/.fstab /etc/fstab
# use fallocate if found to create swapfile, else use dd
type fallocate > /dev/null
if [ $? -eq 0 ]; then
fallocate -l "${CONF_SWAPSIZE}"M "${CONF_SWAPFILE}" 2> /dev/null
else
dd if=/dev/zero of="${CONF_SWAPFILE}" bs=1048576 \
count="${CONF_SWAPSIZE}" 2> /dev/null
fi
# ensure that only root can read possibly critical stuff going in here
chmod 600 "${CONF_SWAPFILE}"
mkswap "${CONF_SWAPFILE}" > /dev/null
# do not mount swapfile via fstab, because swapfile may only
# be created after partitions are all mounted, not here yet
# so just add warning comment line that swapfile is not in fstab
# and because of this will get mounted by this script
# get rid of possibly already existing comment about
# swapfile mounted by this script, to avoid duplicate comments
grep -v "a swapfile is not" /etc/fstab > /etc/.fstab
grep -v "${NAME}" /etc/.fstab > /etc/fstab
# add new comment about this
echo "# a swapfile is not a swap partition, no line here" >> /etc/fstab
echo "# use ${NAME} swap[on|off] for that" >> /etc/fstab
# and inform the user what we did
echo -n " of ${CONF_SWAPSIZE}MBytes"
fi
echo
;;
install)
# synonym for setup, in case someone types this
"$0" setup
;;
swapon)
# as there can be no swapon in /etc/fstab, do it from here
# this is due to no possible insertion of code (at least in Debian)
# between mounting of /var (where swap file most likely resides)
# and executing swapon, where the file already needs to be existing
if [ -f "${CONF_SWAPFILE}" ] ; then
swapon "${CONF_SWAPFILE}" 2>&1 > /dev/null
else
echo "$0: ERROR: swap file ${CONF_SWAPFILE} missing!" \
"you need to first run $0 setup to generate one"
fi
;;
swapoff)
# as there can also be no swapoff in /etc/fstab, do it from here
# first test if swap is even active, else error from swapoff
if [ "`swapon -s | grep "${CONF_SWAPFILE}" | \
cut -f 1 -d ' '`" != "" ] ; then
swapoff "${CONF_SWAPFILE}" 2>&1 > /dev/null
fi
;;
uninstall)
# note: there is no install), as setup) can run from any blank system
# it auto-installs as side effect of recomputing and checking size
# deactivate before deleting
"$0" swapoff
if [ -f "${CONF_SWAPFILE}" ] ; then
# reclaim the file space
rm "${CONF_SWAPFILE}"
fi
# and get rid of now superfluous comment about swapfile mounting
grep -v "a swapfile is not" /etc/fstab > /etc/.fstab
grep -v "${NAME}" /etc/.fstab > /etc/fstab
;;
*)
echo "Usage: $0 {setup|swapon|swapoff|uninstall}"
exit 1
;;
esac
exit 0
答案2
计算时中止执行是LP#1788681并且已在当前开发分支 Cosmic 中修复,但尚未在 18.04 Bionic 中修复。(我似乎无法将该错误标记为影响特定的 Ubuntu 版本,因此需要其他人来做这件事。)
这是由于dc
随着时间的推移变得更加挑剔而造成的,正确的解决办法是将所有出现的p q
(仅显示在输入到的命令中dc
) 替换为p
。
完整补丁可在 Debian 的 Gitlab 中使用。
在 Bionic 上本地修复此问题的最简单方法可能是从 Bionic 上的 Ubuntu Cosmic 安装 dphys-swapfile。例如从 Launchpad 下载相应的二进制包dpkg -i dphys-swapfile_20100506-5_all.deb
然后使用root 权限安装或升级它。
PS:无需将脚本切换为bash。