OpenCPN-low-energy/Hard drive halt

Jump to: navigation, search

Why

On a boat, during shipping, the sailor only watch his PC to check his route and his position. Data which are written in logs or elsewhere aren't critical, moreover the laptop is plugged on the boat battery and consume resources that are essential for automatic pilot. On our laptops, it saves 0.8 W to stop hard disk.

Issues

hdparm is a tool to manage hard disk parameters, such as head parking, cache size and many other dangerous things. The way to stop a hdd is:

hdparm -Y /dev/[device ((h|s)d(a|b|c))]

However the hard drive is woken up by any attempt to write on the disk. We made a cron which stops the HDD every minutes, but it still consumes a lot for each awakening.

First approach

Principles

There isn't any option in the kernel which allows to halt a drive properly. Thus we need to mount the file system on RAM and change root mount point. For example, here is the way used by a bootable key to mount his file system in RAM:

  • mount a tmpfs on a folder like /media/tmp
  • into this tmpfs, we create 2 folders: "unionfs" which is the chroot and contains /root(read-only) and /rw(writable), and "union" which will be the mount point for unionfs
  • use unionfs-fuse to mount /media/tmp/unionfs on /media/tmp/union
  • mount the /proc on /media/tmp/union
  • change root to /tmp/union and set old root on /media/tmp/oldroot

Mount a tmpfs

The command is:

mount -t tmpfs -o size=1G tmpfs /mnt/myfs
  • -t is type of filesystem, like ext4 or ntfs
  • -o allows to precise the filesystem size
  • Then comes the device address (/dev/sdb) and the mount point

Mount an unionfs

On OpenSuse 12.3, you can't use mount for unionfs. You should use unionfs-fuse to do this:

  • Create two folders which will be two branches: one will be read-only, other will be rewritable.
mkdir -p /mnt/ram/unionfs/root
mkdir -p /mnt/ram/unionfs/rw
  • Create the folder which will be used for mount point
mkdir -p /mnt/ram/union
  • Call unionfs to use as chroot "/mnt/ram/unionfs"
unionfs $FUSE_OPT $UNION_OPT /rw=RW:/root=RO /mnt/ram/union

FUSE_OPT is defined as -o allow_other,use_ino,suid,dev,nonempty:

  • allow_other gives "read" right to "other" group
  • use_ino asks to use file index to spot them
  • suid allows to use sticky bit
  • dev asks to use devices files (in /dev)
  • nonempty allows to overwrite when mounting

UNION_OPT is defined as -ocow,chroot=$CHROOT_PATH,max_files=32768:

  • cow allows copy-on-write.
  • chroot is the path where root is set to define branches
  • max_files is the limit of files opened simultaneously

Change root mount point

To change root mount point, the only way is to use pivot_root. Unfortunately, systemd mounts all file systems in the fstab as shared. We need to make before any pivot_root mount --make-rprivate /. Once pivot_root is finished, Systemd doesn't want to be moved by pivot_root and can't be chrooted. It tries to call another init program(upstart or sysvinit). Graphical environment will work, but systemd functionalities and graphical console won't be available. With another pivot_root on the initial mount point, systemd accepts all requests. If we try to chroot systemd, it will lock the tty with "Failed to get D-Bus connection. Failed to connect to socket /org/freedesktop/systemd/private" but this error is thrown because systemd tries before to reach socket /run/systemd/private. Nonetheless, graphical console will be obtainable but launched from the old root.

Conclusion

systemd doesn't allow this approach though graphic session is still usable. Moreover, it continues to wake up the hard disk.

Second approach

Principles

The idea is to mount in RAM every parts of the system that needs to be modified when the system is idle and mount the root in read-only mode.


Mount /tmp

The simplest way is to add a line in /etc/fstab:

tmpfs                /tmp         tmpfs      defaults    0 0

Mount logs and cache in tmpfs

We choose to make a service which execute a script at initialization. This script checks if there is enough memory to mount the folder in RAM, then mount a backup in /mnt and mount the folder in RAM, copying backup files into the new mount.

Sometimes, /home/username/.cache and /home/username/.config can host some runtime files, for example Chromium. That's why we need to keep a backup on the disk. We can't use the service, for we need to know which user logs in. Thus .cache and .config are mount in a script launched when the session is starting.

Mount read-only root

There is two ways to do this:

  • call mount - / -o remount=ro(may fail because root is busy) and to undo this mount - / - o remount=rw
  • add the flag ro in this line in /etc/fstab:
your-disk-path / ext4  acl,user_xattr,ro        1 1

and at reboot the system won't be able to write on hard disk.

Mount root in read-only mode increases consumption

Without optimization, it consumes 2W more than usual.

Kernel tweaks

We pushed the power consumption to the kernel options. Here is the options we set with sysctl in /etc/init.d/suse_studio_custom :

vm.dirty_writeback_centisecs=1500
vm.dirty_background_ratio=20
vm.dirty_ratio=20

Force the disk to stop if he isn't in use

To do this, we used a cron task to stop the hard(s) drives. The cron manages several disks because your system can be spread across multiple drives. The cron task is generated at the first boot after the installation of the distribution. Here is the script that create the cron task.

Some mount options

In the installation guide we recommend the user to disable the journal, set the noatime and the commit=75 options. Disabling the journal and set the noatime option for mount have an impact on the disk. If you let those options enabled, the disk is continuously woke up to write time and action related informations about files. So, if you disable those options, the disk activity drops. The commit options is described as follow in the mount manual :

commit=nrsec
Sync all data and metadata every nrsec seconds. The default value is 5 seconds. Zero means default.

Let's look at the impact of this particular option on the consumption :

Impact of the commit option

It's quite interesting to note that it's not because the value is high that the power consumption will be reduced. We can see also that a threshold can be deduced, we choose to advice to set the commit option to the value 75 for the distribution.

How to trace the writing programs

To shut down the hard disk, we used this command :

# echo 1 > /proc/sys/vm/block_dump

The name of programs can be found in dmesg. Take a close look at the device programs are writing on, some of them can be mounted in ram. For example the syslog-ng program doesn't write on disk but on our ram (we mounted /var/logs in ram). You can see which device is mounted where with the mount -l command.

We also discovered that right after the installation, the disk is very busy with the ext4lazyinit process. Actually, when you install the distribution, the disk isn't completely formated right away, the format action is completed while your laptop is running after the installation.

External links

First approach

Second approach