From a54ec11ae7f068898be6408581a86a4bf0b28fac Mon Sep 17 00:00:00 2001 From: tituspijean Date: Thu, 30 May 2024 22:11:57 +0200 Subject: [PATCH 01/11] Implement config panel for swap management --- helpers/helpers.v1.d/hardware | 102 ++++++++++++++++++++++++++++++++++ hooks/conf_regen/53-swap | 29 ++++++++++ share/config_global.toml | 23 ++++++++ src/settings.py | 6 ++ 4 files changed, 160 insertions(+) create mode 100755 hooks/conf_regen/53-swap diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 091f023f6..bab855c42 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -103,3 +103,105 @@ ynh_require_ram() { return 0 fi } + +# Add swap +# +# usage: ynh_add_swap --size=SWAP in MB +# | arg: -s, --size= - Amount of SWAP to add in MB. +ynh_add_swap () { + # Declare an array to define the options of this helper. + declare -Ar args_array=( [s]=size= ) + local size + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + local swap_max_size=$(( $size * 1024 )) + + local free_space=$(df --output=avail / | sed 1d) + # Because we don't want to fill the disk with a swap file, divide by 2 the available space. + local usable_space=$(( $free_space / 2 )) + + SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} + + # Swap on SD card only if it's is specified + if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ] + then + ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage to it. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'" + return + fi + + # Compare the available space with the size of the swap. + # And set a acceptable size from the request + if [ $usable_space -ge $swap_max_size ] + then + local swap_size=$swap_max_size + elif [ $usable_space -ge $(( $swap_max_size / 2 )) ] + then + local swap_size=$(( $swap_max_size / 2 )) + elif [ $usable_space -ge $(( $swap_max_size / 3 )) ] + then + local swap_size=$(( $swap_max_size / 3 )) + elif [ $usable_space -ge $(( $swap_max_size / 4 )) ] + then + local swap_size=$(( $swap_max_size / 4 )) + else + echo "Not enough space left for a swap file" >&2 + local swap_size=0 + # Store the swap size + yunohost settings set 'swap.swapfile.swapfile_size' -v ${swap_size} + fi + + # If there's enough space for a swap, and no existing swap here + if [ $swap_size -ne 0 ] && [ ! -e /swap_file ] + then + # Create file + truncate -s 0 /swap_file + + # set the No_COW attribute on the swapfile with chattr + chattr +C /swap_file + + # Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case + if ! fallocate -l ${swap_size}K /swap_file + then + dd if=/dev/zero of=/swap_file bs=1024 count=${swap_size} + fi + chmod 0600 /swap_file + # Create the swap + mkswap /swap_file + # And activate it + swapon /swap_file + # Then add an entry in fstab to load this swap at each boot. + echo -e "/swap_file swap swap defaults 0 0 #Swap added by YunoHost config panel" >> /etc/fstab + # Store the swap size + yunohost settings set 'swap.swapfile.swapfile_size' -v ${swap_size} + fi +} + +ynh_del_swap () { + # If there a swap at this place + if [ -e /swap_file ] + then + # Clean the fstab + sed -i "/#Swap added by YunoHost config panel/d" /etc/fstab + # Desactive the swap file + swapoff /swap_file + # And remove it + rm /swap_file + fi +} + +# Check if the device of the main mountpoint "/" is an SD card +# +# [internal] +# +# return 0 if it's an SD card, else 1 +ynh_is_main_device_a_sd_card () { + local main_device=$(lsblk --output PKNAME --noheadings $(findmnt / --nofsroot --uniq --output source --noheadings --first-only)) + + if echo $main_device | grep --quiet "mmc" && [ $(tail -n1 /sys/block/$main_device/queue/rotational) == "0" ] + then + return 0 + else + return 1 + fi +} diff --git a/hooks/conf_regen/53-swap b/hooks/conf_regen/53-swap new file mode 100755 index 000000000..b3e6f89dc --- /dev/null +++ b/hooks/conf_regen/53-swap @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +. /usr/share/yunohost/helpers + +do_pre_regen() { +} + +do_post_regen() { + + swapfile_enabled="$(yunohost settings get 'swap.swapfile.swapfile_enabled')" + swapfile_size="$(yunohost settings get 'swap.swapfile.swapfile_size')" + + if [ "${swapfile_enabled}" == "True" ]; then + # If a swapfile is requested + if [ $(stat -c%s /swap_file) -ne $swapfile_size ]; then + # Let's delete it first if it is not of the requested size + ynh_del_swap + fi + # create the swapfile + ynh_add_swap --size=$swapfile_size + else + # If not, make sure it is deleted + ynh_del_swap + fi +} + +do_$1_regen ${@:2} diff --git a/share/config_global.toml b/share/config_global.toml index 40b71ab19..54a80ede4 100644 --- a/share/config_global.toml +++ b/share/config_global.toml @@ -169,3 +169,26 @@ name = "Other" choices.ipv4 = "IPv4 Only" choices.ipv6 = "IPv6 Only" default = "both" +[swap] +name = "Swap" + [swap.swapfile] + name = "Swap file configuration" + [swap.swapfile.swapfile_enabled] + ask = "Do you need to create a swap file?" + help = "A swap file will extend the available RAM by using some of your storage space." + type = "boolean" + default = false + visible = "swapfile_enabled" + + [swap.swapfile.swapfile_warning] + ask = "Absolutely do not create a swap file if your root partition is on a SD card!" + help = "The intensive writing on the SD card will degrade it fast." + type = "alert" + style = "danger" + + [swap.swapfile.swapfile_size] + ask = "How many megabytes should the swap file be?" + help = "Only integers are accepted. Beware, if you reduce its current size, you may crash your server." + type = "number" + default = 1 + visible = "swapfile_enabled" diff --git a/src/settings.py b/src/settings.py index abe1a8f13..7650f8d53 100644 --- a/src/settings.py +++ b/src/settings.py @@ -366,3 +366,9 @@ def reconfigure_dovecot(setting_name, old_value, new_value): regen_conf(names=["dovecot"]) command = ["apt-get", "-y", "remove", dovecot_package] subprocess.call(command, env=environment) + +@post_change_hook("swapfile_enabled") +@post_change_hook("swapfile_size") +def reconfigure_swapfile(setting_name, old_value, new_value): + if old_value != new_value: + regen_conf(names=["swap"]) From 38fc88dcbeebb0f972ae07a51a7027b8d7b32d23 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Thu, 30 May 2024 21:34:49 +0000 Subject: [PATCH 02/11] Fixes and enhancements for swap management --- helpers/helpers.v1.d/hardware | 23 ++++++++++------------- hooks/conf_regen/53-swap | 16 +++++++++------- share/config_global.toml | 19 +++++++++---------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index bab855c42..071cd2f72 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -106,8 +106,8 @@ ynh_require_ram() { # Add swap # -# usage: ynh_add_swap --size=SWAP in MB -# | arg: -s, --size= - Amount of SWAP to add in MB. +# usage: ynh_add_swap --size=SWAP in MiB +# | arg: -s, --size= - Amount of SWAP to add in MiB. ynh_add_swap () { # Declare an array to define the options of this helper. declare -Ar args_array=( [s]=size= ) @@ -121,7 +121,7 @@ ynh_add_swap () { # Because we don't want to fill the disk with a swap file, divide by 2 the available space. local usable_space=$(( $free_space / 2 )) - SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} + SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} # Swap on SD card only if it's is specified if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ] @@ -134,21 +134,19 @@ ynh_add_swap () { # And set a acceptable size from the request if [ $usable_space -ge $swap_max_size ] then - local swap_size=$swap_max_size + swap_size=$swap_max_size elif [ $usable_space -ge $(( $swap_max_size / 2 )) ] then - local swap_size=$(( $swap_max_size / 2 )) + swap_size=$(( $swap_max_size / 2 )) elif [ $usable_space -ge $(( $swap_max_size / 3 )) ] then - local swap_size=$(( $swap_max_size / 3 )) + swap_size=$(( $swap_max_size / 3 )) elif [ $usable_space -ge $(( $swap_max_size / 4 )) ] then - local swap_size=$(( $swap_max_size / 4 )) + swap_size=$(( $swap_max_size / 4 )) else echo "Not enough space left for a swap file" >&2 - local swap_size=0 - # Store the swap size - yunohost settings set 'swap.swapfile.swapfile_size' -v ${swap_size} + swap_size=0 fi # If there's enough space for a swap, and no existing swap here @@ -158,7 +156,8 @@ ynh_add_swap () { truncate -s 0 /swap_file # set the No_COW attribute on the swapfile with chattr - chattr +C /swap_file + # let's not fail here, as some filesystems like ext4 do not support COW + chattr +C /swap_file || true # Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case if ! fallocate -l ${swap_size}K /swap_file @@ -172,8 +171,6 @@ ynh_add_swap () { swapon /swap_file # Then add an entry in fstab to load this swap at each boot. echo -e "/swap_file swap swap defaults 0 0 #Swap added by YunoHost config panel" >> /etc/fstab - # Store the swap size - yunohost settings set 'swap.swapfile.swapfile_size' -v ${swap_size} fi } diff --git a/hooks/conf_regen/53-swap b/hooks/conf_regen/53-swap index b3e6f89dc..fdb719afa 100755 --- a/hooks/conf_regen/53-swap +++ b/hooks/conf_regen/53-swap @@ -1,27 +1,29 @@ #!/bin/bash -set -e - -. /usr/share/yunohost/helpers +source /usr/share/yunohost/helpers do_pre_regen() { + : } do_post_regen() { - swapfile_enabled="$(yunohost settings get 'swap.swapfile.swapfile_enabled')" swapfile_size="$(yunohost settings get 'swap.swapfile.swapfile_size')" - if [ "${swapfile_enabled}" == "True" ]; then + if [ ${swapfile_enabled} -eq 1 ]; then # If a swapfile is requested - if [ $(stat -c%s /swap_file) -ne $swapfile_size ]; then + if [ -f /swap_file ] && [ $(stat -c%s /swap_file) -ne $swapfile_size ]; then # Let's delete it first if it is not of the requested size - ynh_del_swap + ynh_print_info --message="Deleting swap first..." + ynh_del_swap fi # create the swapfile + ynh_print_info --message="Attempting to create $swapfile_size MB swap..." ynh_add_swap --size=$swapfile_size + ynh_print_info --message="A $((swap_size / 1024)) MB swap has been created." else # If not, make sure it is deleted + ynh_print_info --message="Deleting swap..." ynh_del_swap fi } diff --git a/share/config_global.toml b/share/config_global.toml index 54a80ede4..4aa939749 100644 --- a/share/config_global.toml +++ b/share/config_global.toml @@ -173,22 +173,21 @@ name = "Other" name = "Swap" [swap.swapfile] name = "Swap file configuration" + [swap.swapfile.swapfile_warning] + ask = "Absolutely do not create a swap file if your root partition is on a SD card!" + help = "The intensive writing on the SD card will degrade it fast." + type = "alert" + style = "warning" + [swap.swapfile.swapfile_enabled] ask = "Do you need to create a swap file?" help = "A swap file will extend the available RAM by using some of your storage space." type = "boolean" default = false - visible = "swapfile_enabled" - - [swap.swapfile.swapfile_warning] - ask = "Absolutely do not create a swap file if your root partition is on a SD card!" - help = "The intensive writing on the SD card will degrade it fast." - type = "alert" - style = "danger" [swap.swapfile.swapfile_size] - ask = "How many megabytes should the swap file be?" - help = "Only integers are accepted. Beware, if you reduce its current size, you may crash your server." + ask = "How many Mebibytes should the swap file be?" + help = "Only integers are accepted ( 1 MiB = 1024 B). Beware, if you reduce its current size, you may crash your server." type = "number" - default = 1 + default = 1024 visible = "swapfile_enabled" From beff899e5ff4940598def317d1ab8726c95f42b5 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 31 May 2024 09:03:01 +0200 Subject: [PATCH 03/11] [enh] Configure swappiness --- helpers/helpers.v1.d/hardware | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 071cd2f72..3183de04c 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -130,6 +130,13 @@ ynh_add_swap () { return fi + # Configure swappiness + if [ ! -e /etc/sysctl.d/999-ynhswap.conf ] + then + echo "vm.swappiness=10" > /etc/sysctl.d/999-ynhswap.conf + sysctl --quiet --system + fi + # Compare the available space with the size of the swap. # And set a acceptable size from the request if [ $usable_space -ge $swap_max_size ] From f005a11a0dfbc427bc6fa68b77cc68aa9ccc5275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:20:54 +0200 Subject: [PATCH 04/11] Update documentation for ynh_add/del_swap --- helpers/helpers.v1.d/hardware | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 3183de04c..e00e2d296 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -104,10 +104,14 @@ ynh_require_ram() { fi } -# Add swap + +# Ask the creation of a swap file for the application. +# The helper might or might not create the swap file, considering the machine's configuration. # -# usage: ynh_add_swap --size=SWAP in MiB -# | arg: -s, --size= - Amount of SWAP to add in MiB. +# [packagingv1] +# +# usage: ynh_add_swap --size=SWAP in Mib +# | arg: -s, --size= - Amount of SWAP to add in Mib. ynh_add_swap () { # Declare an array to define the options of this helper. declare -Ar args_array=( [s]=size= ) @@ -181,6 +185,10 @@ ynh_add_swap () { fi } +# Delete the swap file created for the app by ynh_add_swap. +# +# [packagingv1] +# ynh_del_swap () { # If there a swap at this place if [ -e /swap_file ] From 2aa14345feff190c6e6e87e6614173c7e3c5dba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:22:21 +0200 Subject: [PATCH 05/11] helpers: replace ynh_is_main_device_a_sd_card with ynh_is_on_sd_card --dir=the_dir_to_check --- helpers/helpers.v1.d/hardware | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index e00e2d296..b02828296 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -128,7 +128,7 @@ ynh_add_swap () { SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} # Swap on SD card only if it's is specified - if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ] + if ynh_is_on_sd_card --dir="$swapfile_dir" && [ "$SD_CARD_CAN_SWAP" == "0" ] then ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage to it. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'" return @@ -202,16 +202,24 @@ ynh_del_swap () { fi } -# Check if the device of the main mountpoint "/" is an SD card +# Check if the device of the provided directory is an SD card # # [internal] # -# return 0 if it's an SD card, else 1 -ynh_is_main_device_a_sd_card () { - local main_device=$(lsblk --output PKNAME --noheadings $(findmnt / --nofsroot --uniq --output source --noheadings --first-only)) +# usage: ynh_is_on_sd_card --dir=/ +# | arg: -d, --dir= - Directory to check +ynh_is_on_sd_card () { + # Declare an array to define the options of this helper. + local -A args_array=( [d]=dir= ) + local dir + # Manage arguments with getopts + ynh_handle_getopts_args "$@" - if echo $main_device | grep --quiet "mmc" && [ $(tail -n1 /sys/block/$main_device/queue/rotational) == "0" ] - then + device_dev=$(findmnt --nofsroot --uniq --output source --noheadings --first-only --target "$dir") + device_pkname=$(lsblk --output PKNAME --noheadings "$device_dev") + device_rotational=$(lsblk --output ROTA --noheadings "$device_dev") + + if [[ "$device_pkname" == *"mmc"* ]] && [[ "$device_rotational" == "0" ]]; then return 0 else return 1 From 0e904304196d42a89a07204ff63ef7b74baf2747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:25:14 +0200 Subject: [PATCH 06/11] helpers: rewrite ynh_del_swap with a variable swap file location. --- helpers/helpers.v1.d/hardware | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index b02828296..91b135668 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -190,16 +190,20 @@ ynh_add_swap () { # [packagingv1] # ynh_del_swap () { - # If there a swap at this place - if [ -e /swap_file ] - then - # Clean the fstab - sed -i "/#Swap added by YunoHost config panel/d" /etc/fstab - # Desactive the swap file - swapoff /swap_file - # And remove it - rm /swap_file + # Could be moved to an argument + swapfile_dir="$(realpath /)" + swapfile_path="$(realpath "$swapfile_dir/swap_file")" + + if [ ! -f "$swapfile_path" ]; then + return fi + + # Clean the fstab... + sed -i "/#Swap added by $app/d" /etc/fstab + # Desactive the swap file... + swapoff "$swapfile_path" + # And remove it. + rm "$swapfile_path" } # Check if the device of the provided directory is an SD card From ee3be7a0ed48ce8ca48c7b65ec1e922b313a9b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:28:25 +0200 Subject: [PATCH 07/11] helpers: rewrite ynh_add_swap: cleaner code with early exits --- helpers/helpers.v1.d/hardware | 36 +++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 91b135668..4b21ff387 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -114,26 +114,42 @@ ynh_require_ram() { # | arg: -s, --size= - Amount of SWAP to add in Mib. ynh_add_swap () { # Declare an array to define the options of this helper. - declare -Ar args_array=( [s]=size= ) + local -A args_array=( [s]=size= ) local size # Manage arguments with getopts ynh_handle_getopts_args "$@" + # Could be moved to an argument + swapfile_dir="$(realpath /)" + swapfile_path="$(realpath "$swapfile_dir/swap_file")" + + # Early warning exit: Can't swap inside LXD + if [[ "$(systemd-detect-virt)" == "lxc" ]]; then + ynh_print_warn --message="You are inside a LXC container, swap will not be added." + ynh_print_warn --message="That can cause troubles for $app. Please make sure you have more than $((size/1024))G of RAM/swap available." + return + fi + + # Early warning exit: Preserve SD cards and do not swap on them + if ynh_is_on_sd_card --dir="$swapfile_dir" && [[ "${SD_CARD_CAN_SWAP:-0}" == "0" ]]; then + ynh_print_warn --message="Swap files on an SD card is not recommended, swap will not be added." + ynh_print_warn --message="That can cause troubles for $app. Please make sure you have more than $((size/1024))G of RAM/swap available." + ynh_print_warn --message="If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'" + return + fi + + # Early warning exit: swapfile already exists + if [ -f "$swapfile_path" ]; then + ynh_print_warn --message="Swap file $swapfile_path already exists!" + return + fi + local swap_max_size=$(( $size * 1024 )) local free_space=$(df --output=avail / | sed 1d) # Because we don't want to fill the disk with a swap file, divide by 2 the available space. local usable_space=$(( $free_space / 2 )) - SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} - - # Swap on SD card only if it's is specified - if ynh_is_on_sd_card --dir="$swapfile_dir" && [ "$SD_CARD_CAN_SWAP" == "0" ] - then - ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage to it. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'" - return - fi - # Configure swappiness if [ ! -e /etc/sysctl.d/999-ynhswap.conf ] then From 662bc6097a176aea987ab57edbfd6714b6d41129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:31:51 +0200 Subject: [PATCH 08/11] helpers: rewrite ynh_add_swap: cleaner code with simpler calculations --- helpers/helpers.v1.d/hardware | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 4b21ff387..4bbd7847d 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -144,11 +144,21 @@ ynh_add_swap () { return fi - local swap_max_size=$(( $size * 1024 )) + local swap_max_size_kb=$(( size * 1024 )) - local free_space=$(df --output=avail / | sed 1d) + local free_space_kb + free_space_kb=$(df --block-size=K --output=avail "$swapfile_dir" | sed 1d | sed -e 's/K$//') # Because we don't want to fill the disk with a swap file, divide by 2 the available space. - local usable_space=$(( $free_space / 2 )) + local usable_space_kb=$(( free_space_kb / 2 )) + + # Compare the available space with the size of the swap. + # And set a acceptable size from the request + size_space_ratio=$(( swap_max_size_kb / usable_space_kb + 1 )) + if (( size_space_ratio > 4)); then + ynh_print_warn --message="Not enough space for a swap file at $swapfile_path." + return + fi + swap_size_kb=$(( swap_max_size_kb / size_space_ratio )) # Configure swappiness if [ ! -e /etc/sysctl.d/999-ynhswap.conf ] @@ -157,25 +167,6 @@ ynh_add_swap () { sysctl --quiet --system fi - # Compare the available space with the size of the swap. - # And set a acceptable size from the request - if [ $usable_space -ge $swap_max_size ] - then - swap_size=$swap_max_size - elif [ $usable_space -ge $(( $swap_max_size / 2 )) ] - then - swap_size=$(( $swap_max_size / 2 )) - elif [ $usable_space -ge $(( $swap_max_size / 3 )) ] - then - swap_size=$(( $swap_max_size / 3 )) - elif [ $usable_space -ge $(( $swap_max_size / 4 )) ] - then - swap_size=$(( $swap_max_size / 4 )) - else - echo "Not enough space left for a swap file" >&2 - swap_size=0 - fi - # If there's enough space for a swap, and no existing swap here if [ $swap_size -ne 0 ] && [ ! -e /swap_file ] then From 03837bd9b8af165c51f81edf314ca4f1e68b5c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:32:15 +0200 Subject: [PATCH 09/11] helpers: rewrite ynh_add_swap: cleaner code --- helpers/helpers.v1.d/hardware | 36 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 4bbd7847d..025da62d8 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -167,29 +167,21 @@ ynh_add_swap () { sysctl --quiet --system fi - # If there's enough space for a swap, and no existing swap here - if [ $swap_size -ne 0 ] && [ ! -e /swap_file ] - then - # Create file - truncate -s 0 /swap_file + # Workaround for some copy-on-write filesystems like btrfs. + # Create the file + truncate -s 0 "$swapfile_path" + # Set the No_COW attribute on the swapfile with chattr + chattr +C "$swapfile_path" || true + # Set the final file size + dd if=/dev/zero of="$swapfile_path" bs=1024 count="$swap_size_kb" + chmod 0600 "$swapfile_path" - # set the No_COW attribute on the swapfile with chattr - # let's not fail here, as some filesystems like ext4 do not support COW - chattr +C /swap_file || true - - # Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case - if ! fallocate -l ${swap_size}K /swap_file - then - dd if=/dev/zero of=/swap_file bs=1024 count=${swap_size} - fi - chmod 0600 /swap_file - # Create the swap - mkswap /swap_file - # And activate it - swapon /swap_file - # Then add an entry in fstab to load this swap at each boot. - echo -e "/swap_file swap swap defaults 0 0 #Swap added by YunoHost config panel" >> /etc/fstab - fi + # Create the swap + mkswap "$swapfile_path" + # And activate it + swapon "$swapfile_path" + # Then add an entry in fstab to load this swap at each boot. + echo -e "$swapfile_path swap swap defaults 0 0 #Swap added by $app" >> /etc/fstab } # Delete the swap file created for the app by ynh_add_swap. From e039d2e195c54f85902e88b1606892a4928a6268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 31 May 2024 16:32:46 +0200 Subject: [PATCH 10/11] helpers: rewrite ynh_add_swap: rename files swap_file->swap_yunohost, sysctl 999-yunohost-swap.conf --- helpers/helpers.v1.d/hardware | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 025da62d8..1f047ded1 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -121,7 +121,7 @@ ynh_add_swap () { # Could be moved to an argument swapfile_dir="$(realpath /)" - swapfile_path="$(realpath "$swapfile_dir/swap_file")" + swapfile_path="$(realpath "$swapfile_dir/swap_yunohost")" # Early warning exit: Can't swap inside LXD if [[ "$(systemd-detect-virt)" == "lxc" ]]; then @@ -161,8 +161,7 @@ ynh_add_swap () { swap_size_kb=$(( swap_max_size_kb / size_space_ratio )) # Configure swappiness - if [ ! -e /etc/sysctl.d/999-ynhswap.conf ] - then + if [ ! -f /etc/sysctl.d/999-yunohost-swap.conf ]; then echo "vm.swappiness=10" > /etc/sysctl.d/999-ynhswap.conf sysctl --quiet --system fi @@ -191,7 +190,7 @@ ynh_add_swap () { ynh_del_swap () { # Could be moved to an argument swapfile_dir="$(realpath /)" - swapfile_path="$(realpath "$swapfile_dir/swap_file")" + swapfile_path="$(realpath "$swapfile_dir/swap_yunohost")" if [ ! -f "$swapfile_path" ]; then return From 43992e1338d3bdb7a4c245ab7a1db085750f31e8 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sat, 17 Aug 2024 09:48:35 +0200 Subject: [PATCH 11/11] More sanity in free memory calculation Co-authored-by: ljf (zamentur) --- helpers/helpers.v1.d/hardware | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/helpers/helpers.v1.d/hardware b/helpers/helpers.v1.d/hardware index 1f047ded1..9f0e447dd 100644 --- a/helpers/helpers.v1.d/hardware +++ b/helpers/helpers.v1.d/hardware @@ -144,21 +144,18 @@ ynh_add_swap () { return fi - local swap_max_size_kb=$(( size * 1024 )) local free_space_kb free_space_kb=$(df --block-size=K --output=avail "$swapfile_dir" | sed 1d | sed -e 's/K$//') - # Because we don't want to fill the disk with a swap file, divide by 2 the available space. - local usable_space_kb=$(( free_space_kb / 2 )) + # We don't want to fill the disk with a swap file. + local usable_space=$(( free_space_kb / 1024 - 1024 )) # Compare the available space with the size of the swap. - # And set a acceptable size from the request - size_space_ratio=$(( swap_max_size_kb / usable_space_kb + 1 )) - if (( size_space_ratio > 4)); then + if (( size > usable_space )); then ynh_print_warn --message="Not enough space for a swap file at $swapfile_path." return fi - swap_size_kb=$(( swap_max_size_kb / size_space_ratio )) + swap_size_kb=$(( size * 1024 )) # Configure swappiness if [ ! -f /etc/sysctl.d/999-yunohost-swap.conf ]; then