I've been getting ready to build a backup machine in case my NAS stops working. While the old one is functioning well, things happen and it's worth a lot to me to reduce downtime.

My main priorities are reliability, storage and low power consumption: the old box uses (software) RAID, carries important data and runs 24/7, and sits mostly idle.

The sticking point with reliability in consumer setups has for a long time been ECC, because of segmentation (Intel only offers it on high end CPUs), spotty motherboard support, more expensive memory, and a perceived lack of need for it – despite the fact that all other memory storage uses some form of error correction.

While some of these problems are easily overcome (cost, perception), others just depend on what others do.

  • does any consumer-grade CPU support ECC?
  • does any matching motherboard support ECC?

Despite much uncertainty and conflicting sources, the answer seems to be: yes!

AMD confirmed that Ryzen does make use of ECC memory. Even though it does not get verified, it's the same silicon as in the high end models, which do get verified, so it most likely works just fine.

The other part of the puzzle is motherboard support. It's hard to come across solid information here. Looking at manufacturers' product specs usually gives an idea: if it says "non-ECC memory", then it's pretty certain that it doesn't support ECC.

However, Gigabyte made sure that reasoning the other way is not reliable: their spec sheets said "ECC supported", but in non-ECC mode.

On the other hand, all AsRock's motherboards I've seen mention ECC support in their manuals, have no fine print, and even list ECC modules in the compatibility lists. Yes, that includes even the lowest-end ones based on the A320 chipset!

I needed to check this, so I wrote to their support.

Dear Technical Expert, my question is short:

Does the current BIOS for A320M-HDV support ECC memory in ECC mode or with ECC disabled only?

The answer:

From: "ASRock Support" <xxx@asrock.nl>
Subject: RE: $A320M-HDV$ ECC mem in ECC mode
Date: Tue, 24 Oct 2017

Hello,

ECC is suported and used.

Best regards,

ASRock Support

They said yes!

Now if only there was a low power APU fitting the socket. Raven Ridge needs more time and makes no TDP promises. Do the recently made available 35W (A6-9500E) APUs support ECC? Only AMD can help me find out.

Idea

I live in an area where the most common view from a window is the window of a neighbor. Or a dozen neighbors. After dark, when people turn on their lights, it's possible to see everything going on inside. It's obvious that the majority of people around have curtains.

neighbors Some of my neighbors don't care

I also like to be woken up by the sunshine, to the point of preferring to live in places with south-eastbound windows.

You can probably see that these two don't mesh so well. In order to have privacy in the evening, I'd have to pull the curtains, and for sunshine wakeup, they need to be open. Of course, opening them when I turn off the lights and go to sleep is too pedestrian. Why not waste some time and make them close and open automatically?

Design

The device floating in my head would consist of two light detectors, fighting against each other. One would be facing the outside world, and the other would be sensing light levels inside the room. The stronger light would win and give an indication on whether it's safe to open the curtains (outside brighter) or not (inside more luminous).

Based on that information, a mechanism would pull the curtains in the resulting position.

Capturing light

For a reasonable first step, I decided to go with a simple analog light detector, and then move on to more interesting stuff. I'd need a light sensitive element, an amplifier and a few basic elements. There's plenty of resources describing how to use a LED as a light detector and get linear voltage out of it. It should be simple, right?

Wrong.

photodiode_schematic Getting light intensity from a photodiode

Problems

Because I am a perfectionist in all the wrong places, I wanted something capable of capturing light in the visible range. The only thing I could get in my local shop was a phototransistor.

Note that the resources above talk about photodiodes. Photodiodes produce current when illuminated, while transistors apparently allow current through when illuminated while subjected to voltage (biased). This tiny detail makes the above guides incorrect.

Long story short, I spent a week with another engineering graduate trying to understand op-amps, and even trying to operate the phototransistor while biased. Despite efforts, nothing worked.

Solution

Note: I have no idea what I'm doing here.

