Search Results: "reg"

3 March 2016

Arturo Borrero Gonz lez: Current status of iptables & nftables in Debian


I would like to give an overview of what is the current status of iptables & nftables in Debian.
Some information contained in this article is not new, this post is about what happened to iptables & nftables in the last 3 months, focusing on the integration with Debian.
versionsBy the time of this article, upstream versions are:
Debian testing (stretch) contains updated versions of all of them:
  • iptables 1.6.0-2
  • nftables 0.5+snapshot20151106-1
  • libnftnl 1.0.5+snapshot20151106-1
The snapshot versioning thing in nftables and libnftnl is the result of packaging a few commits ahead of last upstream release to workaround some nasty bugs.
the iptables-compat stuff
The iptables 1.6.0 release contains a new set of tools called 'compat'. These tools uses the same syntax of iptables,ip6tables,arptables,ebtables but internally read/write data to the nf_tables kernel subsystem.
You can find these compat tools in a binary pacakge: 'iptables-nftables-compat'.

That is one of the approaches available to help admins migrate from iptables to nftables.

Other approach is textual translations. In this case, the admin calls the translation utility using iptables syntax to get the same rule written in native nft syntax.
However, this approach is a work in progress and Debian lacks of this functionality right now . I hope next upstream release of iptables will include some of this.
iptables maintenance
In Debian bug #805018, I contacted former maintainer Laurence J. Lane about the 1.6.0 upstream release and the need to pay attention to such a big release.
Unfortunately, it seems Laurence got his key expired, and he can no longer maintain any package until a new key is in place. Hope we can see him back soon.

So, I took over the maintenance of iptables, with the help of Ana Guerrero, which has been reviewing my work and sponsoring the uploads. Thanks Ana!

As part of this new maintenance, I cleaned up a bit the iptables bug tracker. I closed some very old bugs (see for example #295567 and #118187) which are no longer useful.
ready for stable?
With the stretch freeze coming by the end of 2016, I want to be sure that the main Netfilter packages are in shape for a Debian stable release.
I won't let packages migrate to stable if there is no extensive testing. It should be clear that packages are ready for Debian stable for me to let them go stable.

My concerns regarding nftables & iptables in stable are different actually:
  • iptables: piece of software too widespread. I don't want to break any system with the 1.6.0 migration.
  • nftables: the 0.5 release is old already with regards to the upstream development.
So please, let me know any feedback you may have :-)

Ben Hutchings: Debian LTS work, February 2016

February marked the end of Debian 6.0 "squeeze" LTS, though there was some initial confusion (partly my fault) over which day of month it should end. I carried over 10 hours from January and was assigned another 11.25 hours of work by Freexian's Debian LTS initiative. I worked a total of 14 hours. I started the month with "the final" update to the linux-2.6 kernel package (DLA-412-1), fixing 5 CVEs and incorporating upstream stable update 2.6.32.70. After it was agreed that support would continue to the end of the month, I made one more update on the last day (DLA-439-1), fixing 4 CVEs, a regression, and some issues I had found lacking CVEs (one is now CVE-2012-6701). I helped to edit the end-of-life announcement for Squeeze LTS. I spent a fairly quiet week in the front desk, triaging new issues for squeeze. As I've volunteered to handle embargoed issues, I prepared security updates to libssh and libssh2 and issued them minutes after the public disclosure of the similarly disastrous CVE-2016-0739 and CVE-2016-0787 issues.

2 March 2016

Dirk Eddelbuettel: RcppEigen 0.3.2.8.1

