最近公司规定晚上走人后必须关闭电脑,但是像我们这样的人,经常会忘记了关闭电脑,而且关闭电脑之后再恢复工作环境也是件挺麻烦的事情,无奈之下只能折腾一下,让linux定时休眠了。
休眠的类型
目前大概由三种类型的休眠:
suspend(suspend to RAM)
指的是除了内存以外的大部分机器部件都进入断电状态。 这种休眠状态恢复速度特别快,但由于内存中的数据并没有被保存下来,因此这个状态的系统并没有进入真正意义上的休眠状态,还在持续耗电。
hibernate(suspend to disk)
这种休眠会将内存中的系统状态写入交换空间内,当系统启动时就可以从交换空间内读回系统状态。 这种情况下系统可以完全断电,但由于要保存/读取系统状态到/从交换空间,因此速度会比较慢,而且需要进行一些配置(下面会说到)
hybrid(suspend to both)
结合了上面两种休眠类型。它像hibernate一样将系统状态存入交换空间内,同时也像suspend一样并不关闭电源。 这种,在电源未耗尽之前,它能很快的从休眠状态恢复。而若休眠期间电源耗尽,则它可以从交换空间中恢复系统状态。
suspend 休眠
进入 suspend 特别简单,无需额外的配置,在 systemd 系统上直接执行 systemctl suspend 就行了。\
systemctl suspend
它的实际动作由 systemd-suspend.service 所定义, 在 archlinux 上,它长成这样子的:
# SPDX-License-Identifier: LGPL-2.1+
## This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Suspend
Documentation=man:systemd-suspend.service(8)
DefaultDependencies=no
Requires=sleep.target
After=sleep.target
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/systemd-sleep suspend
Hibernation 休眠
由于 hibernation 休眠要求将内存中的内容写入到交换空间中,因此你至少要有一个空间大于内存的交换分区或者交换文件。 (其实若交换空间不够内存大也不是一定就无法进行hibernation休眠,可以尝试运行 echo 0 |sudo tee /sys/power/image_size, 这会让系统在写入交换空间时尽可能的进行压缩,但这种方法也无法保证一定能够休眠成功)
若之前没有创建交换分区,那么可以临时创建一个交换文件来用。比如下面命令创建一个5G的交换文件
sudo dd if=/dev/zero of=/swapfile bs=10240 count=524288
sudo mkswap /swapfile
sudo chmod 0600 /swapfile
sudo swapon /swapfile
sudo cp /etc/fstab /etc/fstab.bak
echo "/swapfile swap swap default 0 0" |tee -a /etc/fstab
Setting up swapspace version 1, size = 5 GiB (5368705024 bytes)
no label, UUID=d0f0c682-e1fa-416f-8fe2-b554b8ca363a
/swapfile swap swap default 0 0
除此创建交换分区之外,我们还需要修改kernel的启动参数,让系统在启动时先尝试从交换空间中恢复状态。 具体操作如下:
1. 如果使用交换分区来保存,则只需要为添加kernel的启动参数 resume=交换分区 即可
(1) 查看那块分区是交换分区
swapon
NAME TYPE SIZE USED PRIO
/dev/sda2 partition 8G 280K -2
/swapfile file 5G 0B -3
可以看出交换分区为 /dev/sda2
(2) 修改 /etc/default/grub, 为 GRUB_CMDLINE_LINUX_DEFAULT 行添加参数 resume=/dev/sda2
sudo sed -i '/GRUB_CMDLINE_LINUX_DEFAULT/ s!"$! resume=/dev/sda2"!' /etc/default/grub
2. 如果是使用交换文件,则需要添加两个参数 resume=交换文件所在磁盘 以及 resume_offset=交换文件在磁盘中的偏移位置:
(1) 查看交换文件所在磁盘
df /swapfile
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/sda3 55253696 27582224 24834972 53% /
说明磁盘为 /dev/sda3
(2) 查看交换文件的偏移位置
sudo filefrag -v /swapfile|head -5
Filesystem type is: ef53
File size of /swapfile is 5368709120 (1310720 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 32767: 4653056.. 4685823: 32768:
1: 32768.. 65535: 4685824.. 4718591: 32768:
这里可以看出物理偏移位置时4653056
(3) 修改 /etc/default/grub, 为 GRUB_CMDLINE_LINUX_DEFAULT 行添加参数 resume=/dev/sda3 resume_offset=4653056
sudo sed -i '/GRUB_CMDLINE_LINUX_DEFM
OPTIONS
systemd-sleep understands the following commands:
-h, --help
Print a short help text and exit.
--version
Print a short version string and exit.
suspend, hibernate, hybrid-sleep
Suspend, hibernate, or put the system to hybrid sleep.
SEE ALSO
systemd-sleep.conf(5), systemd(1), systemctl(1), systemd.special(7),
systemd-halt.service(8)
NOTES
1. Inhibitor interface
https://www.freedesktop.org/wiki/Software/systemd/inhibit
systemd 238 SYSTEMD-SUSPEND.SERVICE(8)
根据 systemd-sleep 的manual pages,可以看到在系统休眠之前以及从休眠状态恢复之后,都会并行地调用 /usr/lib/systemd/system-sleep 中的脚本,并传递两个参数。
第一个参数用来指定是开始休眠还是从休眠状态恢复,分别对应的字符串 “pre” 与 “post”.
第二个参数用来指明休眠的类型,分别为字符串 “suspend”, “hibernate” 以及 “hybrid-sleep”
定时执行休眠
systemd 系统中的定时任务是由timer来实现的,而每个timer都与一个service相对应。
一般情况下,timer的名称与service一致,但必要时可以通过在.timer文件中的 [Timer] 部分指定 Unit= 选项来控制一个与timer不同名的service。
下面是一个timer的例子,每天21:30分开始自动hibernate休眠
[Unit]
Description=Hibernate every 21:30:00
[Timer]
OnCalendar=*-*-* 21:30:00
Persistent=true
Unit=systemd-hibernate.service
[Install]
WantedBy=timers.target
定时唤醒休眠的linux
使用 rtcwake 可以在给定的时间唤醒处于休眠状态的电脑
其主要用法为:
sudo rtcwake -m ${mode} -t ${time_t}
# 或者
sudo rtcwake -m ${mode} -s ${seconds}
其中,参数mode为待机模式,有以下几个选项:
standby
普通待机模式,为默认选项,对应 ACPI state S1
mem
suspend休眠,对应 ACPI state S3
disk
hibernation 休眠,对应 ACPI state S4
off
通过调用系统的关机命令来休眠,对应 ACPI state S5
参数 time_t 为从 1970-01-01, 00:00 UTC 开始到现在的秒数,可以通过 date 命令来将时间字符串转换成这个秒数,比如
sudo rtcwake -m disk -t $(date -d 08:30 +%s)
就是进行 hibernation 休眠,并于08:30分唤醒
参数 seconds 为秒数,表示从现在开始的多少秒后,系统唤醒。
总结
以上所述是小编给大家介绍的linux 定时休眠的实现思路,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对社区网站的支持! |