Nothing worked, until I came across a stackexchange answer. It did not get answered in the way I wanted, but it worked.

phototransistor_schematic Getting light intensity from a phototransistor

What I don't understand is how is the phototransistor biased if the voltage across it is between input and ground? Does input voltage have a defined relationship with Vcc?

light_intensity voltage response in response to light intensity I wanted: linear from 0V to 5V - vs the one I got: linear from 2.5V to 5V

To make the result a bit more useful, I added a 5V buzzer to the output to wake me up. Because the buzzer makes noise already at about 2V, and the output will never go less than 2.5V, I had to come up with a kludge.

Note: here I have no idea what I'm doing again

I added 2 LEDS in series to it, and indeed, the buzz can only be heard when the phototransistor is actually illuminated!

kludge_schematic Light-sensitive buzzer

I suspect that because the LEDs drop ~1.5V each, no current gets through until the output voltage overcomes them. But the buzzer sounds like it's on full volume, why could that be?

Next

The next step would be figuring out how to connect two phototransistors against each other. Or just buy 2 diodes and connect them in series in opposite. Time will tell - other projects are waiting.

This task, while sounding easy, is surprisingly difficult to achieve. There are plenty of programs to do this on Linux: you can find mentions of pdfcrop script in various places, there's also PDFEdit, PoDoFo, and some random scripts all over the place.

All the tools I checked work fine - as long as you don't print the document (to a printer, to PDF, to PS). For some reason, they lose the boundaries in that operation.

Perhaps PDFEdit could do the job - after all, it advertises itself as an authoring tool, therefore it should do a deep reencoding. However, I didn't want to waste time manually adjusting the margins in millimeters.

Surely there must be an easy way to crop margins automatically. KDE's Okular can do it, therefore can I!

Finding the params

First off, if I can't find any automatic tool to give me nice margin values, let's find a semi-automatic one.

GhostScript comes to the rescue:

# gs -dBATCH -dSAFER -dNOPAUSE -dUseCropBox -sDEVICE=bbox doc.pdf
...
Page 2
%%BoundingBox: 110 130 506 723
%%HiResBoundingBox: 110.267997 130.139996 505.781985 722.177978
...

It outputs the bounding box after cropping any white space from around it. Now I can pick some average page and use the values.

The mechanism

Turns out, PDF files have several properties called "boxes" that are used for cropping the margin for different purposes:

  • MediaBox
  • TrimBox
  • CropBox
  • BleedBox
  • ArtBox

Most cropping programs modify the MediaBox parameter. That operation doesn't modify any original content, only sets the displayed boundaries when viewing the document in digital form. Therefore, it's easy to reset this value back to original - and print incorrectly.

The problem might be in the way CUPS handles printing: it converts PDF documents into PS format. Try it yourself: open the document in a viewer of choice and choose the option to print to PS. Result? Original margins restored.

uncropped This is how pages printed, and how they ended up after printing to PS.

The conclusion might be: there's something broken in PDF->PS conversion.

PDF to PS

If it's broken, best do it manually. My first attempt was to convert the original document to PS and then crop it, but the tools to do that are harder to find. Therefore, I came up with a different process:

Let's crop the PDF and convert to PS while respecting the boundaries.

It might be crazy, after all I just said that printing to PS (a form of conversion) is broken! Well, it's broken in the builtin mechanism. Perhaps there's another program to do it right. Indeed, there is! pdftocairo helped me out.

cropped pdftocairo could see my pages without margins!

Putting it all together

First, use gs command to find out the bounding box. My average page has the dimensions:

# gs -dBATCH -dSAFER -dNOPAUSE -dUseCropBox -sDEVICE=bbox doc.pdf

I have no idea what the units are, but as long as they work, I'm happy. The values appear to be left, top, right, bottom:

108 127 506 723