A good week after the update to Eigen 3.2.8 in our RcppEigen package 0.3.2.8.0, we have another (local) update with RcppEigen 0.3.2.8.1 which should fix another UBSAN issue. This new version in now on CRAN and in Debian. Big thanks once again to Yixuan Qiu for liasing with Eigen upstream, reporting the bug and preparing a PR with the fix. The NEWS file entry follows.
Changes in RcppEigen version 0.3.2.8.1 (2016-02-29)
  • Applied another upstream UBSAN fix (PR #30 by Yixuan)
Courtesy of CRANberries, there is also a diffstat report for the most recent release.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.

1 March 2016

Vincent Sanders: Hope is tomorrow's veneer over today's disappointment.

Recently I have been very hopeful about the 96boards Hikey SBC and as Evan Esar predicted I have therefore been very disappointed. I was given a Hikey after a Linaro connect event some time ago by another developer who could not get the system working usefully and this is the tale of what followed.
The Standard Design
This board design was presented as Linaro creating a standard for the 64bit Single Board Computer (SBC) market. So I had expected that a project with such lofty goals would have considered many factors and provided at least as good a solution as the existing 32bit boards.

The lamentable hubris of creating a completely new form factor unfortunately sets a pattern for the whole enterprise. Given the aim towards "makers" I would have accepted that the system would not be a ATX PC size motherboard, but mini/micro/nano and pico ITX have been available for several years.

If opting for a smaller "credit card" form factor why not use one of the common ones that have already been defined by systems such as the Raspberry Pi B+? Instead now every 96Board requires special cases and different expansion boards.

Not content with defining their own form factor the design also uses a 8-18V supply, this is the only SBC I own that is not fed from a 5V supply. I understand that a system might require more current than a micro USB connector can provide, but for example the Banana Pi manages with a DC barrel jack readily capable of delivering 25W which would seem more than enough

The new form factor forced the I/O connectors to be placed differently to other SBC, given the opportunity to concentrate all connectors on one edge (like ATX designs) and avoid the issues where two or three sides are used. The 96board design instead puts connectors on two edges removing any possible benefit this might have given.

The actual I/O connectors specified are rather strange. There is a mandate for HDMI removing the possibility of future display technology changes. The odd USB arrangement of two single sockets instead of a stacked seems to be an attempt to keep height down but the expansion headers and CPU heatsink mean this is largely moot.

The biggest issue though is mandating WIFI but not Ethernet (even as an option), everything else in the design I could logically understand but this makes no sense. It means the design is not useful for many applications without adding USB devices.

Expansion is presented as a 2mm pitch DIL socket for "low speed" signals and a high density connector for "high speed" signals. The positioning and arrangement of these connectors proffered an opportunity to improve upon previous SBC designs which was not taken. The use of 2mm pitch and low voltage signals instead of the more traditional 2.54mm pitch 3.3v signals means that most maker type applications will need adapting from the popular Raspberry Pi and Arduino style designs.

In summary the design appears to have been a Linaro project to favour one of their members which took a Hisilicon Android phone reference design and put it onto a board with no actual thought beyond getting it done. Then afterwards attempted to turn that into a specification, this has simply not worked as an approach.

My personal opinion is that this specification is fatally flawed and, is a direct cause of, the bizarre situation where the "consumer" specification exists alongside the "enterprise" edition which itself has an option of microATX form factor anyhow!
The ImplementationIf we ignore the specification appearing to be nothing more than a codification of the original HiKey design we can look at the HiKey as an implementation.

Initially the board required modifying to add headers to attach a USB to 1.8V LVTTL serial adaptor on the UART0 serial port. Once Andy Simpkins had made this change for me I was able to work through the instructions and attempt to install a bootloader and OS image.

The initial software was essentially HiSilicon vendor code using the Android fastboot system to configure booting. There was no source and the Ubuntu OS images were an obvious afterthought to the Android images. Just getting these images installed required a great deal of effort, repetition and debugging. It was such a dreadful experience this signalled the commencement one of the repeated hiatuses throughout this project, the allure of 64 bit ARM computing has its limits even for me.

When I returned to the project I attempted to use the system from the on-board eMMC but the pre-built binary only kernel and OS image were very limited. Building a replacement kernel , or even modules for the existing one proved fruitless and the system was dreadfully unstable.

I wanted to use the system as a builder for some Open Source projects but the system instability ruled this out. I considered attempting to use virtualisation which would also give better system isolation for builder systems. By using KVM running a modern host kernel and OS as a guest this would also avoid issues with the host systems limitations. At which point I discovered the system had no virtualisation enabled apparently because the bootloader lacked support.

In addition to these software issues there were hardware problems, despite forcing the use of USB for all additional connectivity the USB implementation was dreadful. For a start all USB peripherals have to run at the same speed! One cannot mix full (12Mbit) and high speed (480Mbit) devices which makes adding a USB Ethernet and SATA device challenging when you cannot use a keyboard.

And because I needed more challenges only one of the USB root hubs was functional. In effect this made the console serial port critical as it was the only reliable way to reconfigure the system without a keyboard or network link (and WIFI was not reliable either)

After another long pause in proceedings I decided that I should house all the components together and that perhaps being out on my bench might be the cause of some instability. I purchased a powered Amazon basics USB 2 hub, an Ethernet adaptor and a USB 2 SATA interface in the hope of accessing some larger mass storage.

The USB hub power supply was 12V DC which matched the Hikey requirements so I worked out I could use a single 4A capable supply and run a 3.5inch SATA hard drive too. I designed a laser cut enclosure and mounted all the components. As it turned out I only had a 2.5inch hard drive handy so the enclosure is a little over size. If I were redoing this design I would attempt to make it fit in 1U of height and be mountable in a 19inch rack instead it is an 83mm high (under 2U) box.

A new software release had also become available which purported to use an UEFI bootloader after struggling to install this version unsuccessfully, made somewhat more problematic by the undocumented change from UART0 (unpopulated header) to UART3 on the low speed 2mm pitch header. The system seemed to start the kernel which panicked and hung either booting from eMMC or SD card. Once again the project went on hold after spending tens of hours trying to make progress.
Third time's a charmAs the year rolled to a close I once again was persuaded to look at the hikey, I followed the much improved instructions and installed the shiny new November software release which appears to have been made for the re-release of the Hikey through LeMaker. This time I obtained a Debian "jessie" system that booted from the eMMC.

Having a booted system meant I could finally try and use it. I had decided to try and use the system to host virtual machines used as builders within the NetSurf CI system.

The basic OS uses a mixture of normal Debian packages with some replacements from Linaro repositories. I would have prefered to see more use of Debain packages even if they were from the backports repositories but on the positive side it is good to see the use of Debian instead of Ubuntu.

The kernel is a heavily patched 3.18 built in a predominantly monolithic (without modules) manner with the usual exceptions such as the mali and wifi drivers (both of which appear to be binary blobs). The use of a non-mainline capable SoC means the standard generic distribution kernels cannot be used and unless Linaro choose to distribute a kernel with the feature built in it is necessary to compile your own from sources.

The default install has a linaro user which I renamed to my user and ensured all the ssh keys and passwords on the system were changed. This is an important step when using this pre-supplied images as often a booted system is identical to every other copy.

To access mass storage my only option was via USB, indeed to add any additional expansion that is the only choice. The first issue here is that the USB host support is compiled in so when the host ports are initialised it is not possible to select a speed other than 12MBit. The speed is changed to 480Mbit by using a user space application found in the users home directory (why this is not a tool provided by a package and held in sbin I do not know).

When the usb_speed tool is run there is a chance that the previously enumerated devices will be rescanned and what was /dev/sda has become /dev/sdb if this happens there is a high probability that the system must be rebooted to prevent random crashes due to the "zombie" device.

Because the speed change operation is unreliable it cannot be reliably placed in the boot sequence so this must be executed by hand on each boot to get access to the mass storage.

NetSurf project already uses a x86_64 virtual host system which runs an LLVM physical volume from which we allocate logical volumes for each VM. I initially hoped to do this with the hikey but as soon as I tried to use the logical volume with a VM the system locked up with nothing shown on console. I did not really try very hard to discover why and instead simply used files on disc for virtual drives which seemed to work.

To provide reliable network access I used a USB attached Ethernet device, this like the mass storage suffered from unreliable enumeration and for similar reasons could not be automated requiring manually using the serial console to start the system.

Once the system was started I needed to install the guest VM. I had hoped I might be able to install locally from Debian install media as I do for x86 using the libvirt tools. After a great deal of trial and error I finally was forced to abandon this approach when I discovered the Linaro kernel is lacking iso9660 support so installing from standard media was not possible.

Instead I used the instructions provided by Leif Lindholm to create a virtual machine image on my PC and copied the result across. These instructions are great except I used version 2.5 of Qemu instead of 2.2 which had no negative effect. I also installed the Debian backports for Jessie to get an up to date 4.3 kernel.

After copying the image to the Hikey I started it by hand from the command line as a four core virtual machine and was successfully able to log in. The guest would operate for up to a day before stopping with output such as

$
Message from syslogd@ciworker13 at Jan 29 07:45:28 ...
kernel:[68903.702501] BUG: soft lockup - CPU#0 stuck for 27s! [mv:24089]

Message from syslogd@ciworker13 at Jan 29 07:45:28 ...

kernel:[68976.958028] BUG: soft lockup - CPU#2 stuck for 74s! [swapper/2:0]

Message from syslogd@ciworker13 at Jan 29 07:47:39 ...
kernel:[69103.199724] BUG: soft lockup - CPU#3 stuck for 99s! [swapper/3:0]

Message from syslogd@ciworker13 at Jan 29 07:53:21 ...
kernel:[69140.321145] BUG: soft lockup - CPU#3 stuck for 30s! [rs:main Q:Reg:505]

Message from syslogd@ciworker13 at Jan 29 07:53:21 ...
kernel:[69192.880804] BUG: soft lockup - CPU#0 stuck for 21s! [jbd2/vda3-8:107]

Message from syslogd@ciworker13 at Jan 29 07:53:21 ...
kernel:[69444.805235] BUG: soft lockup - CPU#3 stuck for 22s! [swapper/3:0]

Message from syslogd@ciworker13 at Jan 29 07:55:21 ...
kernel:[69570.177600] BUG: soft lockup - CPU#1 stuck for 112s! [systemd:1]

Timeout, server 192.168.7.211 not responding.

After this output the host system would not respond and had to be power cycled never mind the guest!

Once I changed to single core operation the system would run for some time until the host suffered from the dreaded kernel OOM killer. I was at a loss as to why the oom killer was running as the VM was only allocated half the physical memory (512MB) allowing the host what I presumed to be an adequate amount.

By adding a 512MB swapfile the system was able to push the few hundred kilobytes it wanted to swap and the system was now stable! The swapfile of course has to be started by hand as the external storage is unreliable and unavailable at boot.

I converted the qemu command line to a libvirt config using the virsh tool
virsh domxml-from-native qemu-argv cmdln.args
The converted configuration required manual editing to get a working system but now I have a libvirt based VM guest I can control along with all my other VM using the virt-manager tool.

This system is now stable and has been in production use for a month at time of writing. The one guest VM is a single core 512MB aarch64 system which takes over 1100 seconds (19 minutes) to do what a Banana Pi 2 dual core 1GB memory 32bit native ARM system manages in 300 seconds.

It seems the single core limited memory system with USB SATA attached storage is very, very slow.

I briefly attempted to run the CI system job natively within the host system but within minutes it crashed hard and required a power cycle to retrieve, it had also broken the UEFI boot. I must thank Leif for walking me through recovering the system otherwise I would have needed to start over.
ConclusionsI must stress these conclusions and observations are my own and do not represent anyone else.

My main conclusions are:

This project has taken almost a year to get to the final state and has been one of the least enjoyable within that time. The only reason I have a running system at the end of it is sheer bloody mindedness because after spending hundreds of hours of my free time I was not prepared to see it all go to waste.

To be fair, the road I travelled is now much smoother and if the application is suited to having a mobile phone without a screen then the Hikey probably works as a solution. For me, however, the Hikey product with the current hardware and software limitations is not something I would recommend in preference to other options.

Ritesh Raj Sarraf: Linux Power Savings 2016

Having moved to a new place, now at times, I also have to deal with power outages. As heat increases, the power outages will be much longer and more frequent. So much, that UPS and Power Inverters run out. Such are ideal times to measure idle power consumption for my laptop. Here's what my default (and idle) OS looks like. It should be standard to most "typical" users. Some minor odds could be apport, dnsmasq, and maybe, tor. Also, thanks to systemd, there are some native services which are now converted to socket activation based ones. There's also Laptop Mode Tools for userspace power savings. But huge thanks to Intel's work in making the kernel more power efficient. With things like Runtime PM and Intel P-State, we can now define, default and aggressive power-savings modes, helping conserve more power. We still have challenges with things like binary-only drivers; and also stock GPL drivers but with an external firmware blob. There have been many instances when my previous machines (which had both) ran into severe power drain. The challenge with power savings is that it is not just the job of the kernel. All components, kernel and userspace, need to be made aware of, and work in unison. Otherwise, one ill behaving web browser tab can be the cause of power drain. P-State driver seems to already be doing some scale down of CPU resources. And with CGroups maturing moe I think we'll eventually have all Desktop Environments making use of it.
systemd-+-ModemManager-+- gdbus 
                        - gmain 
         -NetworkManager-+- gdbus 
                          - gmain 
         -accounts-daemon-+- gdbus 
                           - gmain 
         -agetty
         -apport-notifyd
         -atd
         -avahi-daemon---avahi-daemon
         -bluetoothd
         -colord-+- gdbus 
                  - gmain 
         -cron
         -dbus-daemon
         -dnsmasq
         -evolution-+- book-client-dbu 
                     - dconf worker 
                     -7*[ evolution ]
                     - gdbus 
                     - gmain 
         -gdm3-+-gdm-session-wor-+-gdm-x-session-+-Xorg
                                                  -gnome-session-b-+-gnome-settings--+- dconf worker 
                                                                                      - gdbus 
                                                                                      - gmain 
                                                                                      - pool 
                                                                                      - threaded-ml 
                                                                    -gnome-shell-+-ibus-daemon-+-ibus-dconf-+- dconf worker 
                                                                                                             - gdbus 
                                                                                                             - gmain 
                                                                                                -ibus-engine-sim-+- gdbus 
                                                                                                                  - gmain 
                                                                                                - gdbus 
                                                                                                - gmain 
                                                                                  - JS GC Helper 
                                                                                  - JS Sour~ Thread 
                                                                                  - dconf worker 
                                                                                  - gdbus 
                                                                                  - gmain 
                                                                                  - threaded-ml 
                                                                    - dconf worker 
                                                                    - gdbus 
                                                                    - gmain 
                                                  - gdbus 
                                                  - gmain 
                                  - gdbus 
                                  - gmain 
                -gdm-session-wor-+-gdm-x-session-+-Xorg
                                                  -gnome-session-b-+-evolution-alarm-+- cal-client-dbus 
                                                                                      - dconf worker 
                                                                                      - evolution-alarm 
                                                                                      - gdbus 
                                                                                      - gmain 
                                                                    -gnome-settings--+- dconf worker 
                                                                                      - gdbus 
                                                                                      - gmain 
                                                                                      - pool 
                                                                                      - threaded-ml 
                                                                    -gnome-shell-+-2*[redshift-+- gdbus ]
                                                                                                - gmain ]
                                                                                  - JS GC Helper 
                                                                                  - JS Sour~ Thread 
                                                                                  - dconf worker 
                                                                                  - gdbus 
                                                                                  - gmain 
                                                                                  - threaded-ml 
                                                                    -parcimonie
                                                                    -parcimonie-appl-+- gdbus 
                                                                                      - gmain 
                                                                    -python3---libinput-debug-
                                                                    -ssh-agent
                                                                    -tracker-extract-+- dconf worker 
                                                                                      - gdbus 
                                                                                      - gmain 
                                                                                      -10*[ pool ]
                                                                    -tracker-miner-a-+- gdbus 
                                                                                      - gmain 
                                                                    -tracker-miner-f-+- dconf worker 
                                                                                      - gdbus 
                                                                                      - gmain 
                                                                    -tracker-miner-u-+- gdbus 
                                                                                      - gmain 
                                                                    - dconf worker 
                                                                    - gdbus 
                                                                    - gmain 
                                                  - gdbus 
                                                  - gmain 
                                  - gdbus 
                                  - gmain 
                - gdbus 
                - gmain 
         -geoclue-+- gdbus 
                   - gmain 
         -gnome-keyring-d-+- gdbus 
                           - gmain 
                           - timer 
         -gpg-agent
         -gsd-printer-+- gdbus 
                       - gmain 
         -ibus-daemon-+-ibus-dconf-+- dconf worker 
                                    - gdbus 
                                    - gmain 
                       -ibus-engine-sim-+- gdbus 
                                         - gmain 
                       - gdbus 
                       - gmain 
         -ibus-x11-+- gdbus 
                    - gmain 
         -iio-sensor-prox-+- gdbus 
                           - gmain 
         -inetd---leafnode
         -libvirtd---15*[ libvirtd ]
         -lvmetad
         -master-+-pickup
                  -qmgr
                  -tlsmgr
         -mcelog
         -minissdpd
         -mount.ntfs
         -onboard-+- dconf worker 
                   - gdbus 
                   - gmain 
         -packagekitd-+- gdbus 
                       - gmain 
         -polkitd-+- gdbus 
                   - gmain 
         -2*[pulseaudio-+-gconf-helper]
                         - alsa-sink-ALC23 ]
                         - alsa-sink-HDMI  ]
                         - alsa-sink-pcspe ]
                         - alsa-source-ALC ]
         -rtkit-daemon---2*[ rtkit-daemon ]
         -systemd-+-(sd-pam)
                   -at-spi-bus-laun-+-dbus-daemon
                                     - dconf worker 
                                     - gdbus 
                                     - gmain 
                   -at-spi2-registr-+- gdbus 
                                     - gmain 
                   -dbus-daemon
                   -dconf-service-+- gdbus 
                                   - gmain 
                   -goa-daemon-+- dconf worker 
                                - gdbus 
                                - gmain 
                   -goa-identity-se-+- gdbus 
                                     - gmain 
                                     - pool 
                   -gvfs-afc-volume-+- gdbus 
                                     - gmain 
                                     - gvfs-afc-volume 
                   -gvfs-goa-volume-+- gdbus 
                                     - gmain 
                   -gvfs-gphoto2-vo-+- gdbus 
                                     - gmain 
                   -gvfs-mtp-volume-+- gdbus 
                                     - gmain 
                   -gvfs-udisks2-vo-+- gdbus 
                                     - gmain 
                   -gvfsd-+- gdbus 
                           - gmain 
                   -gvfsd-fuse-+- gdbus 
                                - gmain 
                                - gvfs-fuse-sub 
                                -2*[ gvfsd-fuse ]
                   -gvfsd-metadata-+- gdbus 
                                    - gmain 
                   -mission-control-+- dconf worker 
                                     - gdbus 
                                     - gmain 
         -systemd-+-(sd-pam)
                   -at-spi-bus-laun-+-dbus-daemon
                                     - dconf worker 
                                     - gdbus 
                                     - gmain 
                   -at-spi2-registr-+- gdbus 
                                     - gmain 
                   -dbus-daemon
                   -gconfd-2
         -systemd-+-(sd-pam)
                   -at-spi-bus-laun-+-dbus-daemon
                                     - dconf worker 
                                     - gdbus 
                                     - gmain 
                   -at-spi2-registr-+- gdbus 
                                     - gmain 
                   -dbus-daemon
                   -dconf-service-+- gdbus 
                                   - gmain 
                   -evolution-addre-+-2*[evolution-addre-+- dconf worker ]
                                                          - evolution-addre ]
                                                          - gdbus ]
                                                          - gmain ]
                                     - dconf worker 
                                     - evolution-addre 
                                     - gdbus 
                                     - gmain 
                   -evolution-calen-+-evolution-calen-+- dconf worker 
                                                       - evolution-calen 
                                                       - gdbus 
                                                       - gmain 
                                                       -6*[ pool ]
                                     -evolution-calen-+- book-client-dbu 
                                                       - dconf worker 
                                                       - evolution-calen 
                                                       - gdbus 
                                                       - gmain 
                                                       - pool 
                                     -2*[evolution-calen-+- dconf worker ]
                                                          - evolution-calen ]
                                                          - gdbus ]
                                                          - gmain ]
                                     - dconf worker 
                                     - evolution-calen 
                                     - gdbus 
                                     - gmain 
                   -evolution-sourc-+- dconf worker 
                                     - gdbus 
                                     - gmain 
                   -gconfd-2
                   -gnome-shell-cal-+- cal-client-dbus 
                                     - dconf worker 
                                     - gdbus 
                                     - gmain 
                                     - gnome-shell-cal 
                   -gnome-terminal--+-bash---pstree
                                     -bash
                                     - dconf worker 
                                     - gdbus 
                                     - gmain 
                   -goa-daemon-+- dconf worker 
                                - gdbus 
                                - gmain 
                   -goa-identity-se-+- gdbus 
                                     - gmain 
                                     - pool 
                   -gpaste-daemon-+- dconf worker 
                                   - gdbus 
                                   - gmain 
                   -gvfs-afc-volume-+- gdbus 
                                     - gmain 
                                     - gvfs-afc-volume 
                   -gvfs-goa-volume-+- gdbus 
                                     - gmain 
                   -gvfs-gphoto2-vo-+- gdbus 
                                     - gmain 
                   -gvfs-mtp-volume-+- gdbus 
                                     - gmain 
                   -gvfs-udisks2-vo-+- gdbus 
                                     - gmain 
                   -gvfsd-+- gdbus 
                           - gmain 
                   -gvfsd-burn-+- gdbus 
                                - gmain 
                   -gvfsd-dnssd-+- gdbus 
                                 - gmain 
                   -gvfsd-fuse-+- gdbus 
                                - gmain 
                                - gvfs-fuse-sub 
                                -2*[ gvfsd-fuse ]
                   -gvfsd-metadata-+- gdbus 
                                    - gmain 
                   -gvfsd-network-+- dconf worker 
                                   - gdbus 
                                   - gmain 
                   -gvfsd-trash-+- gdbus 
                                 - gmain 
                   -mission-control-+- dconf worker 
                                     - gdbus 
                                     - gmain 
                   -nautilus-+-gedit
                              - dconf worker 
                              - gdbus 
                              - gmain 
                   -tracker-store-+- dconf worker 
                                   - gdbus 
                                   - gmain 
                                   -4*[ pool ]
         -systemd-journal
         -systemd-logind
         -systemd-network
         -systemd-timesyn--- sd-resolve 
         -systemd-udevd
         -thermald--- thermald 
         -tor
         -udisksd-+- cleanup 
                   - gdbus 
                   - gmain 
                   - probing-thread 
         -upowerd-+- gdbus 
                   - gmain 
         -wpa_supplicant
