diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ddcb2f5..a0f1ae9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,11 +5,21 @@ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { "dockerfile": "Dockerfile" - } + }, // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "StefanMayrhofer.shellspec-tester", + "timonwong.shellcheck" + ] + } + } + // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], diff --git a/README.md b/README.md index 462f41e..1e2bdcd 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,39 @@ This script supports only systems with a swap file on ext4 file system. The syst ## Requirements -- Ubuntu 24.04(#1) or its flavors (e.g., Kubuntu, Ubuntu Mate, etc.) -- ext4 file system -- swap file (not swap partition) -- sudo privileges +- Ubuntu 24.04(#1) or newer. + - The flavors (e.g., Kubuntu, Ubuntu Mate, etc.). +- ext4 file system. +- swap file (not swap partition). +- sudo privileges. +- Secure boot disabled in the BIOS/UEFI settings (#2). --- - (#1) Ubuntu updated the the Polkit major version from Ubuntu 24.04. So, this script may not work on Ubuntu versions prior to 24.04. +- (#2) Linux kernel lockdown feature prevents the resume from hibernation during the secure boot. To use hibernation, you need to disable secure boot in the BIOS/UEFI settings. ## Test environment and results + +### Version 3.0.x +The following table shows the test environment and results for version 3.0.x of this script. +| OS | Platform | Note | +| ----------------- | -----------| ---------- | +| Ubuntu 24.04 | Hyper-V | Works fine| +| Ubuntu 26.04 | Hyper-V | Need workaround (#1)| +| Kubuntu 26.04 | Hyper-V | Works fine | +| Kubuntu 26.04 | Fujitsu FMV Lifebook U9312 | Works fine | +| Lubuntu 26.04 | Hyper-V | Need Workaround (#1)| + +--- +- (#1) After executing the `fuyujitaku.sh` script, reboot the system and then, run `update-initramfs -u -k all` command. See [Workarounds for certain flavors of Ubuntu 26.04 LTS](#workarounds-for-certain-flavors-of-ubuntu-2604-lts) section for details. + +### Version 2.0.x +The following table shows the test environment and results for version 2.0.x of this script. +| OS | Platform | Note | +| ----------------- | ------------------------------ | ---------- | +| Kubuntu 25.10 | Fujitsu FMV Lifebook U939 | Works fine | + + ### Version 1.x.x The following table shows the test environment and results for version 1.x.x of this script. | OS | Platform | Note | @@ -38,14 +62,11 @@ The following table shows the test environment and results for version 1.x.x of - (#3) The mouse cursor is rendered incorrectly after resuming. The workaround is to reboot the system. - (#4) Intel Core i5-8365U, 8GB RAM, 256GB SSD. -### Version 2.0.x -The following table shows the test environment and results for version 1.x.x of this script. -| OS | Platform | Note | -| ----------------- | ------------------------------ | ---------- | -| Kubuntu 25.10 | Fujitsu FMV Lifebook U939 | Works fine | - ## How to use +> [!Caution] +> For the certain flavors of Ubuntu 26.04 LTS, you need special workaround to avoid a problem. Read this section carefully before using the script. + 1. Download the latest release from [here](https://github.com/suikan4github/fuyujitaku). 2. Extract the downloaded archive. 3. Open a terminal and navigate to the extracted folder. @@ -84,16 +105,44 @@ Finally, you can specify both parameter at once. ./fuyujitaku.sh -s 12G -d 600s ``` +### Workarounds for certain flavors of Ubuntu 26.04 LTS +Certain flavors of Ubuntu 26.04 LTS (e.g., Ubuntu and Lubuntu) have a problem that prevent the execusion of `systemctl hibernate` command after running the `fuyujitaku.sh` script. + +Usually, the following command can configure the system hibernate possible. + +```sh +./fuyujitaku.sh +sudo reboot +``` +But you may see the following error message when you run `systemctl hibernate` command after running the above commands, in some flavors of Ubuntu 26.04 LTS. + +``` +Call to Hibernate failed: Invalid resume config: resume= is not populated yet resume_offset= is +``` +This is reported in the [issue #15](https://github.com/suikan4github/fuyujitaku/issues/15). + +The workaround is to run the following command **after** rebooting the system. + +```bash +# Run these commands after rebooting the system. +sudo update-initramfs -u -k all +sudo reboot +``` + + ## How to revert -The revert.sh script is provided to revert the changes made by fuyujitaku.sh script. +The `revert.sh` script is provided to revert the changes made by `fuyujitaku.sh` script. To revert the changes, run the following command: ```bash -. ./revert.sh +./revert.sh ``` -Note that the revert.sh script works only if the fuyujitaku.sh script was run without any errors. +> [!Note] +> The revert.sh script works only if the fuyujitaku.sh script run without any errors. + +The `revert.sh` script will restore the original swap size and the original kernel parameters. It will also remove the backup files created by `fuyujitaku.sh` script. ## How to test To run the auto tests, you need to install [shellspec](https://github.com/shellspec/shellspec). @@ -110,6 +159,7 @@ shellspec If you encounter any issues while using this script, please check the following: - Ensure that you have a swap file and not a swap partition. This script does not support systems with swap partitions. - Ensure that you have enough disk space to extend the swap file. The script will attempt to double the size of the swap file, by default. +- Ensure that secure boot is disabled in the BIOS/UEFI settings. - Check the system logs for any error messages related to hibernation or swap file. Generally, the script should work on Ubuntu and its flavors. However, if you encounter any issues, please feel free to open an issue on the [GitHub repository](https://github.com/suikan4github/fuyujitaku/wiki) diff --git a/fuyujitaku.sh b/fuyujitaku.sh index 3670f49..c20b622 100755 --- a/fuyujitaku.sh +++ b/fuyujitaku.sh @@ -68,7 +68,7 @@ case "$RESPONSE" in esac echo "" -save_original_swap_size +save_original_config # If it returns non zero, abort the script. resize_swap_file diff --git a/lib/functions.sh b/lib/functions.sh index e5c8347..fc36756 100644 --- a/lib/functions.sh +++ b/lib/functions.sh @@ -1,5 +1,17 @@ #!/bin/sh +# Check whether the backup directory exists. +# Return true(0) if it exists, false(1) if it does not exist. +# This is helper function for the test to check whether the backup directory is created. +backup_dir_exists() { + BACKUPDIR=$(get_backup_dir_name) + if [ -d "$BACKUPDIR" ]; then + return 0 + else + return 1 + fi +} + # Write a stream to a file. # This is a helper function to make test easier. # Usage: @@ -201,15 +213,25 @@ validate_swap_file_size() { # Save original swap size -save_original_swap_size() { +save_original_config() { # This directory is shared with inform_swap_location_to_kernel() function. BACKUPDIR=$(get_backup_dir_name) SWAPSIZEFILE=$(get_original_swap_size_file_name) - mkdir -p "$BACKUPDIR" - ORIGINAL_SWAP_SIZE=$(free --mega | awk '/Swap:/{print $2}') - write_stream "$ORIGINAL_SWAP_SIZE" "$BACKUPDIR/$SWAPSIZEFILE" + # if the backup directory does not exist, create it and save the original swap size and grub file. + # if not, skip creating it because it may contain the backup files. + if ! backup_dir_exists; then + # Create backup directory. + mkdir -p "$BACKUPDIR" + # Get the original swap size in MByte and save it to a file. + ORIGINAL_SWAP_SIZE=$(free --mega | awk '/Swap:/{print $2}') + write_stream "$ORIGINAL_SWAP_SIZE" "$BACKUPDIR/$SWAPSIZEFILE" + + # Get the file name to store original grub. + GRUBFILE=$(get_original_grub_file_name) + copy_grub "$BACKUPDIR/$GRUBFILE" + fi return 0 } @@ -276,9 +298,6 @@ resize_swap_file() { inform_swap_location_to_kernel() { echo "----------- Editing GRUB configuration -----------" - # Get the file name to store original grub. - GRUBFILE=$(get_original_grub_file_name) - # Get the UUID of the root filesystem (where the swap file stays). UUID=$(findmnt / -o UUID --noheadings) @@ -291,9 +310,8 @@ inform_swap_location_to_kernel() { # Save the current GRUB configuration to a temporary file. TEMP_GRUB=$(mktemp) - SAVED_GRUB=$(mktemp) copy_grub "$TEMP_GRUB" - copy_grub "$SAVED_GRUB" + # If the grub configuration contains resume/resume_offset, remove them first. sudo sed -i /^GRUB_CMDLINE_LINUX_DEFAULT/s/resume[_=a-zA-Z0-9-]*//g $TEMP_GRUB @@ -312,14 +330,8 @@ inform_swap_location_to_kernel() { update_grub if [ $? -ne 0 ]; then echo "!!!!! Failed to update GRUB configuration." - # Restore the original GRUB configuration. - echo "!!!!! Restoring original GRUB configuration." - write_grub "$SAVED_GRUB" /etc/default/grub echo "!!!!! Aborted." return 1 - else - # Save the original file. - write_file "$SAVED_GRUB" "$BACKUPDIR/$GRUBFILE" fi echo "----------- GRUB configuration updated -----------" diff --git a/revert.sh b/revert.sh index 39c39d8..83c1a8b 100755 --- a/revert.sh +++ b/revert.sh @@ -73,13 +73,14 @@ if [ $? -ne 0 ]; then fi #----------------------------------------------------------------------- # Update the grub configuration -echo "----------- Updating GRUB configuration -----------" +echo "----------- Reverting GRUB configuration -----------" sudo update-grub if [ $? -ne 0 ]; then echo "!!!!! Failed to update GRUB configuration." echo "!!!!! Aborted." exit 1 fi + #----------------------------------------------------------------------- # Remove the custom sleep configuration echo "----------- Removing sleep configuration -----------" @@ -108,14 +109,20 @@ if [ $? -ne 0 ]; then echo "!!!!! Aborted." exit 1 fi +#----------------------------------------------------------------------- +# Remove the backup files +echo "----------- Removing backup files -----------" +sudo rm -rf "$BACKUPDIR" + #----------------------------------------------------------------------- # All done echo "----------- Revert completed -----------" -echo "Swap file size reverted to original size: $ORIGINAL_SWAP_SIZE MB" -echo "GRUB configuration reverted to original." -echo "Sleep configuration reverted to original." -echo "Policykit configuration reverted to original." +echo "Reverted swap file size to original size: $ORIGINAL_SWAP_SIZE MB" +echo "Reverted GRUB configuration to original." +echo "Reverted sleep configuration to original." +echo "Reverted policykit configuration to original." echo "Systemd daemon reloaded." +echo "Original files removed." echo "All done." echo "Please reboot your system to apply the changes." diff --git a/spec/inform_swap_location_to_kernel_spec.sh b/spec/inform_swap_location_to_kernel_spec.sh index 9dafa2c..213bcd1 100644 --- a/spec/inform_swap_location_to_kernel_spec.sh +++ b/spec/inform_swap_location_to_kernel_spec.sh @@ -25,7 +25,7 @@ File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes) 3: 16384.. 28671: 2557952.. 2570239: 12288: 2535424: EOF return 0 - } + } # filefrag() Before 'write_file() { SOURCE_FILENAME="$1"; @@ -55,7 +55,7 @@ GRUB_CMDLINE_LINUX="" #GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef" EOF return 0 - } + } # copy_grub() # shellcheck disable=SC3033 update_grub() { diff --git a/spec/save_original_config_spec.sh b/spec/save_original_config_spec.sh new file mode 100644 index 0000000..0109cd9 --- /dev/null +++ b/spec/save_original_config_spec.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +Include 'lib/functions.sh' + +Describe 'save_original_config function' + + + # Mock of sudo command + sudo() { + # Simulate sudo by calling the command directly. + "$@" + } + + # Mock of write_stream() function + write_stream() { + # shellcheck disable=SC2034 + STREAM="$1" + # shellcheck disable=SC2034 + FILENAME="$2" + return 0; + } + + # Mock of free command + free() { + echo " total used free shared buff/cache available" + echo "Mem: 15926 2345 11234 123 2345 13245" + echo "Swap: 15892 0 15892" + } + + # Mock of copy_grub() function + copy_grub() { + # shellcheck disable=SC2034 + COPY_GRUB_DESTINATION_FILENAME="$1"; + return 0 + } + + # Mock of mkdir() function to simulate the creation of backup directory + mkdir() { + # shellcheck disable=SC2034 + MKDIR_FLAG="$1"; + # shellcheck disable=SC2034 + MKDIR_DIR="$2"; + return 0 + } + + It 'should give the original swap size and backup file name to stdn in and parameter, respectively, if backup directory does not exist' + # Mock of backup_dir_exists() function to simulate the case when the backup directory does not exist. + # shellcheck disable=SC2329 + backup_dir_exists() { + return 1 + } + + When call save_original_config + The variable MKDIR_FLAG should equal "-p" + The variable MKDIR_DIR should equal "backup" + The variable FILENAME should equal "backup/original_swap_size" + The variable STREAM should equal "15892" + The variable COPY_GRUB_DESTINATION_FILENAME should equal "backup/original_grub_config" + End + + It 'should not give anything if backup directory already exists' + # Mock of backup_dir_exists() function to simulate the case when the backup directory already exists. + backup_dir_exists() { + return 0 + } + + When call save_original_config + The variable FILENAME should be undefined + The variable COPY_GRUB_DESTINATION_FILENAME should be undefined + End + + +End \ No newline at end of file diff --git a/spec/save_original_swap_size_spec.sh b/spec/save_original_swap_size_spec.sh deleted file mode 100644 index e8d2e66..0000000 --- a/spec/save_original_swap_size_spec.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -Include 'lib/functions.sh' - -Describe 'save_original_swap_size function' - # Mock of write_stream() function - write_stream() { - STREAM="$1" - FILENAME="$2" - return 0; - } - - # Mock of free command - free() { - echo " total used free shared buff/cache available" - echo "Mem: 15926 2345 11234 123 2345 13245" - echo "Swap: 15892 0 15892" - } - - It 'should give the original swap size and backup file name to stdn in and parameter, respectively' - When call save_original_swap_size - The variable FILENAME should equal "backup/original_swap_size" - The variable STREAM should equal "15892" - End -End \ No newline at end of file