View previous topic :: View next topic |
Author |
Message |
Rockman8 n00b
Joined: 19 Sep 2023 Posts: 36
|
Posted: Wed Jul 10, 2024 7:32 pm Post subject: Need help setting initramfs to hibernate. |
|
|
Hello guys,
I got this init where I mount all the lvm partitions and I whish to set it to hibernate (elogind) I used this init as model
https://wiki.gentoo.org/wiki/Custom_Initramfs/Examples
This code in particular
Code: |
for p in \$(cat /proc/cmdline); do
case "\${p}" in
crypt_root=*)
crypt_root="\${p#*=}"
;;
root=*)
root="\${p#*=}"
;;
resume=*)
resume="\${p#*=}"
;;
ro|rw)
mount_ro_rw="\${p}"
;;
esac
done
# enable resume from hibernate
if [ -n "\${resume}" ]; then
# copy the major:minor of the swap block device into /sys/power/resume
printf '%u:%u\\n' \$(stat -L -c '0x%t 0x%T' "\${resume}") > /sys/power/resume || \
rescue_shell "Activating resume failed."
fi
|
and changed it into
Code: |
resume_hibernate() {
# set hardcoded default values
resume="/dev/vg0/swap"
# parse kernel command line
for p in $(cat /proc/cmdline); do
if ["${p}"=resume]; then
resume="${p#*=}"
fi
done
# enable resume from hibernate
if [ -n "${resume}" ]; then
# copy the major:minor of the swap block device into /sys/power/resume
printf '%u:%u\n' $(stat -L -c '0x%t 0x%T' "${resume}") > /sys/power/resume || rescue_shell "Activating resume failed."
fi
}
|
Is this code safe to run?
This is my current init
Code: |
#!/bin/busybox sh
rescue_shell() {
#load keymap
loadkmap < /keymap.bmap
echo "$@"
echo "Something went wrong. Dropping you to a shell."
module_usb_install
busybox --install -s /usr/local/bin
setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
#exec /bin/sh
}
uuidlabel_root() {
for cmd in $(cat /proc/cmdline) ; do
case $cmd in
root=*)
type=$(echo $cmd | cut -d= -f2)
echo "Mounting rootfs"
if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then
uuid=$(echo $cmd | cut -d= -f3)
mount -o ro $(findfs "$type"="$uuid") /mnt/root
else
mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root
fi
;;
esac
done
}
check_filesystem() {
# most of code coming from /etc/init.d/fsck
local fsck_opts= check_extra= RC_UNAME=$(uname -s)
# FIXME : get_bootparam forcefsck
if [ -e /forcefsck ]; then
fsck_opts="$fsck_opts -f"
check_extra="(check forced)"
fi
echo "Checking local filesystem $check_extra : $1"
if [ "$RC_UNAME" = Linux ]; then
fsck_opts="$fsck_opts -C0 -T"
fi
trap : INT QUIT
# using our own fsck, not the builtin one from busybox
/bin/fsck -p $fsck_opts $1
case $? in
0) return 0;;
1) echo "Filesystem repaired"; return 0;;
2|3) if [ "$RC_UNAME" = Linux ]; then
echo "Filesystem repaired, but reboot needed"
reboot -f
else
rescue_shell "Filesystem still have errors; manual fsck required"
fi;;
4) if [ "$RC_UNAME" = Linux ]; then
rescue_shell "Fileystem errors left uncorrected, aborting"
else
echo "Filesystem repaired, but reboot needed"
reboot
fi;;
8) echo "Operational error"; return 0;;
12) echo "fsck interrupted";;
*) echo "Filesystem couldn't be fixed";;
esac
rescue_shell
}
module_install() {
#This function must be called AFTER the lvm partitions have been mounted
#export FIRMWARE_DIR=/mnt/root/lib/firmware/
# Loading r8169 (ethernet) and amdgpu (graphic card) firmware and modules
#ln -st /lib/modules/ /mnt/root/usr/lib/modules/$(uname -r)/
#(busybox's ln does not support -t option, must move into desired directory and then the target directory symlink is created.)
#creating modules' directory lin
cd /lib/
ln -s /mnt/root/usr/lib/modules/
#creating link firmware's directory link
cd /lib/
ln -s /mnt/root/lib/firmware/
#moving out from the directory
cd
/bin/modprobe -av realtek 8169 #drm amdgpu
}
module_usb_install() {
#load usb support
insmod /modules/xhci-hcd.ko || echo "Failed to load xhci-hcd"
insmod /modules/ehci-hcd.ko || echo "Failed to load eci-hcd"
insmod /modules/ohci-hcd.ko || echo "Failed to load ohci-hcd"
insmod /modules/usb-storage.ko || echo "Failed to load usb-storage"
insmod /modules/uas.ko || echo "Failed to load uas"
}
resume_hibernate() {
# set hardcoded default values
resume="${RESUME}"
# parse kernel command line
for p in \$(cat /proc/cmdline); do
if ["\${p}"=resume]; then
resume="\${p#*=}"
fi
done
# enable resume from hibernate
if [ -n "\${resume}" ]; then
# copy the major:minor of the swap block device into /sys/power/resume
printf '%u:%u\\n' \$(stat -L -c '0x%t 0x%T' "\${resume}") > /sys/power/resume || \
rescue_shell "Activating resume failed."
fi
}
# temporarily mount proc and sys
#module_usb_install
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
# disable kernel messages from popping onto the screen
echo 0 > /proc/sys/kernel/printk
# clear the screen
clear
# mounting rootfs on /mnt/root
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
lvm lvchange -a ly vg0/root || rescue_shell
lvm lvchange -a ly vg0/boot || rescue_shell
lvm lvchange -a ly vg0/usr || rescue_shell
lvm lvchange -a ly vg0/var || rescue_shell
lvm lvchange -a ly vg0/var_tmp || rescue_shell
lvm lvchange -a ly vg0/var_log || rescue_shell
lvm lvchange -a ly vg0/swap || rescue_shell
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/vg0-root /dev/vg0/root
uuidlabel_root || rescue_shell "Error with uuidlabel_root"
# space separated list of mountpoints that ...
mountpoints="/boot /usr /var /var/tmp /var/log" #note: you can add more than just usr, but make sure they are declared in /usr/src/initramfs/initramfs_list
# ... we want to find in /etc/fstab ...
ln -s /mnt/root/etc/fstab /etc/fstab
# ... to check filesystems and mount our devices.
for m in $mountpoints ; do
check_filesystem $m
echo "Mounting $m"
# mount the device and ...
mount $m || rescue_shell "Error while mounting $m"
# ... move the tree to its final location
mount --move $m "/mnt/root"$m || rescue_shell "Error while moving $m"
done
# install modules
# currently not installing any early modules
#module_install || rescue_shell "Error while installing modules"
=========================================================================================
#Resuming after lvm partitions have been started and mounted
#resume_hibernate || rescue_shell
=========================================================================================
echo "All done. Switching to real root."
# clean up. The init process will remount proc sys and dev later
umount /proc
umount /sys
umount /dev
# switch to the real root and execute init
exec switch_root /mnt/root /sbin/init
|
and grub.conf
Code: |
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/vg0/swap"
|
Is this OK? Can I hibernate safely and wake up without messing with my system?
Thanks in advance! |
|
Back to top |
|
|
sublogic Apprentice
Joined: 21 Mar 2022 Posts: 269 Location: Pennsylvania, USA
|
Posted: Thu Jul 11, 2024 1:48 am Post subject: Re: Need help setting initramfs to hibernate. |
|
|
Rockman8 wrote: | Is this OK? Can I hibernate safely and wake up without messing with my system? | NO !
Your script mounts root before attempting to resume. The kernel docs say: Documentation/power/swsusp.rst wrote: | **BIG FAT WARNING**
If you touch anything on disk between suspend and resume...
...kiss your data goodbye.
If you do resume from initrd after your filesystems are mounted...
...bye bye root partition.
[this is actually same case as above] |
You should attempt to resume as soon as you have /dev/vg0/swap.
(Also there is no need for a rescue shell if the resume fails. That's normal after a shutdown instead of a hibernate: there is no hibernation signature. Your script just continues. Now you can mount root and do the switch_root.)
I didn't check deeply. I assume this /init boots correctly with the resume_hibernate commented out ? |
|
Back to top |
|
|
Rockman8 n00b
Joined: 19 Sep 2023 Posts: 36
|
Posted: Thu Jul 11, 2024 5:09 am Post subject: |
|
|
Thank you for answering.
Quote: |
I didn't check deeply. I assume this /init boots correctly with the resume_hibernate commented out ?
|
It does although my rescue shell does not allow keyboard input somehow, tried to load usb kernel modules or call mdev to detect keyboard or install modules before mounting devtmpfs but it did not work, after trying for some days and not getting anywhere I moved on and just left it alone.
Also tried to load early some kernel modules by linking the firmware and modules directory into the initramfs after mounting the partitions but that did not work either, so again I left it alone after tweaked the kernel to somewhat how it was working before I got stuck in the boot process. kinda satisfied now but puzzled as to why i could not load the ethernet driver or the amdgpu module, because if the time comes to when i need to load something early I might not be able to do it.
So leaving the modules out it does load the lvm partitions and checks every partition without any issue.
And how about now?
Code: |
...
# mounting rootfs on /mnt/root
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
lvm lvchange -a ly vg0/root || rescue_shell
lvm lvchange -a ly vg0/boot || rescue_shell
lvm lvchange -a ly vg0/usr || rescue_shell
lvm lvchange -a ly vg0/var || rescue_shell
lvm lvchange -a ly vg0/var_tmp || rescue_shell
lvm lvchange -a ly vg0/var_log || rescue_shell
lvm lvchange -a ly vg0/swap || rescue_shell
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/vg0-root /dev/vg0/root
#resume_hibernate
...
|
or perhaps like this?
and call it before all the other partitions are mounted maybe right after devtmpfs is mounted?
Code: |
resume_hibernate() {
# set hardcoded default values
resume="/dev/vg0/swap"
# parse kernel command line
for p in $(cat /proc/cmdline); do
if ["${p}"=resume]; then
resume="${p#*=}"
fi
done
# enable resume from hibernate
if [ -n "${resume}" ]; then
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
lvm lvchange -a ly vg0/swap || rescue_shell
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
# copy the major:minor of the swap block device into /sys/power/resume
printf '%u:%u\n' $(stat -L -c '0x%t 0x%T' "${resume}") > /sys/power/resume || rescue_shell "Activating resume failed."
fi
}
|
|
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5050 Location: Bavaria
|
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 22598
|
Posted: Thu Jul 11, 2024 2:08 pm Post subject: |
|
|
The main value of modules is to defer loading them until they are needed. If you need them so early that the initramfs always loads them, it seems like you are not getting any value from using a module, and are instead going through extra trouble that would be avoided if those features were built in. If it were my system, I would set as =y any kernel features that I always want enabled in every boot. Use modules only for those things that I might reasonably go hours or days without loading. |
|
Back to top |
|
|
sublogic Apprentice
Joined: 21 Mar 2022 Posts: 269 Location: Pennsylvania, USA
|
Posted: Fri Jul 12, 2024 2:34 am Post subject: |
|
|
Rockman8 wrote: | And how about now?
Code: |
...
# mounting rootfs on /mnt/root
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
lvm lvchange -a ly vg0/root || rescue_shell
lvm lvchange -a ly vg0/boot || rescue_shell
lvm lvchange -a ly vg0/usr || rescue_shell
lvm lvchange -a ly vg0/var || rescue_shell
lvm lvchange -a ly vg0/var_tmp || rescue_shell
lvm lvchange -a ly vg0/var_log || rescue_shell
lvm lvchange -a ly vg0/swap || rescue_shell
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/vg0-root /dev/vg0/root
#resume_hibernate
...
|
|
Better. Back up your system before you try.
You have a lot of lvm commands. My initramfs runs just these two: Code: | lvm vgscan
lvm vgchange -ay --sysinit | (Created by genkernel, I confess, I'll write my own clean /init any day now. It's only been three years.)
Quote: | or perhaps like this?
and call it before all the other partitions are mounted maybe right after devtmpfs is mounted?
Code: | resume_hibernate() {
# set hardcoded default values
resume="/dev/vg0/swap"
# parse kernel command line
for p in $(cat /proc/cmdline); do
if ["${p}"=resume]; then
resume="${p#*=}"
fi
done
# enable resume from hibernate
if [ -n "${resume}" ]; then
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
lvm lvchange -a ly vg0/swap || rescue_shell
lvm vgscan --mknodes || rescue_shell # creates /dev/mapper/control
# copy the major:minor of the swap block device into /sys/power/resume
printf '%u:%u\n' $(stat -L -c '0x%t 0x%T' "${resume}") > /sys/power/resume || rescue_shell "Activating resume failed."
fi
} |
|
Personally I prefer the first solution, where it is clear that you attempt to resume as soon as the swap volume is available and before you touch anything else.
(There is something to be said for inline code, within reason; why write a function that is called only once ?)
Second Hu on compiling keyboard/usb drivers built-in. Run lsmod when fully booted to see what's loaded and convert the important ones to =y.
Also if you kernel has CONFIG_DEVTMPFS_MOUNT=y you shouldn't have to mount /dev yourself. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5050 Location: Bavaria
|
Posted: Fri Jul 12, 2024 9:40 am Post subject: |
|
|
sublogic wrote: | Also if you kernel has CONFIG_DEVTMPFS_MOUNT=y you shouldn't have to mount /dev yourself. |
Be aware: This is only true IF the kernel mounts the root partition ...
When using an initramfs, the kernel will not mount the root partition, because it is now the job of the initramfs. This means: This kernel option has no effect when using an initramfs AND you must always have this line in your initramfs (if you have no manual defined devices): mount -t devtmpfs none /dev _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
Rockman8 n00b
Joined: 19 Sep 2023 Posts: 36
|
Posted: Fri Jul 12, 2024 3:32 pm Post subject: |
|
|
Thanks guys for answering!
Quote: |
Maybe try to find the reason for this ... and then you dont need trying to load modules. I see you configure your kernel yourself; that is a big advantage: Enable all for the keyboard as built-in; especially:
Code: | Code:
Device Drivers --->
Input device support --->
[*] Keyboards --->
[*] AT keyboard |
|
I did find out while following your wiki that atkb is actually set to built in and that I got ps/2 ports in the back of my motherboard, I don't have the adapter ps/2 to usb on me now, but I'm pretty sure that's where the shell is looking to receive input? And Ironically I only got the atkb set as built in in there but all the others are deactivated.
Ah and one more thing, setting this atkb option will automatically set the serial i/o support.
Maybe that explains why it's expecting a ps/2 input instead of usb one?
Code: | Say Yes here if you have any input device that uses serial I/O to
communicate with the system. This includes the
* standard AT keyboard and PS/2 mouse *
well as serial mice, Sun keyboards, some joysticks and 6dof
devices and more.
Location:
-> Device Drivers
-> Input device support
-> Hardware I/O ports
-> Serial I/O support (SERIO [=y])
Selected by [y]:
KEYBOARD_ATKBD [=y] && INPUT [=y] && INPUT_KEYBOARD [=y]
|
Quote: |
The main value of modules is to defer loading them until they are needed. If you need them so early that the initramfs always loads them, it seems like you are not getting any value from using a module, and are instead going through extra trouble that would be avoided if those features were built in. If it were my system, I would set as =y any kernel features that I always want enabled in every boot. Use modules only for those things that I might reasonably go hours or days without loading.
|
I wanted to keep the amdgpu and ethernet driver as modules to make updates easier or any case I need to kill video, ethernet or sound without rebooting? But I don't think any of these reasons make any sense anymore, is there really a reason that I should be compiling any module as not built in besides for testing puposes?
Ah and yes if keep something this much time just hanging around without loading I just might forget completely about them and maybe even not using at all? Just found a few modules compiled that I found out that were never used but were there just in case and only remebered because I stumbled upon them when I was tweaking the kernel. So I might just leave them off perhaps and compile as module when I really need them?
Quote: | Better. Back up your system before you try.
You have a lot of lvm commands. My initramfs runs just these two:
Code: | Code:
lvm vgscan
lvm vgchange -ay --sysinit |
(Created by genkernel, I confess, I'll write my own clean /init any day now. It's only been three years.) |
I think that I must activated 1 by 1 just in case need any of them deactivated and also be aware of their presence I think that's why went for lvchange instead of vgchange
It might take a while to properly back up my system, I'm thinking of setting up a second system perhaps another gentoo, maybe a lighter one to run on 250gb external drive to run fsarchiver when this one is offline.
By the way I'm following pietinger wiki and I'm considering really go monolithic just seems to be easier and maybe even put initramfs inside it, been running gen_initramfs.sh so much that I don't mind running it again and compiling kernel all together and the grub file will be close to its default setting, although I'll just comment the line and leave there for reference |
|
Back to top |
|
|
sublogic Apprentice
Joined: 21 Mar 2022 Posts: 269 Location: Pennsylvania, USA
|
Posted: Fri Jul 12, 2024 9:50 pm Post subject: |
|
|
pietinger wrote: | sublogic wrote: | Also if you kernel has CONFIG_DEVTMPFS_MOUNT=y you shouldn't have to mount /dev yourself. |
Be aware: This is only true IF the kernel mounts the root partition ...
When using an initramfs, the kernel will not mount the root partition, because it is now the job of the initramfs. This means: This kernel option has no effect when using an initramfs AND you must always have this line in your initramfs (if you have no manual defined devices): mount -t devtmpfs none /dev | Thank you. Another gentoo learning experience, done the easy way |
|
Back to top |
|
|
sublogic Apprentice
Joined: 21 Mar 2022 Posts: 269 Location: Pennsylvania, USA
|
Posted: Fri Jul 12, 2024 9:58 pm Post subject: |
|
|
Rockman8 wrote: | is there really a reason that I should be compiling any module as not built in besides for testing puposes? |
Not having to maintain a in-kernel firmware list; unloading and reloading buggy drivers (I had to do that with my previous wireless card). If your built-in drivers can mount the root and finish booting, you have enough. |
|
Back to top |
|
|
Rockman8 n00b
Joined: 19 Sep 2023 Posts: 36
|
Posted: Thu Jul 18, 2024 3:56 am Post subject: |
|
|
Quote: |
Not having to maintain a in-kernel firmware list; unloading and reloading buggy drivers (I had to do that with my previous wireless card). If your built-in drivers can mount the root and finish booting, you have enough. |
Luckily, mine is just some dated desktop, I guess there's a lot well tested drivers for me, got no issues that i know of so far.
]
Although I didn't try to hibernate yet I did follow pietinger's guide and spent some time trying to make it work with current configuration, I tried to go monolithic but turns out I do have some itens that I'm not sure if should have then built in or as module, so I ended up following hu's advice, at very least the number of modules went down by a great amount. Maybe even sped up my boot time.
Now I'll have to set up the back up machine before I try to pull this up. |
|
Back to top |
|
|
|