So I used the standard power measurement tool, powertop. Below is a screenshot of PowerTop claiming 9 - 10 hours of possible battery backup. This is idle state. "Idle" would mean when the user is not interacting with the machine. When under basic usage (email, web), the actual battery backup I've sensed is somewhere around 6-7 hrs, which is still good from what we got a couple years ago. There's one oddity in the screenshot though. The estimated power consumption reported is 4.55W, where as, the power consumption of just the wifi card is reported 6.17W. That too, when the wifi was disconnected. This reminded me of the bug report against PowerTop, which is now more than 2 years old. We've still not concluded in that bug report, so if anyone can shed some light on PowerTop's reporting, please do share it in the bug report. Note: Please ignore the terminal's title in the screenshot. That is wrong and I've not bothered to figure out why it is displaying the title name constructed from an outdated session, which is already terminated.

Categories:

Keywords:

Like:

Enrico Zini: Static site generators

I decided to rethink the state of my personal site, and try out some of the new static site generators that are available now. To do that, I jotted down a series of things that I want in a static site generator, then wrote a tool to convert my ikiwiki site to other formats, and set out to evaluate things. As a benchmark I did a full rebuild of my site, which currently contains 1164 static files and 458 markdown pages. My requirements Free layout for my site My / is mostly a high-level index to the site contents. Blog posts are at /blog. My talk archive is organised like a separate blog at /talks. I want the freedom to create other sections of the site, each with its own rss feed, located wherever I want in the site hierarchy. Assets next to posts I occasionally blog just a photo with a little comment, and I would like the .md page with the comment to live next to the image in the file system. I did not even know that I had this as a requirement until I found static site generators that mandated a completely different directory structure for markdown contents and for static assets. Multiple RSS/Atom feeds I want at least one RSS/Atom feed per tag, because I use tags for marking which articles go to http://planet.debian.org. I also want RSS/Atom feeds for specific parts of the site, like the blog and talks. Arbitrary contents in /index.html I want total control over the contents of the main home page of the site. Quick preview while editing contents I do not like to wait several seconds for the site to be rebuilt at every review iteration of the pages I write. This makes me feel like the task of editing is harder than it should, and makes me lose motivation to post. Reasonable time for a full site rebuild I want to be able to run a full rebuild of the site in a reasonable time. I could define "reasonable" in this case as how long I can stare at the screen without getting bored, starting to do something else, and forgetting what it was that I was doing with the site. It is ok if a rebuild takes something like 10 or 30 seconds. It is not ok if it takes minutes. Code and dependency ecosystems that I can work with I can deal with Python and Go. I cannot deal with Ruby or JavaScript. I forgot all about Perl. Also, if it isn't in Debian it does not exist. Decent themes out of the box One of my hopes in switching to a more mainstream generator is to pick and choose themes and easily give my site a more modern look. Hugo Hugo is written in Go and is in Debian testing. Full rebuild time for my site is acceptable, and it can even parallelize:
  $ time hugo
  real      0m5.285s
  user      0m9.556s
  sys       0m1.052s
Free layout for my site was hard to get. I could replace /index.html by editing the template page for it, but then I did not find out how to create another similar index in an arbitrary place. Also, archetypes are applied only on the first path component of new posts, but I would like them instead to be matched on the last path component first, and failing that traveling up to the path until the top. This should be easy to fix by reorganizing the content a bit around here For example, a path for a new blog post of mine could be blog/2016/debian/ and I would like it to match the debian archetype first, and failing that the blog archetype. Assets next to posts almost work. Hugo automatically generates one feed per taxonomy element, and one feed per section. This would be currently sufficient for me, although I don't like the idea that sections map 1 to 1 to toplevel directories in the site structure. Hugo has a server that watches the file system and rerenders pages as they are modified, so the quick preview while editing works fine. About themes, it took me several tries to find a theme that would render navigation elements for both sections and tags, and most themes would render by pages with white components all around, and expect me to somehow dig in and tweak them. That frustrated me, because for quite a while I could not tell if I had misconfigured Hugo's taxonomies or if the theme was just somehow incomplete. Nikola Nikola is written in Python and is in Debian testing. Full rebuild time for my site is almost two orders of magnitude more than Hugo, and I am miffed to find the phrases "Nikola is fast." or "Fast building process" in its front page and package description:
  $ time nikola build
  real      3m31.667s
  user      3m4.016s
  sys       0m24.684s
Free layout could be achieved fiddling with the site configuration to tell it where to read sources. Assets next to post work after tweaking the configuration, but they require to write inconsistent links in the markdown source: https://github.com/getnikola/nikola/issues/2266 I have a hard time accepting that that, because I want to author content with consistent semantic interlinking, because I want to be able 10 years from now to parse it and convert it to something else if a new technology comes out. Nikola generates one RSS/Atom feed per tag just fine. I have not tried generating feeds for different sections of the site. Incremental generation inside its built in server works fine. Pelican Pelican is written in Python and is in Debian testing. Full rebuild time for my site is acceptable:
  $ time pelican -d
  real      0m18.207s
  user      0m16.680s
  sys       0m1.448s
By default, pelican seems to put generate a single flat directory of html files regardless of the directory hierarchy of the sources. To have free layout, pelican needs some convincing in the configuration:
  PATH_METADATA = r"(?P<relpath>.+)\.md"
  ARTICLE_SAVE_AS = " relpath /index.html"
but even if I do that, the urls that it generates still point to just slug /index.html and I have not trivially found a configuration option to fix that accordingly. I got quite uncomfortable at the idea of needing to configure content generation and linking to match, instead of having one automatically being in sync with the other. Having assets next to posts seems to be possible (also setting STATIC_PATHS = ["."]), but I do not recall making progress on this front. I did not manage to generate a feed for each tag out of the box, and probably there is some knob in the configuration for it. I gave up with Pelican as trying it out felt like a constant process of hacking the configuration from defaults that do not make any sense for me, withouth even knowing if a configuration exists that would do what I need Ikiwiki Ikiwiki is written in Perl and is in Debian. Although I am not anymore proficient with Perl, I was already using it, so it was worth considering. Full rebuild time feels a bit on the slow side but is still acceptable:
  $ time ikiwiki --setup site.setup
  real      0m37.356s
  user      0m34.488s
  sys       0m1.536s
