1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,28 @@ |
1 |
+#!/usr/bin/env bash |
|
2 |
+# Compute MAX_SWAPFILES by duplicating the computations found in swap.h as of 2023-08. |
|
3 |
+ |
|
4 |
+function get_swap_define { |
|
5 |
+ local value="${1}" |
|
6 |
+ local kernel_release="$(uname -r | cut -d- -f1,2)" |
|
7 |
+ local swap_h_path="/usr/src/linux-headers-${kernel_release}-common/include/linux/swap.h" |
|
8 |
+ perl -nE 'say $1 if (m/#define\s+'${value}'\s+(\d+)/ && $1 > 0)' "${swap_h_path}" |
|
9 |
+} |
|
10 |
+ |
|
11 |
+function get_kernel_config { |
|
12 |
+ local config="${1}" |
|
13 |
+ local kernel_config="/boot/config-$(uname -r)" |
|
14 |
+ grep -q "^${config}=y\$" "${kernel_config}" |
|
15 |
+} |
|
16 |
+ |
|
17 |
+MAX_SWAPFILES_SHIFT=$(get_swap_define MAX_SWAPFILES_SHIFT) |
|
18 |
+SWP_DEVICE_NUM=$(get_swap_define SWP_DEVICE_NUM) |
|
19 |
+SWP_MIGRATION_NUM=$(get_swap_define SWP_MIGRATION_NUM) |
|
20 |
+SWP_HWPOISON_NUM=$(get_swap_define SWP_HWPOISON_NUM) |
|
21 |
+SWP_PTE_MARKER_NUM=$(get_swap_define SWP_PTE_MARKER_NUM) |
|
22 |
+ |
|
23 |
+((MAX_SWAPFILES=1 << MAX_SWAPFILES_SHIFT)) |
|
24 |
+kernel_config="/boot/config-$(uname -r)" |
|
25 |
+get_kernel_config CONFIG_MIGRATION && ((MAX_SWAPFILES-=SWP_MIGRATION_NUM)) |
|
26 |
+get_kernel_config CONFIG_MEMORY_FAILURE && ((MAX_SWAPFILES-=SWP_HWPOISON_NUM)) |
|
27 |
+get_kernel_config CONFIG_DEVICE_PRIVATE && ((MAX_SWAPFILES-=SWP_DEVICE_NUM)) |
|
28 |
+((MAX_SWAPFILES-=SWP_PTE_MARKER_NUM)) |
0 | 29 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,20 @@ |
1 |
+#!/usr/bin/env bash |
|
2 |
+# Compute MAX_SWAPFILES by "running" swap.h using the C preprocessor. |
|
3 |
+ |
|
4 |
+kernel_config="/boot/config-$(uname -r)" |
|
5 |
+kernel_release="$(uname -r | cut -d- -f1,2)" |
|
6 |
+# Debian provides swap.h through package linux-headers-xxx-common: |
|
7 |
+swap_h_path="/usr/src/linux-headers-${kernel_release}-common/include/linux/swap.h" |
|
8 |
+MAX_SWAPFILES=$( |
|
9 |
+ { |
|
10 |
+ # Turn the current kernel's configuration into a sequence of #define statements: |
|
11 |
+ perl -ne 'printf(qq[#define %s %s\n], $1, $2) if m#^([^=]+)=(.*)$#' "${kernel_config}" |
|
12 |
+ # Append include/linux/swap.h but get rid of #include statements for the sake of simplicity: |
|
13 |
+ grep -v '#include' "${swap_h_path}" |
|
14 |
+ # Last line: instruct the C preprocessor to output the value of |
|
15 |
+ # MAX_SWAPFILES; we expect a single-line math expression, written with C in |
|
16 |
+ # mind yet Python/Perl-friendly, hence the addition of print() for Perl: |
|
17 |
+ echo 'print(MAX_SWAPFILES)' |
|
18 |
+ } | cpp | tail -1 | perl - |
|
19 |
+ # ^ Feed the whole thing to the C preprocessor, keep only the last line and feed it to Perl |
|
20 |
+) |
0 | 21 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+#!/usr/bin/env bash |
|
2 |
+# Create and enable as many 1-GiB swap files as the kernel allows. |
|
3 |
+source determine-max-swapfiles-2.bash |
|
4 |
+echo "MAX_SWAPFILES: ${MAX_SWAPFILES}" |
|
5 |
+ |
|
6 |
+umask 0077 |
|
7 |
+hostname=$(hostname -s) |
|
8 |
+((bs=1024**2)) |
|
9 |
+((size=1*1024*bs)) |
|
10 |
+((count=size/bs)) |
|
11 |
+for num in $(seq 1 "${MAX_SWAPFILES}"); do |
|
12 |
+ printf -v num_padded "%02d" "${num}" |
|
13 |
+ file="/data/swap/${num_padded}" |
|
14 |
+ label="${hostname^^}SWAP${num_padded}" |
|
15 |
+ # 4-KiB swap partition header: |
|
16 |
+ truncate -s 4096 "${file}" |
|
17 |
+ # Fill it with zeroes: |
|
18 |
+ dd if=/dev/zero of="${file}" bs=4096 count=1 status=none |
|
19 |
+ # Add the desired swap size, filled with zeroes too: |
|
20 |
+ dd if=/dev/zero of="${file}" conv=notrunc oflag=append count="${count}" bs="${bs}" status=none |
|
21 |
+ # Format the swap partition: |
|
22 |
+ mkswap -L "${label}" "${file}" |
|
23 |
+ swapon "${file}" |
|
24 |
+done |