Now, set the bounding boxes. I used a custom program that I found randomly and adapted to change all the boxes (cause I don't know which one is the correct one, and as long as it works I don't care). The script requires pyPdf and you can find it at the end of the post.

./croppdf -b 108 127 506 723 -i doc.pdf -o marked.pdf

The new marked.pdf document will work on the screen, but still not in print.

Last stage: applying the crop.

pdftocairo -ps marked.pdf cropped.ps

Done! The cropped.ps document is neatly trimmed and ready for printing.

The script

#! /usr/bin/python2

# Originally found on http://www.mobileread.com/forums/showthread.php?t=25565

import argparse, sys
from pyPdf import PdfFileWriter, PdfFileReader

parser = argparse.ArgumentParser(description='Crop/mark pdf to size. Works best with ghostscript.', epilog='Originally by sjvr767. Modified by rhn')
parser.add_argument('-b', metavar=('left', 'top', 'right', 'bottom'), type=int, nargs=4,
                    required=True, help='bounding box')
parser.add_argument('-i', '--input', metavar='input', required=True, help='input file')
parser.add_argument('-o', '--output', metavar='input', help='Specify the name and path of the output file. If none specified, the script appends \'_cropped\' to the input file name (before extension).')
parser.add_argument('--skip', action='store_true', help='skip first page ')
args = parser.parse_args()
input_file = args.input
        
if input_file[-4:]!='.pdf':
    print "Input file must be a PDF."
    sys.exit(2) #exit if no appropriate input file

if args.output:
    output_file = args.output
    if output_file[-4:]!='.pdf':
        print "Output file must be a PDF."
        sys.exit(2)
else:
    output_file = "%s_cropped.pdf" %input_file[:-4] #default output


import collections
Box = collections.namedtuple('Box',
                             ('l', 't', 'r', 'b'))

box = Box(*args.b)

input1 = PdfFileReader(file(input_file, "rb"))

output = PdfFileWriter()
outputstream = file(output_file, "wb")

pages = input1.getNumPages()

right = input1.getPage(1).mediaBox.getUpperRight_x()
top = input1.getPage(1).mediaBox.getUpperRight_y()
left = input1.getPage(1).mediaBox.getUpperLeft_x()
bottom = input1.getPage(1).mediaBox.getLowerRight_y()

new_tr = (box.r, box.t)
new_br = (box.r, box.b)
new_tl = (box.l, box.t)
new_bl = (box.l, box.b)

start = 1 if args.skip else 0

for i in range(start, pages):
    page = input1.getPage(i)
    page.mediaBox.upperLeft = new_tl
    page.mediaBox.upperRight = new_tr
    page.mediaBox.lowerLeft = new_bl
    page.mediaBox.lowerRight = new_br
    page.cropBox.upperLeft = new_tl
    page.cropBox.upperRight = new_tr
    page.cropBox.lowerLeft = new_bl
    page.cropBox.lowerRight = new_br

    page.trimBox.upperLeft = new_tl
    page.trimBox.upperRight = new_tr
    page.trimBox.lowerLeft = new_bl
    page.trimBox.lowerRight = new_br
    page.bleedBox.upperLeft = new_tl
    page.bleedBox.upperRight = new_tr
    page.bleedBox.lowerLeft = new_bl
    page.bleedBox.lowerRight = new_br

    output.addPage(page)

output.write(outputstream)
outputstream.close()

Some time ago, I snatched the awesome game Monaco on Humble Bundle. All the reviews I read were praising the co-op option, and because I had another eager player at home, I decided to check it out.

Problems

The game offers a few modes of multiplayer: online and offline. It would sound perfect, until you realize that both had dealbreaking problems for my purpose.

Online gaming requires a Steam version of the game. Unfortunately, none of us had a Steam account, and even then I'm not paying for the game again.

Offline multiplayer works fine with the Humble version, however, the game designers designed to only allow 1 player to use a keyboard, and others need to use gamepads :(. That means - no '00s style multi-palm keyboard action for you, and if you bring your own keyboard, you're also out of luck.

Player selection screen

Options

Well, of course, I could buy an Xbox 360 pad. Realistically, though, I'm not going to do that for a single game, and to have more junk that I need to carry when I move.

The game itself is not open source, so I can't fix it properly. Crossed out.

Monaco input is built on top of the SDL library - awesome! I could write a LD_PRELOAD wrapper to interpret keypresses as pad events.

The xboxdrv solution

I decided to go for the fourth option: play with the Linux input subsystem itself. SDL would probably be easier, but this way it's more fun!

There's a project called xboxdrv, which manipulates input from various game controllers to make it look like something else. With some effort I could surely make it pretend thay my keyboard is an Xbox gamepad!

Work

xboxdrv does marvels when it comes to turning gamepad input into keypresses, or making a gamepad pretend it's something else. However, in the upstream version, it doesn't support turning keyboard input into gamepad events. That I had to do myself.

Patch

I created a patch to xboxdrv, which fixes the inability to understand keyboard input. If you compile that version of xboxdrv, you will be able to specify what key on the keyboard should correspond to what event on a gamepad, using special syntax I introduced.

My monaco.cfg file for Monaco specified that some keys should be mapped to gamepad events:

[xboxdrv]

[evdev-keymap]
KEY_E=BTN_A
KEY_ENTER=BTN_start
KEY_Q=BTN_Y
KEY_RIGHTSHIFT=BTN_X
KEY_SPACE=BTN_B

KEY_A=BTN_dl # buttons
KEY_w=BTN_du
KEY_SN=BTN_dd
KEY_d=BTN_dr

KEY_UP=ABS_Y1:10000:0 # axis values - axis:pressed value:released value
KEY_DOWN=ABS_Y1:-10000:0
KEY_RIGHT=ABS_X1:10000:0
KEY_LEFT=ABS_X1:-10000:0
#KEY_DOT=ABS_X1:-10000:0+ABS_Y1:10000:0 # you can specify both axes to be triggered when you press a key

Button mappings

The default button mappings might help you a bit.

Using it

To use it, you have to let xboxdrv receive input from your keyboard. First, you must find out which /dev/input/event entry your keyboard actually is:

$ cat /proc/bus/input/devices | grep -C 10 keyboard

I: Bus=0011 Vendor=0001 Product=0001 Version=ab54
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input3
U: Uniq=
H: Handlers=sysrq kbd event3 
B: PROP=0
B: EV=120013
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7

The interesting line is:

H: Handlers=sysrq kbd event3 

That means our keyboard is /dev/input/event3. Now we can let xboxdrv use it.

$ sudo xboxdrv --evdev /dev/input/event3 --evdev-no-grab --config monaco.cfg
$ ./Monaco/Monaco.bin.x86

Important: remember to add --evdev-no-grab or you won't be able to use your keyboard as a keyboard again.

Result

The patch is still awaiting review as of the end of 2014, so don't count on this to work out of the box anytime soon.

There are slight problems with the axes support. If you decide that two keys should trigger the same axis (say, left-right), releasing one will reset axis to 0, even if you hold the other. It's not an easily solved problem right now.

In the end, before I finished the patch, we already finished the game by taking turns :P.

How does it all work?

The Linux input system is separated into 3 layers: the input devices (producers), the input drivers and the applications (consumers).

Normally, the producers pass their keypresses, button and axis events to the input drivers, where applications can request to be fed data.

Input layers

The fancy thing in this setup is that you can write a program to create a virtual input device. This is a technique some people are using to create virtual keyboards, for example programs interpreting speech or screen keyboards.

xboxdrv takes advantage of that, to pretend that it is a new keyboard, or a new controller, and to send the correct input events as a producer. But how does it know what events to send? Well, it registers to the same input system as a consumer, meaning, it can read all input from a device of your choice.

virtual xboxdrv

In our case, xboxdrv takes input from the keyboard event device (evdev) and translates it to the input events of a virtual Xbox controller that it registered. More commonly, it is used to create a keyboard and translate controller events to keypresses.

The possibilities!

The input system is flexible enough that you can create whatever virtual device you want and you can take input from any source you wish. There's an interesting program called uinput-mapper, which can save keystrokes to a file and play them back again.

Network

One of the fancy things it can do is send data over a network. This way, you can redirect a keyboard from any Linux machine to any other.

I had to figure out what was the keyboard on my device again. Then, on the host machine, I did something like this:

$ su # or change permissions to /dev/uinput
$ ssh root@N900 /path-to-uinput-mapper/input-read /dev/input7 -G -D | ./uinput-mapper/input-create

The input-read program takes over the event device, and input-create reads the output to a new virtual device of the same kind. Then, it creates a new device - another /dev/input/eventX. The ssh program makes sure the transmission is safe.

Chaining

You might have noticed, that the device that came out of input-create is the same kind that xboxdrv accepts. In fact, it's possible to chain them, so that a device somewhere over the network pretends to be an Xbox controller. In fact, I did just that: while testing xboxdrv, I played Monaco using my Nokia N900.

After you started uinput-mapper, you only need the config file and a slightly modified xboxdrv command (replace /dev/input/eventX with the actual device that input-create made):

$ sudo xboxdrv --evdev /dev/input/eventX --config monaco.cfg

The difference here is in grabbing. Grabbing is called when an application takes over a device exclusively. In case of xboxdrv, the keyboard will stop sending regular keys and you may get locked out of your machine (pro tip: if this happens, kill xboxdrv if you can).

When we're giving xboxdrv our sole keyboard, that's not the best idea. But if we got an extra keyboard from another device while keeping another for emergency - then it doesn't matter.

Background

Once in a while, I find myself exploring something new and dangeous. One day it might be changing the root filesystem, another day it may be replacing swap with something bigger, yet another it might be upgrade to EFI. All of those have met with various amounts of pain and sometimes were outright failures.

Yesterday, I was evaluating applications containers because they hold the promise of making services deployment easier. Every system upgrade brings me pain with incompatible configuration changes, so wouldn't it be nice if I could decouple system upgrades and app upgrades?

Usually, when I do these experiments, I set up a dedicated VM to prevent my main system from being contaminated or disabled. This time, I decided that chroot is simple enough to do it without protection. Famous last words?

I set up a minimal chroot jail. I mounted --rbind the necessary directories and bootstrapped it successfully.

The problems started when I wantedd to stop it. umount said the mount point was busy. I thought "no worries", decided umount -l will fix the problem, and proceeded as usual.

Disaster

After resuming my system from hibernation the next day... I could no longer start new terminals - Konsole windows showed up empty. While I could use su and sudo, new terminals couldn't be opened.

$ xterm
xterm: Error 32, errno 2: No such file or directory
Reason: get_pty: not enough ptys
$ screen
Must be connected to a terminal.
$ rxvt
rxvt: can't load font "-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1"
rxvt: can't open pseudo-tty
rxvt: aborting

Luckily, I have another system with a similar setup, so I was able to compare to something working.

Via painstaking strace and gdb tracing, I figured out that:

  1. /dev/pts became unmounted
  2. /dev/pts MUST be mounted with -o gid=5 (5 stands for tty).

After mounting /dev/pts:

mount -t devpts devpts /dev/pts -o mode=620 -o gid=5

I can open terminal windows again.

The tools: top, iotop, powertop2

The hardware: Lenovo X230, HDD, 29Wh battery (nominal)

The software: Fedora 20, KDE 4.12, Linux 3.13 to 3.14

Idle power consumption: about 11W with WiFi on, brightness 20% (Linux 3.13), about 9.5W with WiFi off, Linux 3.14.

Goal: get as much battery time as possible for productive work.

Computer usage patterns

The easiest way to reduce power consumption is to turn it off. However, this is not very useful. Because of that, the first step in reducing power usage is to identify how I'm going to use the computer. This will let me avoid removing functionality which I actually need.

The programs and devices I will probably use:

  • Firefox with noscript - keep my docs open
  • USB modem + NetworkManager
  • gkrellm & plasma monitors - useful for knowing whether I'm killing the CPU
  • email client
  • Konversation - even though it logs conversations to filesystem as they come
  • ssh
  • text editors & IDEs
  • PDF readers

These features will need to stay enabled and behave somewhat decently while on battery.

Basic optimizations

The basic rule of optimization is: if you don't need it, don't use it. I attempted to disable unnecessary features while keeping the system somewhat idle, somewhat work-ready.

Services

The first line of optimizations is to disable unnecessary services. On KDE side, one of the first ones to go was Klipper (right-click icon, quit, do not start).

Next was Nepomuk: System settings -> Desktop search -> Basic settings -> uncheck Enable Nepomuk Additional services at your leisure.

System-wide services are another thing wasting cycles. Postfix, fingerprint daemon, nfs, had to stop.

After applying those changes, at 20% backlight, the system took about 9.5W.

Power states

powertop --calibrate will help you figure out what consumes how much power. You will probably need to unlplug first.

Powertop suggests many optimizations that you can enable for moderate gain (1-2W idle gain on my system). Most of them don't have significant drawbacks (are you really using power-on-lan on your laptop?). I usually turn on all except VM Writeback timeout for fear of data loss (this delays writes to disk to help it spin down, but it didn't change much for me).