In terms of free site structure, all feeds for all or part of the site, ikiwiki just excels. I even considered writing a python web server that monitors the file system and calls ikiwiki --refresh when anything changes, and calling it a day. However, when I tried to re-theme my website around a simple bootstrap boilerplate, I found that to be hard, as a some of the HTML structure is hardcoded in Perl (and it's also my fault) and there is only so much that can be done by tweaking the (rather unreadable) templates. siterefactor During all these experiments I had built siterefactor to generate contents for all those static site engines, and it was going through all the contents quite fast:
  $ time ./siterefactor src dst -t hugo
  real  0m1.222s
  user  0m0.904s
  sys   0m0.308s
So I wondered how slow it would become if, instead of making it write markdown, I made it write HTML via python markdown and Jinja2:
  $ time ./siterefactor ~/zz/ikiwiki/pub/ ~/zz/ikiwiki/web -t web
  real  0m6.739s
  user  0m5.952s
  sys   0m0.416s
I then started wondering how slower it would become if I implemented postprocessing of all local URLs generated by Markdown to make sure they are kept consistent even if the path of a generated page is different than the path of its source. Not much slower, really. I then added taxonomies. And arbitrary Jinja2 templates in the input, able to generate page lists and RSS/Atom feeds. And theming. And realised that reading all the sources and cross-linking them took 0.2 seconds, and the rest was generation time. And that after cross-linking, each page can be generated independently from all the others. staticsite So my site is now generated with staticsite:
  $ time ssite build
  real  0m6.833s
  user  0m5.804s
  sys   0m0.500s
It's comparable with Hugo, and on a single process.

Russ Allbery: Review: The Lost Steersman

Review: The Lost Steersman, by Rosemary Kirstein
Series: Steerswomen #3
Publisher: Rosemary Kirstein
Copyright: 2003, 2014
Printing: 2014
ISBN: 0-9913546-2-1
Format: Kindle
Pages: 432
This is the third book in the Steerswomen series and a direct follow-up to the events of The Outskirter's Secret. It does, marvel of marvels, feature an in-character summary of the events of the series to date! I do love when authors do this; it helps immensely if you come back to a series after a bit of a break between books. But this whole series is so good, and the emotional tone and development of Rowan as a character is so strong, that I recommend against starting here. After the events of the last book, Rowan has returned to the Inner Lands. She's sent her report back to the Archives, but stopped at the Annex in Alemeth. This is an auxiliary library that should have copies of the journals and other research that Rowan wants to search, and stopping there saves substantial travel time. However, she finds the steerswoman who was custodian of the Annex is deceased and the Annex is, from Rowan's perspective, a mess. Nothing is organized, the books aren't properly cared-for, and Mira's interactions with the townsfolk were far different than Rowan's natural attitude. The start of this book was a surprising shift. After the large-scale revelations at the end of The Outskirter's Secret, and the sense of escalating danger, Rowan's return to small-town life in the Inner Lands comes as a shock. That's true for both the reader and for Rowan, and the parallels make it a remarkably effective bit of writing. At the beginning of the story, the reader is already familiar with Rowan (at least if you've read the previous books) and how she thinks of being a steerswoman. Rowan is very much on edge and in a hurry given what's going on in the broader world. But the town is used to Mira: a gregarious socializer who cared far more about town gossip and her role as coordinator of it than she cared about most of her steerswoman duties. (At least as seen from Rowan's perspective. By the end of the book, we have a few hints that something else might be going on, but the damage to the books at least feels unforgivable.) Rowan is resented and even disliked at first, particularly by Steffie and Gwen who did most of the chores at the Annex and were closest to Mira. One of the reasons why I love this series so much is that Kirstein has a gift for characterization. Rowan (and Bel, who largely doesn't appear in this book) are brilliant characters, but it's not just them. At the start of this book, the reader tends to share Rowan's opinion of the town: a sort of half-bemused, half-exasperated indifference. Even as the characters start to grow on one, it seems like a backwater and a diversion from the larger story. But it becomes clear that Rowan is very on-edge from her experience in the Outskirts, that she's underestimated the relevance of Mira to at least the town's happiness, and she's greatly underestimated the ability of the townsfolk to help her. Steffie, in particular, is a wonderful character; by the end of the book, he had become one of my favorite people in the series so far. He doesn't think he's particularly smart, and his life before Rowan is very simple, but there are depths to him that no one, including him, expected. There is a plot here, apart from small town politics and Rowan's slow relaxation. (Although those were so compelling that I'm not sure I would have minded if that were the entire book.) The lost steersman of the title is an old student friend of Rowan that she unexpectedly meets in town, a former steersman who quit the order and refused to explain why. Rowan, of course, cannot resist trying to fix this situation. The second plot driver is a dangerous invasion of Outskirts monsters into the town. Those who have read the previous books will have some immediate guesses as to why this might be, and Rowan does as well. But there's more going on than it might first appear. This book is not entirely a diversion. It returns to the main plot of the series by the end of the book, and we learn much more about Rowan's world. But, somewhat surprisingly, that was my least favorite part of the book. It has some nice bits of exploration and puzzle-solving, and Rowan is always a delight to spend time with. But the last section of the book is similar to many other genre books I've read before well-written, to be sure, but not as unique. It also features a rather long section following a character who is severely physically ill, which is something I always find very hard to read (a personal quirk). But there's a lot of meat here for the broader plot, and I have no idea what will happen in the next book. The part of The Lost Steersman that I'm going to remember, though, are the town bits, up through the arrival of Zenna (another delightful character who adds even more variety to Kirstein's presentation of steerswomen). Kirstein is remarkably good at mixing small-town characters with the scientific investigation of the steerswomen and letting them bounce off of each other to reveal more about the character of both. If it weren't for the end of the book, which bothered me for partly idiosyncratic reasons, I think this would have been my favorite book of the series. Followed by The Language of Power, and be warned that this book ends on something close to a cliffhanger. Rating: 8 out of 10

Stein Magnus Jodal: February contributions

The following is a short summary of my open source work in February, just like in previous months.

Debian

Mopidy
  • Released Mopidy-Spotify 2.3.1: Works around search being broken in libspotify by using the Spotify Web API for the search functionality, and nothing else.
  • Wrapped up and released Mopidy 2.0 release. This was a quite large release that ports to GStreamer 1.x and adds support for gapless playback. It was uploaded to Debian in time to be part of Ubuntu 16.04 LTS.
  • Released Mopidy-Spotify 3.0.0: A couple of small compatibility fixes to work with Mopidy 2.x and GStreamer 1.x.
  • Updates to packages not in Debian, only at apt.mopidy.com:
    • Uploaded mopidy-spotify-tunigo 1.0.0-0mopidy1. Far down the chain, it depends on libspotify, which is not in Debian.
    • Uploaded mopidy-spotify 2.0.0-0mopidy1.
  • Updated homebrew-mopidy with lots of new releases:
    • Mopidy 2.0.0
    • Mopidy-Dirble 1.3.0
    • Mopidy-SoundCloud 2.0.2
    • Mopidy-Spotify 2.3.0, 2.3.1 and 3.0.0
    • python-backports-abc 0.4
    • python-backports-ssl-match-hostname 3.5.0.1
    • python-certifi 2015.11.20.1
    • python-cffi 1.5.0 and 1.5.2
    • python-requests 2.9.1
    • python-singledispatch 3.4.0.3
    • python-six 1.10.0
    • python-tornado 4.3
  • Rebased my feature/py3-compat branch on top of Mopidy 2.0.
  • Planned breaking changes for Mopidy 3.0: unbundling of Mopidy.js, removal of deprecated core APIs, model APIs, audio APIs and removal of the http/static_dir config.
  • Planned breaking changes to modernize Mopidy.js: change default calling convention to by-position-or-by-name, replace When.js with ES6 Promise, replace Bane.js with EventEmitter, and replace Buster.js with Karma+Mocha.

Comics
  • Started working on the upgrade to Django 1.8. Most deps are upgraded. The major remaining pieces is to upgrade django-registration from 0.8 to 2.0 and to replace the years-old vendored copy of django-invitation (singular) with django-invitations (plural).

29 February 2016

Chris Lamb: Free software activities in February 2016

