2017-03-11 更新:

  1. 优化部分文字描述;
  2. 默认情况下禁用 swap 分区, 当执行休眠操作时先启用 swap 分区, 然后再执行休眠操作(给 /usr/bin/{swapon,swapoff} 添加 S 权限位, 以便普通用户修改 swap 配置);

基础配置

因为笔记本只有 180GB 的固态硬盘, 当初安装系统就使用 swap 文件代替 swap 分区. 首先检查下 swap 文件大小, 确定其足以 dump 整个内存:

  1. $ swapon -s
  2. 文件名 类型 大小 已用 权限
  3. /swapfile file 8388604 1467244 -1

然后就是配置 GRUB 启动参数:

  1. title Arch
  2. kernel (hd0,5)/boot/vmlinuz-linux root=/dev/sda6 rw quiet resume=/dev/sda6 resume_offset=2537472
  3. initrd (hd0,5)/boot/initramfs-linux.img

其中 resume 参数是 swap 文件所在分区, resume_offset 是真正存储内存 dump 数据(physical_offset)的偏移, 可通过 filefrag 命令获取:

  1. # filefrag -v /swapfile
  2. Filesystem type is: ef53
  3. File size of /swapfile is 8589934592 (2097152 blocks of 4096 bytes)
  4. ext: logical_offset: physical_offset: length: expected: flags:
  5. 0: 0.. 0: 2537472.. 2537472: 1:
  6. 1: 1.. 2047: 2537473.. 2539519: 2047: unwritten
  7. 2: 2048.. 4095: 2899968.. 2902015: 2048: 2539520: unwritten
  8. 3: 4096.. 6143: 2914304.. 2916351: 2048: 2902016: unwritten
  9. ....

在我的电脑上, resume_offset 值就是 2537472.

测试和问题分析

完成以上准备工作后执行 systemctl hibernate 命令执行休眠(dump 内存到 swap 文件并关机), 重启时发现, 只有少数几次能够从休眠中复原环境, 大多数是恢复失败直接进入登录页面(另外, 4.4 版本的内核对休眠支持有bug, 重启后黑屏, 升级 4.9 后解决该问题). 查看日志发现:

  1. 2 25 20:10:07 hostname systemd[1]: Starting Hibernate...
  2. 2 25 20:10:39 hostname kernel: PM: Hibernation image not present or could not be loaded.
  3. 2 25 20:10:39 hostname kernel: PM: Hibernation image partition 8:6 present
  4. 2 25 20:10:39 hostname kernel: PM: Hibernation image not present or could not be loaded.

为什么会提示 Hibernation image not present or could not be loaded, 但为什么有时候又能成功呢? 猜测在某些情况下将内存 dump 到 swap 文件时出错了.

查看 Wiki 发现有个 /sys/power/image_size 参数配置, Wiki 说:

/sys/power/image_size 用来控制将内存 dump 到硬盘时所占空间的大小. 在 dump 内存时, 所占用的硬盘空间不会超过 /sys/power/image_size 的大小. 如果内存数据太多, 那就只会 dump 最小的镜像到硬盘. 如果该文件值为 0, 则在 dump 内存时尽可能压缩数据占用最少的硬盘空间(上限是 swap 分区/文件的大小). 该文件的默认值是内存的 2/5 .

看了上面这段描述, 猜测是/sys/power/image_size 值过小致使内存 dump 文件不完整, 从而导致无法从休眠中启动恢复环境. 于是将其修改为 0:

  1. $ sudo tee /sys/power/image_size <<< 0
  2. [sudo] username 的密码:
  3. 0

在内存使用率超过 2/5 的情况下测试通过.

然而, 重启后 /sys/power/image_size 配置值又恢复为默认的内存大小的 2/5, System: Temporary Files 介绍了一种方法:

新建文件 /etc/tmpfiles.d/modify_power_image_size.conf, 内容为:

  1. w /sys/power/image_size - - - - 0

重启后确认已生效:

  1. $ cat /sys/power/image_size
  2. 0

扩展配置

通过 acpid 捕获合上笔记本屏幕事件

安装并启用 acpid:

  1. sudo pacman -S acpid
  2. sudo systemctl enable acpid

编辑 /etc/acpi/handler.shbutton/lid 部分, 当合上笔记本屏幕时, 执行锁屏和挂起(睡眠)操作:

  1. DISPLAY=:0.0 su -c - your_username /usr/bin/slimlock &
  2. systemctl suspend

