OpenCPN-low-energy/Hard drive halt
为什么
在船上,航行期间,水手只会观察他的电脑来检查航线和位置。写入日志或其他地方的数据并不重要,而且笔记本电脑连接到船上的电池,消耗自动驾驶仪所需的资源。在我们的笔记本电脑上,停止硬盘可以节省 0.8W 的电量。
问题
hdparm 是一个管理硬盘参数的工具,例如磁头驻留、缓存大小和许多其他危险的东西。停止硬盘的方法是
hdparm -Y /dev/[device ((h|s)d(a|b|c))]
然而,硬盘会被任何尝试写入磁盘的动作唤醒。我们制作了一个 cron 任务,每分钟停止一次硬盘,但每次唤醒仍然会消耗大量电量。
第一种方法
原理
内核中没有允许正确停止驱动器的选项。因此,我们需要将文件系统挂载到 RAM 并更改根挂载点。例如,这是可引导密钥挂载其文件系统到 RAM 的方法
- 将 tmpfs 挂载到像 /media/tmp 这样的文件夹
- 在这个 tmpfs 中,我们创建 2 个文件夹:“unionfs”,它是 chroot,包含 /root(只读)和 /rw(可写),以及“union”,它将是 unionfs 的挂载点
- 使用 unionfs-fuse 将 /media/tmp/unionfs 挂载到 /media/tmp/union
- 将 /proc 挂载到 /media/tmp/union
- 将根目录更改为 /tmp/union,并将旧根目录设置为 /media/tmp/oldroot
挂载 tmpfs
命令是
mount -t tmpfs -o size=1G tmpfs /mnt/myfs
- -t 是文件系统类型,例如 ext4 或 ntfs
- -o 允许精确指定文件系统大小
- 然后是设备地址 (/dev/sdb) 和挂载点
挂载 unionfs
在 OpenSuse 12.3 上,您不能使用 mount 命令来挂载 unionfs。您应该使用 unionfs-fuse 来执行此操作
- 创建两个文件夹,它们将是两个分支:一个将是只读的,另一个将是可重写的。
mkdir -p /mnt/ram/unionfs/root mkdir -p /mnt/ram/unionfs/rw
- 创建将用于挂载点的文件夹
mkdir -p /mnt/ram/union
- 调用 unionfs 将 "/mnt/ram/unionfs" 用作 chroot
unionfs $FUSE_OPT $UNION_OPT /rw=RW:/root=RO /mnt/ram/union
FUSE_OPT 定义为 -o allow_other,use_ino,suid,dev,nonempty
- allow_other 赋予“其他”组“读取”权限
- use_ino 要求使用文件索引来识别它们
- suid 允许使用粘滞位
- dev 要求使用设备文件(在 /dev 中)
- nonempty 允许在挂载时覆盖
UNION_OPT 定义为 -ocow,chroot=$CHROOT_PATH,max_files=32768
- cow 允许复制写入。
- chroot 是设置分支的根目录路径
- max_files 是同时打开文件的限制
更改根挂载点
要更改根挂载点,唯一的方法是使用 pivot_root。不幸的是,systemd 将 fstab 中的所有文件系统都挂载为共享的。我们需要在任何 pivot_root 之前执行 mount --make-rprivate /。一旦 pivot_root 完成,Systemd 不希望被 pivot_root 移动,并且无法被 chroot。它会尝试调用另一个 init 程序(upstart 或 sysvinit)。图形环境将正常工作,但 systemd 功能和图形控制台将不可用。使用另一个 pivot_root 到初始挂载点,systemd 接受所有请求。如果我们尝试 chroot systemd,它将锁定 tty 并显示“Failed to get D-Bus connection. Failed to connect to socket /org/freedesktop/systemd/private”,但此错误是由于 systemd 在尝试访问套接字 /run/systemd/private 之前抛出的。尽管如此,图形控制台将可获得,但从旧根目录启动。
结论
systemd 不允许这种方法,尽管图形会话仍然可用。此外,它会继续唤醒硬盘。
第二种方法
原理
这个想法是将系统所有需要修改的部分挂载到 RAM 中,并在系统空闲时以只读模式挂载根目录。
挂载 /tmp
最简单的方法是在 /etc/fstab 中添加一行
tmpfs /tmp tmpfs defaults 0 0
将日志和缓存挂载到 tmpfs
我们选择创建一个服务,该服务在初始化时执行 一个脚本。该脚本检查是否有足够的内存将文件夹挂载到 RAM 中,然后将备份挂载到 /mnt 中,并将备份文件复制到新的挂载点。
有时,/home/username/.cache 和 /home/username/.config 可能会托管一些运行时文件,例如 Chromium。这就是为什么我们需要在磁盘上保留备份的原因。我们无法使用该服务,因为我们需要知道哪个用户登录。因此,.cache 和 .config 在会话启动时启动的脚本中挂载。
以只读模式挂载根目录
有两种方法可以做到这一点
- 调用 mount - / -o remount=ro(可能失败,因为根目录正在使用)并撤消此操作 mount - / - o remount=rw
- 在 /etc/fstab 中的这一行中添加标志 ro
your-disk-path / ext4 acl,user_xattr,ro 1 1
并在重新启动时,系统将无法写入硬盘。
在没有优化的情况下,它比平时多消耗 2W 的电量。
内核调整
我们将功耗推送到内核选项。这是我们在 /etc/init.d/suse_studio_custom 中使用 sysctl 设置的选项
vm.dirty_writeback_centisecs=1500 vm.dirty_background_ratio=20 vm.dirty_ratio=20
如果未被使用,强制磁盘停止
为此,我们使用 cron 任务来停止硬盘(们)。cron 管理多个磁盘,因为您的系统可以分布在多个驱动器上。cron 任务在安装分发版后的第一次启动时生成。 这里 是创建 cron 任务的脚本。
一些挂载选项
在 安装指南 中,我们建议用户禁用日志记录,设置 noatime 和 commit=75 选项。禁用日志记录并为挂载设置 noatime 选项会对磁盘产生影响。如果您让这些选项启用,磁盘将不断被唤醒以写入有关文件的时间和操作信息。因此,如果您禁用这些选项,磁盘活动将减少。commit 选项在挂载手册中描述如下
commit=nrsec
每 nrsec 秒同步所有数据和元数据。默认值为 5 秒。零表示默认值。
让我们看看这个特定选项对功耗的影响
值得注意的是,值越高,功耗不会降低。我们还可以看到可以推断出一个阈值,我们建议为分发版将 commit 选项设置为值 75。
如何追踪写入程序
为了关闭硬盘,我们使用了这个命令
# echo 1 > /proc/sys/vm/block_dump
可以在 dmesg 中找到程序的名称。仔细查看程序写入的设备,其中一些可以挂载到 ram 中。例如,syslog-ng 程序不会写入磁盘,而是写入我们的 ram(我们将 /var/logs 挂载到 ram 中)。您可以使用 mount -l 命令查看挂载了哪个设备。
我们还发现,安装后不久,磁盘非常繁忙,ext4lazyinit 进程正在运行。实际上,当您安装分发版时,磁盘不会立即完全格式化,格式化操作在笔记本电脑运行后才完成。
外部链接
第一种方法
- unionfs-fuse 手册页
- fuse 手册页
- Unionfs-fuse 示例
- mount 手册页
- 关于 systemd init 配置的一个主题
- 根目录和 cwd 之间的区别
- initramfs 带来的变化
- newns 手册页
- 内核如何挂载根分区
- Initrd 源代码