Here is my monthly update covering a large part of what I have been doing in the free software world (previously):
Debian
  • Updated travis.debian.net a hosted script to easily test and build Debian packages on the Travis CI continuous integration platform to support:
    • Automatic bumping of the version number in debian/changelog based on TRAVIS_BUILD_NUMBER. (#14)
    • Security repositories. Thanks to Stefan Jenkner for the initial pull request. These are additionally now enabled by default. (#15)
    • The backports repositories. (#13)
  • Applied #812830 and #812830 from James Clark to the Debian Archive Kit to improve the interface of various webpages it generates.
  • Updated the SSL certificate for try.diffoscope.org, a hosted version of the diffoscope in-depth and content-aware diff utility. Thanks to Bytemark for sponsoring the hardware.
  • Worked on my slides for Reproducible Builds - fulfilling the original promise of free software, to be presented at FOSSASIA '16.
My work in the Reproducible Builds project was also covered in more depth in Lunar's weekly reports (#40, #41, #42, #43)
LTS

This month I have been paid to work 18 hours on Debian Long Term Support (LTS). In that time I did the following:
  • "Frontdesk" duty for the week of 22nd 28th, triaging CVEs, etc.
  • Proofread announcements, etc. for the upcoming migration to wheezy-lts.
  • Issued DLA 417-1 for xdelta3 to fix a buffer overflow that allowed arbitrary code execution from input files.
  • Issued DLA 420-1 for libmatroska, correcting a heap information leak.
  • Issued DLA 428-1 for websvn fixing a cross-site scripting vulnerability.
  • Issued DLA 429-1 for pixman fixing a buffer overflow issue.
  • Issued DLA 430-1 & DLA 431-1 for libfcgi and libfcgi-perl respectfully, fixing a remote denial-of-service (DoS) vulnerability.

Uploads
  • redis (2:3.0.7-2) Correcting my SOURCE_DATE_EPOCH reproducibility patch as the conditional was accidentally inverted. Thanks to Reiner Herrmann (deki).
  • disque (1.0~rc1-5) Making the parallel SOURCE_DATE_EPOCH patch change and additionally tidying the packaging after introducing procps as a build-dependency.


RC bugs


I also filed 137 FTBFS bugs against aac-tactics, angular.js, astyle, bcftools, blacs-mpi, bogofilter, boxes, caldav-tester, ccdproc, ckeditor, coq-float, cqrlog, dasher, django-recurrence, dspdfviewer, eclipse-egit, ess, etcd, felix-latin, fio, flexml, funny-manpages, gap-atlasrep, garmin-plugin, gitlab, gnome-mines, graphicsmagick, haskell-nettle, healpy, hg-git, hunspell, hwloc, ijs, ipset, janest-core-extended, jpathwatch, kcompletion, kcompletion, keyrings.alt, kodi-pvr-hts, kodi-pvr-vdr-vnsi, libcommons-compress-java, libgnome2-wnck-perl, libkate, liblrdf, libm4ri, libnet-server-mail-perl, libsis-jhdf5-java, libspectre, libteam, libwnck, libwnckmm, libxkbcommon, lombok, lombok-patcher, mako, maven-dependency-analyzer, mopidy-mpris, mricron, multcomp, netty-3.9, numexpr, ocaml-textutils, openimageio, openttd-openmsx, osmcoastline, osmium-tool, php-guzzle, php-net-smartirc, plexus-component-metadata, polari, profitbricks-client, pyentropy, pynn, pyorbital, pypuppetdb, python-aioeventlet, python-certifi, python-hglib, python-kdcproxy, python-matplotlib-venn, python-mne, python-mpop, python-multipletau, python-pbh5tools, python-positional, python-pydot-ng, python-pysam, python-snuggs, python-tasklib, r-cran-arm, r-cran-httpuv, r-cran-tm, rjava, ros-geometry-experimental, ros-image-common, ros-pluginlib, ros-ros-comm, rows, rr, ruby-albino, ruby-awesome-print, ruby-default-value-for, ruby-fast-gettext, ruby-github-linguist, ruby-gruff, ruby-hipchat, ruby-omniauth-crowd, ruby-packetfu, ruby-termios, ruby-thinking-sphinx, ruby-tinder, ruby-versionomy, ruby-zentest, sbsigntool, scikit-learn, scolasync, sdl-image1.2, signon-ui, sisu-guice, sofa-framework, spykeutils, ssreflect, sunpy, tomcat-maven-plugin, topmenu-gtk, trocla, trocla, tzdata, verbiste, wcsaxes, whitedune, wikidiff2, wmaker, xmlbeans, xserver-xorg-input-aiptek & zeroc-icee-java.

FTP Team

As a Debian FTP assistant I ACCEPTed 107 packages: androguard, android-platform-dalvik, android-platform-development, android-platform-frameworks-base, android-platform-frameworks-native, android-platform-libnativehelper, android-platform-system-core, android-platform-system-extras, android-platform-tools-base, android-sdk-meta, apktool, armci-mpi, assertj-core, bart, bind9, caja, caldav-tester, clamav, class.js, diamond, diffoscope, django-webpack-loader, djangocms-admin-style, dnsvi, esptool, fuel-astute, gcc-6-cross, gcc-6-cross-ports, gdal, giella-core, gnupg, golang-github-go-ini-ini, golang-github-tarm-serial, gplaycli, gradle-jflex-plugin, haskell-mountpoints, haskell-simple, hurd, iceweasel, insubstantial, intellij-annotations, jetty9, juce, keyrings.alt, leptonlib, libclamunrar, libdate-pregnancy-perl, libgpg-error, libhtml5parser-java, libica, libvoikko, linux, llvm-toolchain-3.8, lombok-patcher, mate-dock-applet, mate-polkit, mono-reference-assemblies, mxt-app, node-abab, node-array-equal, node-array-flatten, node-array-unique, node-bufferjs, node-cors, node-deep-extend, node-original, node-setimmediate, node-simplesmtp, node-uglify-save-license, node-unpipe, oar, openjdk-8, openjdk-9, pg8000, phantomjs, php-defaults, php-random-compat, php-symfony-polyfill, pnetcdf, postgresql-debversion, pulseaudio-dlna, pyconfigure, pyomo, pysatellites, python-fuelclient, python-m3u8, python-pbh5tools, python-qtpy, python-shellescape, python-tunigo, pyutilib, qhull, r-cran-rjsonio, r-cran-tm, reapr, ruby-fog-dynect, scummvm-tools, symfony, talloc, tesseract, twextpy, unattended-upgrades, uwsgi, vim-command-t, win-iconv, xkcdpass & xserver-xorg-video-ast. I additionally REJECTed 4 packages.

Scott Kitterman: Debian LTS Work February 2016

This was my tenth month as a Freexian sponsored LTS contributor. I was assigned 8 hours for the month of February. As I did last month, I worked on updating clamav in wheezy and squeeze-lts. As with previous updates to clamav, we updated it to the new upstream version[1]. As an added complexity, this version bumped soname, so it s now libclamav7 instead of libclamav6. This bump necessitated a small transition in jessie/wheezy-proposed-updates and squeeze-lts. The update for Jessie (included for completeness here) was done early in the month by other pkg-clamav team members. It and the rebuilt/update libclamav reverse-depends will be included in the next Jessie point release. For wheezy, I uploaded libclamunrar (which bumped soname as well) and worked with other pkg-clamav team members on getting clamav to build on sparc and preparing a fix for c-icap. It and the rebuilt/update libclamav reverse-depends will be included in the next Wheezy point release. As a result of the amount of time it took, the squeeze-lts update landed later than I hoped it would, but it is there. As documented in DLA 437-1, there are new packages for clamav, libclamunrar, python-clamav, and klamav. The last squeeze libclamav reverse-depend, dansguardian, took more work, but it too is updated, see DLA 440-1.
[1] The primary reason for this is that anti-virus is an arms race. Unlike other types of packages being stable with only fixes for severe bugs and security issues does not result in a stable capability. It will regress over time. In order to keep up, the new version is needed.

Daniel Silverstone: Kicad hacking - Intra-sheet links and ERC

This is a bit of an odd posting since it's about something I've done but is also here to help me explain why I did it and thus perhaps encourage some discussion around the topic within the Kicad community...
Recently (as you will know if you follow this blog anywhere it is syndicated) I have started playing with Kicad for the development of some hardware projects I've had a desire for. In addition, some of you may be aware that I used to work for a hardware/software consultancy called Simtec, and there I got to play for a while with an EDA tool called Mentor Designview. Mentor was an expensive, slow, clunky, old-school EDA tool, but I grew to understand and like the workflow. I spent time looking at gEDA and Eagle when I wanted to get back into hardware hacking for my own ends; but neither did I really click with. On the other hand, a mere 10 minutes with Kicad and I knew I had found the tool I wanted to work with long-term. I designed the beer'o'meter project (a flow meter for the pub we are somehow intimately involved with) and then started on my first personal surface-mount project -- SamDAC which is a DAC designed to work with our HiFi in our study at home. As I worked on the SamDAC project, I realised that I was missing a very particular thing from Mentor, something which I had low-level been annoyed by while looking at other EDA tools -- Kicad lacks a mechanism to mark a wire as being linked to somewhere else on the same sheet. Almost all of the EDA tools I've looked at seem to lack this nicety, and honestly I miss it greatly, so I figured it was time to see if I could successfully hack on Kicad. Kicad is written in C++, and it has been mumble mumble years since I last did any C++, either for personal hacking or professionally, so it took a little while for that part of my brain to kick back in enough for me to grok the codebase. Kicad is not a small project, taking around ten minutes to build on my not-inconsiderable computer. And while it beavered away building, I spent time looking around the source code, particularly the schematic editor eeschema. To skip ahead a bit, after a couple of days of hacking around, I had a proof-of-concept for the intra-sheet links which I had been missing from my days with Mentor, and some ERC (electrical rules checking) to go alongside that to help produce schematics without unwanted "sharp corners". In total, I added: I forked the Kicad mirror on Github and pushed my own branch with this work to my Kicad fork. All of this is meant to allow schematic capture engineers to more clearly state their intentions regarding what they are drawing. The intra-sheet link could be thought of like a no-connect element, except instead of saying "this explicitly goes nowhere" we're saying "this explicitly goes somewhere else on this sheet, you can go look for it". Obviously, people who dislike (or simply don't want to use) such intra-sheet link elements can just disable that ERC tickybox and not be bothered by them in the least (well except for the toolbar button and menu item I suppose). Whether this work gets accepted into Kicad, or festers and dies on the vine, it was good fun developing it and I'd like to illustrate how it could help you, and why I wrote it in the first place:

A contrived story
Note, while this story is meant to be taken seriously, it is somewhat contrived, the examples are likely electrical madness, but please just think about the purpose of the checks etc.
To help to illustrate the feature and why it exists, I'd like to tell you a somewhat contrived story about Fred. Fred is a schematic capture engineer and his main job is to review schematics generated by his colleagues. Fred and his colleagues work with Kicad (hurrah) but of late they've been having a few issues with being able to cleanly review schematics. Fred's colleagues are not the neatest of engineers. In particular they tend to be quite lazy when it comes to running busses, which are not (for example) address and data busses, around their designs and they tend to simply have wires which end in mid-space and pick up somewhere else on the sheet. All this is perfectly reasonable of course, and Kicad handles it with aplomb. Sadly it seems quite error prone for Fred's workplace. As an example, Fred's colleague Ben has been designing the power supply for a particular board. As with most power supplies, plenty of capacitors are needed to stabilise the regulators and smooth the output. In the example below, the intent is that all of the capacitors are on the FOO net. Contrived problem example 1 Sadly there's a missing junction and/or slightly misplaced label in the upper section which means that C2 and C3 simply don't join to the FOO net. This could easily be missed, but the ERC can't spot it at all since there's more than one thing on each net, so the pins of the capacitors are connected to something. Fred is very sad that this kind of problem can sometimes escape notice by the schematic designer Ben, Fred himself, and the layout engineer, resulting in boards which simply do not work. Fred takes it upon himself to request that the strict wiring checks ERC is made mandatory for all designs, and that the design engineers be required to use intra-sheet link symbols when they have signals which wander off to other parts of the sheet like FOO does in the example. Without any further schematic changes, strict wiring checks enabled gives the following points of ERC concern for Ben to think about: Contrived problem example 2 As you can see, the ERC is pointing at the wire ends and the warnings are simply that the wires are dangling and that this is not acceptable. This warning is very like the pin-not-connected warnings which can be silenced with an explicit no-connect schematic element. Ben, being a well behaved and gentle soul, obeys the design edicts from Fred and seeks out the intra-sheet link symbols, clearing off the ERC markers and then adding intra-sheet links to his design: Contrived problem example 3 This silences the dangling end ERC check, which is good, however it results in another ERC warning: Contrived problem example 4 This time, the warning for Ben to deal with is that the intra-sheet links are pointless. Each exists without a companion to link to because of the net name hiccough in the top section. It takes Ben a moment to realise that the mistake which has been made is that a junction is missing in the top section. He adds the junction and bingo the ERC is clean once more: Contrived problem example 5 Now, this might not seem like much gain for so much effort, but Ben can now be more confident that the FOO net is properly linked across his design and Fred can know, when he looks at the top part of the design, that Ben intended for the FOO net to go somewhere else on the sheet and he can look for it.

Why do this at all? Okay, dropping out of our story now, let's discuss why these ERC checks are worthwhile and why the intra-sheet link schematic element is needed.
Note: This bit is here to remind me of why I did the work, and to hopefully explain a little more about why I think it's worth adding to Kicad...
Designers are (one assumes) human beings. As humans we (and I count myself here too) are prone to mistakes. Sadly mistakes are often subtle and could easily be thought of as deliberate if the right thought processes are not followed carefully when reviewing. Anyone who has ever done code review, proofread a document, or performed any such activity, will be quite familiar with the problems which can be introduced by a syntactically and semantically valid construct which simply turns out to be wrong in the greater context. When drawing designs, I often end up with bits of wire sticking out of schematic sections which are not yet complete. Sadly if I sleep between design sessions, I often lose track of whether such a dangling wire is meant to be attached to more stuff, or is simply left because the net is picked up elsewhere on the sheet. With intra-sheet link elements available, if I had intended the latter, I'd have just dropped such an element on the end of the wire before I stopped for the day. Also, when drawing designs, I sometimes forget to label a wire, especially if it has just passed through a filter or current-limiting resistor or similar. As such, even with intra-sheet link elements to show me when I mean for a net to go bimbling off across the sheet, I can sometimes end up with unnamed nets whose capacitors end up not used for anything useful. This is where the ERC comes in. By having the ERC complain if a wire dangles -- the design engineer won't forget to add links (or check more explicitly if the wire is meant to be attached to something else). By having junctions which don't actually link anything warned about, the engineer can't just slap a junction blob down on the end of a wire to silence that warning, since that doesn't mean anything to a reviewer later down the line. By having the ERC warn if a net has exactly one intra-sheet link attached to it, missing net names and errors such as that shown in my contrived example above can be spotted and corrected. Ultimately this entire piece of work is about ensuring that the intent of the design engineer is captured clearly in the schematic. If the design engineer meant to leave that wire dangling because it's joining to another bit of wire elsewhere on the sheet, they can put the intra-sheet links in to show this. The associated ERC checks are there purely to ensure that the validation of this intent is not bypassed accidentally, or deliberately, in order to make the use of this more worthwhile and to increase the usefulness of the ERC on designs where signals jump around on sheets where wiring them up directly would just create a mess.

Dirk Eddelbuettel: New CRAN package gunsales

This is based on joint work with Gregor Aisch and Josh Keller of the New York Times. A new package gunsales is now on the CRAN network for R. It is based the NYTimes/gunsales repository underlying the excellent New York Times visualizations, first published first in December 2015 and updated with more recent data since. The analysis takes public government data on gun sales from the National Instant Criminal Background Check System (NICS). The original data is scraped from the pdf, included in the package, and analysed in a cross-section and time-series manner. The standard US Census tool X-13ARIMA-SEATS is used to deseasonalize the timeseries at the national or state level. (Note that Buzzfeed also published data and (Python) code in another GitHub repo.) As an aside, it was the use of X-13ARIMA-SEATS here -- and its somewhat awkward and manual installation also seen in the initial versions of the code in the NYTimes/gunsales repo -- which lead to the recent work by Christoph Sax and myself. We now provide a new package x13binary on CRAN so that Christoph's excellent seasonal package can simply depend upon it and have a working binary provided and installed ready to use; see the recent blog post for more. The net result is that a package like this new gunsales project can simply depend upon seasonal and also be assurred that x13binary "just works". As Martha would say, "A Good Thing". Back to the gunsales project. Following the initial publication of the repository with the data and R code in a simple script, I felt compelled to reorganize it as a package. Packages for R, as we teach our students, colleagues, or anybody else who wants to listen are really the best way to bundle code, data, documentation (i.e. vignettes) and tests. All that exists now in the gunsales package. The package now has one main function, analysis(), which returns a single dataframe object. This dataframe object can then be fed to two plotting functions. The first, plot_gunsales(), will then recreate all the (base R) plots from the original code base. The second, ggplot_gunsales(), does the same but via ggplot2. This should give anybody the ability to look at the data, study the transformations done, form and maybe test new hypotheses and visualize in manner comparable to the original publication. As an amuse gueule, here are the key plots also shown in the main README.md at GitHub: Total Estimated Gun Sales Total Estimated Gun Sales, Seasonally Adjusted Total Estimated Gun Sales, Population-Growth Adjusted Handguns vs Longguns Six States DC We look forward to more remixes and analysis of this data. The plan of the GitHub repository is to keep the data set updated as new data points are published.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.

25 February 2016

Matthew Garrett: I bought some awful light bulbs so you don't have to

I maintain an application for bridging various non-Hue lighting systems to something that looks enough like a Hue that an Amazon Echo will still control them. One thing I hadn't really worked on was colour support, so I picked up some cheap bulbs and a bridge. The kit is badged as an iSuper iRainbow001, and it's terrible.

Things seemed promising enough at first, although the bulbs were alarmingly heavy (there's a significant chunk of heatsink built into them, which seems to get a lot warmer than I'd expect from something that claims a 7W power consumption). The app was a bit clunky, but eh - I wasn't planning on using it for long. I pressed the button on the bridge, launched the app and could control the bulbs. The first thing I noticed was that they had a separate "white" and "colour" mode. White mode was pretty bright, but colour mode massively less so - presumably the white LEDs are entirely independent of the RGB ones, and much higher intensity. Still, potentially useful as mood lighting.

Anyway. Next step was to start playing with the protocol, which meant finding the device on my network. I checked anything that had picked up a DHCP lease recently and nmapped them. The OS detection reported Linux, which wasn't hugely surprising - there was no GPL notice or source code included with the box, but I'm way past the point of shock at that. It also reported that there was a telnet daemon running. I connected and got a login prompt. And then I typed admin as the username and admin as the password and got a root prompt. So, there's that. The copy of Busybox included even came with tftp, so it was easy to get copies of tcpdump and strace on there to see what was up.

So. Next step. Protocol sniffing. I wanted to know how discovery worked, so reset the device to factory and watched what happens. The app on my phone sent out a discovery packet on UDP port 18602 which looked like this:

INLAN:CLIP:23.21.212.48:CLPT:22345:MAC:02:00:00:00:00:00

The CLIP and CLPT fields refer to the cloud server that allows for management when you're not on the local network. The mac field contains an utterly fake address. If you send out a discovery packet and your mac hasn't been registered with the device, you get a denial back. If your mac has been (and by "mac" here I mean "utterly fake mac that's the same for all devices"), you get back a response including the device serial number and IP address. And if you just leave out the mac field entirely, you get back a response no matter whether your address is registered or not. So, that's a start. Once you've registered one copy of the app with the device, anything can communicate with it by just using the same fake mac in the discovery packets.

Onwards. The command format turns out to be simple. They start ##, are followed by two ascii digits encoding a command, four ascii digits containing a bulb id, two ascii digits containing the number of following bytes and then the command data (in ascii). An example is:

##05010002ff

which decodes as command 5 (set white intensity) on bulb 1 with two bytes of data following, each of which is an f. This translates as "Set bulb 1 to full white intensity". I worked out the rest pretty quickly - command 03 sets the RGB colour of the bulb, 0A asks the bridge to search for new bulbs, 0B tells you which bulbs are available and their capabilities and 0E gives you the MAC addresses of the bulbs( ). 0C crashes the server process, and 06 spews a bunch of garbage back at you and potentially crashes the bulb in a hilarious way that involves it flickering at about 15Hz. It turns out that 06 is actually the "Rename bulb" command, and if you send it less data than it's expecting something goes hilariously wrong in string parsing and everything is awful.

Ok. Easy enough, but not hugely exciting. What about the remote protocol? This turns out to involve sending a login packet and then a wrapped command packet. The login has some length data, a header of "MQIsdp", a long bunch of ascii-encoded hex, a username and a password.

The username is w13733 and the password is gbigbi01. These are hardcoded in the app. The ascii-encoded hex can be replaced with 0s and the login succeeds anyway.

Ok. What about the wrapping on the command? The login never indicated which device we wanted to talk to, so presumably there's some sort of protection going on here oh wait. The command packet is a length, the serial number of the bridge and then a normal command packet. As long as you know the serial number of the device (which it tells you in response to a discovery packet, even if you're unauthenticated), you can use the cloud service to send arbitrary commands to the device (including the one that crashes the service). One of which involves the device then doing some kind of string parsing that doesn't appear to work that well. What could possibly go wrong?

Ok, so that seemed to be the entirety of the network protocol. Anything else to do? Some poking around on the bridge revealed (a) that it had an active wireless device and (b) a running DHCP server. They wouldn't, would they?

Yes. Yes, they would.

The devices all have a hardcoded SSID of "iRainbow", although they don't broadcast it. There's no security - anybody can associate. It'll then hand out an IP address. It's running telnetd on that interface as well. You can bounce through there to the owner's internal network.

So, in summary: it's a device that infringes my copyright, gives you root access in response to trivial credentials, has access control that depends entirely on nobody ever looking at the packets, is sufficiently poorly implemented that you can crash both it and the bulbs, has a cloud access protocol that has no security whatsoever and also acts as an easy mechanism for people to circumvent your network security. This may be the single worst device I've ever bought.

I called the manufacturer and they insisted that the device was designed in 2012, was no longer manufactured or supported, that they had no source code to give me and there would be no security fixes. The vendor wants me to pay for shipping back to them and reserves the right to deduct the cost of the original "free" shipping from the refund. Everything is awful, which is why I just ordered four more random bulbs to play with over the weekend.

comment count unavailable comments

24 February 2016

Dirk Eddelbuettel: RcppEigen 0.3.2.8.0

Another minor release of RcppEigen is on CRAN and getting into Debian. The main focus is an upgrade to the recent 3.2.7 release of Eigen which should address another UBSAN issue. And once again Yixuan Qiu did all the heavy lifting. The NEWS file entry follows.
Changes in RcppEigen version 0.3.2.8.0 (2016-02-23)
  • Updated to version 3.2.8 of Eigen (PR #29 by Yixuan)
Courtesy of CRANberries, there is also a diffstat report for the most recent release.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.

23 February 2016

Alessio Treglia: Analog thinking: the boldness to be creative

The binary code, although necessary for major social and technological developments, is annihilating the Homo Technologicus, stifling his innate freedom for analog connections.

Rodin1The first widespread use of the binary code was the Morse code alphabet. For decades, this communication system allowed to transmit information over long distances, between ships in the ocean and the mainland, between one continent and another, and today its use is still active in emergency situations. In its disarming simplicity (connect or interrupt two electrical wires), this system proved to be the shortest way to transcribe an alphabet.

Then, the Boolean algebra (binary) represented the language of communication between humans and computers, enabling the translation of instructions and commands towards the processing unit (microprocessor / CPU). This determined the Big Bang of the computers and the technological era

<Read More...>

22 February 2016

Norbert Preining: The Good, the Bad, and the Ugly refugees acceptance

Coming from a country that has taken lots of refugees, especially in the years after the second world war (although not any more), and while living in Japan still feeling connected to Europe and what is going on there, the current situation of refugees from the near east gives lots of material to think about. One of these things recently was passed around on various SNS sites. It is about the number of refugees a country can accept . refugees The situation is difficult, and after an initial wave of empathy it seems that especially governments are retracting and trying to stop the influx of refugees:
We cannot accommodate any more refugees in Europe, that s not possible.
Manuel Valls, Prime Minister of France
I am well aware about the difficult situation in Europe, and consider the dealing with the refugee crisis the biggest challenge of these decade. In this blog, without many words, I only want to focus on how Japan deals with refugees. Europe might be bad, but Japan I am bare of words.
Lebanon European Community Japan
Population 4.467.000 (2013) 503.000.000 127.300.000 (2013)
Refugees 2015 ~1.000.000 850.000 27
Ratio 4.4 : 1 590 : 1 4714814 : 1
Sources of the data: No words are necessary.

21 February 2016

Mario Lang: Generating C++ from a DTD with Jinja2 and lxml

I recently stumbled across an XML format specified in a DTD that I wanted to work with from within C++. The XML format is document centric, which is a bit of a pain with existing data binding compilers according to my limited experience. So to learn something new, and to keep control over generated code, I started to investigate what it would take to write my own little custom data binding compiler.
Writing a program that writes a program It turns out that there are two very helpful libraries in Python which can really make your life a lot easier:
To keep my life simple, I am focusing on generating accessors for XML attributes only for now. I leave it up to the library client to figure out how to deal with child elements.
A highly simplified DOM Inspired by the hybrid example from libstudxml, we define a simple base class that can store raw XML elements.
class element  
public:
  using attributes_type = std::map<xml::qname, std::string>;
  using elements_type = std::vector<std::shared_ptr<element>>;
  element(const xml::qname& name) : tag_name_(name)  
  virtual ~element() = default;
  xml::qname const& tag_name() const   return tag_name_;  
  attributes_type const& attributes() const   return attributes_;  
  attributes_type&       attributes()         return attributes_;  
  std::string const& text() const   return text_;  
  void text(std::string const& text)   text_ = text;  
  elements_type const& elements() const  return elements_; 
  elements_type&       elements()         return elements_;  
  element(xml::parser&, bool start_end = true);
  void serialize (xml::serializer&, bool start_end = true) const;
  template<typename T> static std::shared_ptr<element> create(xml::parser& p)  
    return std::make_shared<T>(p, false);
   
private:
  xml::qname tag_name_;
  attributes_type attributes_;
  std::string text_;           // Simple content only.
  elements_type elements_;     // Complex content only.
 ;
For each element name in the DTD, we're going to define a class that inherits from the element class, implementing special methods to make attribute access easier. The element(xml::parser&) constructor is going to create the corresponding class whenever it sees a certain element name. This calls for some sort of factory:
class factory  
public:
  static std::shared_ptr<element> make(xml::parser& p);
protected:
  struct element_info  
    xml::content content_type;
    std::shared_ptr<element> (*construct)(xml::parser&);
   ;
  using map_type = std::map<xml::qname, element_info>;
  static map_type *get_map()  
    if (!map) map = new map_type;
    return map;
   
private:
  static map_type *map;
 ;
template<typename T>
struct register_element : factory  
  register_element(xml::qname const& name, xml::content const& content)  
    get_map()->insert( name, element_info content, &element::create<T> );
   
 ;
shared_ptr<element> factory::make(xml::parser& p)  
  auto name = p.qname();
  auto iter = get_map()->find(name);
  if (iter == get_map()->end())  
    // No subclass found, so store plain data so we do not loose on roundtrip.
    return std::make_shared<element>(p, false);
   
  auto const& element = iter->second;
  p.content(element.content_type);
  return element.create(p);
 
The header template Now that we have our required infrastructure, we can finally start writing Jinja2 templates to generate classes for all elements in our DTD:
 %- for elem in dtd.iterelements() % 
   %- if elem.name in forwards_for % 
     %- for forward in forwards_for[elem.name] % 
class  forward ;
     %- endfor % 
   %- endif % 
class  elem.name  : public dom::element  
  static register_element< elem.name > factory_registration;
public:
   elem.name (xml::parser& p, bool start_end = true) : dom::element(p, start_end)  
   
   %- for attr in elem.iterattributes() % 
     %- if attr is required_string_attribute % 
  std::string  attr.name () const;
  void  attr.name (std::string const&);
     %- elif attr is implied_string_attribute % 
  optional<std::string>  attr.name () const;
  void  attr.name (optional<std::string>);
     # more branches to go here # 
     %- endif % 
   %- endfor % 
 ;
 %- endfor % 
required_string_attribute and implied_string_attribute are so-called Jinja2 tests. They are a nice way to isolate predicates such that the Jinja2 templates can stay relatively free of complicated expressions:
templates.tests['required_string_attribute'] = lambda a: \
  a.type in ['id', 'cdata', 'idref'] and a.default == 'required'
templates.tests['implied_string_attribute'] = lambda a: \
  a.type in ['id', 'cdata', 'idref'] and a.default == 'implied'
That is nice, but we have only seen C++ header declarations so far. Lets have a look into the implementation of some of our attribute accessors.
Enum conversion One interesting aspect of DTD based code generation is the fact that attributes can have enumerations specified. Assume that we have some extra data-structure in Python which helps us to define a nice name for each individual enumeration attribute. Then, a part of the Jinja2 template to generate the implementation for an enumeration attribute looks like:
     %- elif attr is known_enumeration_attribute % 
       %- set enum = enumerations[tuple(attr.values())]['name'] % 
       %- if attr.default == 'required' % 
 enum   elem.name :: attr.name () const  
  auto iter = attributes().find(qname " attr.name " );
  if (iter != attributes().end())  
         %- for value in attr.values() % 
     % if not loop.first % else  % else %       % endif -% 
    if (iter->second == " value ") return  enum :: value   mangle ;
         %- endfor % 
    throw illegal_enumeration ;
   
  throw missing_attribute ;
 
void  elem.name :: attr.name ( enum  value)  
  static qname const attr " attr.name " ;
  switch (value)  
         %- for value in attr.values() % 
  case  enum :: value   mangle :
    attributes()[attr] = " value ";
    break;
         %- endfor % 
  default:
    throw illegal_enumeration ;
   
 
       %- elif attr.default == 'implied' % 
 # similar implementation using boost::optional # 
       %- endif % 
     %- endif % 
Putting it all together The header for the library is generated like this:
from jinja2 import DictLoader, Environment
from lxml.etree import DTD
LIBRARY_HEADER = """
 # Our template code # 
"""
bmml = DTD('bmml.dtd')
templates = Environment(loader=DictLoader(globals()))
templates.filters['mangle'] = lambda ident: \
   '8th_or_128th': 'eighth_or_128th',
   '256th': 'twohundredfiftysixth',
   'continue': 'continue_'
   .get(ident, ident)
def template(name):
  return templates.get_template(name)
def hpp():
  print(template('LIBRARY_HEADER').render(
     'dtd': bmml,
     'enumerations': enumerations,
     'forwards_for':  'ornament': ['ornament_type'],
                      'score': ['score_data', 'score_header'] 
     ))
With all of this in place, we can have a look at a small use case for our library.
Printing document content I haven't really explained anything about the document format we're working with until now. Braille Music Markup Language is an XML based plain text markup language. Its purpose is to be able to enhance plain braille music scores with usually hard-to-calcuate meta information. Almost all element text content is supposed to be printed as-is to reconstruct the original plain text. So we could at least define one very basic operation in our library: printing the plain text content of an element. I found an XML stylesheet that is supposed to convert BMML documents to HTML. This stylesheet apparently has a bug, insofar as it forgets to treat the rest_data element in the same way as it already treats the note_data element. note to self, I wish I would've done a code review before the EU-project that developed BMML was finished. It looks like resurrecting maintainance is one of the things I might be able to look into in a meeting in Pisa in the first three days of March this year. If we keep this in mind, we can easily reimplement what the stylesheet does in idiomatic C++:
template<typename T>
typename std::enable_if<std::is_base_of<element, T>::value, std::ostream&>::type
operator<<(std::ostream &out, std::shared_ptr<T> elem)  
  if (!std::dynamic_pointer_cast<note_data>(elem) &&
      !std::dynamic_pointer_cast<rest_data>(elem) &&
      !std::dynamic_pointer_cast<score_header>(elem))
   
    auto const& text = elem->text();
    if (text.empty()) for (auto child : *elem) out << child; else out << text;
   
  return out;
 
The use of std::enable_if is necessary here so that operator<< is defined on the element class and all of its subclasses. Without the std::enable_if magic, client code would be forced to manually make sure it is passing std::shared_ptr<element> each time it wants to use the operatr<< on any of our specially defined subclasses. Now we can easily print BMML documents and get their actual plain text representation.
#include <fstream>
#include <iostream>
#include <xml/parser>
#include <xml/serializer>
#include "bmml.hxx"
using namespace std;
using namespace xml;
int main (int argc, char *argv[])  
  if (argc < 2)  
    cerr << "usage: " << argv[0] << " [<filename.bmml>...]" << endl;
    return EXIT_FAILURE;
   
  try  
    for (int i = 1; i < argc; ++i)  
      ifstream ifs argv[i] ;
      if (ifs.good())  
        parser p ifs, argv[i] ;
        p.next_expect(parser::start_element, "score", content::complex);
        cout << make_shared<bmml::score>(p, false) << endl;
        p.next_expect(parser::end_element, "score");
        else  
        cerr << "Unable to open '" << argv[i] << "'." << endl;
        return EXIT_FAILURE;
       
     
    catch (xml::exception const& e)  
    cerr << e.what() << endl;
    return EXIT_FAILURE;
   
 
That's it for now. The full source for the actual library which inspired this posting can be found on github in my bmmlcxx project. If you have an comments or questions, send me mail. If you like bmmlcxx, don't forget to star it :-).

Mario Lang: Generating C++ from a DTD with Jinja2 and lxml

I recently stumbled across an XML format specified in a DTD that I wanted to work with from within C++. The XML format is document centric, which is a bit of a pain with existing data binding compilers according to my limited experience. So to learn something new, and to keep control over generated code, I started to investigate what it would take to write my own little custom data binding compiler.
Writing a program that writes a program It turns out that there are two very helpful libraries in Python which can really make your life a lot easier:
To keep my life simple, I am focusing on generating accessors for XML attributes only for now. I leave it up to the library client to figure out how to deal with child elements.
A highly simplified DOM Inspired by the hybrid example from libstudxml, we define a simple base class that can store raw XML elements.
class element  
public:
  using attributes_type = std::map<xml::qname, std::string>;
  using elements_type = std::vector<std::shared_ptr<element>>;
  element(const xml::qname& name) : tag_name_(name)  
  virtual ~element() = default;
  xml::qname const& tag_name() const   return tag_name_;  
  attributes_type const& attributes() const   return attributes_;  
  attributes_type&       attributes()         return attributes_;  
  std::string const& text() const   return text_;  
  void text(std::string const& text)   text_ = text;  
  elements_type const& elements() const  return elements_; 
  elements_type&       elements()         return elements_;  
  element(xml::parser&, bool start_end = true);
  void serialize (xml::serializer&, bool start_end = true) const;
  template<typename T> static std::shared_ptr<element> create(xml::parser& p)  
    return std::make_shared<T>(p, false);
   
private:
  xml::qname tag_name_;
  attributes_type attributes_;
  std::string text_;           // Simple content only.
  elements_type elements_;     // Complex content only.
 ;
For each element name in the DTD, we're going to define a class that inherits from the element class, implementing special methods to make attribute access easier. The element(xml::parser&) constructor is going to create the corresponding class whenever it sees a certain element name. This calls for some sort of factory:
class factory  
public:
  static std::shared_ptr<element> make(xml::parser& p);
protected:
  struct element_info  
    xml::content content_type;
    std::shared_ptr<element> (*construct)(xml::parser&);
   ;
  using map_type = std::map<xml::qname, element_info>;
  static map_type *get_map()  
    if (!map) map = new map_type;
    return map;
   
private:
  static map_type *map;
 ;
template<typename T>
struct register_element : factory  
  register_element(xml::qname const& name, xml::content const& content)  
    get_map()->insert( name, element_info content, &element::create<T> );
   
 ;
shared_ptr<element> factory::make(xml::parser& p)  
  auto name = p.qname();
  auto iter = get_map()->find(name);
  if (iter == get_map()->end())  
    // No subclass found, so store plain data so we do not loose on roundtrip.
    return std::make_shared<element>(p, false);
   
  auto const& element = iter->second;
  p.content(element.content_type);
  return element.create(p);
 
The header template Now that we have our required infrastructure, we can finally start writing Jinja2 templates to generate classes for all elements in our DTD:
 %- for elem in dtd.iterelements() % 
   %- if elem.name in forwards_for % 
     %- for forward in forwards_for[elem.name] % 
class  forward ;
     %- endfor % 
   %- endif % 
class  elem.name  : public dom::element  
  static register_element< elem.name > factory_registration;
public:
   elem.name (xml::parser& p, bool start_end = true) : dom::element(p, start_end)  
   
   %- for attr in elem.iterattributes() % 
     %- if attr is required_string_attribute % 
  std::string  attr.name () const;
  void  attr.name (std::string const&);
     %- elif attr is implied_string_attribute % 
  optional<std::string>  attr.name () const;
  void  attr.name (optional<std::string>);
     # more branches to go here # 
     %- endif % 
   %- endfor % 
 ;
 %- endfor % 
required_string_attribute and implied_string_attribute are so-called Jinja2 tests. They are a nice way to isolate predicates such that the Jinja2 templates can stay relatively free of complicated expressions:
templates.tests['required_string_attribute'] = lambda a: \
  a.type in ['id', 'cdata', 'idref'] and a.default == 'required'
templates.tests['implied_string_attribute'] = lambda a: \
  a.type in ['id', 'cdata', 'idref'] and a.default == 'implied'
That is nice, but we have only seen C++ header declarations so far. Lets have a look into the implementation of some of our attribute accessors.
Enum conversion One interesting aspect of DTD based code generation is the fact that attributes can have enumerations specified. Assume that we have some extra data-structure in Python which helps us to define a nice name for each individual enumeration attribute. Then, a part of the Jinja2 template to generate the implementation for an enumeration attribute looks like:
     %- elif attr is known_enumeration_attribute % 
       %- set enum = enumerations[tuple(attr.values())]['name'] % 
       %- if attr.default == 'required' % 
 enum   elem.name :: attr.name () const  
  auto iter = attributes().find(qname " attr.name " );
  if (iter != attributes().end())  
         %- for value in attr.values() % 
     % if not loop.first % else  % else %       % endif -% 
    if (iter->second == " value ") return  enum :: value   mangle ;
         %- endfor % 
    throw illegal_enumeration ;
   
  throw missing_attribute ;
 
void  elem.name :: attr.name ( enum  value)  
  static qname const attr " attr.name " ;
  switch (value)  
         %- for value in attr.values() % 
  case  enum :: value   mangle :
    attributes()[attr] = " value ";
    break;
         %- endfor % 
  default:
    throw illegal_enumeration ;
   
 
       %- elif attr.default == 'implied' % 
 # similar implementation using boost::optional # 
       %- endif % 
     %- endif % 
Putting it all together The header for the library is generated like this:
from jinja2 import DictLoader, Environment
from lxml.etree import DTD
LIBRARY_HEADER = """
 # Our template code # 
"""
bmml = DTD('bmml.dtd')
templates = Environment(loader=DictLoader(globals()))
templates.filters['mangle'] = lambda ident: \
   '8th_or_128th': 'eighth_or_128th',
   '256th': 'twohundredfiftysixth',
   'continue': 'continue_'
   .get(ident, ident)
def template(name):
  return templates.get_template(name)
def hpp():
  print(template('LIBRARY_HEADER').render(
     'dtd': bmml,
     'enumerations': enumerations,
     'forwards_for':  'ornament': ['ornament_type'],
                      'score': ['score_data', 'score_header'] 
     ))
With all of this in place, we can have a look at a small use case for our library.
Printing document content I haven't really explained anything about the document format we're working with until now. Braille Music Markup Language is an XML based plain text markup language. Its purpose is to be able to enhance plain braille music scores with usually hard-to-calcuate meta information. Almost all element text content is supposed to be printed as-is to reconstruct the original plain text. So we could at least define one very basic operation in our library: printing the plain text content of an element. I found an XML stylesheet that is supposed to convert BMML documents to HTML. This stylesheet apparently has a bug, insofar as it forgets to treat the rest_data element in the same way as it already treats the note_data element. note to self, I wish I would've done a code review before the EU-project that developed BMML was finished. It looks like resurrecting maintainance is one of the things I might be able to look into in a meeting in Pisa in the first three days of March this year. If we keep this in mind, we can easily reimplement what the stylesheet does in idiomatic C++:
template<typename T>
typename std::enable_if<std::is_base_of<element, T>::value, std::ostream&>::type
operator<<(std::ostream &out, std::shared_ptr<T> elem)  
  if (!std::dynamic_pointer_cast<note_data>(elem) &&
      !std::dynamic_pointer_cast<rest_data>(elem) &&
      !std::dynamic_pointer_cast<score_header>(elem))
   
    auto const& text = elem->text();
    if (text.empty()) for (auto child : *elem) out << child; else out << text;
   
  return out;
 
The use of std::enable_if is necessary here so that operator<< is defined on the element class and all of its subclasses. Without the std::enable_if magic, client code would be forced to manually make sure it is passing std::shared_ptr<element> each time it wants to use the operatr<< on any of our specially defined subclasses. Now we can easily print BMML documents and get their actual plain text representation.
#include <fstream>
#include <iostream>
#include <xml/parser>
#include <xml/serializer>
#include "bmml.hxx"
using namespace std;
using namespace xml;
int main (int argc, char *argv[])  
  if (argc < 2)  
    cerr << "usage: " << argv[0] << " [<filename.bmml>...]" << endl;
    return EXIT_FAILURE;
   
  try  
    for (int i = 1; i < argc; ++i)  
      ifstream ifs argv[i] ;
      if (ifs.good())  
        parser p ifs, argv[i] ;
        p.next_expect(parser::start_element, "score", content::complex);
        cout << make_shared<bmml::score>(p, false) << endl;
        p.next_expect(parser::end_element, "score");
        else  
        cerr << "Unable to open '" << argv[i] << "'." << endl;
        return EXIT_FAILURE;
       
     
    catch (xml::exception const& e)  
    cerr << e.what() << endl;
    return EXIT_FAILURE;
   
 
That's it for now. The full source for the actual library which inspired this posting can be found on github in my bmmlcxx project. If you have an comments or questions, send me mail. If you like bmmlcxx, don't forget to star it :-).