处理合上笔记本屏幕事件:

  1. button/lid)
  2. case "$3" in
  3. close)
  4. logger 'LID closed'
  5. DISPLAY=:0.0 su -c - your_username /usr/bin/slimlock &
  6. systemctl suspend
  7. ;;
  8. open)
  9. logger 'LID opened'
  10. ;;
  11. *)
  12. logger "ACPI action undefined: $3"
  13. ;;

/etc/acpi/handler.sh 完整文件:

  1. #!/bin/bash
  2. # Default acpi script that takes an entry for all actions
  3. case "$1" in
  4. button/power)
  5. case "$2" in
  6. PBTN|PWRF)
  7. logger 'PowerButton pressed'
  8. ;;
  9. *)
  10. logger "ACPI action undefined: $2"
  11. ;;
  12. esac
  13. ;;
  14. button/sleep)
  15. case "$2" in
  16. SLPB|SBTN)
  17. logger 'SleepButton pressed'
  18. ;;
  19. *)
  20. logger "ACPI action undefined: $2"
  21. ;;
  22. esac
  23. ;;
  24. ac_adapter)
  25. case "$2" in
  26. AC|ACAD|ADP0)
  27. case "$4" in
  28. 00000000)
  29. logger 'AC unpluged'
  30. ;;
  31. 00000001)
  32. logger 'AC pluged'
  33. ;;
  34. esac
  35. ;;
  36. *)
  37. logger "ACPI action undefined: $2"
  38. ;;
  39. esac
  40. ;;
  41. battery)
  42. case "$2" in
  43. BAT0)
  44. case "$4" in
  45. 00000000)
  46. logger 'Battery online'
  47. ;;
  48. 00000001)
  49. logger 'Battery offline'
  50. ;;
  51. esac
  52. ;;
  53. CPU0)
  54. ;;
  55. *) logger "ACPI action undefined: $2" ;;
  56. esac
  57. ;;
  58. button/lid)
  59. case "$3" in
  60. close)
  61. logger 'LID closed'
  62. DISPLAY=:0.0 su -c - your_username /usr/bin/slimlock &
  63. systemctl suspend
  64. ;;
  65. open)
  66. logger 'LID opened'
  67. ;;
  68. *)
  69. logger "ACPI action undefined: $3"
  70. ;;
  71. esac
  72. ;;
  73. *)
  74. logger "ACPI group/action undefined: $1 / $2"
  75. ;;
  76. esac
  77. # vim:set ts=4 sw=4 ft=sh et:

借助 zenity 编写系统操作的小程序

借助 zenity 编写系统操作APP, 支持 睡眠(挂起)/深度睡眠/休眠/关机/重启(在休眠前启用 swap 分区):

  1. #!/bin/sh
  2. function Suspend() {
  3. slimlock &
  4. sleep 1
  5. systemctl suspend
  6. }
  7. HybridSleep() {
  8. slimlock &
  9. sleep 1
  10. /usr/bin/swapon /swapfile && systemctl hybrid-sleep
  11. }
  12. function Hibernate() {
  13. slimlock &
  14. /usr/bin/swapon /swapfile && systemctl hibernate
  15. }
  16. function Shutdown() {
  17. zenity --question --text="确定关机?" && \
  18. # echo "do shutdown" \
  19. systemctl poweroff
  20. }
  21. function Reboot() {
  22. zenity --question --text="确定重启?" && \
  23. # echo "do reboot" \
  24. systemctl reboot
  25. }
  26. type=$(zenity --list \
  27. --timeout="10" \
  28. --width="200" \
  29. --height="240" \
  30. --title="要抛弃我啦?" \
  31. --column="操作" \
  32. "Suspend" \
  33. "HybridSleep" \
  34. "Hibernate" \
  35. "Shutdown" \
  36. "Reboot"
  37. )
  38. ret=$?
  39. if [ $ret == 1 ]
  40. then
  41. # 点击 "关闭" 或 "取消"
  42. echo "no choice, exit"
  43. exit
  44. elif [ $ret == 5 ]
  45. then
  46. echo "timeout"
  47. exit
  48. fi
  49. eval $type

参考链接:

Archlinux休眠设置的更多相关文章

  1. Arch Linux 的休眠设置

    https://wiki.archlinux.org/index.php/Power_management/Suspend_and_hibernate_(简体中文)https://wiki.archl ...

  2. Archlinux风扇设置

    在笔记本(ThinkPad T440)连续两天因过热而死机后, 对内核的风扇控制算法果断失去信心. 风扇的用户层控制接口是 /proc/acpi/ibm/fan, 但为防止用户控制不当烧坏机器, 默认 ...

  3. [adminitrative][archlinux][setfont] 设置console的字体大小

    电脑的分辨率高了之后,用命令行进入的时候,完全看不清楚,是否容易导致眼瞎. 第一步便把字体调大就成了很必要的操作. 使用一个命令能马上生效: setfont 使用配置文件 /etc/vconsole. ...

  4. Ubuntu:笔记本计算机屏幕合盖后进入/不进入休眠设置

    造冰箱的大熊猫,本文在Ubuntu 18.04上验证通过@cnblogs 2019/5/12 1.问题描述 安装有Ubuntu的笔记本计算机与KVM控制器相连,同时一台台式机也与KVM相连.启动笔记本 ...

  5. 取消Debian屏保及显示器休眠

    在产品展示场合,屏保及休眠会带来不好的体验,很多时候需要关闭掉. dpms显示器休眠设置: 开启:$ sudo xset dpms 1 1 2取消:$ sudo xset -dpms xset设置屏保 ...

  6. 自己家里搭建NAS服务器有什么好方案?

    转自:https://www.zhihu.com/question/21359049 作者:陈二发链接:https://www.zhihu.com/question/21359049/answer/6 ...

  7. Andriod WIFI驱动模块

    一:什么是WIFI WIFI是一种无线连接技术,可用于手机.电脑.PDA等终端.WIFI技术产生的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11标 ...

  8. ACPI

    高级配置与电源接口(Advanced Configuration and Power Interface),简称ACPI.1997年由Intel.Microsoft.Toshiba 所共同制定提供操作 ...

  9. UE4网络同步属性笔记

    GameMode只有服务端有,适合写游戏逻辑.PlayerController每个客户端拥有一个,并拥有主控权.GameState在服务端同步到全端. CLIENT生成的Actor对其有Authori ...

随机推荐

  1. chrome浏览器无法安装非应用商店插件的解决办法

    不久前,安装了一个非chrome应用商店的第三方应用,今天突然发现无法使用,打开chrome的扩展程序后,发现该插件以及被禁用,在网上查找了解决方法,设置“开发者模式”,修改了chrome的参数,仍然 ...

  2. web常见攻击总结

    1.Sql注入 攻击者把sql命令插入到web表单的输入域或页面请求的查询字符串, 欺骗服务器执行恶意的sql命令 防御措施 前端: 1.正则验证字符串格式 2.过滤字符串的非法字符 后端: 1.不要 ...

  3. Juice Junctions

    Juice Junctions 题目描述 你被雇佣升级一个旧果汁加工厂的橙汁运输系统.系统有管道和节点构成.每条管道都是双向的,且每条管道的流量都是11升每秒.管道可能连接节点,每个节点最多可以连接3 ...

  4. vue 中父子组件传值:props和$emit

    更新----------- 1 父组件向子组件传值:通过props数组: 在vue-cli Login.vue父组件中有AcceptAndRefuse.vue子组件,首先import进子组件hello ...

  5. pat 团体天梯 L3-011. 直捣黄龙

    L3-011. 直捣黄龙 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题是一部战争大片 —— 你需要从己方大本营出发,一路 ...

  6. 自己写的页面加载进度条jquery插件

    (function ($) { var progressId = "progress" + Math.round(Math.random() * 100) var progress ...

  7. 从头实现一个koa框架

    koajs是最流行的nodejs后端框架之一,有很多网站都使用koa进行开发,同时社区也涌现出了一大批基于koa封装的企业级框架.然而,在这些亮眼的成绩背后,作为核心引擎的koa代码库本身,却非常的精 ...

  8. [LeetCode] Permutations II 排列

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  9. 又看了一次EM 算法,还有高斯混合模型,最大似然估计

    先列明材料: 高斯混合模型的推导计算(英文版): http://www.seanborman.com/publications/EM_algorithm.pdf 这位翻译写成中文版: http://w ...

  10. 转载——Java与WCF交互(二):WCF客户端调用Java Web Service

    在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttp ...