diary at Telent Netowrks

Light touch regulation#

Wed, 02 Oct 2019 23:34:42 +0000

Or less obliquely, how to configure the Thinkpad X1 Carbon (gen 4, if it matters) touchpad in NixOS to not respond to the lightest brush of a finger as if it were a click. An end to accidentally favouriting random tweets while browsing Twitter on Firefox. Or at least, I hope, the elimination of a significant source of such.

First off, the instructions at https://people.freedesktop.org/~whot/libinput-rtd/touchpad-pressure.html#touchpad-pressure-hwdb are very nearly all true, and you should read them because I am not going to recapitulate them. I say "almost" because I found that where it says list-quirks I had to say quirks list instead. Following that process led me to create a file /etc/libinput/local-overrides.quirks that reads as follows:

[Section touchpad pressure]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon4th*
AttrPressureRange=45:42

Second, it's more complicated than that. In NixOS 19.03, the libinput binary doesn't look at that file, it looks at /nix/store/9lwm03xqd8pkbxc3hgq9iiginddiyha3-libinput-1.12.6/etc/libinput/local-overrides.quirks, which is owned by the libinput derivation and can't be changed. (This is probably a bug. I will report it in the morning). Because I am trying to stick to channels and not maintain more forks of nixpkgs than I need to, I decided to patch it with an overlay. Therefore

[dan@noetbook:~]$ cat /etc/nixos/overlays/libinput.nix
self : super: {
  libinput = super.libinput.overrideAttrs (o: {
    mesonFlags = o.mesonFlags ++ [
      "--sysconfdir=/etc"
    ];
  });
}

and