20 February 2016

Mark Brown: Expedient ABIs

The biggest change we ve seen in the Linux kernel for ARM over the past few years has been the transition to providing descriptions of the hardware in systems via device tree. This splits out the description of the devices in the system that can t be automatically enumerated from the kernel into a separate binary instead of being part of the kernel binary. Currently for most systems that are actively used upstream the device tree source code is kept in the kernel but the goal is to allow people to use device trees that are distributed separately to the kernel, especially device trees that are shipped as part of the board firmware. This is something that other platforms have done for a long time, PowerPC Macs and Sun SPARC systems use device tree as the mechanism for describing the hardware to the operating system. One consequence of this desire to allow the kernel and device tree to be shipped separately is that the device tree becomes an ABI. This is a really big change for people working in the embedded and consumer electronics areas where ARM has been most widely deployed, it means that any descriptions of the hardware need to be something that can stand the test of time. Anything we release is something we have to expect to carry code for indefinitely. When everything was done as part of the kernel binary we could easily do something that doesn t quite represent the hardware with the intention of replacing it later, now it is much harder to do that. An example of this is the SAW in Qualcomm SoCs. This is a block in the SoC which provides control of some regulators used for the CPU cores in the PMIC in very low power states and also allows the CPU to control the regulator with fast memory mapped registers rather than the slower buses used to control the PMIC. Unfortunately it doesn t fully replace direct access to the PMIC, it supports a subset of the control we need for the PMIC but not all of it. We could represent the SAW as an independent regulator but from a system integration point of view it is functioning as an extra control interface for the external PMIC and if we want to use the extra functionality that is only available via direct access to the PMIC we need to consider that and represent the SAW as an extension of it. If we don t need that extra PMIC functionality at the current time this means we need to do some extra work to make sure we describe the PMIC before we can use the SAW even if we have no intention to use anything other than the SAW. Now, few if any people are actually using the device tree as an ABI at present so those working on enabling platforms often forget about the requirement and find it an obstacle to getting things done they have pressure to get things done, they don t have quite the same pressure to make sure that attention is paid to device tree compatibility so it can easily get forgotten. Over time this may change, especially if people start to take advantage of the device tree as an ABI that become more and more important, but for now if we want to enable that in the future it s something we have to actively think about and work on, accepting that this means we won t always be able to do the most expedient thing.

