dphys-swapfile 不会计算大于 2GB 的交换文件

dphys-swapfile 不会计算大于 2GB 的交换文件

动态交换文件程序 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/bashlet所有行前面添加计算内容。

这解决了问题,现在可以动态调整交换文件的大小!

下面是我修复的 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。

相关内容