You should also disable any devices you're not using (preferably in BIOS), like the camera or bluetooth module. You might want to flip the physical WiFi switch.

CPU

Any program ececuting will wake the CPU and make it consume power. For those, we have the basic tool - top. Ideally, all non-crucial programs should stay at 0.0% CPU usage. While I'm writing this post, four processes stand out:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND  
  695 root      20   0  222500  46396  27484 S   4.6  1.2   6:03.13 X        
  981 rhn       20   0 3258612  87304  37772 S   3.3  2.3   3:38.16 kwin     
  994 rhn       20   0 3530188 171456  48828 S   3.0  4.4   5:03.44 plasma-+ 
 2887 rhn       20   0  979396  36796  17800 S   2.3  1.0   0:33.99 gedit    

Looks good - no obvious wasted resources.

Let's look at the details with powertop. You might follow the estimates of power usage to identify processes that keep the CPU in a higher power state than necessary. The only non-crucial process that's above 10 mW on my system is ksysguardd, but it's a required for my CPU monitoring widgets.

I/O

The second obvious way to drain power is to do I/O activity. While I don't know about a way to monitor per-process network traffic in Linux (pointers appreciated), I can find out the HD usage.

Any disk write will prevent the HD from spinning down, making it consume power. This doesn't apply to all reads, as these can be cached in RAM - as long as these are reads from the same resource.