[dan@noetbook:~]$ grep -B1 -A9 overlays /etc/nixos/configuration.nix 
{
  nixpkgs.overlays = [ (import /etc/nixos/overlays/libinput.nix) ];
  environment.etc."libinput/local-overrides.quirks" = {
    text = ''
[Section touchpad pressure]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon4th*
AttrPressureRange=45:42
'';
  };

and nixos-rebuild switch, and after some swearing caused mostly by accidentally forgetting to exit all the nix-shells I had accidentally got myself into, about 30 minutes rebuilding later, it worked.

Note that adding overlays in configuration.nix does not make them available to nix-env or nix run, so you probably also want to add libinput to environment.systemPackages if you want to test your quirks are getting picked up. Then you can do this:

[dan@noetbook:~]$ strace -e openat libinput quirks list /dev/input/event7 2>&1 |grep etc 
openat(AT_FDCWD, "/etc/libinput/local-overrides.quirks", O_RDONLY) = 3

[dan@noetbook:~]$ libinput quirks list /dev/input/event7 ModelSynapticsSerialTouchpad=1 AttrPressureRange=45:42 AttrThumbPressureThreshold=100

A great improvement / A+++ would recommend. Wish I'd done it three years ago.

Nix wrought#

Tue, 03 Sep 2019 22:00:29 +0000

Time from unboxing new GL.iNet GL-MT300N-V2 to an ssh-able NixWRT installation: 30 minutes. Though admittedly this does not include the actual firmware build time itself as I did that bit yesterday when I ordered the box.

I lost the CPU for my backup server somewhere when we moved - I still have the disk, just not the bit that makes it go. Probably it's in a box I haven't unpacked yet, but anyway. Having generated much new "content" over the past few days - I've now scanned something over 500 pieces of paper into my paperless archive - it becomes somewhat more pressing to get the automated backup service running again.

  1. make the image
  2. find some scissors, open the box
  3. plug the device LAN port into my laptop and configure it to use a different RFC1918 address than the one it came with (which conflicts with the LAN here)
  4. upload the firmware.bin using the gl.inet web router admin page
  5. wait
  6. why is it not showing up on the LAN?
  7. wait
  8. ah yes, because it's still plugged into my laptop. Try plugging it into a LAN switch instead
  9. odds bodikins, I can ssh into it!

So, 30 minutes, would have been quicker if I weren't an idiot at step 6. To say I am mildly stoked this went so smoothly would be an understatement.

There are a couple of niggles: I need to rebuild the image because I forgot to update the name of the syslog host and I think I have probably also forgotten to put a real password on the rsync service. But both those are (or should be) simple fices.

Cracking over the papers#

Fri, 30 Aug 2019 11:19:35 +0000

One of the several billion things that needs sorting in our new house is a filing system for all the paper junk we get sent that we don't immediately need to deal with but probably shouldn't throw away: bills, PAYE coding notices, letters from the council, bank statements etc. After some thought and thanks to @antifuchs alerting me to the existence of the Paperless project I decided to go digital. Recommend.

Notes, in the order they occur to me

    services.paperless = {
      enable = true;
      extraConfig = {
        PAPERLESS_CORS_ALLOWED_HOSTS="http://localhost:8080";
      };
    };

sudo -u scanner scanimage --format png --batch=/var/spool/scans/$(date +%Y%m%d%H%M%S)Z_p%04d.png  --resolution 300 --source 'ADF Duplex'

where scanner is the username that paperless is running as and /var/spool/scans/ is where I arbitrarily decided the consumption directory should be. I scan to png not pdf because scanimage was silently failing to convert to pdf and instead leaving the files as pbm images. (1) pbm images are huge; (2) pbm images files with .pdf suffixes confuse the paperless web frontend and they confuse me too. I would like to automate this so it runs whenever I (or a family member) presses the "scan" button on the scanner itself, but haven't got that far yet. scanbd will probably do it but seems excessively featureful for my needs.

[dan@loaclhost:~]$ systemctl cat paperless-consumer.service| grep 'ExecStart='
ExecStart=/nix/store/2jaqzp6yhqwb2p0vs93whkwj0r0jf509-paperless document_consumer
[dan@loaclhost:~]$ sudo -u scanner /nix/store/2jaqzp6yhqwb2p0vs93whkwj0r0jf509-paperless document_correspondents

Switched out#

Wed, 26 Jun 2019 20:55:18 +0000

I have spent an inordinate amount of time lately to get a working NixWRT wireless extender running on my MT300A. The symptom is that whenever I reboot it, about 30-60 seconds later it will lock up every device on the switch it is plugged into for a minute - and as this presently includes my build system, which also serves as my NAS, the problem is a high-priority one.

I've had all kinds of hypotheses, many of which involved bridging loops somewhere on the LAN, but no amount of staring at network diagrams, poring over wireshark captures or or fiddling with STP seemed to have any effect. Until last night when I tried to do a TFTP boot forgetting that I'd unplugged it from the TFTP server, and that resulted in exactly the same problem without even starting the Linux kernel.

So, I guess we can eliminate NixWRT from our enquiries. Whether the problem is hardware, or is something to do with how U-Boot initializes the hardware - or both, even - I am in some sense cheered to learn that it was probably nothing I did. At this point I'm going to flash the latest extensino.nix build to it, put the cover back on, and go and plug it in somewhere I have wireless dead spots, so that I can actually start working on the new router that arrived last week. And maybe not reboot it too often, but actually I'm hoping that once the image can be booted from flash, U-boot won't need to initialize the network device at all and there will be no problem.

Well, I might just add in support for STP first, it seems like a sensible thing to have.

Blogging on logging#

Fri, 14 Jun 2019 08:34:20 +0000

Before I put NixWRT on my primary internet connection, I want to deploy this wireless range extender, which means unplugging the serial connection. So, I really need to make it send syslog over the network.

"Just [* ] install syslogd", you say, "how hard can it be?". There's a syslogd applet in Busybox, all I need is something elsewhere on the LAN to receive the messages (hint: not Journald ). But, before I can send log messages over the network, I need the network to be available:

Which in sum is about 96% of everything it needs to do when it boots up, and whether that all goes to plan or not, any log messages it generates will be lost like tears in rain. Forgotten like a politician's manifesto commitments. Cast to the ground like a toddler's breakfast. I wanted something a bit more comprehensive, and didn't want to write the messages to flash because I'm not using any writable flash filesystem.

Avery Pennaruns blog article The log/event processing pipeline you can't have is not only a fun read about log processing at scale, but contains a really neat solution to this problem: instead of having klogd suck kernel messages and push them into syslogd which spits them out to files on disk, why not run the pump in reverse and push all the userland log messages into the kernel printk buffer? We have lots of RAM (I mean, by comparison with how much flash we can spare) and can squirrel all the boot time messages away until the network is up and ready to send them to the loghost.

Copying from /dev/log to /dev/kmsg is either simple or as complicated as you care to make it (the Google Fiber app has clearly encountered and addressed a whole bunch of real-world issues I haven't had to deal with).

Sending messages from the kernel printk buffer is slightly more complicated but only in the incidentals not in the essentials. We need to

1. read from /dev/kmsg and parse the strings we get. The format is documented and the only challenge here is that for reasons of keeping the system size down I felt obliged to write it in C, which is peculiarly suitable for text processing tasks. Emphasis here on "peculiar" not "suitable". Slightly annoyingly, the log entries don't include a timestamp field which can be related to time of day: instead they use a monotonic timestamp which is probably the number of seconds since boot but doesn't account for time while the system is suspended.

2. transform it into something J Random Syslog Server will recognise. There are two contenders here: RFC 5424 says how you're supposed to do it, with options for PROCID, MSGID and STRUCTURED-DATA which I probably don't need, and RFC 3164 says how everyone actually does it, which as you can imagine encompasses a wide variety of exciting brokenness (it's descriptive not prescriptive, and what it describes is little more constrained than "there might be a facility in angle brackets, there might be a timestamp, there's probably some other stuff). Initially I tried 3164 with ISO8601 timestamps instead of the weird legacy date format it recommends, but rsyslog declined to parse the rest of the line, so I switched to 5424. After making this decision I noticed that the author of rsyslog is also the author of RFC5242, so, uh, I guess there's that. I had to add my own timestamps here because see complaint about step 1, and I had to add in the hostname.

3. Send it to the internet. This bit at least is well-trodden ground.

There's only one other thing to say here, which is that the lines you write into /dev/kmsg are whatever you want to write. My klogcollect just writes more or less anything that turn up in /dev/log, without attempting to parse it, which means whatever format the C library syslog() function writes. So when forwarding the messages I have to check the message origin (kernel or userland) before deciding whether to format it for RFC5424 or whether to wing it as-is.

Summarising

After the monolog(ue), the epilog(ue)...

klogforward is on Github, and you can have this working in your NixWRT by adding

(syslog { loghost = "loghost.example.com" ; })

to your modules.

When I next come back to this I am going to play with the PRINTK_PERSIST patch that Avery talks about, and also I should have a proper look at logos - it probably solves problems I haven't seen yet. But more pressing right now is working out why I can't reboot my wireless extender without freezing every other device on the switch it's attached to for a minute. Wireshark says it's "MAC PAUSE" frames, and my working hypothesis is a switching loop.