19 February 2016

Julien Danjou: Gnocchi 2.0 release

A little more than 3 months after our latest minor release, here is the new major version of Gnocchi, stamped 2.0.0. It contains a lot of new and exciting features, and I'd like to talk about some of them to celebrate! You may notice that this release happens in the middle of the OpenStack release cycle. Indeed, Gnocchi does not follow that 6-months cycle, and we release whenever our code is ready. That forces us to have a more iterative approach, less disruptive for other projects and allow us to achieve a higher velocity. Applying the good old mantra release early, release often. Documentation
This version features a large documentation update. Gnocchi is still the only OpenStack server project that implements a "no doc, no merge" policy, meaning any code must come with the documentation addition or change included in the patch. The full documentation is included in the source code and available online at gnocchi.xyz. Data split & compression
I've already covered this change extensively in my last blog about timeseries compression. Long story short, Gnocchi now splits timeseries archives in small chunks that are compressed, increasing speed and decreasing data size. Measures batching support
Gnocchi now supports batching, which allow submitting several measures for different metric in a single request. This is especially useful in the context where your application tends to cache metrics for a while and is able to send them in a batch. Usage is fully documented for the REST API. Group by support in aggregation
One of the most demanded features was the ability to do measure aggregation no resource, using a group by type query. This is now possible using the new groupby parameter to aggregation queries. Ceph backend optimization
We improved the Ceph back-end a lot. Mehdi Abaakouk wrote a new Python binding for Ceph, called Cradox, that is going to replace the current Python rados module in the subsequent Ceph releases. Gnocchi makes usage of this new module to speed things up, making the Ceph based driver really, really faster than before. We also implemented asynchronous data deletion, which improves performance a bit. The next step will be to run some new benchmarks like I did a few months ago and compare with the Gnocchi 1.3 series. Stay tuned!

Next.

Previous.