Despite disabling all unneeded services the HDD didn't spin down on my system and I could hear a faint noise coming from the computer. Using iotop -a and leaving it on for a few minutes, I found some programs writing to disk when the system was idle:

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND       
  300 be/3 root          0.00 B     48.00 K  0.00 %  0.63 % [jbd2/sda5-8]
  545 be/3 root          0.00 B    132.00 K  0.00 %  0.33 % [jbd2/sda6-8]
  387 be/4 root        104.00 K    264.00 K  0.00 %  0.10 % systemd-journald

Ideally, nothing should exceed 0 on this screen.

The first two, jbd2-sda5-8 and jbd2-sda6-8, are kernel threads, having something to do with my root and home partitions. My educated guess is that they manage metadata written by some userspace applications. Unfortunately, I don't know a way to trace which application exactly is causing the writes, but they usually happened together with other writes.

noatime

That's why I decided to act preemptively and add noatime option to my / and /home mount points. Additional benefit of this is that your system should be much faster after this change. Excerpt from /etc/fstab:

UUID=XXXXXXXXX /                       ext4    defaults,noatime        1 1
UUID=XXXXXXXXX /boot                   ext4    defaults        1 2
UUID=XXXXXXXXX          /boot/efi               vfat    umask=0077,shortname=winnt 0 0
UUID=XXXXXXXXX /home                   ext4    defaults,noatime        1 2

Make sure you restart your machine immediately to catch errors early.

WARNING: mistakes may break your system. Have a rescue system ready (e.g. live USB).

ModemManager

systemd-journald writes pointed me to the system journal, where broken programs might leave warnings. journalctl --since=today revealed that ModemManager is misbehaving:

May 03 21:31:20 movable ModemManager[630]: <info>  Modem /org/freedesktop/ModemManager1/Modem/1: signal quality updated (40)

There's no need for this kind of spam on my system. Unfortunately, documentation is scarce and I could only find how to disable it temporarily.

$ mmcli -G WARN
Successfully set logging level

Another way (you may have to replace ModemManager1 with something else, look at your logs):

$ dbus-send --system --dest=org.freedesktop.ModemManager1 --print-reply /org/freedesktop/ModemManager1 org.freedesktop.ModemManager1.SetLogging string:Warn
method return sender=:1.2 -> dest=:1.59 reply_serial=2

If you know how to make it permanent, let me know.

Work-time optimizations

The second line of defense is reducing power usage from programs you actually use. I'm going to re-analyze iotop results under some load.

Firefox proved to do many unnecessary writes even when it wasn't used. The most likely reason for that is that a web page keeps doing something in the background (very bad for power consumption). I recommend only keeping simple web sites open, using NoScript or some strict Adblock rules.

There are some programs in KDE that write for reasons unknown to me. Why does an idle Okular need to touch the filesystem every few minutes? Why does Dolphin and plasma-desktop do the same?

Nothing really can be done about programs that modify files on your hard drive - like file editors, development environments, email client or messengers with logging on.

There's another way however to deal with this.

SSD

You might use a solid-state drive for frequently accessed files, like your workspace or to store logs or keep data of misbehaving programs. Additional device means more power consumption, but if it allows HD to spin down and stay that way most of the time, then the overall power usage should be less. Of course, you need to have a place to put the SSD in - my computer has a free mSATA slot.

I'm going to use it for Firefox, system logs, IRC logs, emails and my immediate workspace.

Keep in mind that this is not SSD caching. SSD caching captures accesses and writes everything to the HD anyway again, but later, after HD can catch up. That means you have a faster system, but you write everything twice. We don't want that.

I decided to go the easy way: some hot places from /home will be symlinked to a SSD partition for ease of testing and to save SSD space. I'm going to move /var/ completely to SSD as well:

  • /home/.cache: for the odd program writing
  • /home/tmp: likewise
  • /home/logs: Konversation chat logs
  • /home/.mozilla: for Firefox needs
  • /home/.claws-mail: local copy of emails

I will update with results as soon as I buy an SSD :)

Troublesome programs

Speech dispatcher

This one was detected with powertop. pulseaudio created 200 wakeups/s, and there were some input streams in pavucontrol named "speech-dispatcher-something". In my case, it was activated by Mumble and never turned off after I turned off Mumble.

I'm never going to remember to kill it manually after I use Mumble on AC power, therefore I disabled it completely by adding the following line in /etc/speech-dispatcher/speechd.conf:

# The DisableAutoSpawn option will disable the autospawn mechanism.
# Thus the server will not start automatically on requests from the clients
DisableAutoSpawn 1

Power loss: 1.5W

libvirtd

I use it extensively, but it leaves network interfaces running all the time until manually stopped. Powertop says they are using power, so I disable them just in case using virt-manager. Power loss: 0?

Results so far

Before I optimized my system, it took 11W while idle on Linux 3.13. After the optimizations idle power usage, it took 8.5W while idle. The next step is to measure power usage while working.

This article will be updated as I find new ways to kill power usage

Recently I decided to give mobile Internet a try. I had an old Three UK branded Huawei E1550 modem laying around, which seemed perfect for my Heyah SIM card.

The modem

The modem has the Three logo printed on the top side, but apart from that, it looks like the regular Huawei E1550 modem. The device is mode switching, meaning it pretends to be a storage device at first, but after it receives a special command, it switches to the actual modem mode.

lspci output in modem mode:

Bus 003 Device 060: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem

Unlocking

When I tried to use the modem with ModemManager GUI, it showed error messages in some sections (e.g. SMS) or, in the "Info" section, it showed a lot of blanks. It turned out that the modem was locked to the Three UK network and needed unlocking to work with my SIM.

There are plenty of unlock tutorials online, but no two of them offer the same solution. Some require the user to update firmware, some need unlock codes. Even worse, no tutorial covered Linux.

The unlock is very simple, it takes only 3 steps: 1. Find out your IMEI number 2. Derive your unlock code from the IMEI 3. Start the HUAWEI connection manager with an unauthorized SIM and enter the unlock code.

Unfortunately, all software I could find was Windows only. * For IMEI detection: E155XUpdate_11.608.13.02.00.B418.exe * For unlock code: Universal MasterCode * The connection manager: Mobile Partner's 11.302.09.01.539 Voice USSD

I managed to find the unlock code algorithm in php:

if (isset($_POST['submit']))
{
    $IMEI = $_POST['imeinum'];
    $MD5U = md5($IMEI.'5e8dd316726b0335');
    $MD5F = md5($IMEI.'97b7bc6be525ab44');
    $vector = 0;

    /* $MD5 for Unlock Code in 16 8-bit digits */
    $UNLOCK_CODE = '';
    $FLASH_CODE = '';
    for ($i = 0; $i < 8; $i=$i+2) 
   { 
       $DGU = hexdec(substr($MD5U, $i,2)) ^ 
                     hexdec(substr($MD5U, $i+8,2)) ^ 
                     hexdec(substr($MD5U, $i+16,2)) ^ 
                     hexdec(substr($MD5U, $i+24,2)); 
       $DGF = hexdec(substr($MD5F, $i,2)) ^ 
                     hexdec(substr($MD5F, $i+8,2)) ^ 
                     hexdec(substr($MD5F, $i+16,2)) ^ 
                     hexdec(substr($MD5F, $i+24,2)); 

       $UBYTE = str_pad(dechex($DGU),2,"0",STR_PAD_LEFT); $FBYTE =    str_pad(dechex($DGF),2,"0",STR_PAD_LEFT); 

      $UNLOCK_CODE = $UNLOCK_CODE.$UBYTE; $FLASH_CODE = $FLASH_CODE.$FBYTE; 
   } 

$UNLOCK_CODE = hexdec($UNLOCK_CODE) & 33554431 | 33554432;
$FLASH_CODE = hexdec($FLASH_CODE) & 33554431 | 33554432; 

echo 'IMEI: '.$IMEI;
echo 'UNLOCK: '.$UNLOCK_CODE;
echo 'FLASH: '.$FLASH_CODE;

}

Linux

The modem works well under Linux, but not perfectly. Sometimes it doesn't reconnect automatically and at each connection attempt, it requires entering the APN password manually multiple times. I have no idea if it's the modem's, network's or NetworkManager's fault.

Profile

rhn

rhn

An open source culture enthusiast (really "Free Source"), software developer, tinkerer in all things electronic. Slight privacy nut. Cyclist, occasional gamer. Some projects: http://rhn.github.com/.

Syndicate

RSS Atom

Expand Cut Tags

No cut tags