blog.rnstlr.chhttps://blog.rnstlr.ch/2024-01-06T00:00:00+01:00Setting up Home Assistant on the Raspberry Pi 32024-01-06T00:00:00+01:002024-01-06T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2024-01-06:/setting-up-home-assistant-on-the-raspberry-pi-3.html<p>Setting up Home Assistant to automate stuff at home</p><h1>Motivation</h1>
<p>From my time working at Sensirion I still have a lot of sensors like the <a href="https://www.sensirion.com/products/catalog/SCD4x-CO2-Gadget">SCD4x
CO2 Gadget</a> and
<a href="https://sensirion.com/de/produkte/katalog/SHT4x-Smart-Gadget">SHT4x Smart
Gadget</a> running.
Also I decided that I want to use smart plugs to power on my coffee machine in
the morning.</p>
<p>While one can see the sensor data perfectly fine with the <a href="https://play.google.com/store/apps/details?id=com.sensirion.myam">Sensirion MyAmbience
App</a> and also
use the specific apps for the smart plugs, I wanted a bit more integration for
everything and thus decided to try out <a href="https://www.home-assistant.io">Home
Assistant</a>.</p>
<h1>Installing Home Assistant</h1>
<p>Installing Home Assistant on a Raspberry Pi is very easy: Just follow the guide
at <a href="https://www.home-assistant.io/installation/raspberrypi">https://www.home-assistant.io/installation/raspberrypi</a>. Since I didn't
want to use the GUI tools to flash the SD card I used the command line
directly:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>wget<span class="w"> </span>https://github.com/home-assistant/operating-system/releases/download/11.3/haos_rpi3-64-11.3.img.xz
$<span class="w"> </span>xz<span class="w"> </span>--decompress<span class="w"> </span>--stdout<span class="w"> </span>haos_rpi3-64-11.3.img.xz<span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>dd<span class="w"> </span><span class="nv">of</span><span class="o">=</span>/dev/sda<span class="w"> </span><span class="nv">bs</span><span class="o">=</span>64k<span class="w"> </span><span class="nv">oflag</span><span class="o">=</span>dsync<span class="w"> </span><span class="nv">status</span><span class="o">=</span>progress
</code></pre></div>
<p>After that I inserted the SD card into the Raspberry Pi and plugged in power.</p>
<h1>Setting it up</h1>
<p>I mostly followed the guide at
<a href="https://www.home-assistant.io/getting-started/onboarding/">https://www.home-assistant.io/getting-started/onboarding/</a></p>
<p>When connecting to <a href="http://homeassistant.local:8123/">http://homeassistant.local:8123/</a> I was greeted by the
setup screen:</p>
<p><img alt="Home Assistant Setup Screen" src="https://blog.rnstlr.ch/images/home_assistant/preparing-home-assistant.png"></p>
<p>This setup screen seemed stuck at the following step in the logs:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="n">supervisor</span><span class="o">.</span><span class="n">host</span><span class="o">.</span><span class="n">manager</span><span class="p">]</span><span class="w"> </span><span class="n">Host</span><span class="w"> </span><span class="n">information</span><span class="w"> </span><span class="n">reload</span><span class="w"> </span><span class="n">completed</span>
</code></pre></div>
<details>
<summary>Full logs</summary>
<div class="highlight"><pre><span></span><code>s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
cont-init: info: running /etc/cont-init.d/udev.sh
INFO: Using udev information from host
cont-init: info: /etc/cont-init.d/udev.sh exited 0
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
services-up: info: copying legacy longrun supervisor (no readiness notification)
services-up: info: copying legacy longrun watchdog (no readiness notification)
s6-rc: info: service legacy-services successfully started
INFO: Starting local supervisor watchdog...
[__main__] Initializing Supervisor setup
[supervisor.docker.network] Can't find Supervisor network, creating a new network
[supervisor.bootstrap] Seting up coresys for machine: raspberrypi3-64
[supervisor.docker.supervisor] Attaching to Supervisor ghcr.io/home-assistant/aarch64-hassio-supervisor with version 2023.12.0
[supervisor.docker.supervisor] Connecting Supervisor to hassio-network
[supervisor.resolution.evaluate] Starting system evaluation with state initialize
[supervisor.resolution.evaluate] System evaluation complete
[__main__] Setting up Supervisor
[supervisor.api] Starting API on 172.30.32.2
[supervisor.hardware.monitor] Started Supervisor hardware monitor
[supervisor.dbus.manager] Connected to system D-Bus.
[supervisor.dbus.agent] Load dbus interface io.hass.os
[supervisor.dbus.hostname] Load dbus interface org.freedesktop.hostname1
[supervisor.dbus.logind] Load dbus interface org.freedesktop.login1
[supervisor.dbus.network] Load dbus interface org.freedesktop.NetworkManager
[supervisor.dbus.rauc] Load dbus interface de.pengutronix.rauc
[supervisor.dbus.resolved] Load dbus interface org.freedesktop.resolve1
[supervisor.dbus.systemd] Load dbus interface org.freedesktop.systemd1
[supervisor.dbus.timedate] Load dbus interface org.freedesktop.timedate1
[supervisor.host.services] Updating service information
[supervisor.host.sound] Updating PulseAudio information
[supervisor.host.sound] Can't update PulseAudio data: Failed to connect to pulseaudio server
[supervisor.host.network] Updating local network information
[supervisor.host.apparmor] Loading AppArmor Profiles: {'hassio-supervisor'}
[supervisor.docker.monitor] Started docker events monitor
[supervisor.updater] Fetching update data from https://version.home-assistant.io/stable.json
[supervisor.docker.interface] Found ghcr.io/home-assistant/aarch64-hassio-cli versions: []
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/aarch64-hassio-cli with version 2023.11.0
[supervisor.plugins.cli] Starting CLI plugin
[supervisor.docker.cli] Starting CLI ghcr.io/home-assistant/aarch64-hassio-cli with version 2023.11.0 - 172.30.32.5
[supervisor.docker.interface] Found ghcr.io/home-assistant/aarch64-hassio-dns versions: []
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/aarch64-hassio-dns with version 2023.06.2
[supervisor.plugins.dns] Starting CoreDNS plugin
[supervisor.docker.dns] Starting DNS ghcr.io/home-assistant/aarch64-hassio-dns with version 2023.06.2 - 172.30.32.3
[supervisor.plugins.dns] Updated /etc/resolv.conf
[supervisor.docker.interface] Found ghcr.io/home-assistant/aarch64-hassio-audio versions: []
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/aarch64-hassio-audio with version 2023.12.0
[supervisor.plugins.audio] Starting Audio plugin
[supervisor.docker.audio] Starting Audio ghcr.io/home-assistant/aarch64-hassio-audio with version 2023.12.0 - 172.30.32.4
[supervisor.docker.interface] Found ghcr.io/home-assistant/aarch64-hassio-observer versions: []
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/aarch64-hassio-observer with version 2023.06.0
[supervisor.plugins.observer] Starting observer plugin
[supervisor.docker.observer] Starting Observer ghcr.io/home-assistant/aarch64-hassio-observer with version 2023.06.0 - 172.30.32.6
[supervisor.docker.interface] Found ghcr.io/home-assistant/aarch64-hassio-multicast versions: []
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/aarch64-hassio-multicast with version 2023.06.2
[supervisor.plugins.multicast] Starting Multicast plugin
[supervisor.docker.multicast] Starting Multicast ghcr.io/home-assistant/aarch64-hassio-multicast with version 2023.06.2 - Host
[supervisor.homeassistant.secrets] Loaded 0 Home Assistant secrets
[supervisor.docker.interface] No version found for ghcr.io/home-assistant/raspberrypi3-64-homeassistant
[supervisor.homeassistant.core] No Home Assistant Docker image ghcr.io/home-assistant/raspberrypi3-64-homeassistant found.
[supervisor.docker.interface] Attaching to ghcr.io/home-assistant/raspberrypi3-64-homeassistant with version landingpage
[supervisor.homeassistant.core] Using preinstalled landingpage
[supervisor.homeassistant.core] Starting HomeAssistant landingpage
[supervisor.homeassistant.module] Update pulse/client.config: /data/tmp/homeassistant_pulse
[supervisor.docker.homeassistant] Starting Home Assistant ghcr.io/home-assistant/raspberrypi3-64-homeassistant with version landingpage
[supervisor.os.manager] Detect Home Assistant Operating System 11.3 / BootSlot A
[supervisor.store.git] Cloning add-on https://github.com/esphome/home-assistant-addon repository
[supervisor.store.git] Cloning add-on https://github.com/hassio-addons/repository repository
[supervisor.store.git] Cloning add-on https://github.com/home-assistant/addons repository
[supervisor.store] Loading add-ons from store: 72 all - 72 new - 0 remove
[supervisor.addons.manager] Found 0 installed add-ons
[supervisor.backups.manager] Found 0 backup files
[supervisor.discovery] Loaded 0 messages
[supervisor.ingress] Loaded 0 ingress sessions
[supervisor.resolution.check] Starting system checks with state setup
[supervisor.resolution.check] System checks complete
[supervisor.resolution.evaluate] Starting system evaluation with state setup
[supervisor.resolution.evaluate] System evaluation complete
[supervisor.jobs] 'ResolutionFixup.run_autofix' blocked from execution, system is not running - setup
[supervisor.resolution.evaluate] Starting system evaluation with state setup
[supervisor.resolution.evaluate] System evaluation complete
[__main__] Running Supervisor
[supervisor.os.manager] Rauc: A - marked slot kernel.0 as good
[supervisor.addons.manager] Phase 'initialize' starting 0 add-ons
[supervisor.addons.manager] Phase 'system' starting 0 add-ons
[supervisor.addons.manager] Phase 'services' starting 0 add-ons
[supervisor.core] Skipping start of Home Assistant
[supervisor.addons.manager] Phase 'application' starting 0 add-ons
[supervisor.misc.tasks] All core tasks are scheduled
[supervisor.core] Supervisor is up and running
[supervisor.homeassistant.core] Home Assistant setup
[supervisor.docker.interface] Updating image ghcr.io/home-assistant/raspberrypi3-64-homeassistant:landingpage to ghcr.io/home-assistant/raspberrypi3-64-homeassistant:2024.1.1
[supervisor.docker.interface] Downloading docker image ghcr.io/home-assistant/raspberrypi3-64-homeassistant with tag 2024.1.1.
[supervisor.host.info] Updating local host information
[supervisor.resolution.check] Starting system checks with state running
[supervisor.resolution.checks.base] Run check for dns_server_failed/dns_server
[supervisor.resolution.checks.base] Run check for pwned/addon
[supervisor.resolution.checks.base] Run check for ipv4_connection_problem/system
[supervisor.resolution.checks.base] Run check for dns_server_ipv6_error/dns_server
[supervisor.resolution.checks.base] Run check for security/core
[supervisor.resolution.checks.base] Run check for docker_config/system
[supervisor.resolution.checks.base] Run check for trust/supervisor
[supervisor.resolution.checks.base] Run check for no_current_backup/system
[supervisor.resolution.module] Create new suggestion create_full_backup - system / None
[supervisor.resolution.module] Create new issue no_current_backup - system / None
[supervisor.resolution.checks.base] Run check for free_space/system
[supervisor.resolution.checks.base] Run check for multiple_data_disks/system
[supervisor.resolution.check] System checks complete
[supervisor.resolution.evaluate] Starting system evaluation with state running
[supervisor.resolution.evaluate] System evaluation complete
[supervisor.resolution.fixup] Starting system autofix at state running
[supervisor.resolution.fixup] System autofix complete
[supervisor.host.services] Updating service information
[supervisor.host.network] Updating local network information
[supervisor.host.sound] Updating PulseAudio information
[supervisor.host.manager] Host information reload completed
</code></pre></div>
</details>
<p>But after like 10 minutes (which the screen tells you it can take) it
continued.</p>
<h1>Configuring</h1>
<p>One of the first things I noticed after setting up the basic system is that:</p>
<ul>
<li>I needed to replace the USB power cable, since the RPI Power status reported a problem</li>
<li>Bluetooth seems broken...</li>
</ul>
<p>While I could easily fix the power supply issue with a different USB cable, I
couldn't figure out what the issue with bluetooth is. Looking at the
bugtrackers of Home Assistant did reveal quite some issues that people are having with bluetooth:</p>
<ul>
<li><a href="https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+bluetooth">https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+bluetooth</a></li>
<li><a href="https://github.com/home-assistant/operating-system/issues?q=bluetooth+is%3Aopen+label%3Aboard%2Fraspberrypi">https://github.com/home-assistant/operating-system/issues?q=bluetooth+is%3Aopen+label%3Aboard%2Fraspberrypi</a></li>
</ul>
<p>I then remembered that I read the following on <a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3</a></p>
<blockquote>
<p>ARMv7 Installation</p>
<p>Use this installation if you require any of the vendor's kernel hacks,
overlays, or closed-source GPU blobs and utilities.</p>
</blockquote>
<p>So maybe we can just use the 32bit version of the OS and everything will work
out of the box?</p>
<p>Turns out it is exactly like that! Just doing the same as above just with the 32bit image worked out of the box:</p>
<div class="highlight"><pre><span></span><code><span class="o">$</span><span class="w"> </span><span class="n">wget</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">home</span><span class="o">-</span><span class="n">assistant</span><span class="o">/</span><span class="n">operating</span><span class="o">-</span><span class="n">system</span><span class="o">/</span><span class="n">releases</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mf">11.3</span><span class="o">/</span><span class="n">haos_rpi3</span><span class="o">-</span><span class="mf">11.3</span><span class="o">.</span><span class="n">img</span><span class="o">.</span><span class="n">xz</span>
<span class="o">$</span><span class="w"> </span><span class="n">xz</span><span class="w"> </span><span class="o">--</span><span class="n">decompress</span><span class="w"> </span><span class="o">--</span><span class="n">stdout</span><span class="w"> </span><span class="n">haos_rpi3</span><span class="o">-</span><span class="mf">11.3</span><span class="o">.</span><span class="n">img</span><span class="o">.</span><span class="n">xz</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">sudo</span><span class="w"> </span><span class="n">dd</span><span class="w"> </span><span class="n">of</span><span class="o">=/</span><span class="n">dev</span><span class="o">/</span><span class="n">sda</span><span class="w"> </span><span class="n">bs</span><span class="o">=</span><span class="mi">64</span><span class="n">k</span><span class="w"> </span><span class="n">oflag</span><span class="o">=</span><span class="n">dsync</span><span class="w"> </span><span class="n">status</span><span class="o">=</span><span class="n">progress</span>
</code></pre></div>
<p>The sensors immediately showed up as discovered devices and could easily be
added and the values shown:</p>
<p><img alt="CO2 measurement" src="https://blog.rnstlr.ch/images/home_assistant/co2-sensor.png" width="100%"></p>Installing ArchLinux ARM on the Raspberry Pi 32023-12-05T00:00:00+01:002023-12-05T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2023-12-05:/installing-archlinux-arm-on-the-raspberry-pi-3.html<p>Replacing my RetroPie installation with ArchLinux ARM on my Raspberry Pi 3</p><p>Today I plugged in my Raspberry Pi 3 which had
<a href="https://retropie.org.uk/">RetroPie</a> installed on it. It notified me, that the
installation is out of date and not longer supported and I should reinstall the
system.</p>
<p>Since I had to do a reinstall anyway and didn't want to be bothered again in
the future, I decided to try out ArchLinux ARM, so I just get the rolling
releases without a need to do re-installs.</p>
<h1>Installation</h1>
<p>To install the base image I followed mostly the guide from ArchLinux ARM:
<a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3</a></p>
<p>For the setup I needed to connect it with an Ethernet cable, since the guide
doesn't explain how to set up WiFi prior to first booting it.</p>
<p>After that I logged in via ssh. I needed to enforce password authentication,
since otherwise ssh would just try all my ssh keys to authenticate which lead
to a <code>Received disconnect from 192.168.0.31 port 22:2: Too many authentication
failures</code></p>
<div class="highlight"><pre><span></span><code>ssh<span class="w"> </span>-o<span class="w"> </span><span class="nv">PreferredAuthentications</span><span class="o">=</span>password<span class="w"> </span>alarm@alarmpi
<span class="c1"># switch to root user</span>
su
<span class="c1"># From the install guide</span>
pacman-key<span class="w"> </span>--init
pacman-key<span class="w"> </span>--populate<span class="w"> </span>archlinuxarm
<span class="c1"># Update the whole system</span>
pacman<span class="w"> </span>-Syu
</code></pre></div>
<p>During the update step I got a scary warning while building the initramfs:</p>
<div class="highlight"><pre><span></span><code>(12/14) Updating linux-rpi initcpios...
==> Building image from preset: /etc/mkinitcpio.d/linux-rpi.preset: 'default'
==> Using configuration file: '/etc/mkinitcpio.conf'
-> -k 6.1.64-2-rpi-ARCH -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
==> Starting build: '6.1.64-2-rpi-ARCH'
-> Running build hook: [base]
-> Running build hook: [udev]
-> Running build hook: [autodetect]
-> Running build hook: [modconf]
-> Running build hook: [kms]
-> Running build hook: [keyboard]
-> Running build hook: [keymap]
-> Running build hook: [consolefont]
==> WARNING: consolefont: no font found in configuration
-> Running build hook: [block]
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: '/boot/initramfs-linux.img'
==> WARNING: errors were encountered during the build. The image may not be complete.
error: command failed to execute correctly
</code></pre></div>
<p>I tried to figure out what went wrong and then decided to just reboot and see
if we can still do that, which worked without problems.</p>
<h2>Configuring WiFi</h2>
<p>Since I didn't want to bother with connecting the raspi with an ethernet cable
at the location were I wanted to run it, I needed to configure WiFi before
continuing.</p>
<p>Since it will run stationary, it is enough to just hard-code a single network:</p>
<div class="highlight"><pre><span></span><code>wpa_passphrase<span class="w"> </span>SSID<span class="w"> </span>PSK<span class="w"> </span>><span class="w"> </span>/etc/wpa_supplicant/wpa_supplicant@wlan0.service
systemctl<span class="w"> </span>start<span class="w"> </span>wpa_supplicant@wlan0.service
systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>wpa_supplicant@wlan0.service
</code></pre></div>
<p>Then we tell systemd-network to enable DHCP for the wlan0 interface by creating
<code>/etc/systemd/network/wlan0.network</code> with the following content:</p>
<div class="highlight"><pre><span></span><code><span class="k">[Match]</span>
<span class="na">Name</span><span class="o">=</span><span class="s">wlan0</span>
<span class="k">[Network]</span>
<span class="na">DHCP</span><span class="o">=</span><span class="s">yes</span>
<span class="na">IgnoreCarrierLoss</span><span class="o">=</span><span class="s">3s</span>
</code></pre></div>
<p>After reloading with <code>systemctl reload systemd-networkd.service</code> WiFi was
connected.</p>
<h3>Update 2023-12-14</h3>
<p>After a while I noticed, that the <code>systemd-networkd-wait-online.service</code> blocks
the startup of the pi for about 2 minutes. This is due to the fact that it will
wait for all links to be fully configured by default. (See
<a href="https://www.freedesktop.org/software/systemd/man/latest/systemd-networkd-wait-online.service.html">https://www.freedesktop.org/software/systemd/man/latest/systemd-networkd-wait-online.service.html</a>)</p>
<p>This can be changed by only waiting for <code>wlan0</code> to be up:</p>
<div class="highlight"><pre><span></span><code><span class="n">sudo</span><span class="w"> </span><span class="n">systemctl</span><span class="w"> </span><span class="n">disable</span><span class="w"> </span><span class="n">systemd</span><span class="o">-</span><span class="n">networkd</span><span class="o">-</span><span class="n">wait</span><span class="o">-</span><span class="n">online</span><span class="p">.</span><span class="n">service</span>
<span class="n">sudo</span><span class="w"> </span><span class="n">systemctl</span><span class="w"> </span><span class="n">enable</span><span class="w"> </span><span class="n">systemd</span><span class="o">-</span><span class="n">networkd</span><span class="o">-</span><span class="n">wait</span><span class="o">-</span><span class="n">online</span><span class="nv">@wlan0</span><span class="p">.</span><span class="n">service</span>
</code></pre></div>
<h1>Installing Kodi</h1>
<p>Since I wanted to run Kodi on the Pi (along side RetroPi / Emulation station)
I followed this guide: <a href="https://kodi.wiki/view/HOW-TO:Install_Kodi_on_Raspberry_Pi">https://kodi.wiki/view/HOW-TO:Install_Kodi_on_Raspberry_Pi</a></p>
<div class="highlight"><pre><span></span><code>pacman -S kodi
# selecting kodi-rpi
</code></pre></div>
<p>After installing the output of pacman showed the following:</p>
<div class="highlight"><pre><span></span><code>>>> Remove any manual tweaks made to /boot/config.txt particulary a line such
as gpu_mem=xxx. Driver setup for Kodi is stored in /boot/kodi.config.txt
Manually append the following to /boot/config.txt to make them active:
[all]
include kodi.config.txt
A reboot will be required to activate them if this is a fresh install.`
</code></pre></div>
<details>
<summary>Optional kodi dependencies</summary>
Kodi showed the following optional dependencies: Since I currently don't want
to use bluetooth for anything, nor want to use pipewire or pulseaudio but plain
ALSA, I didn't install any of them.
<div class="highlight"><pre><span></span><code>Optional dependencies for kodi-rpi
afpfs-ng: Apple shares support
bluez: Blutooth support
linux-rpi: HW accelerated decoding [installed]
python-pybluez: Bluetooth support
pulseaudio: PulseAudio support
pipewire: PipeWire support
</code></pre></div>
</details>
<p>So I edited it accordingly, enabled the kodi service and rebooted:</p>
<div class="highlight"><pre><span></span><code>sudo systemctl enable kodi.service
</code></pre></div>
<p>So far everything is working quite nicely and one of the next things will be to
get a spotify plugin to run on the Raspberry Pi.</p>Building an out-of-tree Rust Kernel Module Part Three2023-06-15T00:00:00+02:002023-06-15T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2023-06-15:/building-an-out-of-tree-rust-kernel-module-part-three.html<p>Trying to build a hello world out-of-tree Rust kernel module for Linux. Part Three.</p><p>In my last <a href="/building-an-out-of-tree-rust-kernel-module-part-two.html">blog post</a>,
I managed to build an out-of-tree kernel module in Rust for a custom 6.1 Linux
kernel I packaged for ArchLinux:
<a href="https://aur.archlinux.org/packages/linux-rust">https://aur.archlinux.org/packages/linux-rust</a>.</p>
<p>While this worked, I couldn't manage to package the correct metadata to build
the out-of-tree kernel module without a local build of the kernel, which kind
of defeats the purpose of the exercise.</p>
<p>In the meantime Linux 6.2 got released so I thought I'd try again.</p>
<h2>Updating our own ArchLinux kernel</h2>
<p>So I went ahead and updated my <a href="https://aur.archlinux.org/packages/linux-rust">linux-rust</a> package to a 6.2 kernel. While
doing this I tried to stay as close as possible to the default ArchLinux kernel
packages <a href="https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/6.2.10.arch1-1/config?ref_type=tags">config</a> file to make it generally usable.</p>
<h2>Building the out-of-tree module</h2>
<p>Linux 6.2 changed the module metadata strings from byte arrays to proper
<code>str</code>s. For that we needed to update the kernel module. See:
<a href="https://github.com/Rust-for-Linux/rust-out-of-tree-module/pull/5">https://github.com/Rust-for-Linux/rust-out-of-tree-module/pull/5</a></p>
<h2>Same error as before</h2>
<p>So I went ahead recompiled the kernel, rebooted, tried to compile the kernel
module and got the same error as before:</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[main] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error[E0461]: couldn't find crate `core` with expected target triple target-12809083303779448358
|
= note: the following crate versions were found:
crate `core`, target triple target-5559158138856098584: /usr/lib/modules/6.2.10-arch1-1-rust/build/rust/libcore.rmeta
</code></pre></div>
<h2>Finding the root cause for the error</h2>
<p>But this time I wanted to find out what the cause for this issue is! It turns
out that it is a bug in rustc, where the file <em>path</em> instead of the <em>content</em>
of the <code>target.json</code> where used. See</p>
<ul>
<li><a href="https://github.com/Rust-for-Linux/linux/issues/792">https://github.com/Rust-for-Linux/linux/issues/792</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/98225">https://github.com/rust-lang/rust/pull/98225</a></li>
</ul>
<h2>Compiling with Rust 1.63.0</h2>
<p>So since this bug got fix in Rust 1.63.0 I decided to try to compile the kernel
with a newer (and thus unsupported, since the Linux kernel uses unstable Rust
features) version.</p>
<p>This will print a scary warning during the build process:</p>
<div class="highlight"><pre><span></span><code>***
*** Rust compiler 'rustc' is too new. This may or may not work.
*** Your version: 1.63.0
*** Expected version: 1.62.0
***
</code></pre></div>
<p>Also there were a few warnings from the Rust compiler itself about features
that got now stabilized:</p>
<div class="highlight"><pre><span></span><code>warning: the feature `nll` has been stable since 1.63.0 and no longer requires an attribute to enable
--> rust/alloc/lib.rs:170:12
|
170 | #![feature(nll)] // Not necessary, but here to test the `nll` feature.
| ^^^
|
= note: `#[warn(stable_features)]` on by default
</code></pre></div>
<h2>Successfully building an out-of-tree kernel module!</h2>
<p>So finally I was able to compile the out-of-tree module without a local build
of the kernel:</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[main] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
MODPOST /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/Module.symvers
CC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.mod.o
LD [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.ko
</code></pre></div>
<p>Which also loaded successfully:</p>
<div class="highlight"><pre><span></span><code>[125766.698929] rust_out_of_tree: loading out-of-tree module taints kernel.
[125766.698985] rust_out_of_tree: module verification failed: signature and/or required key missing - tainting kernel
[125766.699611] rust_out_of_tree: Rust out-of-tree sample (init)
[125771.403175] rust_out_of_tree: My numbers are [72, 108, 200]
[125771.403183] rust_out_of_tree: Rust out-of-tree sample (exit)
</code></pre></div>
<p>I also spent some time figuring out which parts of the build metadata are
really needed, since previously I just copied the whole <code>rust/</code> folder. In the
end we just need:</p>
<ul>
<li><code>rust/target.json</code> the custom target description</li>
<li><code>rust/*.rmeta</code> the compiled rust libraries</li>
<li><code>rust/*.so</code> the pre-compiled procedural macros</li>
<li><code>rust-toolchain</code> such that we use the same Rust compiler version that was
used to compile the kernel</li>
</ul>
<h2>Looking forward</h2>
<p>In the meantime Linux 6.3 got released and 6.4 will be released shortly. But it
doesn't look like they will bump the minimum version of Rust needed to compile:
<a href="https://github.com/torvalds/linux/blob/v6.4-rc6/scripts/min-tool-version.sh#L29">https://github.com/torvalds/linux/blob/v6.4-rc6/scripts/min-tool-version.sh#L29</a></p>
<p>But reading <a href="https://rust-for-linux.com/rust-version-policy">https://rust-for-linux.com/rust-version-policy</a> it looks like
there are plans to start tracking the latest Rust release for Linux:</p>
<blockquote>
<p>It remains to be decided how often the Rust version upgrades will land.
Ideally we would track the latest Rust release, but it remains to be seen how
other kernel developers feel about it.</p>
</blockquote>Switching my Desktop to PipeWire2023-05-29T00:00:00+02:002023-05-29T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2023-05-29:/switching-my-desktop-to-pipewire.html<p>How I switched my desktop from PulseAudio to PipeWire</p><h1>Background</h1>
<p>While I did setup my new laptop directly with PipeWire back in December 2021,
my existing desktop PC did remain with a PulseAudio setup.</p>
<h2>What is PipeWire?</h2>
<blockquote>
<p><a href="https://pipewire.org/">PipeWire</a> is a new low-level multimedia framework. It aims to offer capture
and playback for both audio and video with minimal latency and support for
PulseAudio, JACK, ALSA and GStreamer-based applications. </p>
<p>Source: <a href="https://wiki.archlinux.org/title/PipeWire">https://wiki.archlinux.org/title/PipeWire</a></p>
</blockquote>
<p>The reason I wanted to switch was, that I had some troubles with my bluetooth
headphones (only the SBC codec was available in the A2DP profile and I had some
reliability issues) and I heard that PipeWire should make this better.</p>
<h2>Installation</h2>
<p>Most of the pipewire packages were already installed as dependencies for other packages:</p>
<details>
<summary>
<tt>pacman -Qi pipewire</tt>
</summary>
<div class="highlight"><pre><span></span><code>Name : pipewire
Version : 1:0.3.71-1
Description : Low-latency audio/video router and processor
Architecture : x86_64
URL : https://pipewire.org
Licenses : MIT LGPL
Groups : None
Provides : None
Depends On : libpipewire=1:0.3.71-1 libcamera-base.so=0.0.5-64 libcamera.so=0.0.5-64 libdbus-1.so=3-64 libglib-2.0.so=0-64 libncursesw.so=6-64 libpipewire-0.3.so=0-64 libreadline.so=8-64 libsystemd.so=0-64 libudev.so=1-64
Optional Deps : gst-plugin-pipewire: GStreamer plugin
pipewire-alsa: ALSA configuration
pipewire-audio: Audio support
pipewire-docs: Documentation
pipewire-jack: JACK support
pipewire-pulse: PulseAudio replacement
pipewire-roc: ROC streaming
pipewire-session-manager: Session manager [installed]
pipewire-v4l2: V4L2 interceptor
pipewire-x11-bell: X11 bell
pipewire-zeroconf: Zeroconf support
realtime-privileges: realtime privileges with rt module
rtkit: realtime privileges with rtkit module [installed]
Required By : lib32-pipewire obs-studio telegram-desktop wireplumber xdg-desktop-portal xdg-desktop-portal-wlr
Optional For : chromium electron electron19 qt5-webengine qt6-webengine sdl2
Conflicts With : None
Replaces : None
Installed Size : 3.11 MiB
Packager : David Runge <dvzrv@archlinux.org>
Build Date : So 21 Mai 2023 15:17:29
Install Date : Di 23 Mai 2023 22:53:42
Install Reason : Installed as a dependency for another package
Install Script : Yes
Validated By : Signature
</code></pre></div>
</details>
<p>But first we install <code>pipewire-audio</code>:</p>
<div class="highlight"><pre><span></span><code>$ sudo pacman -S pipewire-audio
</code></pre></div>
<p>Then we remove <code>pulseaudio-alsa</code> and install <code>pipewire-alsa</code>:</p>
<div class="highlight"><pre><span></span><code>$ sudo pacman -Rs pulseaudio-alsa
$ sudo pacman -S pipewire-alsa
</code></pre></div>
<p>Then we install <code>pipewire-pulse</code> (which will remove <code>pulseaudio</code> and <code>pulseaudio-bluetooth</code>)</p>
<div class="highlight"><pre><span></span><code>$ sudo pacman -S pipewire-pulse
resolving dependencies...
looking for conflicting packages...
:: pipewire-pulse and pulseaudio are in conflict. Remove pulseaudio? [y/N] y
:: pipewire-pulse and pulseaudio-bluetooth are in conflict. Remove pulseaudio-bluetooth? [y/N] y
</code></pre></div>
<p>When trying to stop the (now uninstalled) pulseaudio service to start pipewire
I got an error:</p>
<div class="highlight"><pre><span></span><code><span class="o">$</span><span class="w"> </span><span class="n">sudo</span><span class="w"> </span><span class="n">systemctl</span><span class="w"> </span><span class="n">stop</span><span class="w"> </span><span class="n">pulseaudio</span><span class="o">.</span><span class="n">service</span>
<span class="n">Failed</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">stop</span><span class="w"> </span><span class="n">pulseaudio</span><span class="o">.</span><span class="n">service</span><span class="p">:</span><span class="w"> </span><span class="n">Unit</span><span class="w"> </span><span class="n">pulseaudio</span><span class="o">.</span><span class="n">service</span><span class="w"> </span><span class="ow">not</span><span class="w"> </span><span class="n">loaded</span><span class="o">.</span>
</code></pre></div>
<p>Since I didn't want to invest too much time (maybe I should just have stopped
it before uninstalling it?) I just logged out and back in to restart my
session.<sup id="fnref:session"><a class="footnote-ref" href="#fn:session">1</a></sup></p>
<h2>Problems</h2>
<p>After restarting the session pulseaudio clients seemed to be broken:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pactl<span class="w"> </span>stat
Connection<span class="w"> </span>failure:<span class="w"> </span>Connection<span class="w"> </span>refused
pa_context_connect<span class="o">()</span><span class="w"> </span>failed:<span class="w"> </span>Connection<span class="w"> </span>refused
</code></pre></div>
<p>It turns out that for some reason the pipewire-pulse.socket listener wasn't
active:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>systemctl<span class="w"> </span>--user<span class="w"> </span>status<span class="w"> </span>pipewire-pulse.socket
○<span class="w"> </span>pipewire-pulse.socket<span class="w"> </span>-<span class="w"> </span>PipeWire<span class="w"> </span>PulseAudio
<span class="w"> </span>Loaded:<span class="w"> </span>loaded<span class="w"> </span><span class="o">(</span>/usr/lib/systemd/user/pipewire-pulse.socket<span class="p">;</span><span class="w"> </span>enabled<span class="p">;</span><span class="w"> </span>preset:<span class="w"> </span>enabled<span class="o">)</span>
<span class="w"> </span>Active:<span class="w"> </span>inactive<span class="w"> </span><span class="o">(</span>dead<span class="o">)</span>
<span class="w"> </span>Triggers:<span class="w"> </span>●<span class="w"> </span>pipewire-pulse.service
<span class="w"> </span>Listen:<span class="w"> </span>/run/user/1000/pulse/native<span class="w"> </span><span class="o">(</span>Stream<span class="o">)</span>
</code></pre></div>
<p>Starting it is as easy as <code>systemctl --user start pipewire-pulse.socket</code> and
now <code>pactl</code> shows some output:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pactl<span class="w"> </span>stat
Currently<span class="w"> </span><span class="k">in</span><span class="w"> </span>use:<span class="w"> </span><span class="m">2</span><span class="w"> </span>blocks<span class="w"> </span>containing<span class="w"> </span><span class="m">8</span>.0<span class="w"> </span>KiB<span class="w"> </span>bytes<span class="w"> </span>total.
Allocated<span class="w"> </span>during<span class="w"> </span>whole<span class="w"> </span>lifetime:<span class="w"> </span><span class="m">2</span><span class="w"> </span>blocks<span class="w"> </span>containing<span class="w"> </span><span class="m">8</span>.0<span class="w"> </span>KiB<span class="w"> </span>bytes<span class="w"> </span>total.
Sample<span class="w"> </span>cache<span class="w"> </span>size:<span class="w"> </span><span class="m">0</span><span class="w"> </span>B
</code></pre></div>
<p>Also pavucontrol now shows me LDAC, AAC, and SBC-XQ in addition to just SBC:</p>
<p><img alt="pavucontrol showing more codecs" src="https://blog.rnstlr.ch/images/pipewire/pavucontrol-bluetooth-profiles.png" width="100%"></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:session">
<p>I should probably have used <code>systemctl --user stop pulseaudio.service</code>, since these are user units. <a class="footnote-backref" href="#fnref:session" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Limiting process RAM usage with systemd-run2023-01-17T00:00:00+01:002023-01-17T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2023-01-17:/limiting-process-ram-usage-with-systemd-run.html<p class="first last">Limiting RAM usage of a build process with systemd-run</p>
<p>While building the Linux kernel with <a class="reference external" href="/building-an-out-of-tree-rust-kernel-module-part-two.html">Rust support for ArchLinux</a>, I ran into a
problem where sphinx-build started using excessive amounts of RAM while
building the HTML documentation.</p>
<p>This caused the system to become unresponsive before the OOM killer decided to
just kill my user session.</p>
<div class="figure align-center" style="width: 100%">
<a class="reference external image-reference" href="https://blog.rnstlr.ch/images/limiting_ram_usage/sphinx-build-excessive-ram-usage.png"><img alt="htop just shortly before killing the build process" src="https://blog.rnstlr.ch/images/limiting_ram_usage/sphinx-build-excessive-ram-usage.png" style="width: 80%;" /></a>
<p class="caption">htop output just before killing the build process</p>
</div>
<p>Looking for a way to not have the OOM killer kill my session, but kill the
build process before it uses up all my available RAM, I found
<a class="reference external" href="https://unix.stackexchange.com/a/536046">https://unix.stackexchange.com/a/536046</a>.</p>
<p>So, spawning the build with the following command will kill the build process
as soon as it uses more than 20GB of RAM:</p>
<div class="highlight"><pre><span></span><span class="gp">$ </span>systemd-run<span class="w"> </span>--scope<span class="w"> </span>-p<span class="w"> </span><span class="nv">MemoryMax</span><span class="o">=</span>20G<span class="w"> </span>--user<span class="w"> </span>makepkg
<span class="go">Running scope as unit: run-r44087c0ea5d445fda135dc0db42b36ab.scope</span>
<span class="go">[1] 426653 killed systemd-run --scope -p MemoryMax=20G --user makepkg</span>
</pre></div>
Building an out-of-tree Rust Kernel Module Part Two2023-01-15T00:00:00+01:002023-01-15T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2023-01-15:/building-an-out-of-tree-rust-kernel-module-part-two.html<p>Trying to build a hello world out-of-tree Rust kernel module for Linux 6.1. Part two.</p><p>In my last <a href="/building-an-out-of-tree-rust-kernel-module.html">blog post</a>, I
tried to build an out-of-tree kernel module in Rust for the 6.1 stock ArchLinux kernel.</p>
<p>During this process I noticed that while <code>CONFIG_HAVE_RUST=y</code> is set in the
<a href="https://github.com/archlinux/svntogit-packages/blob/706494f4555dca158c9f02932717550e7b66b534/trunk/config">ArchLinux kernel config</a>,
Rust support get's silently disabled since conflicting options are set.</p>
<h2>Building our own ArchLinux kernel</h2>
<p>So I went ahead and started to build my own kernel with a custom config:
<a href="https://aur.archlinux.org/packages/linux-rust">https://aur.archlinux.org/packages/linux-rust</a>.</p>
<p>I based it off the official ArchLinux kernel package, disabled the conflicting
options, ran <code>make menuconfig</code> and enabled Rust support.</p>
<p>A few iterations on the configuration and <code>PKGBUILD</code> later, I had a successfully
building kernel with Rust support enabled!</p>
<p>After installing the custom kernel and booting into it, we should finally be
ready!</p>
<h2>Building the out-of-tree module</h2>
<p>So back to the
<a href="https://github.com/rnestler/rust-out-of-tree-module/tree/fix-build-for-linux-6.1">Rust-for-Linux/rust-out-of-tree-module</a>:</p>
<div class="highlight"><pre><span></span><code>make<span class="w"> </span><span class="nv">KDIR</span><span class="o">=</span>~/projects/archpkg/linux-rust/src/archlinux-linux<span class="w"> </span><span class="nv">LLVM</span><span class="o">=</span><span class="m">1</span>
sudo<span class="w"> </span>insmod<span class="w"> </span>rust_out_of_tree.ko
</code></pre></div>
<p>And we see in the <code>dmesg</code> output that the module successfully loaded! 🎉</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="w"> </span><span class="mf">451.297415</span><span class="p">]</span><span class="w"> </span><span class="n">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="n">loading</span><span class="w"> </span><span class="n">out</span><span class="o">-</span><span class="n">of</span><span class="o">-</span><span class="n">tree</span><span class="w"> </span><span class="n">module</span><span class="w"> </span><span class="n">taints</span><span class="w"> </span><span class="n">kernel</span><span class="o">.</span>
<span class="p">[</span><span class="w"> </span><span class="mf">451.297460</span><span class="p">]</span><span class="w"> </span><span class="n">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="n">module</span><span class="w"> </span><span class="n">verification</span><span class="w"> </span><span class="n">failed</span><span class="p">:</span><span class="w"> </span><span class="n">signature</span><span class="w"> </span><span class="ow">and</span><span class="o">/</span><span class="ow">or</span><span class="w"> </span><span class="n">required</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="n">missing</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">tainting</span><span class="w"> </span><span class="n">kernel</span>
<span class="p">[</span><span class="w"> </span><span class="mf">451.297724</span><span class="p">]</span><span class="w"> </span><span class="n">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="n">Rust</span><span class="w"> </span><span class="n">out</span><span class="o">-</span><span class="n">of</span><span class="o">-</span><span class="n">tree</span><span class="w"> </span><span class="n">sample</span><span class="w"> </span><span class="p">(</span><span class="n">init</span><span class="p">)</span>
</code></pre></div>
<p>If we unload it with <code>sudo rmmod rust_out_of_tree.ko</code> we get the following in
<code>dmesg</code>:</p>
<div class="highlight"><pre><span></span><code><span class="k">[ 461.206748] rust_out_of_tree: My numbers are [72, 108, 200]</span>
<span class="na">[ 461.206753] rust_out_of_tree</span><span class="o">:</span><span class="w"> </span><span class="s">Rust out-of-tree sample (exit)</span>
</code></pre></div>
<h2>Packing the correct metadata</h2>
<p>You may have noticed, that we passed
<code>KDIR=~/projects/archpkg/linux-rust/src/archlinux-linux</code> to the make call. This
is because the build requires the Rust metadata which is generated during the
kernel build. To make it easier for other people installing the <code>linux-rust</code>
kernel, we should package it in <code>linux-rust-headers</code> (<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>).</p>
<p>If we don't pass the <code>KDIR</code> option, we get the following build error:</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[fix-build-for-linux-6.1] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
make[1]: Entering directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error: target file "./rust/target.json" does not exist
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
<p>So let's add this file to the package and try to rebuild:</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[fix-build-for-linux-6.1] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
make[1]: Entering directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error[E0463]: can't find crate for `core`
|
= note: the `target` target may not be installed
= help: consider downloading the target with `rustup target add target`
= help: consider building the standard library from source with `cargo build -Zbuild-std`
</code></pre></div>
<details>
<summary>Rest of the terminal output ...</summary>
<div class="highlight"><pre><span></span><code>error[E0463]: can't find crate for `compiler_builtins`
error[E0463]: can't find crate for `kernel`
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:5:5
|
5 | use kernel::prelude::*;
| ^^^^^^ can't find crate
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:35:9
|
35 | pr_info!("Rust out-of-tree sample (exit)\n");
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:34:9
|
34 | pr_info!("My numbers are {:?}\n", self.numbers);
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:21:9
|
21 | pr_info!("Rust out-of-tree sample (init)\n");
| ^^^^^^^
error: cannot find macro `module` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:7:1
|
7 | module! {
| ^^^^^^
error[E0463]: can't find crate for `kernel`
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:19:6
|
19 | impl kernel::Module for RustOutOfTree {
| ^^^^^^ can't find crate
error[E0433]: failed to resolve: use of undeclared type `Vec`
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:23:27
|
23 | let mut numbers = Vec::new();
| ^^^ use of undeclared type `Vec`
error[E0412]: cannot find type `Vec` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:16:14
|
16 | numbers: Vec<i32>,
| ^^^ not found in this scope
error[E0412]: cannot find type `ThisModule` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:31
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `Result` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:46
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^ not found in this scope
error[E0405]: cannot find trait `Drop` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:32:6
|
32 | impl Drop for RustOutOfTree {
| ^^^^ not found in this scope
error[E0635]: unknown feature `core_ffi_c`
--> <crate attribute>:1:9
|
1 | feature(core_ffi_c)
| ^^^^^^^^^^
error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:28:9
|
28 | Ok(RustOutOfTree { numbers })
| ^^ not found in this scope
error: aborting due to 15 previous errors
Some errors have detailed explanations: E0405, E0412, E0425, E0433, E0463, E0635.
For more information about an error, try `rustc --explain E0405`.
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
</details>
<p>Ok, so the build system is unable to find all the required crates that got
built as part of the kernel.</p>
<p>So to keep it simple, we just add everything form the <code>rust/</code> folder into the
package.</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[fix-build-for-linux-6.1] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
make[1]: Entering directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error[E0514]: found crate `core` compiled by an incompatible version of rustc
|
= note: the following crate versions were found:
crate `core` compiled by rustc 1.62.0 (a8314ef7d 2022-06-27): /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libcore.rmeta
= help: please recompile that crate using this compiler (rustc 1.66.0 (69f9c33d7 2022-12-12)) (consider running `cargo clean` first)
</code></pre></div>
<details>
<summary>Rest of the terminal output ...</summary>
<div class="highlight"><pre><span></span><code>error[E0514]: found crate `kernel` compiled by an incompatible version of rustc
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:5:5
|
5 | use kernel::prelude::*;
| ^^^^^^
|
= note: the following crate versions were found:
crate `kernel` compiled by rustc 1.62.0 (a8314ef7d 2022-06-27): /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libkernel.rmeta
= help: please recompile that crate using this compiler (rustc 1.66.0 (69f9c33d7 2022-12-12)) (consider running `cargo clean` first)
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:35:9
|
35 | pr_info!("Rust out-of-tree sample (exit)\n");
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:34:9
|
34 | pr_info!("My numbers are {:?}\n", self.numbers);
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:21:9
|
21 | pr_info!("Rust out-of-tree sample (init)\n");
| ^^^^^^^
error: cannot find macro `module` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:7:1
|
7 | module! {
| ^^^^^^
error[E0514]: found crate `kernel` compiled by an incompatible version of rustc
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:19:6
|
19 | impl kernel::Module for RustOutOfTree {
| ^^^^^^
|
= note: the following crate versions were found:
crate `kernel` compiled by rustc 1.62.0 (a8314ef7d 2022-06-27): /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libkernel.rmeta
= help: please recompile that crate using this compiler (rustc 1.66.0 (69f9c33d7 2022-12-12)) (consider running `cargo clean` first)
error[E0433]: failed to resolve: use of undeclared type `Vec`
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:23:27
|
23 | let mut numbers = Vec::new();
| ^^^ use of undeclared type `Vec`
error[E0412]: cannot find type `Vec` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:16:14
|
16 | numbers: Vec<i32>,
| ^^^ not found in this scope
error[E0412]: cannot find type `ThisModule` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:31
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `Result` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:46
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^ not found in this scope
error[E0405]: cannot find trait `Drop` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:32:6
|
32 | impl Drop for RustOutOfTree {
| ^^^^ not found in this scope
error[E0635]: unknown feature `core_ffi_c`
--> <crate attribute>:1:9
|
1 | feature(core_ffi_c)
| ^^^^^^^^^^
error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:28:9
|
28 | Ok(RustOutOfTree { numbers })
| ^^ not found in this scope
error: aborting due to 14 previous errors
Some errors have detailed explanations: E0405, E0412, E0425, E0433, E0635.
For more information about an error, try `rustc --explain E0405`.
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
</details>
<p>Alright, so it finds the crates, but the <code>rustc</code> versions do not match.
Apparently, the build is executed in
<code>/usr/lib/modules/6.1.5-arch2-1-rust/build</code>, so we need to tell <code>rustup</code> that we
want the 1.62.0 toolchain for that folder.</p>
<p>For that, we just add the <code>rust-toolchain</code> to the package as well.</p>
<div class="highlight"><pre><span></span><code>..Rust-for-Linux/rust-out-of-tree-module (git)-[fix-build-for-linux-6.1] % make LLVM=1
make -C /lib/modules/`uname -r`/build M=$PWD
make[1]: Entering directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error[E0461]: couldn't find crate `core` with expected target triple target-12809083303779448358
|
= note: the following crate versions were found:
crate `core`, target triple target-3911737072772191946: /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libcore.rmeta
</code></pre></div>
<details>
<summary>Rest of the terminal output ...</summary>
<div class="highlight"><pre><span></span><code>error[E0461]: couldn't find crate `compiler_builtins` with expected target triple target-12809083303779448358
|
= note: the following crate versions were found:
crate `compiler_builtins`, target triple target-3911737072772191946: /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libcompiler_builtins.rmeta
error[E0461]: couldn't find crate `kernel` with expected target triple target-12809083303779448358
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:5:5
|
5 | use kernel::prelude::*;
| ^^^^^^
|
= note: the following crate versions were found:
crate `kernel`, target triple target-3911737072772191946: /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libkernel.rmeta
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:35:9
|
35 | pr_info!("Rust out-of-tree sample (exit)\n");
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:34:9
|
34 | pr_info!("My numbers are {:?}\n", self.numbers);
| ^^^^^^^
error: cannot find macro `pr_info` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:21:9
|
21 | pr_info!("Rust out-of-tree sample (init)\n");
| ^^^^^^^
error: cannot find macro `module` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:7:1
|
7 | module! {
| ^^^^^^
error[E0461]: couldn't find crate `kernel` with expected target triple target-12809083303779448358
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:19:6
|
19 | impl kernel::Module for RustOutOfTree {
| ^^^^^^
|
= note: the following crate versions were found:
crate `kernel`, target triple target-3911737072772191946: /usr/lib/modules/6.1.5-arch2-1-rust/build/rust/libkernel.rmeta
error[E0433]: failed to resolve: use of undeclared type `Vec`
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:23:27
|
23 | let mut numbers = Vec::new();
| ^^^ use of undeclared type `Vec`
error[E0412]: cannot find type `Vec` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:16:14
|
16 | numbers: Vec<i32>,
| ^^^ not found in this scope
error[E0412]: cannot find type `ThisModule` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:31
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `Result` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:46
|
20 | fn init(_module: &'static ThisModule) -> Result<Self> {
| ^^^^^^ not found in this scope
error[E0425]: cannot find function, tuple struct or tuple variant `Ok` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:28:9
|
28 | Ok(RustOutOfTree { numbers })
| ^^ not found in this scope
error[E0405]: cannot find trait `Drop` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:32:6
|
32 | impl Drop for RustOutOfTree {
| ^^^^ not found in this scope
error[E0635]: unknown feature `core_ffi_c`
--> <crate attribute>:1:9
|
1 | feature(core_ffi_c)
| ^^^^^^^^^^
error: aborting due to 15 previous errors
Some errors have detailed explanations: E0405, E0412, E0425, E0433, E0635.
For more information about an error, try `rustc --explain E0405`.
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/usr/lib/modules/6.1.5-arch2-1-rust/build'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
</details>
<p>I didn't really understand what the strange target triple meant. Usually a
target triple looks something like <code>x86_64-unknown-linux-gnu</code> (<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>). But in
our case we are using a <code>target.json</code> to define the target, so I've no clue
where the difference comes from, since we are using the same JSON file.</p>
<h2>Summing it up</h2>
<p>While we managed to compile and run our out-of-tree kernel module in Rust, we
couldn't get the build metadata packaged in a way to do it without a local
build of the kernel.</p>
<p>Well, let's see if anything changes with the 6.2 Linux kernel which should get
released in February. In the meantime, this kernel provides an easy way to start
playing with Rust kernel modules on ArchLinux.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>The name of the package may be a bit misleading, since the package not
only bundles the headers but also build scripts and other metadata required
to build modules. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>See also <a href="https://doc.rust-lang.org/rustc/targets/index.html">https://doc.rust-lang.org/rustc/targets/index.html</a> <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>Building an out-of-tree Rust Kernel Module2022-12-19T00:00:00+01:002022-12-19T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2022-12-19:/building-an-out-of-tree-rust-kernel-module.html<p>Trying to build a hello world out-of-tree Rust kernel module for Linux 6.1</p><p>With the release of <a href="https://lwn.net/Articles/917504/">Linux 6.1</a>, minimal Rust
support landed and it should be possible to <del>easily</del> build a hello
world kernel module in Rust.</p>
<h2>Installing Linux 6.1</h2>
<p>At the time of writing Linux 6.1 was still in testing on ArchLinux, so I
enabled the testing repositories:</p>
<div class="highlight"><pre><span></span><code><span class="gd">--- pacman.conf 2022-12-18 15:25:10.742819293 +0100</span>
<span class="gi">+++ /etc/pacman.conf 2022-12-18 00:32:56.404801925 +0100</span>
<span class="gu">@@ -69,8 +69,8 @@</span>
<span class="w"> </span># repo name header and Include lines. You can add preferred servers immediately
<span class="w"> </span># after the header, and they will be used before the default mirrors.
<span class="gd">-#[testing]</span>
<span class="gd">-#Include = /etc/pacman.d/mirrorlist</span>
<span class="gi">+[testing]</span>
<span class="gi">+Include = /etc/pacman.d/mirrorlist</span>
<span class="w"> </span>[core]
<span class="w"> </span>Include = /etc/pacman.d/mirrorlist
<span class="gu">@@ -78,8 +78,8 @@</span>
<span class="w"> </span>[extra]
<span class="w"> </span>Include = /etc/pacman.d/mirrorlist
<span class="gd">-#[community-testing]</span>
<span class="gd">-#Include = /etc/pacman.d/mirrorlist</span>
<span class="gi">+[community-testing]</span>
<span class="gi">+Include = /etc/pacman.d/mirrorlist</span>
<span class="w"> </span>[community]
<span class="w"> </span>Include = /etc/pacman.d/mirrorlist
<span class="gu">@@ -87,8 +87,8 @@</span>
<span class="w"> </span># If you want to run 32 bit applications on your x86_64 system,
<span class="w"> </span># enable the multilib repositories as required here.
<span class="gd">-#[multilib-testing]</span>
<span class="gd">-#Include = /etc/pacman.d/mirrorlist</span>
<span class="gi">+[multilib-testing]</span>
<span class="gi">+Include = /etc/pacman.d/mirrorlist</span>
<span class="w"> </span>[multilib]
<span class="w"> </span>Include = /etc/pacman.d/mirrorlist
</code></pre></div>
<h2>A first start</h2>
<p>Since I just want to play around, I decided to build an out-of-tree Rust module.
Luckily, there is an example module available for that already:
<a href="https://github.com/Rust-for-Linux/rust-out-of-tree-module">https://github.com/Rust-for-Linux/rust-out-of-tree-module</a>.</p>
<p>So I went ahead, cloned the repo and tried to just execute make:</p>
<div class="highlight"><pre><span></span><code>rust-out-of-tree-module (git)-[main] % make
make -C /lib/modules/`uname -r`/build M=$PWD
make[1]: Entering directory '/usr/lib/modules/6.1.0-arch1-1/build'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error: target file "./rust/target.json" does not exist
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/usr/lib/modules/6.1.0-arch1-1/build'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
<p>Well...</p>
<p>Reading through <a href="https://www.kernel.org/doc/html/latest/rust/quick-start.html">https://www.kernel.org/doc/html/latest/rust/quick-start.html</a>,
it seemed that I have everything I need to get started.</p>
<p>The README mentions the following though:</p>
<blockquote>
<p>The kernel tree (KDIR) requires the Rust metadata to be available. These are
generated during the kernel build, but may not be available for
installed/distributed kernels (the scripts that install/distribute kernel
headers etc. for the different package systems and Linux distributions are
not updated to take into account Rust support yet).</p>
</blockquote>
<h2>Trying an in-kernel build</h2>
<p>To check if it is just a tooling issue, I cloned the
<a href="https://github.com/Rust-for-Linux/linux">https://github.com/Rust-for-Linux/linux</a> repo and executed the check according
to the documentation:</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/linux (git)-[rust] % make LLVM=1 rustavailable
***
*** Rust compiler 'rustc' is too new. This may or may not work.
*** Your version: 1.66.0
*** Expected version: 1.62.0
***
***
*** Rust bindings generator 'bindgen' is too new. This may or may not work.
*** Your version: 0.63.0
*** Expected version: 0.56.0
***
Rust is available!
</code></pre></div>
<p>Since my toolchain seems to be too new, I installed the older versions with</p>
<div class="highlight"><pre><span></span><code>rustup<span class="w"> </span>override<span class="w"> </span><span class="nb">set</span><span class="w"> </span><span class="k">$(</span>scripts/min-tool-version.sh<span class="w"> </span>rustc<span class="k">)</span>
rustup<span class="w"> </span>component<span class="w"> </span>add<span class="w"> </span>rust-src
cargo<span class="w"> </span>install<span class="w"> </span>--locked<span class="w"> </span>--version<span class="w"> </span><span class="k">$(</span>scripts/min-tool-version.sh<span class="w"> </span>bindgen<span class="k">)</span><span class="w"> </span>bindgen
</code></pre></div>
<p>Then I enabled Rust support with <code>make menuconfig</code> in the <em>General setup</em> menu.
The option is only shown if the toolchain is installed, and in my case I also
had to disable the <code>GCC_PLUGINS</code> option.</p>
<p>I then just compiled the whole kernel to test it:</p>
<div class="highlight"><pre><span></span><code>make LLVM=1
</code></pre></div>
<p>This went smoothly, so I continued to build the actual ArchLinux kernel which matches my running kernel:</p>
<div class="highlight"><pre><span></span><code>git remote add archlinux git@github.com:archlinux/linux.git
git fetch archlinux v6.1-arch1
git checkout v6.1-arch1
</code></pre></div>
<p>To be sure, I ran <code>make menuconfig</code> again and applied the same changes again.</p>
<p>A few minutes later, I had my kernel ready:</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/linux (git)-[rust] % make -j8 LLVM=1
...
Kernel: arch/x86/boot/bzImage is ready (#2)
make -j8 LLVM=1 1557.69s user 133.21s system 745% cpu 3:46.77 total
</code></pre></div>
<h2>Back to the out-of-tree module</h2>
<p>Having successfully built the whole kernel with Rust support, I went back to the
<code>rust-out-of-tree-module</code> repository and tried to build it:</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/rust-out-of-tree-module (git)-[main] % make KDIR=../linux LLVM=1
make -C ../linux M=$PWD
make[1]: Entering directory '/home/roughl/projects/github/Rust-for-Linux/linux'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
error: proc macro panicked
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:7:1
|
7 | / module! {
8 | | type: RustOutOfTree,
9 | | name: "rust_out_of_tree",
10 | | author: "Rust for Linux Contributors",
11 | | description: "Rust out-of-tree sample",
12 | | license: "GPL",
13 | | }
| |_^
|
= help: message: Expected byte string
error[E0412]: cannot find type `CStr` in this scope
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:29
|
20 | fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
| ^^^^ not found in this scope
|
help: consider importing this struct
|
5 | use core::ffi::CStr;
|
error[E0425]: cannot find value `__LOG_PREFIX` in the crate root
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:21:9
|
21 | pr_info!("Rust out-of-tree sample (init)\n");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root
|
= note: this error originates in the macro `$crate::print_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0425]: cannot find value `__LOG_PREFIX` in the crate root
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:34:9
|
34 | pr_info!("My numbers are {:?}\n", self.numbers);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root
|
= note: this error originates in the macro `$crate::print_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0425]: cannot find value `__LOG_PREFIX` in the crate root
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:35:9
|
35 | pr_info!("Rust out-of-tree sample (exit)\n");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root
|
= note: this error originates in the macro `$crate::print_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0050]: method `init` has 2 parameters but the declaration in trait `init` has 1
--> /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.rs:20:20
|
20 | fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 parameter, found 2
|
= note: `init` from trait: `fn(&'static kernel::ThisModule) -> core::result::Result<Self, kernel::error::Error>`
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0050, E0412, E0425.
For more information about an error, try `rustc --explain E0050`.
make[2]: *** [scripts/Makefile.build:307: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o] Error 1
make[1]: *** [Makefile:1992: /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module] Error 2
make[1]: Leaving directory '/home/roughl/projects/github/Rust-for-Linux/linux'
make: *** [Makefile:6: default] Error 2
</code></pre></div>
<p>Looking into the compile errors, it seemed that the <code>fn init</code> signature changed
and that the <code>module!</code> marco expects byte strings.</p>
<p>Changing that:</p>
<div class="highlight"><pre><span></span><code><span class="gh">diff --git a/rust_out_of_tree.rs b/rust_out_of_tree.rs</span>
<span class="gh">index e280409..58cc9ba 100644</span>
<span class="gd">--- a/rust_out_of_tree.rs</span>
<span class="gi">+++ b/rust_out_of_tree.rs</span>
<span class="gu">@@ -6,10 +6,10 @@ use kernel::prelude::*;</span>
<span class="w"> </span>module! {
<span class="w"> </span> type: RustOutOfTree,
<span class="gd">- name: "rust_out_of_tree",</span>
<span class="gd">- author: "Rust for Linux Contributors",</span>
<span class="gd">- description: "Rust out-of-tree sample",</span>
<span class="gd">- license: "GPL",</span>
<span class="gi">+ name: b"rust_out_of_tree",</span>
<span class="gi">+ author: b"Rust for Linux Contributors",</span>
<span class="gi">+ description: b"Rust out-of-tree sample",</span>
<span class="gi">+ license: b"GPL",</span>
<span class="w"> </span>}
<span class="w"> </span>struct RustOutOfTree {
<span class="gu">@@ -17,7 +17,7 @@ struct RustOutOfTree {</span>
<span class="w"> </span>}
<span class="w"> </span>impl kernel::Module for RustOutOfTree {
<span class="gd">- fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {</span>
<span class="gi">+ fn init(_module: &'static ThisModule) -> Result<Self> {</span>
<span class="w"> </span> pr_info!("Rust out-of-tree sample (init)\n");
<span class="w"> </span> let mut numbers = Vec::new();
</code></pre></div>
<p>We get a successful build!</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/rust-out-of-tree-module (git)-[main] % make KDIR=../linux LLVM=1
make -C ../linux M=$PWD
make[1]: Entering directory '/home/roughl/projects/github/Rust-for-Linux/linux'
RUSTC [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.o
MODPOST /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/Module.symvers
LD [M] /home/roughl/projects/github/Rust-for-Linux/rust-out-of-tree-module/rust_out_of_tree.ko
make[1]: Leaving directory '/home/roughl/projects/github/Rust-for-Linux/linux'
</code></pre></div>
<p>But trying to load the resulting module fails:</p>
<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>insmod<span class="w"> </span>rust_out_of_tree.ko
insmod:<span class="w"> </span>ERROR:<span class="w"> </span>could<span class="w"> </span>not<span class="w"> </span>insert<span class="w"> </span>module<span class="w"> </span>rust_out_of_tree.ko:<span class="w"> </span>Invalid<span class="w"> </span>module<span class="w"> </span>format
</code></pre></div>
<p>We see this in the <code>dmesg</code> output as well:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="mf">24593.691184</span><span class="p">]</span><span class="w"> </span><span class="n">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="n">magic</span><span class="w"> </span><span class="s1">'6.1.0-arch1 SMP preempt mod_unload '</span><span class="w"> </span><span class="n">should</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="s1">'6.1.0-arch1-1 SMP preempt mod_unload '</span>
</code></pre></div>
<p>Of course we aren't setting the version the same as the ArchLinux kernel. I
copied a few steps from
<a href="https://github.com/archlinux/svntogit-packages/blob/packages/linux/trunk/PKGBUILD">https://github.com/archlinux/svntogit-packages/blob/packages/linux/trunk/PKGBUILD</a>
to set the same version (we could also just copy the config from there, but
lets see what happens first)</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/linux (git)-[tags/v6.1-arch1] % echo "-1" > localversion.10-pkgrel
Rust-for-Linux/linux (git)-[tags/v6.1-arch1] % make -s kernelrelease > version
Rust-for-Linux/linux (git)-[tags/v6.1-arch1] % cat version
6.1.0-arch1-1
</code></pre></div>
<p>It didn't work again:</p>
<div class="highlight"><pre><span></span><code>Rust-for-Linux/rust-out-of-tree-module (git)-[fix-build-for-linux-6.1] % sudo insmod rust_out_of_tree.ko
insmod: ERROR: could not insert module rust_out_of_tree.ko: Unknown symbol in module
</code></pre></div>
<p>The <code>dmesg</code> output shows:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="m m-Double">25300.463334</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvNtNtCsfATHBUcknU9_6kernel5print14format_strings4INFO</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463353</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvNtCsfATHBUcknU9_6kernel5print11call_printk</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463371</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">__rust_dealloc</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463386</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">__rust_realloc</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463400</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">__rust_alloc</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463414</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvNtCs3yuwAp0waWO_4core9panicking5panic</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463428</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMs7_NtCs3yuwAp0waWO_4core3fmtNtB5_9Formatter15debug_lower_hex</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463442</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvXsS_NtNtCs3yuwAp0waWO_4core3fmt3numlNtB7_8LowerHex3fmt</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463456</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMs7_NtCs3yuwAp0waWO_4core3fmtNtB5_9Formatter15debug_upper_hex</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463469</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvXsT_NtNtCs3yuwAp0waWO_4core3fmt3numlNtB7_8UpperHex3fmt</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463483</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvXs2_NtNtNtCs3yuwAp0waWO_4core3fmt3num3implNtB9_7Display3fmt</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463497</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMs7_NtCs3yuwAp0waWO_4core3fmtNtB5_9Formatter10debug_list</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463510</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMs5_NtNtCs3yuwAp0waWO_4core3fmt8buildersNtB5_9DebugList5entry</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463524</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMs5_NtNtCs3yuwAp0waWO_4core3fmt8buildersNtB5_9DebugList6finish</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463538</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvXs_NtCsfATHBUcknU9_6kernel5errorNtB4_5ErrorINtNtCs3yuwAp0waWO_4core7convert4FromNtNtCsdvv6pRyacSq_5alloc11collections15TryReserveErrorE4from</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="p">[</span><span class="m m-Double">25300.463552</span><span class="p">]</span><span class="w"> </span><span class="nx">rust_out_of_tree</span><span class="p">:</span><span class="w"> </span><span class="nx">Unknown</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">_RNvMNtCsfATHBUcknU9_6kernel5errorNtB2_5Error15to_kernel_errno</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="w"> </span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
</code></pre></div>
<p>So lets try with the ArchLinux config:</p>
<div class="highlight"><pre><span></span><code><span class="nx">wget</span><span class="w"> </span><span class="nx">https</span><span class="p">:</span><span class="c1">//raw.githubusercontent.com/archlinux/svntogit-packages/packages/linux/trunk/config</span>
<span class="nx">make</span><span class="w"> </span><span class="nx">olddefconfig</span>
<span class="nx">diff</span><span class="w"> </span><span class="o">-</span><span class="nx">u</span><span class="w"> </span><span class="nx">config</span><span class="w"> </span><span class="p">.</span><span class="nx">config</span>
</code></pre></div>
<p>The configuration difference isn't big</p>
<div class="highlight"><pre><span></span><code><span class="gd">--- config 2022-12-18 20:51:38.269359290 +0100</span>
<span class="gi">+++ .config 2022-12-18 20:53:48.896025137 +0100</span>
<span class="gu">@@ -11,6 +11,7 @@</span>
<span class="w"> </span>CONFIG_LD_IS_BFD=y
<span class="w"> </span>CONFIG_LD_VERSION=23900
<span class="w"> </span>CONFIG_LLD_VERSION=0
<span class="gi">+CONFIG_RUST_IS_AVAILABLE=y</span>
<span class="w"> </span>CONFIG_CC_CAN_LINK=y
<span class="w"> </span>CONFIG_CC_CAN_LINK_STATIC=y
<span class="w"> </span>CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
</code></pre></div>
<p>A bit strange that <code>CONFIG_RUST_IS_AVAILABLE=y</code> isn't set, but
<code>CONFIG_HAVE_RUST=y</code> is enabled, so all should be good.</p>
<p>Quite some time later, we built the ArchLinux kernel as well:</p>
<div class="highlight"><pre><span></span><code>make -j8 LLVM=1 15202.68s user 1464.06s system 800% cpu 34:42.57 total
</code></pre></div>
<p>But this lead to build failures in the kernel module!</p>
<div class="highlight"><pre><span></span><code><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="w"> </span><span class="p">(</span><span class="nx">git</span><span class="p">)</span><span class="o">-</span><span class="p">[</span><span class="nx">fix</span><span class="o">-</span><span class="nx">build</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">linux</span><span class="o">-</span><span class="m m-Double">6.1</span><span class="p">]</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="nx">KDIR</span><span class="p">=..</span><span class="o">/</span><span class="nx">linux</span><span class="w"> </span><span class="nx">LLVM</span><span class="p">=</span><span class="mi">1</span>
<span class="nx">make</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="p">..</span><span class="o">/</span><span class="nx">linux</span><span class="w"> </span><span class="nx">M</span><span class="p">=</span><span class="err">$</span><span class="nx">PWD</span>
<span class="nx">make</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span><span class="w"> </span><span class="nx">Entering</span><span class="w"> </span><span class="nx">directory</span><span class="w"> </span><span class="err">'</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">linux</span><span class="err">'</span>
<span class="w"> </span><span class="nx">MODPOST</span><span class="w"> </span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">Module</span><span class="p">.</span><span class="nx">symvers</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvNtNtCsfATHBUcknU9_6kernel5print14format_strings4INFO"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvNtCsfATHBUcknU9_6kernel5print11call_printk"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"__rust_dealloc"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"__rust_realloc"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"__rust_alloc"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvMs7_NtCs3yuwAp0waWO_4core3fmtNtB5_9Formatter15debug_lower_hex"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvXsS_NtNtCs3yuwAp0waWO_4core3fmt3numlNtB7_8LowerHex3fmt"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvMs7_NtCs3yuwAp0waWO_4core3fmtNtB5_9Formatter15debug_upper_hex"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvXsT_NtNtCs3yuwAp0waWO_4core3fmt3numlNtB7_8UpperHex3fmt"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="s">"_RNvXs2_NtNtNtCs3yuwAp0waWO_4core3fmt3num3implNtB9_7Display3fmt"</span><span class="w"> </span><span class="p">[</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">rust_out_of_tree</span><span class="p">.</span><span class="nx">ko</span><span class="p">]</span><span class="w"> </span><span class="nx">undefined</span><span class="p">!</span>
<span class="nx">WARNING</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">:</span><span class="w"> </span><span class="nx">suppressed</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="nx">unresolved</span><span class="w"> </span><span class="nx">symbol</span><span class="w"> </span><span class="nx">warnings</span><span class="w"> </span><span class="nx">because</span><span class="w"> </span><span class="nx">there</span><span class="w"> </span><span class="nx">were</span><span class="w"> </span><span class="nx">too</span><span class="w"> </span><span class="nx">many</span><span class="p">)</span>
<span class="nx">make</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="p">[</span><span class="nx">scripts</span><span class="o">/</span><span class="nx">Makefile</span><span class="p">.</span><span class="nx">modpost</span><span class="p">:</span><span class="mi">126</span><span class="p">:</span><span class="w"> </span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">rust</span><span class="o">-</span><span class="nx">out</span><span class="o">-</span><span class="nx">of</span><span class="o">-</span><span class="nx">tree</span><span class="o">-</span><span class="nx">module</span><span class="o">/</span><span class="nx">Module</span><span class="p">.</span><span class="nx">symvers</span><span class="p">]</span><span class="w"> </span><span class="nx">Error</span><span class="w"> </span><span class="mi">1</span>
<span class="nx">make</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="p">[</span><span class="nx">Makefile</span><span class="p">:</span><span class="mi">1944</span><span class="p">:</span><span class="w"> </span><span class="nx">modpost</span><span class="p">]</span><span class="w"> </span><span class="nx">Error</span><span class="w"> </span><span class="mi">2</span>
<span class="nx">make</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span><span class="w"> </span><span class="nx">Leaving</span><span class="w"> </span><span class="nx">directory</span><span class="w"> </span><span class="err">'</span><span class="o">/</span><span class="nx">home</span><span class="o">/</span><span class="nx">roughl</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">github</span><span class="o">/</span><span class="nx">Rust</span><span class="o">-</span><span class="k">for</span><span class="o">-</span><span class="nx">Linux</span><span class="o">/</span><span class="nx">linux</span><span class="err">'</span>
<span class="nx">make</span><span class="p">:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="p">[</span><span class="nx">Makefile</span><span class="p">:</span><span class="mi">6</span><span class="p">:</span><span class="w"> </span><span class="k">default</span><span class="p">]</span><span class="w"> </span><span class="nx">Error</span><span class="w"> </span><span class="mi">2</span>
</code></pre></div>
<p>These are now the compile time equivalent of the runtime errors we got before!</p>
<p>Apparently, the ArchLinux kernel <em>doesn't</em> have Rust support, despite it being
set in the config. Executing <code>make menuconfig</code> reveals, that options which
conflict with <code>CONFIG_HAVE_RUST=y</code> are enabled:</p>
<div class="highlight"><pre><span></span><code>│ Symbol: RUST [=n] │
│ Type : bool │
│ Defined at init/Kconfig:1925 │
│ Prompt: Rust support │
│ Depends on: HAVE_RUST [=y] && RUST_IS_AVAILABLE [=y] && !MODVERSIONS [=n] && !GCC_PLUGINS [=y] && !RANDSTRUCT [=n] && !DEBUG_INFO_BTF [=y] │
</code></pre></div>
<h2>Giving up for now</h2>
<p>At this point I'd probably need to compile and run a custom kernel which
actually has Rust support enabled.</p>
<p>I'll probably try this at a later point, but for now I'll give it a bit more
time to settle.</p>
<p>I'm also considering reporting this to the ArchLinux developers, but I'm not
sure how much priority Rust kernel modules should have, given the early stage.
I'll probably wait until Linux 6.2 is released before investigating further.</p>Learning Ruby Like it's 2009 — Part 12022-02-15T00:00:00+01:002022-02-15T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2022-02-15:/learning-ruby-like-its-2009-part-1.html<p>First part of my journey to learn ruby and rails. Focusing on bundler and version management.</p><p>As announced in my previous post I will document my journey of learning Ruby
and especially Ruby on Rails. Or how a friend of mine put it after hearing
about my idea:</p>
<blockquote>
<p>Blogging about Rails like it's 2009 😄.</p>
<p><a href="https://blog.dbrgn.ch/about/">@dbrgn</a> February, 2022</p>
</blockquote>
<h2>Learning Ruby like it's 2009</h2>
<p>One of my first exercises was to investigate a case where an automatic update
done by the <a href="https://depfu.com/">depfu</a>-bot failed the tests and as such
couldn't be merged. It looked similar to
<a href="https://github.com/renuo/pingen-client/pull/15">this</a> but failed the tests and
had a lot more updates including some major ones.</p>
<p>Already knowing a few programming languages and package managers my first idea
was: «Easy: Let's just first do all the minor and patch upgrades and see if
this breaks anything». Assuming the gems follow semantic versioning this should
just work.</p>
<h2>Bundler and version specifier</h2>
<p>First thing I noticed is that Bundler, while recommending semantic versioning,
doesn't directly support semantic version specifiers like for example
<a href="https://doc.rust-lang.org/cargo/reference/semver.html">cargo</a> does. It does
support defining your own ranges like the following:</p>
<div class="highlight"><pre><span></span><code><span class="n">gem</span><span class="w"> </span><span class="s1">'foo'</span><span class="p">,</span><span class="w"> </span><span class="s1">'>= 2.2.0'</span><span class="p">,</span><span class="w"> </span><span class="s1">'< 3.0'</span><span class="sb">`</span>
</code></pre></div>
<p>or using the <code>~></code> operator which achives the same thing:</p>
<div class="highlight"><pre><span></span><code><span class="n">gem</span><span class="w"> </span><span class="s1">'foo'</span><span class="p">,</span><span class="w"> </span><span class="s1">'~> 2.2'</span>
</code></pre></div>
<p>For
<a href="https://doc.rust-lang.org/cargo/reference/resolver.html#semver-compatibility">cargo</a>
one would just specify</p>
<div class="highlight"><pre><span></span><code><span class="n">foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"2.2.0"</span>
</code></pre></div>
<p>with the same result and in
<a href="https://docs.npmjs.com/about-semantic-versioning">npm</a> we can use the <code>^</code>
operator:</p>
<div class="highlight"><pre><span></span><code><span class="nt">"foo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^2.2.0"</span>
</code></pre></div>
<p>For bundler there is an <a href="https://github.com/rubygems/rubygems/issues/1919">issue on
GitHub</a> to add a SemVer
operator since 2017.</p>
<p>The code base I was working on didn't have a lot of version specifiers. The
reason is that Renuo generally tries to use the latest versions of all Ruby
dependencies for applications. This is possible since we have extensive test
suites which we trust and it enables an open and fast upgrade path for
customers if they need new features in the future.</p>
<p>Exceptions are made if a gem update causes problems or if it is a very central
gem like rails. To still have reproducible environments for applications the
<code>Gemfile.lock</code> file is of course checked into source control as it is <a href="https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/">best
practice</a>.</p>
<p>So just running <code>bundle update</code> would update to the latest major version of
almost all dependencies, which was exactly the thing I didn't want to do.</p>
<p>Luckily bundler has the
<a href="https://bundler.io/v2.3/man/bundle-update.1.html"><code>--minor</code></a> option which one
can pass to the <code>update</code> command which should <em>Prefer updating only to next
minor version.</em></p>
<h2>A minor inconvenience</h2>
<p>So here we go executing <code>bundler update --minor</code>! And the result was...
Nothing! It just didn't update anything!</p>
<p>Confused I started reading up documentation, version specifiers, tried to
update individual packages with <code>bundle update --minor $package</code> (which worked)
and finally found <a href="https://github.com/rubygems/rubygems/issues/3360">https://github.com/rubygems/rubygems/issues/3360</a>. Apparently
it's a known issue since 2018 that bundle update just fails to do the <code>--patch</code>
and <code>--minor</code> updates.</p>
<p>From the same GitHub issue I copied the handy shell one-liner <code>bundle update
$(bundle list | awk '$1 ~ /^\*/ {print $2}' | grep -v bundler) --minor</code> which
did the job!</p>
<p>Doing just the semver compatible updates worked, all the tests did pass and we
could deploy it. My shattered trust in the Ruby ecosystem from the <code>bunlder</code>
failure was restored!</p>
<p>All in all bundler is a decent package manager and I love that the Ruby
ecosystem seems to embrace semantic versioning and one can do fearless upgrades
to get bug- and security fixes of the dependencies.</p>Starting to blog again2022-02-10T00:00:00+01:002022-02-10T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2022-02-10:/starting-to-blog-again.html<p class="first last">Why I want to start blogging again</p>
<p>My <a class="reference external" href="https://blog.rnstlr.ch/visiting-hacklab01.html">last post</a> on this blog is from 2017 when I was traveling around Europe to
visit different hackerspaces. I have fond memories of that time and still
regret not finishing the post about visiting <a class="reference external" href="https://wiki.ljudmila.org/Main_Page">LJUDMILA</a> in Sarajevo. I also
regret that I immediately stopped writing blog posts after that and never wrote
a summary of my "Tour de Hackerspace".</p>
<p>The <a class="reference external" href="https://github.com/rnestler/rnestler.github.io/blob/main/content/articles/2017/2017-05-20_visiting_ljudmila.rst">drafts</a> of these <a class="reference external" href="https://github.com/rnestler/rnestler.github.io/blob/main/content/articles/2017/2017-05-20_tour_de_hackerspace_wrap_up.rst">posts</a> lingering around in the git repository serve as a
reminder of this tragedy 😉.</p>
<div class="section" id="a-new-beginning">
<h2>A new beginning</h2>
<p>Anyway: A lot has changed since then and beginning this year I started a new
job at <a class="reference external" href="https://www.renuo.ch/">Renuo</a>. Previously I was working at <a class="reference external" href="https://www.sensirion.com/">Sensirion</a> for 8 years, where I
was doing various kind of software development, ranging from embedded C++,
developing a sensor evaluation desktop software in Python, creating a
demonstrator prototype in Rust for an automotive PM2.5 sensor to developing
infrastructure on Azure to power remote running long term studies of various
sensors.</p>
<p>So switching to a software agency that almost exclusively does Web development
with Ruby on Rails is quite a big change for me. Especially since I never
really worked with Ruby or Rails before.</p>
<p>Since I find my expedition into this new terrain quite exciting, I want to
share my experience of learning Ruby on this blog!</p>
</div>
Visiting hacklab012017-05-17T00:00:00+02:002017-05-17T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-17:/visiting-hacklab01.html<p class="first last">Visiting <a class="reference external" href="https://hacklab01.org/">hacklab01</a> in Zagreb</p>
<p>After an entertaining BlaBlaCar ride with a mixed group of 7 Croatians who did
enjoy a weekend of river rafting, I arrived in Zagreb at around 22:00. I
agreed with Vedran from <a class="reference external" href="https://hacklab01.org/">hacklab01</a> to meet in front of the building.</p>
<p>During my email conversations with Vedran I kinda realized, that I'm not just
visiting a hackerspace, but an alternative culture centre called Medika <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>
which is run by <a class="reference external" href="http://attack.hr/">AKC Attack</a>. So upon arrival I was quite enchanted by the
charm of the place.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_3.jpg"><img alt="Entry hall in Medika" src="/images/tour_de_hackerspace/hacklab01/hacklab01_3.jpg" style="width: 80%;" /></a>
<p class="caption">Entry hall in Medika</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_entry.jpg"><img alt="Entry to hacklab01" src="/images/tour_de_hackerspace/hacklab01/hacklab01_entry.jpg" style="width: 80%;" /></a>
<p class="caption">Entry to hacklab01</p>
</div>
<p>Since Vedran was in the middle of a meeting, I just sat down and started to
talk to a few members. One girl brought some cookies made with cricket flour.
Since we did a similar things with a few of the coredump members some months
ago <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a>, this immediately sparked an interesting discussion about meat
production, insect growing and that strangely no company shares <em>how</em> to grow
insects by yourself. Also quite a few members were interested in Rust, so we
decided that I will give a short introduction to Rust on Tuesday.</p>
<p>When Vedran had finished his meeting he gave me a quick show around. The
hackerspace itself consists of a single room, containing an electronics
workspace, some tables for laptop work, couches and a bunch of other stuff.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_room.jpg"><img alt="The hacklab01 room" src="/images/tour_de_hackerspace/hacklab01/hacklab01_room.jpg" style="width: 80%;" /></a>
<p class="caption">The hacklab01 room</p>
</div>
<p>But since there are various other NGOs and artist in the same complex, there
was plenty of stuff to see! <a class="footnote-reference" href="#footnote-3" id="footnote-reference-3">[3]</a></p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_hallway.jpg"><img alt="Hallway in Medika" src="/images/tour_de_hackerspace/hacklab01/hacklab01_hallway.jpg" style="width: 80%;" /></a>
<p class="caption">Hallway in Medika</p>
</div>
<p>The rooms for residents of Medika, including showers and toilets, are separated
from the rest of the building.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_1.jpg"><img alt="Door to the living part of Medika" src="/images/tour_de_hackerspace/hacklab01/hacklab01_1.jpg" style="width: 80%;" /></a>
<p class="caption">Door to the living part of Medika</p>
</div>
<p>Sadly I didn't take pictures of every room. In the "headquarter" of the
building I had the pleasure to meet Dina. She took up the challenge to manage
this quite chaotic space two weeks ago. The government announced them a week
ago, that they will need to move out <a class="footnote-reference" href="#footnote-4" id="footnote-reference-4">[4]</a>. Due to this the week was rather
stressful for her and most of the people living or working in Medika. On the
bright side this also forced them to closely work together, which strengthened
their the Medika community as a whole.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_2.jpg"><img alt=""headquarters" of Medika" src="/images/tour_de_hackerspace/hacklab01/hacklab01_2.jpg" style="width: 80%;" /></a>
<p class="caption">"headquarters" of Medika</p>
</div>
<p>They told me that similar stuff happened before and that the situation as a
whole is kind of strange. On one hand the government supports some of the
projects running in Medika financially, on the other hand there is a plan to
build some kind of congress center in this area.</p>
<p>I agreed with Vedran to spend my night in the hacklab, so he handed me the keys
<a class="footnote-reference" href="#footnote-5" id="footnote-reference-5">[5]</a> and showed me where toilet, shower are located. They even would have
provided me with a sleeping bag, shampoo and everything else, since I forgot to
tell them that I have all that stuff with me! I found this level of
hospitality quite amazing and welcoming!</p>
<p>The next day Vedran showed my around the old town of the city in the afternoon.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_city_6.jpg"><img alt="The national theatre" src="/images/tour_de_hackerspace/hacklab01/hacklab01_city_6.jpg" style="width: 80%;" /></a>
<p class="caption">The national theatre</p>
</div>
<p>When we got a coffee, we started to talk about the problems they have with the
government. He told me it is probably related to the elections which will be
soon and the major just needs to get some attention. He also told me that the
major is charged with <a class="reference external" href="http://www.croatiaweek.com/zagreb-mayor-arrested-for-corruption/">corruption</a>. I was kind of shocked, that a major can
be charged because of corruption, but doesn't need to resign because of that.
According to an <a class="reference external" href="https://www.unodc.org/documents/data-and-analysis/statistics/corruption/Croatia_corruption_report_web_version.pdf">UN report</a> corruption and bribery is very common in Croatia,
so maybe the population just got used to it.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_city_2.jpg"><img alt="View over the old town" src="/images/tour_de_hackerspace/hacklab01/hacklab01_city_2.jpg" style="width: 80%;" /></a>
<p class="caption">View over the old town</p>
</div>
<p>The rest of the afternoon I spent in the hackerspace itself, writing my blog
posts, preparing for the Rust workshop and talking to the members which were
present. Later in the evening I went to get some beers with Vedran in a nice
bar close to Medika. I met quite an interesting guy there, who explained me
the history of Croatia, its cultural inheritance and how lots of it got
destroyed during the time of the Austrian Hungarian empire and the <a class="reference external" href="https://en.wikipedia.org/wiki/Ottoman_wars_in_Europe">Ottoman
wars</a>. We also talked about the difficult economic situation in Croatia
including the recent <a class="reference external" href="http://www.dw.com/en/croatias-agrokor-business-empire-too-big-to-fail/a-38757333">collapse of Agrokor</a>, Croatias biggest business empire,
which has the potential to bring the whole country down.</p>
<p>Tuesday May 16th. This day marked the deadline which the government has given
Medika to move out of the space. But in the meantime they met with some of the
government's representatives for this matter and got assured that the could
stay. Apparently the whole thing about them needing to move out was triggered
because the building doesn't fit the fire safety requirements anymore, so the
government would need to fix it. But they try to find a way without them
needing to move out completely and later move back in.</p>
<p>Also, probably because of all the media attention, a girl on Facebook
independently organized a party in Medika to show support for the place. So
when I got up people where already preparing stuff for the party.</p>
<p>Since it was very nice weather I decided to take a look at the Botanics garden
in Zagreb.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_botanic_garden_4.jpg"><img alt="Botanics garden" src="/images/tour_de_hackerspace/hacklab01/hacklab01_botanic_garden_4.jpg" style="width: 80%;" /></a>
<p class="caption">Botanics garden</p>
</div>
<p>After that I wandered around the city and got some coffee (and somehow got
member of a <a class="reference external" href="https://www.facebook.com/pages/Booksa/101023279982162">book club</a>). This lead to me almost missing the introduction to
Rust workshop I agreed to give in hacklab01! So I rushed back to the space and
shortly after had an awesome time helping people getting started with Rust.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_rust_intro.jpg"><img alt="Introduction to Rust" src="/images/tour_de_hackerspace/hacklab01/hacklab01_rust_intro.jpg" style="width: 80%;" /></a>
<p class="caption">Introduction to Rust</p>
</div>
<p>After the workshop we joined the party</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/hacklab01/hacklab01_party.jpg"><img alt="Party time!" src="/images/tour_de_hackerspace/hacklab01/hacklab01_party.jpg" style="width: 80%;" /></a>
<p class="caption">Party time!</p>
</div>
<p>Vedran suggested that I also visit another hackerspace in Zagreb, namely
RADIONA. One member of them offered to pick up by car at Medika and drive us
to the space.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/radiona/radiona_1.jpg"><img alt="Electronic lab and 3D printers in RADIONA" src="/images/tour_de_hackerspace/radiona/radiona_1.jpg" style="width: 80%;" /></a>
<p class="caption">Electronic lab and 3D printers in RADIONA</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/radiona/radiona_2.jpg"><img alt="Famous Nikola Tesla in RADIONA" src="/images/tour_de_hackerspace/radiona/radiona_2.jpg" style="width: 80%;" /></a>
<p class="caption">Famous Nikola Tesla in RADIONA</p>
</div>
<p>It is a rather small space, even smaller than coredump, but the community is
very alive. One of the members built his own electric skateboard and we had
lots of fun talking about the design of it and testing it.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/radiona/radiona_skate_board.mp4"><img alt="DIY electric skateboard" src="/images/tour_de_hackerspace/radiona/radiona_skate_board_2.jpg" style="width: 80%;" /></a>
<p class="caption">DIY electric skateboard</p>
</div>
<p>After our short visit, we returned back to Medika, enjoying the party for the
rest of the evening.</p>
<p>The next day it was already time to leave. I met with Vedran to have some
breakfast and we talked about the various projects they run. Medika itself
hosts many artists and arts projects, amongst others</p>
<ul class="simple">
<li>A <a class="reference external" href="http://attack.hr/foto-filmski-studio-medika/?lang=en">photo film studio</a></li>
<li>A <a class="reference external" href="http://attack.hr/galerija-siva/?lang=en">gallery</a></li>
<li>A <a class="reference external" href="http://attack.hr/klub-attack/?lang=en">club</a></li>
<li>A <a class="reference external" href="http://attack.hr/faki-19/?lang=en">theatre group</a></li>
</ul>
<p>Vedran and Dina are especially involved in the glitch art community. They
organize a festival called <a class="reference external" href="http://fubar.space/">fu:bar</a> and developed a gallery management
software called <a class="reference external" href="http://pivilion.net/">pivilion</a>.</p>
<p>The time I spent at hacklab01 / Medika was truly amazing! I've seen so many
things and met so many interesting people! If you want to visit them as well
you may apply for their <a class="reference external" href="https://hacklab01.org/hackn3t">hackn3t</a> program, a hackers residency program. I
basically means, they will try to cover for your travel costs if you visit them
and present some project or idea or whatever.</p>
<p>But as much as I enjoyed my time in Zagreb, I was also looking forward to my
next destination Ljubljana, Slovenia!</p>
<table class="docutils footnote" frame="void" id="footnote-1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>Medika is actually the name of a company which was located there some time ago</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="footnote-2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td>We ordered stuff from <a class="reference external" href="https://insekten-shop.ch/">https://insekten-shop.ch/</a> and tried out different recipies</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="footnote-3" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-3">[3]</a></td><td>You can get an overview of organisations / projects here: <a class="reference external" href="http://attack.hr/projekti/?lang=en">http://attack.hr/projekti/?lang=en</a></td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="footnote-4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td><a class="reference external" href="http://attack.hr/medika-ostaje/?lang=en">http://attack.hr/medika-ostaje/?lang=en</a></td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="footnote-5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-5">[5]</a></td><td>I was again impressed by the level of trust!</td></tr>
</tbody>
</table>
Visiting Sarajevo2017-05-14T00:00:00+02:002017-05-14T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-14:/visiting-sarajevo.html<p class="first last">Visiting Sarajevo</p>
<p>My BlaBlaCar ride <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> to Sarajevo was a very pleasant experience. My driver
was really nice, we talked a lot, and he explained my the different places
while we were passing by. I loved the experience of entering Bosnia when
suddenly the whole landscape looks different, with lots of hills and forests.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_travel_2.jpg"><img alt="View during a break on the car ride" src="/images/tour_de_hackerspace/sarajevo/sarajevo_travel_2.jpg" style="width: 80%;" /></a>
<p class="caption">View during a break on the car ride</p>
</div>
<p>We then arrived in the early afternoon in Sarajevo. Quite early during my
"Tour de Hackerspace" <a class="reference external" href="https://twitter.com/czesiekhaker">czesiek</a>, a close friend of <a class="reference external" href="https://twitter.com/andrewhobden">hoverbear</a> and
<a class="reference external" href="https://twitter.com/NGC_3572">thomascovenant</a>, offered <a class="reference external" href="https://twitter.com/czesiekhaker/status/852902273189634049">via Twitter</a> to show me around Sarajevo when I get
there for a visit, which I found quite amazing! So I arranged with him to
couch surf at his place and meet him there in the evening.</p>
<p>Since I had the whole afternoon to explore the city I decided to store my
luggage in a nearby hostel and wander around the old town of the city. I had
some of the <a class="reference external" href="https://duckduckgo.com/?q=bosnian+coffee&yeg=B&iax=1&ia=images">Bosnian coffee</a> and tried the Ćevapi for late lunch.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_city_2.jpg"><img alt="Sarajevo old town" src="/images/tour_de_hackerspace/sarajevo/sarajevo_city_2.jpg" style="width: 80%;" /></a>
<p class="caption">Sarajevo old town</p>
</div>
<p>At some point during the afternoon I noticed that I forgot my Ferris plushie in
the BlaBlaCar! So I contacted the driver again and we arranged to meet the
next day in the morning.</p>
<p>In the evening I met with czesiek and after placing my luggage in his flat, we
proceeded to go to a micro brewery to get some of the local beer. Afterwards
we went to a few other places and at one of them ended up meeting some Australian
guys I've seen earlier in the afternoon in the old town. I always love meeting
other people who are travelling because they are most of the time easy going
and have some interesting stories to tell.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_city_6.jpg"><img alt="Sarajevo during the night" src="/images/tour_de_hackerspace/sarajevo/sarajevo_city_6.jpg" style="width: 80%;" /></a>
<p class="caption">Sarajevo during the night</p>
</div>
<p>We ended up having lots of fun this night which lead to me having a very hard
time getting up at 8:00 to retrieve my Ferris. But it amazed me how when
meeting other hackers during my trip I feel connected to them instantly as if
we knew each others for years.</p>
<p>Since the weather was just too nice, I spent the next day visiting the <a class="reference external" href="http://www.openstreetmap.org/way/23723340">Bijela
Tabija castle</a> where one has a nice view over the city. During my way up I
also enjoyed exploring this part of the city which consist of many small
streets and alleyways.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_city_8.jpg"><img alt="On my way to Bijela Tabija" src="/images/tour_de_hackerspace/sarajevo/sarajevo_city_8.jpg" style="width: 80%;" /></a>
<p class="caption">On my way to Bijela Tabija</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_city_14.jpg"><img alt="Ruins of the Bijela Tabija castle" src="/images/tour_de_hackerspace/sarajevo/sarajevo_city_14.jpg" style="width: 80%;" /></a>
<p class="caption">Ruins of the Bijela Tabija castle</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_city_17.jpg"><img alt="View over Sarajevo" src="/images/tour_de_hackerspace/sarajevo/sarajevo_city_17.jpg" style="width: 80%;" /></a>
<p class="caption">View over Sarajevo</p>
</div>
<p>In the evening we had again lots of fun, this time visiting a shisha bar /
hookah lounge where there was some live music. In the meantime I found out,
that the hackerspace which is mentioned in the HackerspaceWiki probably
doesn't exist. So during the evening I talked with czesiek and his friends
about founding one in Sarajevo.</p>
<p>The next day I slept in, met with czesiek for lunch and then proceeded
to visit his workplace in Sarajevo. He works for the <a class="reference external" href="https://www.occrp.org/index.php">Organized Crime and
Corruption Reporting Project</a> (OCCRP), which does a great job supporting
investigative journalism all over the world.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_occrp_office.jpg"><img alt="Door to czesiek's office in the OCCRP place" src="/images/tour_de_hackerspace/sarajevo/sarajevo_occrp_office.jpg" style="width: 80%;" /></a>
<p class="caption">Door to czesiek's office in the OCCRP place</p>
</div>
<p>Since I wanted to avoid taking pictures of any sensitive material I just took a
picture of the door to the office. ;)</p>
<p>czesiek described his work as follows:</p>
<blockquote>
I'm a hacker at OCCRP, I'm in charge of developing editorial pipeline
(newsroom software geared towards investigative journalist teams; we plan
to opensource it after internal testing) and digital security.</blockquote>
<p>After my short visit, I proceeded to verify if the hackerspace in Sarajevo
exists or not. When arriving at the place it's supposed to be I found an
interesting technology hub called <a class="reference external" href="http://www.hub387.com/">HUB387</a>. Nobody there heard about a
hackerspace, so I changed the wiki entry to reflect that. Because I was
already there and had no other plans, I rented a desk at the <a class="reference external" href="http://www.nest71.com/">NEST71</a>
coworking space for €10 and spent some time working on this blog post.</p>
<p>In the evening there was a party at czesiek's house and I had the pleasure to
meet more of the OCCRP crew and other interesting people. I enjoyed the fact
that our group consisted of people from 7 different nations (Polish, French,
Bosnian, Mexican, American, British and Swiss)!</p>
<p>Despite of having some slight trouble getting up on Saturday morning, czesiek
and I attended a <a class="reference external" href="https://www.mreza-mira.net/vijesti/razno/lgbti-zajednica-odrzala-lekciju-vlastima/">protest</a> against violence towards LGBT people. It was a
very peaceful and somewhat cheerful event.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="http://static.ba.n1info.com/Picture/112125/jpeg/Sequence-01.Still011.jpg"><img alt="Protesters, source: http://ba.n1info.com/a153795/Vijesti/Vijesti/Odrzan-protest-LGBTI-osoba.html" src="http://static.ba.n1info.com/Picture/112125/jpeg/Sequence-01.Still011.jpg" style="width: 80%;" /></a>
<p class="caption">Protesters, source: <a class="reference external" href="http://ba.n1info.com/a153795/Vijesti/Vijesti/Odrzan-protest-LGBTI-osoba.html">http://ba.n1info.com/a153795/Vijesti/Vijesti/Odrzan-protest-LGBTI-osoba.html</a></p>
</div>
<p>After the protest we went for some coffee and I had the opportunity to meet
interesting people including a German guy who works for the European embassy.</p>
<p>In the afternoon I visited the <a class="reference external" href="http://museum.warchildhood.com/">War Childhood Museum</a>. It was a very heart
touching experience, reading the stories of how children were experiencing the
war. Also, after more than 20 years, marks of the war are still visible
in Sarajevo.</p>
<p>In the evening we went to the after party of the protest and again I met some
amazing people, amongst others Emina Bošnjak from the <a class="reference external" href="http://soc.ba/en/about-us/team/">Sarajevo Open Centre</a>.</p>
<p>The next day I had a BlaBlaCar booked for the early afternoon, so we had bearly
enough time to go up to <a class="reference external" href="https://en.wikipedia.org/wiki/Trebević">Trebević</a> mountain, enjoy the view and walk the way
down.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/sarajevo/sarajevo_mountain_2.jpg"><img alt="View from Trebević" src="/images/tour_de_hackerspace/sarajevo/sarajevo_mountain_2.jpg" style="width: 80%;" /></a>
<p class="caption">View from Trebević</p>
</div>
<p>I really loved my stay in Sarajevo. czesiek is an awesome host and I can
highly recommend to stay with him if you are in Sarajevo ;)</p>
<p>However, next stop: Zagreb, Croatia!</p>
<table class="docutils footnote" frame="void" id="footnote-1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>This was my first BlaBlaCar ride. I can really recommend to travel with it!</td></tr>
</tbody>
</table>
Visiting Hacklab Belgrade2017-05-10T00:00:00+02:002017-05-10T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-10:/visiting-hacklab-belgrade.html<p class="first last">Visiting the <a class="reference external" href="http://oosm.org/">Hacklab Belgrade</a>.</p>
<p>After the quite long train ride from Timișoara to Belgrade via Budapest, I
finally arrived in Belgrade around 16:00. Like most of the time, the first
thing I did was getting some local currency, sitting in a café and figure out
where I can stay. I chose the <a class="reference external" href="https://www.booking.com/hotel/rs/hostel-white-town.de.html">Hostel White Town</a> because it is really close
to the <a class="reference external" href="http://oosm.org/">Hacklab Belgrade</a>.</p>
<p>This turned out to be a great choice! It's not really a hostel, but more of a
guest house. And the owner is one of the most lovely persons I've ever met!
She tries hard to make your stay as pleasant as possible and it's also fun to
hang out with her. For example she provided me with a mobile hotspot so I
could have access to the internet on the go. I also met a Russian guy who
lives there since a few month. It was fun to hang out with him and he showed
me some cool places in the city.</p>
<p>Sadly the hackerspace wasn't open during my stay. But I contacted them on
their mailing list and one of them told me that we could meet the next day in
the afternoon so I can take a look at the hacklab.</p>
<p>So the next day I took a look at the city and then proceeded to the hacklab in
the afternoon.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/belgrad/belgrad_city.jpg"><img alt="View in Belgrade where the Danube and Sava rivers join" src="/images/tour_de_hackerspace/belgrad/belgrad_city.jpg" style="width: 80%;" /></a>
<p class="caption">View in Belgrade where the Danube and Sava rivers join</p>
</div>
<p>The hacklab is actually located in a former flat and thus contains a nice
kitchen and bathroom.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/belgrad/belgrad_main_room.jpg"><img alt="Main room of the hacklab" src="/images/tour_de_hackerspace/belgrad/belgrad_main_room.jpg" style="width: 80%;" /></a>
<p class="caption">Main room of the hacklab</p>
</div>
<p>The space basically consists of the main room which has some working places and
sofas. There is also a place to do electronics work.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/belgrad/belgrad_electronics_work.jpg"><img alt="Electronics work place" src="/images/tour_de_hackerspace/belgrad/belgrad_electronics_work.jpg" style="width: 80%;" /></a>
<p class="caption">Electronics work place</p>
</div>
<p>They also have a second room which provides some more working space.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/belgrad/belgrad_room_2.jpg"><img alt="Second room" src="/images/tour_de_hackerspace/belgrad/belgrad_room_2.jpg" style="width: 80%;" /></a>
<p class="caption">Second room</p>
</div>
<p>An interesting thing in their space is the book scanning machine. One can use
it to digitize books.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/belgrad/belgrad_book_scanning.jpg"><img alt="Book scanning machine" src="/images/tour_de_hackerspace/belgrad/belgrad_book_scanning.jpg" style="width: 80%;" /></a>
<p class="caption">Book scanning machine</p>
</div>
<p>After showing me around we got to talk about what they mainly do in the space.
He told me they have lots of meetups and language training courses. They
provide these as a kind of free education, because a lot of students who
finished studying can't find a job related to their field and thus try to find
a programming related job.</p>
<p>So after my rather short visit in both Belgrade and the hacklab, I continued my
travel to Sarajevo!</p>
Visiting Plan Zero2017-05-08T00:00:00+02:002017-05-08T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-08:/visiting-plan-zero.html<p class="first last">Visiting the <a class="reference external" href="http://planzero.ro">Plan Zero</a> hackerspace</p>
<p>After a quite relaxing train ride, I arrived in Timișoara at 21:30. After
contacting the hackerspace via email, Mihai, a member of the space, suggested
that he can pick me up from the train station and I can spend the night in the
hackerspace. After some difficulties finding each other at the train station
we went directly to the space.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_entry.jpg"><img alt="Entry to the Plan Zero hackerspace" src="/images/tour_de_hackerspace/plan_zero/plan_zero_entry.jpg" style="width: 80%;" /></a>
<p class="caption">Entry to the <a class="reference external" href="http://planzero.ro">Plan Zero</a> hackerspace</p>
</div>
<p>He then gave me a short tour around the space, especially showing me their (or
mainly his) awesome collection of fully working retro computers.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_retro_3.jpg"><img alt="Retro computer collection" src="/images/tour_de_hackerspace/plan_zero/plan_zero_retro_3.jpg" style="width: 80%;" /></a>
<p class="caption">Retro computer collection</p>
</div>
<p>Amongst others they own a C-64, an Amiga, Apple-II clones and a <a class="reference external" href="/images/tour_de_hackerspace/plan_zero/plan_zero_retro_2.jpg">Mac Classic</a>.
After the quick show around he just handed me the keys for the space, showed me
the couch and explained me which doors I need to close over night. I was
impressed by this level of trust they showed me!</p>
<p>So after hacking a <em>tiny bit</em> on the C-64 while getting constant attention from
the cat which lives in the space, I went to sleep around 3 in the morning.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_c64.mp4"><img alt="Having fun with the C-64" src="/images/tour_de_hackerspace/plan_zero/plan_zero_c64.jpg" style="width: 80%;" /></a>
<p class="caption">Having fun with the C-64</p>
</div>
<p>The next day I explored the city and met with Mihai in the afternoon. We then
took a quick look at the art atelier where his wife works. After that we
returned to the hackerspace.</p>
<p>Like almost every hackerspace Plan Zero also has a main room. In contrast to
other spaces the main room is more about hanging out and eating than working.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_main_room.jpg"><img alt="Main room" src="/images/tour_de_hackerspace/plan_zero/plan_zero_main_room.jpg" style="width: 80%;" /></a>
<p class="caption">Main room</p>
</div>
<p>Next there is a room with electronics equipment 3D printers and work places.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_electronics_working_room.jpg"><img alt="Electronics / working room" src="/images/tour_de_hackerspace/plan_zero/plan_zero_electronics_working_room.jpg" style="width: 80%;" /></a>
<p class="caption">Electronics / working room</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_3d_printers.jpg"><img alt="3D printers" src="/images/tour_de_hackerspace/plan_zero/plan_zero_3d_printers.jpg" style="width: 80%;" /></a>
<p class="caption">3D printers</p>
</div>
<p>While three 3D printers are fully operational, one of the members is building a
forth printer next to them.</p>
<p>The space is also well equipped for most mechanic needs, with a nice workshop.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_work_shop_2.jpg"><img alt="Workshop tooling" src="/images/tour_de_hackerspace/plan_zero/plan_zero_work_shop_2.jpg" style="width: 80%;" /></a>
<p class="caption">Workshop tooling</p>
</div>
<p>Also similar to other spaces there is a small storage room for random stuff.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_storage.jpg"><img alt="Storage room" src="/images/tour_de_hackerspace/plan_zero/plan_zero_storage.jpg" style="width: 80%;" /></a>
<p class="caption">Storage room</p>
</div>
<p>After I spent some time taking a closer look at the space, taking pictures and
talking to the members, we ordered the classic hackers dinner (pizza). Although
spending the night at the hackerspace was nice, it didn't have a shower, so I
booked a hostel nearby. Despite their website saying one can check in until
23:00, when we arrived there, nobody was present. Luckily Claudiu and Andrei
helped me contacting the owner of the hostel so he could let me in.</p>
<p>When everything related to the hostel was resolved, they showed me some of the
cooler bars in Timișoara, where we had some beer, live music and a fun time
together! What I learned that night was, that the Romanians party a bit harder
then what I can handle, so I was glad when we ordered a taxi together to get
back to my hostel at 5am ;)</p>
<p>After sleeping in and having some late breakfast I returned to the hackerspace.</p>
<p>Mihai was also at the space and tried to hook up an Amiga with a floppy
emulator which allows to connect USB thumb drives with images on it. After
trying several USB drives and bricking one due to wrong wiring, he finally got
it working:</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/plan_zero/plan_zero_retro_4.jpg"><img alt="Amiga running a disk image with the floppy emulator" src="/images/tour_de_hackerspace/plan_zero/plan_zero_retro_4.jpg" style="width: 80%;" /></a>
<p class="caption">Amiga running a disk image with the floppy emulator</p>
</div>
<p>When planning for my next destination I realized that traveling through the
Balkan area by train is harder than I thought. Apparently the direct line from
Timișoara to Belgrade got canceled some time ago (But was still present on the
InterRail map). So I tried to find a ride on BlaBlaCar which worked, but then
the ride got cancelled some hours before the start because the driver had
problems with his car. So in order to get to Belgrade I needed to take an 18h
train ride via Budapest. Well, this at least gave me some time to write this
blog post ;)</p>
Visiting Hackerspace Szeged2017-05-06T00:00:00+02:002017-05-06T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-06:/visiting-hackerspace-szeged.html<p class="first last">Visiting the Hackerspace Szeged</p>
<p>After returning from RustFest I spent one more day in Budapest to pick up my
luggage from the Hackerspace Budapest and to recover a bit from the lack of
sleep during my visit in Kiev.</p>
<p>Since I had some trouble contacting the <a class="reference external" href="http://www.hackerspace-szeged.org/">Hackerspace Szeged</a> and I didn't
bother to book a hostel or anything, I just took the train to Szeged and hoped
for the best. As it turns out once more, the advantage of not planing anything
at all is, that one can't get disappointed and is open to positive surprises!</p>
<p>This time I had the pleasure to meet Zsuzsa who studies in Budapast and lives
in Szeged. Upon hearing about my trip, she spontaneously invited me to stay
with her and Balint in their apartment. Sometimes it's hard to grasp for me
how incredibly lucky I am to meet all these amazing people during my travel!</p>
<p>So after sharing some pizza for dinner with them I tried to visit the
Hackerspace Szeged, since they told me they had a lock picking workshop this
evening. Sadly I arrived to late at their space and their workshop was already
over and they left the space. I guess this is one of the downsides of not
planing ;)</p>
<p>Anyway, I spent the next day taking a look at the wonderful city of Szeged,
including a visit to the <a class="reference external" href="https://en.wikipedia.org/wiki/Szeged_witch_trials">"Witch Island" area</a> and the local zoo.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/szeged/city/szeged_city_5.jpg"><img alt="Szeged Cathedral" src="/images/tour_de_hackerspace/szeged/city/szeged_city_5.jpg" style="width: 80%;" /></a>
<p class="caption">Szeged Cathedral</p>
</div>
<p>In the evening I finally managed to pay a short visit to the Hackerspace
Szeged. They had a follow up of their lock picking workshop of the day before,
so they explained me how to theoretically pick combination locks.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/szeged/szeged_lock.jpg"><img alt="Combination lock for the workshop" src="/images/tour_de_hackerspace/szeged/szeged_lock.jpg" style="width: 80%;" /></a>
<p class="caption">Combination lock for the workshop</p>
</div>
<p>They are a young and rather small hackerspace, but active nevertheless! The
space consist of the classical main room:</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/szeged/szeged_main_room_1.jpg"><img alt="Main room of the Hackerspace Szeged" src="/images/tour_de_hackerspace/szeged/szeged_main_room_1.jpg" style="width: 80%;" /></a>
<p class="caption">Main room of the Hackerspace Szeged</p>
</div>
<p>And a second smaller room which they mostly use as a storage room.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/szeged/szeged_second_room.jpg"><img alt="Main room of the Hackerspace Szeged" src="/images/tour_de_hackerspace/szeged/szeged_second_room.jpg" style="width: 80%;" /></a>
<p class="caption">Main room of the Hackerspace Szeged</p>
</div>
<p>Since I already made plans to spend the rest of the evening with Zsuzsa and
Balint, I spent just about 2 hours in their space. I'd loved to hear more
about the projects they are working on, so maybe I'll return in the future to
visit them again.</p>
<p>All in all I had an amazing stay in Szeged! While I'd loved to stay a few more
days, I was really looking forward to visit Timişoara in Romania!</p>
RustFest and Visiting Hacklab Kyiv2017-05-01T00:00:00+02:002017-05-01T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-05-01:/rustfest-and-visiting-hacklab-kyiv.html<p class="first last">Attending RustFest and visiting the Hacklab Kyiv</p>
<p>I originally planed to fly to Kiev on Friday to visit <a class="reference external" href="http://hacklab.kiev.ua/en/">Hacklab Kyiv</a> and
attend the <a class="reference external" href="http://2017.rustfest.eu">RustFest</a> workshops the next day. But as <a class="reference external" href="https://twitter.com/rnstlr/status/857902876588486658">you may heard about</a>,
I missed my flight due to my silliness. So I was busy for most of Friday
riding trains, trying to learn a bit of Ukrainian <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>, discuss the validity of
my ticket with the train crew, buying additional tickets and so on.</p>
<p>The train ride was quite an adventure and I even got to ride the famous
"platzkart" class night train.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_train_ride_3.jpg"><img alt="The famous platzkart" src="/images/tour_de_hackerspace/kiev/kiev_train_ride_3.jpg" style="width: 80%;" /></a>
<p class="caption">The famous platzkart</p>
</div>
<p>I didn't take many pictures during the platzkart train ride, but if you want
the get a better feeling for it just <a class="reference external" href="https://duckduckgo.com/?q=platzkart&atb=v10&iar=images&iax=1&ia=images">search for pictures</a>. I arrived in Kiev
around 11 in the morning (original plan was to arrive at 9) and met with
<a class="reference external" href="https://github.com/dns2utf8">Dns2utf8</a> at the train station because I arranged to share a hotel room with
him for the duration of RustFest.</p>
<div class="section" id="rustfest">
<h2><a class="reference external" href="http://2017.rustfest.eu">RustFest</a></h2>
<p>After getting a long overdue shower, we went to the RustFest workshops. I was
really happy to meet <a class="reference external" href="https://twitter.com/andrewhobden">@andrewhobden</a> and <a class="reference external" href="https://twitter.com/NGC_3572">thomascovenant (@NGC_3572)</a>, which
both did an amazing job as part of the <a class="reference external" href="http://2017.rustfest.eu/about/">RustFest team</a>!</p>
<p>Despite being a few hours to late we could still attend the workshops. I
attended the <a class="reference external" href="https://github.com/exonum/workshop">Exonum cryptocurrency workshop</a> instead of the web development I
originally signed up for. Since I missed the introduction, I jumped right into
writing Rust code without having any clue how their blockchain implementation
even works. By the end of the workshop we had some kind of crypto currency
implemented with a little node based web app to create new wallets, add funds
out of nowhere and transfer funds.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_rustfest_crypto_3.png"><img alt="Screenshots from the webapp" src="/images/tour_de_hackerspace/kiev/kiev_rustfest_crypto_3.png" style="width: 80%;" /></a>
<p class="caption">Screenshots from the webapp</p>
</div>
<p>I found a bug in the implementation, where if one transferred funds from a
wallet to itself it would just increase the balance of this wallet! The fix
was as simple as adding</p>
<div class="highlight"><pre><span></span><span class="k">if</span><span class="w"> </span><span class="n">sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">receiver</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</pre></div>
<p>inside a function. I didn't have time to figure out why the bug happened
exactly, since all the function does is decrement on the <tt class="docutils literal">sender</tt> and
increment on the <tt class="docutils literal">receiver</tt>, which should lead to an equal final balance if
<tt class="docutils literal">sender == receiver</tt>.</p>
<p>After the workshop we formed a little group of Rustaceans and had a great time
taking a look at the city!</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_7.jpg"><img alt="View over parts of Kiev" src="/images/tour_de_hackerspace/kiev/city/kiev_city_7.jpg" style="width: 80%;" /></a>
<p class="caption">View over parts of Kiev</p>
</div>
<p>Here are some more images:</p>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_1.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_1.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_2.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_2.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_3.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_3.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_4.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_4.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_5.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_5.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_6.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_6.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_7.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_7.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_8.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_8.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_9.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_9.jpg" style="width: 10%;" /></a>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/city/kiev_city_10.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/city/kiev_city_10.jpg" style="width: 10%;" /></a>
<p>In the evening we found a wonderful place for dinner and later met with some
other Rustaceans to spend some time in a bar which <a class="reference external" href="https://twitter.com/steveklabnik">Steve Klabnik</a> suggested.</p>
<p>The next morning it was time for a quite diverse range of <a class="reference external" href="http://2017.rustfest.eu/talks/">talks</a>. I
particularly enjoyed:</p>
<ul class="simple">
<li>"'Open' as in 'Welcoming': Facilitating Contributions" by <a class="reference external" href="https://github.com/Manishearth">Manish
Goregaokar</a> because it basically summarized what RustFest is all about.</li>
<li>"The Illustrated Adventure Survival Guide for New Rustaceans" by <a class="reference external" href="https://twitter.com/_lbaillie">Liz
Baillie</a> as it was super entertaining with cute images</li>
<li>"Making a game in Rust" by <a class="reference external" href="https://github.com/lislis">lislis</a> because I also tried to create a <a class="reference external" href="https://github.com/coredump-ch/rpsrtsrs">game
with Rust</a> (still not finished)</li>
</ul>
<p>During the day I had the pleasure to met the brilliant author of the <a class="reference external" href="http://edunham.net/2016/04/11/plushie_rustacean_pattern.html">Plushie
Rustacean Pattern</a>, <a class="reference external" href="https://twitter.com/qedunham">E Dunham</a>. She was impressed, that my girlfriend
actually managed to create a Plushie Ferris from her description.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="https://twitter.com/NGC_3572/status/852546171440685056"><img alt="My Plushie Ferris" src="/images/tour_de_hackerspace/kiev/ferris.jpg" style="width: 80%;" /></a>
<p class="caption">My Plushie Ferris, picture taken by <a class="reference external" href="https://twitter.com/NGC_3572">thomascovenant (@NGC_3572)</a></p>
</div>
<p>In the evening we had a great time during the after party. Getting to know the
community from this very relaxed and personal side was absolutely awesome! I
talked to quite a few people and learned lots of stuff. I also talked to
<a class="reference external" href="https://twitter.com/ag_dubs">Ashley Williams</a> about how to best teach kids programming and other stuff,
since we <a class="reference external" href="https://www.coredump.ch/2014/11/10/ferienpass-im-hackerspace/">do that</a> in <a class="reference external" href="https://www.coredump.ch/2016/11/01/ferienpass-2016/">our hackerspace</a>.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="https://twitter.com/NGC_3572/status/858773710869803008"><img alt="Me and some other Rustaceans" src="/images/tour_de_hackerspace/kiev/kiev_rustaceans.jpg" style="width: 80%;" /></a>
<p class="caption">Me and some other Rustaceans</p>
</div>
<p>Just like last year, RustFest was super amazing! It's so awesome to meet this
incredible community! I'm really looking forward to the next RustFest this
fall in <a class="reference external" href="https://rustfest.ch/">Zurich</a>!</p>
</div>
<div class="section" id="visiting-hacklab-kyiv">
<h2>Visiting Hacklab Kyiv</h2>
<p>The next day I met with Dmitriy, who I met at RustFest, to get lunch together.
Since he speaks Russian it was quite easy for him to chat with the locals and
find us a good place to get some Ukrainian food.</p>
<p>I arranged with Anastasia from the Hacklab Kyiv that I could couch surf at
their place. Since I wanted to meet with Anastasia to drop off my luggage, I
agreed with Dimitry to split and see each other again in the hackerspace.
Anastasia and her partner Sasha are some of the most lovely people I've ever
met! They showed me around the city, helped me with public transport and it
was always fun to hang out with them. So I was happy I brought some Swiss
chocolate with me which I could give them as a gift.</p>
<p>After dropping my luggage we went to the hackerspace.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_entry.jpg"><img alt="Entry to the HackLab Kyiv" src="/images/tour_de_hackerspace/kiev/kiev_entry.jpg" style="width: 80%;" /></a>
<p class="caption">Entry to the HackLab Kyiv</p>
</div>
<p>Their hackerspace consist mostly of people which are interested in mechanical
engineering and electronics. Due to that they own some awesome equippment such
as multiple CNC machines, 3D printers, compressors and lots of other tools.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_cnc.jpg"><img alt="CNC mill" src="/images/tour_de_hackerspace/kiev/kiev_cnc.jpg" style="width: 80%;" /></a>
<p class="caption">CNC mill</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_big_cnc.jpg"><img alt="Even bigger CNC mill" src="/images/tour_de_hackerspace/kiev/kiev_big_cnc.jpg" style="width: 80%;" /></a>
<p class="caption">Even bigger CNC mill</p>
</div>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_3d_printers.jpg"><img alt="3D printers" src="/images/tour_de_hackerspace/kiev/kiev_3d_printers.jpg" style="width: 80%;" /></a>
<p class="caption">3D printers</p>
</div>
<p>They created quite some awesome stuff with their 3D printer, including molds to
create metallic stuff!</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_3d_prints.jpg"><img alt="Awesome stuff they created with the 3D printers" src="/images/tour_de_hackerspace/kiev/kiev_3d_prints.jpg" style="width: 80%;" /></a>
<p class="caption">Awesome stuff they created with the 3D printers</p>
</div>
<p>Like most hackerspaces they also feature a big main working room</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_main_room_2.jpg"><img alt="Main room" src="/images/tour_de_hackerspace/kiev/kiev_main_room_2.jpg" style="width: 80%;" /></a>
<p class="caption">Main room</p>
</div>
<p>Additionally to that they feature:</p>
<ul>
<li><dl class="first docutils">
<dt>A workshop</dt>
<dd><a class="first last reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_workshop.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/kiev_workshop.jpg" style="width: 10%;" /></a>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>A storage room</dt>
<dd><a class="first last reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_workshop.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/kiev_workshop.jpg" style="width: 10%;" /></a>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Chemistry lab</dt>
<dd><a class="first last reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_chemistry.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/kiev_chemistry.jpg" style="width: 10%;" /></a>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>A soldering place</dt>
<dd><a class="first last reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_soldering.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/kiev_soldering.jpg" style="width: 10%;" /></a>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>A Tesla coil</dt>
<dd><a class="first last reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_tesla_coil.jpg"><img alt="" src="/images/tour_de_hackerspace/kiev/kiev_tesla_coil.jpg" style="width: 10%;" /></a>
</dd>
</dl>
</li>
</ul>
<p>In a room next to the hackerspace there is a studio for people working with
ceramics. They told me that they share some tools and generally support each
other.</p>
<div class="figure align-center" style="width: 80%">
<a class="reference external image-reference" href="/images/tour_de_hackerspace/kiev/kiev_ceramics_2.jpg"><img alt="Ceramics studio" src="/images/tour_de_hackerspace/kiev/kiev_ceramics_2.jpg" style="width: 80%;" /></a>
<p class="caption">Ceramics studio</p>
</div>
<p>After they had shown me around and I talked to most of them for some time, some
of us went to get dinner together. We spent a considerable amount of time
discussing various things, amongst others the problem that a lot of spaces
share: The founders are basically the only ones taking care of everything in
regard to organizing the space.</p>
<p>We have this problem as well in our space and tried to solve it, by actively
splitting responsibilities for various tasks. An example is: For a long time
<a class="reference external" href="https://github.com/dbrgn">Danilo Bargen</a>, our formal president, was responsible for every single IT
infrastructure task at coredump. So I encouraged him to show me how to manage
our servers, update services and so on. This not only to let him have more
time at hand, but also to remove a single point of failure in our organization.</p>
<p>The next day I spent some time trying to <a class="reference external" href="https://twitter.com/rnstlr/status/859351392871428097">repair my Fairphone</a>. At first it
seemed to work perfectly, but after some time it did again refuse to charge.</p>
<p>My flight back was on 16:45. This time I actually was able to catch it, but if
you want to hear a funny story on how I almost missed it again, feel free to DM
me on Twitter ;)</p>
<p>I definitely enjoyed my stay in Kiev and my visit to Hacklab Kyiv. I'd loved
to stay a few more days, but my travel continued back to Budapest and then
further on to Szeged.</p>
<table class="docutils footnote" frame="void" id="footnote-1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>It always amazes me how much communication is possible with just <a class="reference external" href="http://www.omniglot.com/language/phrases/ukrainian.php">some sentences</a>, lots of smiling, gestures and some pictures from a mobile phone.</td></tr>
</tbody>
</table>
</div>
Visiting Hackerspace Budapest2017-04-29T00:00:00+02:002017-04-29T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-29:/visiting-hackerspace-budapest.html<p class="first last">Visiting the Hackerspace Budapest</p>
<p>When arriving in Budapest in the afternoon, I noticed that the <a class="reference external" href="https://hsbp.org/">Hackerspace
Budapest</a> was still closed, so I used the time to organize my flight to Kiev
for <a class="reference external" href="http://2017.rustfest.eu">RustFest</a> and book a hotel close to the airport. As it turned out this
was a bit unnecessary, but more about that later.</p>
<p>Since I couldn't figure out where the Hackerspace Budapest had its IRC channel
(turns out it is <tt class="docutils literal">#hspbp</tt> on IRCnet. One can connect to it using
<tt class="docutils literal">open.ircnet.net</tt>), I just waited till the state on their website turned to
"open".</p>
<p>Finding their hackerspace was a lot harder then I thought! They give you the
street name and number on the <a class="reference external" href="https://wiki.hackerspaces.org/Hackerspace_Budapest">hackerspace wiki</a>, but when I arrived at this
street I found a three floor building with various flats. I looked around
there and asked a plumber which was working there, if he knew about a
hackerspace. He couldn't help me, but confirmed that I'm in the correct
building according to the street name and number. So I continued to look
around, which led to some neighbours getting suspicious about me. I had a
rather strange conversation with one of them who apparently couldn't speak any
English. After trying to help me for a while he showed me out. When I was
just walking away I noticed a small door about a meter away from the entry to
the building:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the Hackerspace Budapest" src="/images/tour_de_hackerspace/budapest/budapest_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the <a class="reference external" href="https://hsbp.org/">Hackerspace Budapest</a></p>
</div>
<p>Seeing the Club Mate crates, reassured me that this <em>must</em> be the Hackerspace I
was looking for! So I entered and told them my story about searching for
their hackerspace. When we finished laughing, they showed me around in their
space.</p>
<p>There is the classical main working room:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Main working room" src="/images/tour_de_hackerspace/budapest/budapest_main_working_area.jpg" style="width: 80%;" />
<p class="caption">Main working room</p>
</div>
<p>In the main working room there is a small <a class="reference external" href="https://en.wikipedia.org/wiki/Biotope">biotope</a> / <a class="reference external" href="https://en.wikipedia.org/wiki/Green_wall">green wall</a> /
biological experiment setup.</p>
<div class="figure align-center" style="width: 80%">
<img alt="biotope / green wall in the main room" src="/images/tour_de_hackerspace/budapest/budapest_biotope.jpg" style="width: 80%;" />
<p class="caption">biotope / green wall in the main room</p>
</div>
<p>Inside there lives an <a class="reference external" href="https://wikipedia.org/wiki/Axolotl">axolotl</a> (named Haxolotl) which, so they told me, forms
a stable ecosystem together with the plants. Apparently the excretion from the
axolotl produce all the minerals the plants need to grow. So they simply pump
the water where the axolotl resides to the top and let it flow down. The only
thing they need to do is to feed the axolotl with worms every day.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Axolotl" src="/images/tour_de_hackerspace/budapest/budapest_axolotl_0.jpg" style="width: 80%;" />
<p class="caption">Axolotl</p>
</div>
<p>They also have built a mechanism to avoid over feeding the axolotl: Whenever
one feeds it, you also press a button which will then change its color from
green to red. This will remain like that until the next feeding time were it
will turn green again. I found this whole thing quite amazing!</p>
<p>Next there is their 3D-printer and electronics lab:</p>
<div class="figure align-center" style="width: 80%">
<img alt="3D printer and electronics lab" src="/images/tour_de_hackerspace/budapest/budapest_3d_printer.jpg" style="width: 80%;" />
<p class="caption">3D printer and electronics lab</p>
</div>
<p>Being a rather small hackerspace, comparable to coredump, they didn't have a
laser cutter, since they can't afford it yet.</p>
<p>The space also features a kitchen and restrooms:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Kitchen and door to the restrooms" src="/images/tour_de_hackerspace/budapest/budapest_kitchen.jpg" style="width: 80%;" />
<p class="caption">Kitchen and door to the restrooms</p>
</div>
<p>A special thing I found in their space is the so called "loot area"</p>
<div class="figure align-center" style="width: 80%">
<img alt="Loot area" src="/images/tour_de_hackerspace/budapest/budapest_loot_area.jpg" style="width: 80%;" />
<p class="caption">Loot area</p>
</div>
<p>The members just put stuff there either if they have no use for it or as a gift
for the other members, mostly in the form of food and drinks. One can loot the
area by just taking the things for free.</p>
<p>They also told to me about the <a class="reference external" href="https://hsbp.org/camppp7e1">Camp++</a> they are organizing every year, which
sounded a bit like a smaller version of the Chaos Communication Camp.</p>
<p>The next day I spent mostly taking a look at Budapest, which is quite an
amazing city.</p>
<p>Since I wanted to travel only with cabin baggage to Kiev, I agreed with the
space, that I can store my suitcase in their room and pick it up when I return
from Kiev. So I arrived in the evening to store my suitcase. Since I and the
only hacker present didn't have any dinner yet, we decided to cook.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Cooking in the hackerspace" src="/images/tour_de_hackerspace/budapest/budapest_cooking.jpg" style="width: 80%;" />
<p class="caption">Cooking in the hackerspace</p>
</div>
<p>So after eating together and talking for a bit, I decided to go to the Hotel
early, since I had the flight to Kiev in the morning.</p>
<p>Sadly I forgot, that I still had my passport in my suitcase in the hackerspace
which I noticed when I was already at the airport. I tried to travel to Kiev
with just my ID card, but when boarding they told me this isn't possible.</p>
<p>So while writing this post I'm on a 18 hour train ride to Kiev which is still
faster than taking the next flight which would be on Saturday afternoon.</p>
<p>I really enjoyed my visit in the Hackerspace Budapest and will visit them
shortly again when I return from Kiev on Tuesday.</p>
Visiting Progressbar and Metalab2017-04-25T00:00:00+02:002017-04-25T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-25:/visiting-progressbar-and-metalab.html<p class="first last">Visiting Progressbar</p>
<p>Since I hit the bars a bit too hard with some of the guys and gals of brmlab, I
had a bit of a hard time getting up in the morning. Anyway, I quite enjoyed
relaxing a bit in the train while travelling to Bratislava.</p>
<div class="section" id="visiting-progressbar">
<h2>Visiting Progressbar</h2>
<p>A member of the hackerspace, Andrew, described me pretty well on IRC how to get
to the <a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> from the train station, while also getting quite a nice
look at Bratislava at the same time.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the Progressbar" src="/images/tour_de_hackerspace/progressbar/progressbar_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the <a class="reference external" href="https://www.progressbar.sk/">Progressbar</a></p>
</div>
<p>After arriving he gave me a tour around the space and then continued to repair
his bike.</p>
<p>The space consists of a nice big main working / presentation / hang-out room.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar main room" src="/images/tour_de_hackerspace/progressbar/progressbar_main_room.jpg" style="width: 80%;" />
<p class="caption"><a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> main room</p>
</div>
<p>There's also a co-working / office room:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar co-working room" src="/images/tour_de_hackerspace/progressbar/progressbar_co_working_space_2.jpg" style="width: 80%;" />
<p class="caption"><a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> co-working room</p>
</div>
<p>And in the next room there's the kitchen:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar kitchen" src="/images/tour_de_hackerspace/progressbar/progressbar_kitchen_2.jpg" style="width: 80%;" />
<p class="caption"><a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> kitchen</p>
</div>
<p>On the opposite site of the space there is also a room with an electronic lab
and some tooling:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar electronic lab" src="/images/tour_de_hackerspace/progressbar/progressbar_electronic_lab.jpg" style="width: 80%;" />
<p class="caption"><a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> electronic lab</p>
</div>
<p>Of course the space also has some awesome decorations:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar animated LED bar" src="/images/tour_de_hackerspace/progressbar/progressbar_decoration.jpg" style="width: 80%;" />
<p class="caption"><a class="reference external" href="https://www.progressbar.sk/">Progressbar</a> animated LED bar</p>
</div>
<p>As soon as Andrew finished fixing his bike, we went to have dinner. He then
continued to show me a bit of Bratislava and the local beer culture.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Outside of Progressbar in the old town" src="/images/tour_de_hackerspace/progressbar/progressbar_outside.jpg" style="width: 80%;" />
<p class="caption">Outside of Progressbar in the old town</p>
</div>
<p>The next day I took a look at the city, which is rather small but pretty. In
the evening I attended the <a class="reference external" href="https://scuttlebot.io/">scuttlebutt</a> workshop in Progressbar. Scuttlebutt
is some kind of distributed cryptographically signed message board, where every
identity has a append only feed. I shortly tested the <a class="reference external" href="https://github.com/ssbc/patchwork">patchwork</a> scuttlebutt
application. For me it felt a bit like a distributed Twitter.</p>
<p>Since a few of the guys there are also Rustaceans we also talked about that,
and they told me that their door lock implementation runs with Rust.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Progressbar door lock system" src="/images/tour_de_hackerspace/progressbar/progressbar_door_lock_system.jpg" style="width: 80%;" />
<p class="caption">Progressbar door lock system</p>
</div>
<p>Later that evening we started to watch some 64k demos, of course including the
two I know of which are written in Rust:</p>
<ul class="simple">
<li><a class="reference external" href="http://www.pouet.net/prod.php?which=69658">Engage</a></li>
<li><a class="reference external" href="https://www.youtube.com/watch?v=rWwNgVwQG1A">Logicoma</a></li>
</ul>
<div class="figure align-center" style="width: 80%">
<img alt="64k demo time with animated LED bar on the left" src="/images/tour_de_hackerspace/progressbar/progressbar_demo_time.jpg" style="width: 80%;" />
<p class="caption">64k demo time with animated LED bar on the left</p>
</div>
<p>I really enjoyed my time in Progressbar and their hospitality was amazing!</p>
</div>
<div class="section" id="visiting-metalab-in-vienna">
<h2>Visiting Metalab in Vienna</h2>
<p>The next day I actually spent in Vienna, which is just a 1h train ride away,
were I visited <a class="reference external" href="https://metalab.at/">Metalab</a>.</p>
<p>The space is located centrally close to the "Rathaus".</p>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab entry" src="/images/tour_de_hackerspace/metalab/metalab_entry.jpg" style="width: 80%;" />
<p class="caption">Metalab entry</p>
</div>
<p>Just on arrival the space was actually empty (but open), because most of the
members were having dinner on the outside. Just moments after that, two
members showed up and I asked them for a tour. But one can't get a tour
without drinking some Mate! So I bought a Flora Power from them after using
their self built "Kassomat" to get some coins!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab Kassomat" src="/images/tour_de_hackerspace/metalab/metalab_kassomat.jpg" style="width: 80%;" />
<p class="caption">Metalab Kassomat</p>
</div>
<p>After that rather impressive start they continued to show me the rest of the
space:</p>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab 3D printers" src="/images/tour_de_hackerspace/metalab/metalab_3d_printer.jpg" style="width: 80%;" />
<p class="caption">Metalab 3D printers</p>
</div>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab almost obligatory laser cutter and electronic lab" src="/images/tour_de_hackerspace/metalab/metalab_laser_cutter_el_lab.jpg" style="width: 80%;" />
<p class="caption">Metalab almost obligatory laser cutter and electronic lab</p>
</div>
<p>What really impressed me was there workshop, containing a decent CNC machine!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab CNC" src="/images/tour_de_hackerspace/metalab/metalab_cnc.jpg" style="width: 80%;" />
<p class="caption">Metalab CNC</p>
</div>
<p>The space actually also includes a big main room, a kitchen, a lounge and some
storage and server rooms. Sadly I didn't take any pictures of them.</p>
<p>While getting rid of my processed Flora Power after the tour, I noticed the
rather beautiful decorations they have in their restrooms!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Metalab restroom decoration" src="/images/tour_de_hackerspace/metalab/metalab_toilet_decoration.jpg" style="width: 80%;" />
<p class="caption">Metalab restroom decoration</p>
</div>
<p>There is even a little screen with a few buttons to play a video game, while
having a longer session.</p>
<p>Since I had only a few hours to spend there, I just briefly attended their
member meeting, were they discussed some Metalab related issues. The rest of
the time I mostly spent talking to some of them.</p>
<p>If you're in Vienna I definitely recommend to check out Metalab, since it is a
quite amazing Hackerspace! I'd loved to spend more time there, but again the
next chapter of my "Tour de Hackerspace" was calling!</p>
</div>
Visiting brmlab2017-04-23T00:00:00+02:002017-04-23T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-23:/visiting-brmlab.html<p class="first last">Visiting brmlab</p>
<p>After a quite pleasant night train ride I arrived around 7am in Prague. This
left me with enough time to book my hotel and get to know the city a bit.</p>
<p>I booked the <a class="reference external" href="http://osmand.net/go?lat=50.090122&lon=14.437044&z=18">A plus Hostel</a> close to the Florenc metro station which is in
the intersection of two metro lines, giving me a great starting point to
explore the city.</p>
<p>Since the <a class="reference external" href="https://brmlab.cz/">brmlab</a> website showed, that the space is apparently open, I
decided to take a look at it quite early in the day. I had some trouble
actually finding the space, so I advice you to use their <a class="reference external" href="https://brmlab.cz/place">well written
description</a> on how to find their space.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the brmlab" src="/images/tour_de_hackerspace/brmlab/brmlab_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the <a class="reference external" href="https://brmlab.cz/">brmlab</a></p>
</div>
<p>The space features some of the usual stuff:</p>
<ul>
<li><p class="first">A big main working room</p>
<blockquote>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/brmlab/brmlab_main_room.jpg"><img alt="brmlab main working room" class="align-center" src="/images/tour_de_hackerspace/brmlab/brmlab_main_room.jpg" style="width: 10%;" /></a>
</blockquote>
</li>
<li><p class="first">A small server room</p>
<blockquote>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/brmlab/brmlab_server_room.jpg"><img alt="brmlab server room" class="align-center" src="/images/tour_de_hackerspace/brmlab/brmlab_server_room.jpg" style="width: 10%;" /></a>
</blockquote>
</li>
<li><p class="first">A workshop</p>
<blockquote>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/brmlab/brmlab_workshop.jpg"><img alt="brmlab workshop" class="align-center" src="/images/tour_de_hackerspace/brmlab/brmlab_workshop.jpg" style="width: 10%;" /></a>
</blockquote>
</li>
</ul>
<p>But what really sets their hackerspace apart from others is that it features a
chemistry and a bio lab!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Parts of the bio lab with a microscope" src="/images/tour_de_hackerspace/brmlab/brmlab_micro_scope.jpg" style="width: 80%;" />
<p class="caption">Parts of the bio lab with a microscope</p>
</div>
<p>We did actually take a look at a small silicon wafer from unknown origin the
same evening.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Looking at a silicon wafer through the microscope" src="/images/tour_de_hackerspace/brmlab/brmlab_micro_scope_silicon.jpg" style="width: 80%;" />
<p class="caption">Looking at a silicon wafer through the microscope</p>
</div>
<p>Inside the bio lab there is also the relax zone / silent room.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Relax zone with awesome graffiti" src="/images/tour_de_hackerspace/brmlab/brmlab_silent_room.jpg" style="width: 80%;" />
<p class="caption">Relax zone with awesome graffiti!</p>
</div>
<p>Quite stunning is their high voltage lab</p>
<div class="figure align-center" style="width: 80%">
<img alt="brmlab high voltage lab" src="/images/tour_de_hackerspace/brmlab/brmlab_high_voltage_lab.jpg" style="width: 80%;" />
<p class="caption">brmlab high voltage lab</p>
</div>
<p>It features some quite huge <a class="reference external" href="images/tour_de_hackerspace/brmlab/brmlab_high_voltage_lab_2.jpg">Tesla coils</a> and other high voltage equipment such
as high voltage capacitors, transformers or high voltage measurement systems.</p>
<p>Also really impressive is the bitcoin ATM they have!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Bitcoin ATM" src="/images/tour_de_hackerspace/brmlab/brmlab_bitcoin_atm.jpg" style="width: 80%;" />
<p class="caption">Bitcoin ATM</p>
</div>
<p>I couldn't resist and <a class="reference external" href="/images/tour_de_hackerspace/brmlab/brmlab_bitcoin_transaction.jpg">bought myself 6 mBTC</a> immediately. They told me that
this is the first prototype of the <a class="reference external" href="https://www.generalbytes.com/first-bitcoin-atm-deployed/">General Bytes bitcoin ATM</a>. It was
installed in their space so they could test it. During testing they found and
reported two security issues, which then could be fixed.</p>
<p>Like most hackerspaces they also have some awesome decorations, in this case a
wall paneled with motherboards.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Wall of motherboards" src="/images/tour_de_hackerspace/brmlab/brmlab_motherboards.jpg" style="width: 80%;" />
<p class="caption">Wall of motherboards</p>
</div>
<p>The also own an <a class="reference external" href="images/tour_de_hackerspace/brmlab/brmlab_ibm.jpg">IBM AS/400 system</a> with a fitting hardware terminal which
gives one some possibilities to discover a mainframe style system.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Terminal connected to the IBM AS/400" src="/images/tour_de_hackerspace/brmlab/brmlab_ibm_terminal.jpg" style="width: 80%;" />
<p class="caption">Terminal connected to the IBM AS/400</p>
</div>
<p>It was real fun interacting with this machine! You can find more information
about it on their <a class="reference external" href="https://brmlab.cz/project/as400/start">wiki</a>.</p>
<p>All in all my Prague and brmlab experience was really amazing! The city is very
beautiful (albeit a bit crowed with tourists) and I enjoyed hanging out with a
few of the brmlab hackers the other night!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Overview of Prague" src="/images/tour_de_hackerspace/brmlab/brmlab_prague.jpg" style="width: 80%;" />
<p class="caption">Overview of Prague</p>
</div>
Visiting Hackerspace Kraków2017-04-19T00:00:00+02:002017-04-19T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-19:/visiting-hackerspace-krakow.html<p class="first last">Visiting Hackerspace Kraków</p>
<p>Since the 3G connection during the train ride was exceptionally bad, I had
trouble with my credit card and the train didn't have electric plugs, I ran out
of battery before I could finish booking a hotel.</p>
<p>So the first thing I did when arriving in Kraków was looking for the
<a class="reference external" href="https://hackerspace-krk.pl/">Hackerspace Kraków</a>. Luckily it's very close to the main train station and
Wiktor, one of the members which talked to me on IRC, was waiting outside to
show me in! This made me feel very welcome!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the Hackerspace Kraków" src="/images/tour_de_hackerspace/krakow/krakow_entry_1.jpg" style="width: 80%;" />
<p class="caption">Entry to the <a class="reference external" href="https://hackerspace-krk.pl/">Hackerspace Kraków</a></p>
</div>
<p>After charging my devices, talking to my credit card company and booking my
hotel, he showed me around. They've actually just moved in a few month ago and
the space isn't yet open for public, so they told me. They are still thinking
about ideas on how to decorate the space. I proposed to make the entry look
like a submarine since the corridor is very narrow and rounded on the top. I'm
looking forward to see what they will do with the space.</p>
<p>The space mainly consist of:</p>
<ul class="simple">
<li>An <a class="reference external" href="/images/tour_de_hackerspace/krakow/krakow_electronic_lab.jpg">electronic lab</a></li>
<li>A <a class="reference external" href="/images/tour_de_hackerspace/krakow/krakow_computer_room.jpg">computer / presentation room</a></li>
<li>A <a class="reference external" href="/images/tour_de_hackerspace/krakow/krakow_work_shop.jpg">workshop room</a></li>
</ul>
<p>In the workshop they actually built the ventilation system themself!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Workshop ventilation system" src="/images/tour_de_hackerspace/krakow/krakow_work_shop_ventilation.jpg" style="width: 80%;" />
<p class="caption">Workshop ventilation system</p>
</div>
<p>And during my visit they actually built a controller board to be able to
regulate the speed of the ventilation system. Was awesome to watch them
getting busy until 1 or 2am.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Workshop ventilation controller" src="/images/tour_de_hackerspace/krakow/krakow_work_shop_ventilation_controlled.jpg" style="width: 80%;" />
<p class="caption">Workshop ventilation with freshly built controller on the bottom right</p>
</div>
<p>They also told me about some past and present projects. In the past they
helped build the lightening system for the Galeria Krakowska, which is a big
shopping mall close to the main train station.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Galeria Krakowska lightening system" src="/images/tour_de_hackerspace/krakow/krakow_galeria.jpg" style="width: 80%;" />
<p class="caption">Galeria Krakowska lightening system</p>
</div>
<p>The green LED wall on the picture can actually change color and also show
different animations and effects.</p>
<p>Another project they are working on is tracking and collecting <a class="reference external" href="https://en.wikipedia.org/wiki/Radiosonde">radiosondes</a>.
This probes are used for weather related analysis and are started with weather
balloons by <a class="reference external" href="http://radiosonde.eu/RS00-D/RS02C-D.html">weather stations</a> all around Europe.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Captured radiosondes" src="/images/tour_de_hackerspace/krakow/krakow_radio_sonde_0.jpg" style="width: 80%;" />
<p class="caption">Captured radiosondes</p>
</div>
<p>One of their member created a <a class="reference external" href="https://hub.docker.com/r/teeed/dxlaprs/">Docker image</a> which contains various software
related to tracking the radiosondes.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Setup used to track radiosondes" src="/images/tour_de_hackerspace/krakow/krakow_radio_sonde_tracking.jpg" style="width: 80%;" />
<p class="caption">Setup used to track radiosondes</p>
</div>
<div class="figure align-center" style="width: 80%">
<img alt="Tracking coverage achieved with the setup above" src="/images/tour_de_hackerspace/krakow/krakow_radio_sonde_coverage.jpg" style="width: 80%;" />
<p class="caption">Tracking coverage achieved with the setup above</p>
</div>
<p>Since I took myself quite some time to have a look at the city (Which is
amazing, I can definitely recommend a visit to the <a class="reference external" href="http://osmand.net/go?lat=50.05451&lon=19.936409&z=17">Wawel Castle</a> and the
<a class="reference external" href="http://osmand.net/go?lat=50.062&lon=19.937761&z=19">underground museum</a>), I only showed up at the hackerspace for a quick goodbye
the other day. But I really enjoyed my stay their nevertheless!</p>
Visiting Warsaw Hackerspace2017-04-17T00:00:00+02:002017-04-17T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-17:/visiting-warsaw-hackerspace.html<p class="first last">Visiting Warsaw Hackerspace</p>
<p>I was warned on IRC that the activity would be rather low in the Warsaw
Hackerspace Due to being Easter. So when I arrived in Warsaw I just monitored
their <a class="reference external" href="http://at.hackerspace.pl/">member tracking site</a> from time to time until it showed some people
being present.</p>
<p>The entry to the space was a bit hard to find, because it's in the basement.
But they later told me, that they will move their space to a different location
next month anyway.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the Warsaw Hackerspace" src="/images/tour_de_hackerspace/warsaw/warsaw_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the <a class="reference external" href="https://www.hackerspace.pl/">Warsaw Hackerspace</a></p>
</div>
<p>On arrival they showed me around their hackerspace. Of course they have a
laser-cutter <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> and some 3D printers.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Laser cutter and 3D printers" src="/images/tour_de_hackerspace/warsaw/warsaw_laser_cutter.jpg" style="width: 80%;" />
<p class="caption">Laser cutter and 3D printers</p>
</div>
<p>I was told, that the <a class="reference external" href="https://www.hackerspace.pl/">Warsaw Hackerspace</a> has around 100 members consisting of
a good mix of computer science, electronic engineering, mechanical engineering
and other people.</p>
<p>What really impressed me was the equipment in their work shop! They have
amongst other stuff a CNC mill and <a class="reference external" href="/images/tour_de_hackerspace/warsaw/warsaw_work_show_cnc_lathe.jpg">lathe</a>, which they control using
<a class="reference external" href="http://linuxcnc.org/">linuxcnc</a>.</p>
<div class="figure align-center" style="width: 80%">
<img alt="CNC mill" src="/images/tour_de_hackerspace/warsaw/warsaw_work_shop_cnc.jpg" style="width: 80%;" />
<p class="caption">CNC mill</p>
</div>
<p>They also have equipment to produce their own PCBs, using a cheap UV nail
curing lamp.</p>
<div class="figure align-center" style="width: 80%">
<img alt="PCB manufactoring equipment" src="/images/tour_de_hackerspace/warsaw/warsaw_pcb_manufactoring.jpg" style="width: 80%;" />
<p class="caption">PCB manufactoring equipment</p>
</div>
<p>Also impressive was their retro computing collection! Amongst other devices
they own a VT520 terminal which they use to print the messages posted on IRC.</p>
<div class="figure align-center" style="width: 80%">
<img alt="VT520 terminal" src="/images/tour_de_hackerspace/warsaw/warsaw_vt520.jpg" style="width: 80%;" />
<p class="caption">VT520 terminal used to print IRC messages</p>
</div>
<p>When I asked for a beverage, they showed me there vending machine, which is
broken and can't accept coins anymore. But stand back, they hacked it to hook
up with their internal payment system! It's apparently as simple as hooking up
a Raspberry Pi to the <a class="reference external" href="https://en.wikipedia.org/wiki/Multidrop_bus#MDB_in_Vending_Machines">Multidrop bus</a> to control the machine.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Hacked vending machine" src="/images/tour_de_hackerspace/warsaw/warsaw_vending_machine.jpg" style="width: 80%;" />
<p class="caption">Hacked vending machine</p>
</div>
<p>Later in the evening I had an awesome debugging session with one of their
members who tried to intercept C library calls (This was part of an university
assignment). Since I never looked into how dynamic linking works in Linux,
this was very interesting for me! Maybe I'll write a separate blog post about
that if I find time to dig a bit deeper into the topic.</p>
<p>I really enjoyed the time I spent with this awesome and very active
hackerspace! My next stop will be Hackerspace Kraków!</p>
<table class="docutils footnote" frame="void" id="footnote-1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>We should really get a laser-cutter for coredump. This will be the first thing I will do when I return!</td></tr>
</tbody>
</table>
Visiting c-base2017-04-15T00:00:00+02:002017-04-15T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-15:/visiting-c-base.html<p class="first last">Visiting c-base</p>
<p>After an exhausting train ride from Amsterdam to Berlin which started at 20.25
and ended at 5.33 the next day, I discovered that I couldn't get a train the
same day to Warsaw since they were all fully booked!</p>
<p>So my plans changed a bit and I would stay a full day in Berlin which was nice
in some way because it meant I could visit <a class="reference external" href="https://www.c-base.org/">c-base</a> in the evening!</p>
<p>Also I discovered by coincidence that a few friends of mine from Switzerland
were staying in Berlin this weekend and I could hang out with them during the
day. I also met with <a class="reference external" href="https://twitter.com/andrewhobden">@andrewhobden</a> in Berlin, whom I met at <a class="reference external" href="http://2016.rustfest.eu/">RustFest
2016</a> last year. This was a very awesome coincidence, since we didn't plan
any of it and we just ended up meeting in Berlin and having a great time
together!</p>
<p>So after dinner we split again and I headed towards c-base. c-base is located
near the "Jannowitzbrücke" and thus very easily reachable with public
transport.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the c-base" src="/images/tour_de_hackerspace/cbase/cbase_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the c-base</p>
</div>
<p>When entering c-base I was amazed because of all the very nicely done
decoration they have inside which leads to a great atmosphere!</p>
<div class="figure align-center" style="width: 80%">
<img alt="The Mate light" src="/images/tour_de_hackerspace/cbase/cbase_mate_light.jpg" style="width: 80%;" />
<p class="caption">The Mate light inside c-base</p>
</div>
<p>The members in the space were a bit busy because they had their "circle"
meeting. So I just started talking to the members not attending the meeting
and somehow got pretty absorbed giving one of them a rather in depth
introduction to basic embedded development using amongst other things</p>
<ul class="simple">
<li><a class="reference external" href="https://www.arduino.cc/">Arduino</a></li>
<li><a class="reference external" href="http://www.nongnu.org/avrdude/">avrdude</a></li>
<li><a class="reference external" href="http://openocd.org/">openocd</a></li>
<li><a class="reference external" href="https://www.segger.com/jlink-debug-probes.html">J-Link</a> debuggers</li>
<li><a class="reference external" href="http://kicad-pcb.org/">KiCad</a> / <a class="reference external" href="http://librepcb.org/">LibrePCB</a></li>
<li><a class="reference external" href="http://dangerousprototypes.com/docs/Bus_Pirate">Bus Pirate</a></li>
<li><a class="reference external" href="https://www.i2c-bus.org/">I2C</a></li>
</ul>
<p>(This list serves primarily as a reference for him in case he forgot to
bookmark them ;)</p>
<p>Since I was still very tired from the lack of sleep during the train ride from
Amsterdam to Berlin I originally planed to stay no longer as midnight. But
since I got really busy and was invited to be given a show around the crashed
space station around 1am, I stayed until 2:30am.</p>
<p>The guided tour through the spaceship was pretty awesome, thanks again to my
guide! Since I didn't really take any pictures I recommend you to visit
<a class="reference external" href="https://www.c-base.org/">c-base</a> by yourself if you're around Berlin next time!</p>
Visiting Technologia Incognita2017-04-13T00:00:00+02:002017-04-13T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-13:/visiting-technologia-incognita.html<p class="first last">Visiting Technologia Incognita</p>
<p>Getting a place to stay in Amsterdam was harder then I thought due to the fact,
that a lot of hotels and hostels where fully or almost fully booked! I still
got a room after a bit of hassle (Thanks to this booking sites "only two rooms
left, book them now!", I accidentally booked "1 bed in the women sleeping
room", silly me) in the "WOW Amsterdam" hostel. It's not that close to the
center, but reachable with either bus or the metro.</p>
<p>After the train ride from Düsseldorf and a bus ride to my hostel I took the
metro to <a class="reference external" href="http://technologia-incognita.nl/">Technologia Incognita</a>.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the Technologia Incognita" src="/images/tour_de_hackerspace/techinc/techinc_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the Technologia Incognita</p>
</div>
<p>The space features the usual stuff with a kitchen, a <a class="reference external" href="/images/tour_de_hackerspace/techinc/techinc_vending_machine_laser_cutter.jpg">laser-cutter</a> (if you
look closely you will see they sell the Diplomatic Passport in their vending
machine on the left), a work shop and of course some <a class="reference external" href="/images/tour_de_hackerspace/techinc/techinc_LED_ball.jpg">awesome decoration</a>!</p>
<div class="figure align-center" style="width: 80%">
<img alt="animated LED fire place" src="/images/tour_de_hackerspace/techinc/techinc_fire.jpg" style="width: 80%;" />
<p class="caption">Animated LED fire place</p>
</div>
<p>I had the luck to arrive when they had their visiting day, so lots of people
where around. Also sine the next day was the <a class="reference external" href="https://conference.hitb.org/">Hack in the Box</a> conference
some attendees of this conference where there as well. I even met some guys
from the <a class="reference external" href="https://www.nycresistor.com/">NYC Resistor</a> which invited me to have a look at their hackerspace
next time I'm in New York (which will be around June). They told me about a
project where they create almost impossible to solve <a class="reference external" href="https://trmm.net/Platonic_puzzle">puzzles</a>.</p>
<p>I also met <a class="reference external" href="http://www.sasj.nl/">Saskia Freeke</a> who creates amazing digital art!</p>
<div class="figure align-center" style="width: 80%">
<img alt="Example of Saskias art" src="http://www.sasj.nl/W14/wp-content/uploads/2014/06/160518.gif" style="width: 80%;" />
<p class="caption">Example of Saskias creative programming / digital art</p>
</div>
<p>She has a project where she creates similar work every single day since 2015!</p>
<p>There was also a cheese, sausage and beer tasting on the same evening which I,
as a Swiss guy, definitely approve!</p>
<div class="figure align-center" style="width: 80%">
<img alt="cheese tasting" src="/images/tour_de_hackerspace/techinc/techinc_cheese_tasting.jpg" style="width: 80%;" />
<p class="caption">Cheese and sausage tasting</p>
</div>
<p>The next day I spontaneously attended the <a class="reference external" href="https://conference.hitb.org/">Hack in the Box</a> conference where
hackerspaces from the Netherlands also had booths. I really enjoyed <a class="reference external" href="http://toool.us/">Toools</a>
lock-picking booth and the talk of Jos Weyers <a class="reference external" href="http://conference.hitb.org/hitbsecconf2017ams/sessions/most-impressive-a-guide-to-key-impressioning-attacks/">Most Impressive: A Guide to Key
Impressioning Attacks</a>.</p>
<p>While I really enjoyed my stay in Amsterdam and with <a class="reference external" href="http://technologia-incognita.nl/">Technologia Incognita</a>
and almost replanned my trip to spend a few more days there, I decided to stick
with my plan for once and travel to Warsaw via Berlin, with a short stop to
visit c-base.</p>
Visiting the chaosdorf2017-04-11T00:00:00+02:002017-04-11T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-11:/visiting-the-chaosdorf.html<p class="first last">Visiting the chaosdorf</p>
<p>While my original "plan" involved traveling directly to Amsterdam from
Stuttgart, the shackspace guys suggested to visit chaosdorf in Düsseldorf,
since it is halfway to Amsterdam anyway.</p>
<p>After asking if anybody will be present on their IRC channel #chaosdorf, I
decided to stay two days in Düsseldorf.</p>
<p>Chaosdorf is awesomely close, just a 20min foot-walk, to the Düsseldorf main
station! Also quite close is the Hostel A&O where I could stay.</p>
<div class="figure align-center" style="width: 80%">
<img alt="chaosdorf location" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_location.png" style="width: 80%;" />
<p class="caption"><a class="reference external" href="http://www.openstreetmap.org/?lat=51.217974999999996&lon=6.788995&zoom=16&layers=M&mlat=51.21656&mlon=6.78347">chaosdorf location</a></p>
</div>
<p>Due to the central location and their prominent front door, they have some
random strangers walking in from time to time, which is pretty awesome!</p>
<div class="figure align-center" style="width: 80%">
<img alt="chaosdorf entrance" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_entrance.jpg" style="width: 80%;" />
<p class="caption">chaosdorf entrance</p>
</div>
<p>For the 130 members they have, the rooms is already getting small, but is with
its 160m² still huge compared to coredump!</p>
<div class="figure align-center" style="width: 80%">
<img alt="main chaosdorf room" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_main_room_1.jpg" style="width: 80%;" />
<p class="caption">main chaosdorf room</p>
</div>
<p>Their space features:</p>
<ul class="simple">
<li>A laptop lounge with presentation screen</li>
</ul>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/chaosdorf/chaosdorf_main_room_0.jpg"><img alt="chaosdorf laptop lounge" class="align-center" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_main_room_0.jpg" style="width: 10%;" /></a>
<ul class="simple">
<li>A kitchen (with a nice hack for the <a class="reference external" href="/images/tour_de_hackerspace/chaosdorf/chaosdorf_kitchen_hack.jpg">hood ventilator light</a>)</li>
</ul>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/chaosdorf/chaosdorf_kitchen.jpg"><img alt="chaosdorf kitchen" class="align-center" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_kitchen.jpg" style="width: 10%;" /></a>
<ul class="simple">
<li>A laser cutter and 3D printers</li>
</ul>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/chaosdorf/chaosdorf_laser_cutter.jpg"><img alt="chaosdorf laser cutter / 3D printer" class="align-center" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_laser_cutter.jpg" style="width: 10%;" /></a>
<ul class="simple">
<li>A combined smoking, TV and workshop room</li>
</ul>
<a class="reference external image-reference" href="/images/tour_de_hackerspace/chaosdorf/chaosdorf_work_shop.jpg"><img alt="chaosdorf work shop" class="align-center" src="/images/tour_de_hackerspace/chaosdorf/chaosdorf_work_shop.jpg" style="width: 10%;" /></a>
<p>Similar to shackspace some members in chaosdorf also cook dinner for the group
and I could join them on Tuesday evening. Having a nice kitchen in your space
seems to pay off!</p>
<p>Due to visiting in the midst of the week and not during the weekend, I couldn't
experience the full chaosdorf experience. I would love to stay until Friday to
experience the <a class="reference external" href="https://wiki.chaosdorf.de/Freitagsfoo">Freitagsfoo</a>, but Amsterdam is calling!</p>
Visiting the shackspace2017-04-09T00:00:00+02:002017-04-09T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-09:/visiting-the-shackspace.html<p class="first last">Visiting the shackspace</p>
<p>I arrived at Stuttgart at 5 pm. During the train ride I asked on the
#shackspace IRC channel if somebody could recommend a place to stay. All they
told me was I should avoid the "Ambiente". So I booked a hotel room close to
the <a class="reference external" href="https://shack.space">shackspace</a> which is 15 minutes from the main train station.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Me and Ferris arriving in Stuttgart" src="/images/tour_de_hackerspace/shackspace/arrival_stuttgart.jpg" style="width: 80%;" />
<p class="caption">Me and <a class="reference external" href="http://www.rustacean.net/">Ferris</a> arriving in Stuttgart.</p>
</div>
<p>Soon after arriving at the hotel I went to the shackspace.</p>
<div class="figure align-center" style="width: 80%">
<img alt="Entry to the shackspace" src="/images/tour_de_hackerspace/shackspace/shack_entry.jpg" style="width: 80%;" />
<p class="caption">Entry to the shackspace.</p>
</div>
<p>I had the luck that they were giving a tour to some visitors just when I
arrived, so I could join them.</p>
<p>Coming from the rather small hackerspace <a class="reference external" href="https://coredump.ch">coredump</a> from Switzerland,
shackspace is huge!</p>
<div class="figure align-center" style="width: 80%">
<img alt="shackspace IT infrastructure" src="/images/tour_de_hackerspace/shackspace/shack_it.jpg" style="width: 80%;" />
<p class="caption">shackspace IT infrastructure.</p>
</div>
<p>They have around 400m² of room in their space, given them the possibility to have:</p>
<ul class="simple">
<li>A kitchen</li>
<li>A big main working room</li>
<li>A machine room with <a class="reference external" href="/images/tour_de_hackerspace/shackspace/shack_laser_cutter.jpg">laser-cutter</a>, 3D-printer, ...</li>
<li>A <a class="reference external" href="/images/tour_de_hackerspace/shackspace/shack_work_shop.jpg">work shop</a> with drilling machines, saws etc.</li>
<li>A silent room, mainly used by student for learning</li>
<li>A <a class="reference external" href="/images/tour_de_hackerspace/shackspace/shack_conference_room.jpg">conference room</a></li>
<li><a class="reference external" href="/images/tour_de_hackerspace/shackspace/shack_roof.jpg">Amateur radio station</a> with <a class="reference external" href="/images/tour_de_hackerspace/shackspace/shack_view.jpg">antennas</a> on the roof</li>
<li>Around 200 members</li>
</ul>
<p>Like every hackerspace they have lots of beautiful installations arround, like
a Back to the Future themed clock which also shows the founding date.</p>
<div class="figure align-center" style="width: 80%">
<img alt="shackspace founding date" src="/images/tour_de_hackerspace/shackspace/shack_founding_date.jpg" style="width: 80%;" />
<p class="caption">Back to the Future themed clock</p>
</div>
<p>They also have a beautiful installation showing the open status of various
hackerspaces, gathered via the <a class="reference external" href="https://spacedirectory.org/">SpaceAPI</a></p>
<div class="figure align-center" style="width: 80%">
<img alt="SpaceAPI status wall" src="/images/tour_de_hackerspace/shackspace/shack_spaceapi_status.jpg" style="width: 80%;" />
<p class="caption">SpaceAPI status wall</p>
</div>
<p>Since a member of the space was preparing food for dinner, they invited me
spontaneously to join them! This was awesome, since it meant spending more time
hacking and less searching for food ;)</p>
<p>Later I joined the conference room, discussing ideas for the <a class="reference external" href="https://2017.spaceappschallenge.org/">Space Apps
Challenge 2017</a> for which the shakspace hosts a <a class="reference external" href="https://2017.spaceappschallenge.org/locations/stuttgart/">hackathon</a>. Last year they
came up with a project to optimize the growth of plants with machine learning.</p>
<div class="figure align-center" style="width: 80%">
<img alt="shackspace plant experiment" src="/images/tour_de_hackerspace/shackspace/shack_space_apps_2016.jpg" style="width: 80%;" />
<p class="caption">shackspace plant experiment for Space Apps Challenge 2016</p>
</div>
<p>I really enjoyed my stay at shackspace! It's a great hackerspace with lots of
creative and technically gifted people hacking on awesome projects.</p>
Starting my "Tour de Hackerspace"2017-04-08T00:00:00+02:002017-04-08T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2017-04-08:/starting-my-tour-de-hackerspace.html<p class="first last">Starting my "Tour de Hackerspace"</p>
<p>Today I start what I call my "Tour de Hackerspace"! I'll be travelling around
Europe and visit various <a class="reference external" href="https://wiki.hackerspaces.org/">hackerspaces</a> on the way. To keep travel costs at a
reasonable level, I bought an <a class="reference external" href="http://www.interrail.eu/en">InterRail</a> ticket, which allows flexible
travelling by train.</p>
<img alt="Map of Europe from https://wiki.hackerspaces.org/Europe" class="align-center" src="/images/tour_de_hackerspace/map_europe.png" style="width: 100%;" />
<p>Since I'm not the kind of person which is great at planing, this will be more
or less a spontaneous adventure. I contacted some hackerspaces upfront and
received some great and welcoming responses, especially from the Eastern part
of Europe!</p>
<p>My first location will be the <a class="reference external" href="https://shack.space/">shackerspace</a> in Stuttgart, Germany. After that
I plan to visit a hackerspace in Amsterdam, then travelling a bit in the east
(Czech Republic, Poland, ...) and probably attend the <a class="reference external" href="http://2017.rustfest.eu/">RustFest 2017</a> in Kyiv,
Ukraine.</p>
<p>According to my definitely not definitive plan I will then travel southwards
visiting Romania, Bulgaria, Croatia, Serbia, Bosnia and Herzegovina, Slovenia,
... before returning to Switzerland.</p>
<p>I'm really looking forward to meet lots of amazing people and see how they live
and hack around Europe!</p>
<p>I will try to write a blog post about every hackerspace I visit on my journey,
so stay tuned.</p>
Switching from SLiM to LightDM2017-01-22T00:00:00+01:002017-01-22T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2017-01-22:/switching-from-slim-to-lightdm.html<p class="first last">Switching from SLiM to LightDM</p>
<p>For a long time I have been using <a class="reference external" href="https://wiki.archlinux.org/index.php/SLiM">SLiM</a> as my display manager on ArchLinux.
It worked quite well for me, but is unmaintained since at least 3 years. Also
according to the <a class="reference external" href="https://wiki.archlinux.org/index.php/SLiM">ArchLinux WiKi</a> there are issues regarding to systemd
compatibility. Also the Linux desktop is headed towards Wayland so I need a
display manager which can start Wayland sessions.</p>
<p>So my choice fell on <a class="reference external" href="https://freedesktop.org/wiki/Software/LightDM/">LightDM</a>, which should "support different display
technologies (X, Mir, Wayland, ...)" according to their website.</p>
<p>Installing it on ArchLinux is as easy as:</p>
<div class="highlight"><pre><span></span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>lightdm-gtk-greeter
</pre></div>
<p>Then we need to deactivate SLiM and activate LightDM:</p>
<div class="highlight"><pre><span></span>sudo<span class="w"> </span>systemctl<span class="w"> </span>disable<span class="w"> </span>slim.service
sudo<span class="w"> </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>lightdm.service
</pre></div>
<p>To switch without a reboot one needs to logout from the X-session, switch to a
TTY with Ctrl-Alt-1 and stop SLiM and start LightDM:</p>
<div class="highlight"><pre><span></span>sudo<span class="w"> </span>systemctl<span class="w"> </span>stop<span class="w"> </span>slim.service
sudo<span class="w"> </span>systemctl<span class="w"> </span>start<span class="w"> </span>lightdm.service
</pre></div>
<p>After that I could login just to notice that my <cite>~/.xinitrc</cite> wasn't getting
executed, so my helper tools like nm-applet weren't running. Since I already
solved that issue under <a class="reference external" href="https://rnestler.github.io/setting-up-the-awesome-window-manager-in-ubuntu-1604.html">Ubuntu</a>, I was a bit surprised that I need to solve
it differently under ArchLinux according to <a class="reference external" href="https://wiki.archlinux.org/index.php/LightDM#Migrating_from_SLiM">the WiKi</a>:</p>
<div class="highlight"><pre><span></span>mv<span class="w"> </span>~/.xinitrc<span class="w"> </span>~/.xprofile
vim<span class="w"> </span>~/.xprofile<span class="w"> </span><span class="c1"># remove the "exec awesome" line</span>
</pre></div>
<p>Finally, I enjoy a working X-Session with the <a class="reference external" href="https://awesomewm.org/">awesome window manager</a> again,
while looking forward to a Wayland based desktop, maybe running the <a class="reference external" href="https://github.com/Immington-Industries/way-cooler">Way
Cooler</a> window manager!</p>
Fixing a Corrupt mandb Database2016-11-26T00:00:00+01:002016-11-26T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2016-11-26:/fixing-a-corrupt-mandb-database.html<p class="first last">Fixing a corrupt mandb database</p>
<p>Recently, probably due to an unexpected power failure, the <a class="reference external" href="https://wiki.archlinux.org/index.php/Man_page">man page</a> cache on
my machine which is managed by <tt class="docutils literal">mandb</tt> got corrupt. I noticed when
<tt class="docutils literal">systemctl</tt> showed the <tt class="docutils literal"><span class="pre">man-db.service</span></tt> as failed:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>sudo<span class="w"> </span>systemctl
...
●<span class="w"> </span>man-db.service<span class="w"> </span>loaded<span class="w"> </span>failed<span class="w"> </span>failed<span class="w"> </span>Update<span class="w"> </span>man-db<span class="w"> </span>cache
...
</pre></div>
<p><tt class="docutils literal">systemctl status</tt> didn't reveal that much information on the issue:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span>status<span class="w"> </span>man-db.service
●<span class="w"> </span>man-db.service<span class="w"> </span>-<span class="w"> </span>Update<span class="w"> </span>man-db<span class="w"> </span>cache
<span class="w"> </span>Loaded:<span class="w"> </span>loaded<span class="w"> </span><span class="o">(</span>/usr/lib/systemd/system/man-db.service<span class="p">;</span><span class="w"> </span>static<span class="p">;</span><span class="w"> </span>vendor<span class="w"> </span>preset:<span class="w"> </span>disabled<span class="o">)</span>
<span class="w"> </span>Active:<span class="w"> </span>failed<span class="w"> </span><span class="o">(</span>Result:<span class="w"> </span>exit-code<span class="o">)</span><span class="w"> </span>since<span class="w"> </span>Sam<span class="w"> </span><span class="m">2016</span>-11-26<span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>CET<span class="p">;</span><span class="w"> </span>10min<span class="w"> </span>ago
<span class="w"> </span>Process:<span class="w"> </span><span class="m">23481</span><span class="w"> </span><span class="nv">ExecStart</span><span class="o">=</span>/usr/bin/mandb<span class="w"> </span><span class="o">(</span><span class="nv">code</span><span class="o">=</span>exited,<span class="w"> </span><span class="nv">status</span><span class="o">=</span><span class="m">1</span>/FAILURE<span class="o">)</span>
<span class="w"> </span>Process:<span class="w"> </span><span class="m">23475</span><span class="w"> </span><span class="nv">ExecStart</span><span class="o">=</span>/usr/bin/mkdir<span class="w"> </span>-p<span class="w"> </span>/var/cache/man<span class="w"> </span><span class="o">(</span><span class="nv">code</span><span class="o">=</span>exited,<span class="w"> </span><span class="nv">status</span><span class="o">=</span><span class="m">0</span>/SUCCESS<span class="o">)</span>
<span class="w"> </span>Main<span class="w"> </span>PID:<span class="w"> </span><span class="m">23481</span><span class="w"> </span><span class="o">(</span><span class="nv">code</span><span class="o">=</span>exited,<span class="w"> </span><span class="nv">status</span><span class="o">=</span><span class="m">1</span>/FAILURE<span class="o">)</span>
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Handbuchseiten<span class="w"> </span>unter<span class="w"> </span>/usr/share/man/ru.KOI8-R<span class="w"> </span>werden<span class="w"> </span>verar
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Alte<span class="w"> </span>Datenbankeinträge<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man/tr<span class="w"> </span>werden<span class="w"> </span>gelösch
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Handbuchseiten<span class="w"> </span>unter<span class="w"> </span>/usr/share/man/tr<span class="w"> </span>werden<span class="w"> </span>verarbeitet
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Alte<span class="w"> </span>Datenbankeinträge<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man/fi<span class="w"> </span>werden<span class="w"> </span>gelösch
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Handbuchseiten<span class="w"> </span>unter<span class="w"> </span>/usr/share/man/fi<span class="w"> </span>werden<span class="w"> </span>verarbeitet
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>mandb<span class="o">[</span><span class="m">23481</span><span class="o">]</span>:<span class="w"> </span>Alte<span class="w"> </span>Datenbankeinträge<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man/zh<span class="w"> </span>werden<span class="w"> </span>gelösch
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>systemd<span class="o">[</span><span class="m">1</span><span class="o">]</span>:<span class="w"> </span>man-db.service:<span class="w"> </span>Main<span class="w"> </span>process<span class="w"> </span>exited,<span class="w"> </span><span class="nv">code</span><span class="o">=</span>exited,<span class="w"> </span><span class="nv">status</span><span class="o">=</span><span class="m">1</span>/F
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>systemd<span class="o">[</span><span class="m">1</span><span class="o">]</span>:<span class="w"> </span>Failed<span class="w"> </span>to<span class="w"> </span>start<span class="w"> </span>Update<span class="w"> </span>man-db<span class="w"> </span>cache.
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>systemd<span class="o">[</span><span class="m">1</span><span class="o">]</span>:<span class="w"> </span>man-db.service:<span class="w"> </span>Unit<span class="w"> </span>entered<span class="w"> </span>failed<span class="w"> </span>state.
Nov<span class="w"> </span><span class="m">26</span><span class="w"> </span><span class="m">16</span>:47:53<span class="w"> </span>tuxedo<span class="w"> </span>systemd<span class="o">[</span><span class="m">1</span><span class="o">]</span>:<span class="w"> </span>man-db.service:<span class="w"> </span>Failed<span class="w"> </span>with<span class="w"> </span>result<span class="w"> </span><span class="s1">'exit-code'</span>.
</pre></div>
<p>So I ran <tt class="docutils literal">mandb</tt> manually to figure out what was wrong:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>sudo<span class="w"> </span>mandb
Purging<span class="w"> </span>old<span class="w"> </span>database<span class="w"> </span>entries<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man...
Processing<span class="w"> </span>manual<span class="w"> </span>pages<span class="w"> </span>under<span class="w"> </span>/usr/share/man...
Purging<span class="w"> </span>old<span class="w"> </span>database<span class="w"> </span>entries<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man/sr@latin...
Processing<span class="w"> </span>manual<span class="w"> </span>pages<span class="w"> </span>under<span class="w"> </span>/usr/share/man/sr@latin...
...
Purging<span class="w"> </span>old<span class="w"> </span>database<span class="w"> </span>entries<span class="w"> </span><span class="k">in</span><span class="w"> </span>/usr/share/man/zh...
gdbm<span class="w"> </span>fatal:<span class="w"> </span>Unexpected<span class="w"> </span>end<span class="w"> </span>of<span class="w"> </span>file
</pre></div>
<p>So gdbm seemed to have some problem. Since I didn't know what <tt class="docutils literal">gdbm</tt> was, I
asked the all knowingly package manager of ArchLinux:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>pacman<span class="w"> </span>-Qi<span class="w"> </span>gdbm
Name<span class="w"> </span>:<span class="w"> </span>gdbm
Version<span class="w"> </span>:<span class="w"> </span><span class="m">1</span>.12-2
Description<span class="w"> </span>:<span class="w"> </span>GNU<span class="w"> </span>database<span class="w"> </span>library
...
</pre></div>
<p>Since it is a database library I assumed that the database must be corrupt.
Lucky enough <tt class="docutils literal">mandb</tt> provides an option to create the database from scratch:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>sudo<span class="w"> </span>mandb<span class="w"> </span>-c
Processing<span class="w"> </span>manual<span class="w"> </span>pages<span class="w"> </span>under<span class="w"> </span>/usr/share/man...
Updating<span class="w"> </span>index<span class="w"> </span>cache<span class="w"> </span><span class="k">for</span><span class="w"> </span>path<span class="w"> </span><span class="sb">`</span>/usr/share/man/man1<span class="err">'</span>.<span class="w"> </span>Wait...mandb:<span class="w"> </span>warning:<span class="w"> </span>/usr/share/man/man1/gdk-pixbuf-csource.1.gz:<span class="w"> </span>whatis<span class="w"> </span>parse<span class="w"> </span><span class="k">for</span><span class="w"> </span>gdk-pixbuf-csource<span class="o">(</span><span class="m">1</span><span class="o">)</span><span class="w"> </span>failed
mandb:<span class="w"> </span>warning:<span class="w"> </span>/usr/share/man/man1/gdk-pixbuf-query-loaders.1.gz:<span class="w"> </span>whatis<span class="w"> </span>parse<span class="w"> </span><span class="k">for</span><span class="w"> </span>gdk-pixbuf-query-loaders<span class="o">(</span><span class="m">1</span><span class="o">)</span><span class="w"> </span>failed
...
Processing<span class="w"> </span>manual<span class="w"> </span>pages<span class="w"> </span>under<span class="w"> </span>/usr/local/man...
<span class="m">124</span><span class="w"> </span>man<span class="w"> </span>subdirectories<span class="w"> </span>contained<span class="w"> </span>newer<span class="w"> </span>manual<span class="w"> </span>pages.
<span class="m">22844</span><span class="w"> </span>manual<span class="w"> </span>pages<span class="w"> </span>were<span class="w"> </span>added.
<span class="m">0</span><span class="w"> </span>stray<span class="w"> </span>cats<span class="w"> </span>were<span class="w"> </span>added.
</pre></div>
<p>It spilled my screen with lots of <a class="reference external" href="https://gist.github.com/rnestler/0ad8fdeb54e732922721bd4ef785a8d9#file-mandb_c_output-txt">output and warnings</a>, but seemed to finish
properly.</p>
<p>It didn't help though and <tt class="docutils literal">mandb</tt> still failed. Looking at the output again I
noticed the line <tt class="docutils literal">Purging old database entries in <span class="pre">/usr/share/man/zh...</span></tt>. To
see which package placed its manpage there I queried pacman again:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span><span class="nv">LANG</span><span class="o">=</span>C<span class="w"> </span>pacman<span class="w"> </span>-Qo<span class="w"> </span>/usr/share/man/zh
/usr/share/man/zh/<span class="w"> </span>is<span class="w"> </span>owned<span class="w"> </span>by<span class="w"> </span>nmap<span class="w"> </span><span class="m">7</span>.31-1
</pre></div>
<p>So I tried to uninstall and reinstall nmap:</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-R<span class="w"> </span>nmap
%<span class="w"> </span>sudo<span class="w"> </span>mandb
%<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>nmap
%<span class="w"> </span>sudo<span class="w"> </span>mandb
</pre></div>
<p>And this time it finally worked! I'm still not sure what exactly triggered the
failure in the first place, but I'm not sure how to further debug it.</p>
Verify Every Single Commit on a git rebase2016-10-31T00:00:00+01:002016-10-31T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2016-10-31:/verify-every-single-commit-on-a-git-rebase.html<p class="first last">Check every commit when reordering commits with git rebase -i</p>
<p>Sometimes when one uses <tt class="docutils literal">git rebase <span class="pre">-i</span></tt> to reorder, split or merge commits,
we screw up the commits in between without noticing, since the final commit
compiles and passes every unit test.</p>
<p>For example imagine we have this little Rust code:</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Hello, world!"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Now we want to show how nicely Rust can print a <tt class="docutils literal"><span class="pre">std::Vec</span></tt> so we create a
branch: <tt class="docutils literal">git checkout <span class="pre">-b</span> add_vector</tt> and add the following:</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">];</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"v: {:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Hello, world!"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This will compile and give us some wonderful output:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>cargo<span class="w"> </span>run
v:<span class="w"> </span><span class="o">[</span><span class="m">1</span>,<span class="w"> </span><span class="m">2</span>,<span class="w"> </span><span class="m">3</span><span class="o">]</span>
Hello,<span class="w"> </span>world!
</pre></div>
<p>We are satisfied with the changes and commit it:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>git<span class="w"> </span>add<span class="w"> </span>src/main.rs
$<span class="w"> </span>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Print vector"</span>
</pre></div>
<p>We than add some more code to show the length of our fancy vector:</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">];</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"v: {:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Hello, world!"</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"v.len(): {}"</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">len</span><span class="p">());</span>
<span class="p">}</span>
</pre></div>
<p>This also works just fine so we commit it:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>git<span class="w"> </span>add<span class="w"> </span>src/main.rs
$<span class="w"> </span>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"Print length of vector"</span>
</pre></div>
<p>But of course we are not satisfied with the commit history and want to
rearrange our two commits. So we do a interactive rebase:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>git<span class="w"> </span>rebase<span class="w"> </span>-i<span class="w"> </span>master
pick<span class="w"> </span>8fc4573<span class="w"> </span>Print<span class="w"> </span>length<span class="w"> </span>of<span class="w"> </span>vector
pick<span class="w"> </span>6d22bd9<span class="w"> </span>Print<span class="w"> </span>vector
</pre></div>
<p>This will succeed without error and we still receive the correct output:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>cargo<span class="w"> </span>run
v:<span class="w"> </span><span class="o">[</span><span class="m">1</span>,<span class="w"> </span><span class="m">2</span>,<span class="w"> </span><span class="m">3</span><span class="o">]</span>
Hello,<span class="w"> </span>world!
v.len<span class="o">()</span>:<span class="w"> </span><span class="m">3</span>
</pre></div>
<p>But we introduced a broken commit while rebasing! To detect this we can run the
following:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>git<span class="w"> </span>rebase<span class="w"> </span>-i<span class="w"> </span>master<span class="w"> </span>-x<span class="w"> </span><span class="s2">"cargo build"</span>
Executing:<span class="w"> </span>cargo<span class="w"> </span>build
<span class="w"> </span>Compiling<span class="w"> </span>git_rebase_x_test<span class="w"> </span>v0.1.0<span class="w"> </span><span class="o">(</span>file:///home/rnestler/proggen/git_rebase_x_test<span class="o">)</span>
error<span class="o">[</span>E0425<span class="o">]</span>:<span class="w"> </span>unresolved<span class="w"> </span>name<span class="w"> </span><span class="sb">`</span>v<span class="sb">`</span>
<span class="w"> </span>--><span class="w"> </span>src/main.rs:4:29
<span class="w"> </span><span class="p">|</span>
<span class="m">4</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>println!<span class="o">(</span><span class="s2">"v.len(): {}"</span>,<span class="w"> </span>v.len<span class="o">())</span><span class="p">;</span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span>^
<std<span class="w"> </span>macros>:2:27:<span class="w"> </span><span class="m">2</span>:58<span class="w"> </span>note:<span class="w"> </span><span class="k">in</span><span class="w"> </span>this<span class="w"> </span>expansion<span class="w"> </span>of<span class="w"> </span>format_args!
<std<span class="w"> </span>macros>:3:1:<span class="w"> </span><span class="m">3</span>:54<span class="w"> </span>note:<span class="w"> </span><span class="k">in</span><span class="w"> </span>this<span class="w"> </span>expansion<span class="w"> </span>of<span class="w"> </span>print!<span class="w"> </span><span class="o">(</span>defined<span class="w"> </span><span class="k">in</span><span class="w"> </span><std<span class="w"> </span>macros><span class="o">)</span>
src/main.rs:4:5:<span class="w"> </span><span class="m">4</span>:38<span class="w"> </span>note:<span class="w"> </span><span class="k">in</span><span class="w"> </span>this<span class="w"> </span>expansion<span class="w"> </span>of<span class="w"> </span>println!<span class="w"> </span><span class="o">(</span>defined<span class="w"> </span><span class="k">in</span><span class="w"> </span><std<span class="w"> </span>macros><span class="o">)</span>
error:<span class="w"> </span>aborting<span class="w"> </span>due<span class="w"> </span>to<span class="w"> </span>previous<span class="w"> </span>error
error:<span class="w"> </span>Could<span class="w"> </span>not<span class="w"> </span>compile<span class="w"> </span><span class="sb">`</span>git_rebase_x_test<span class="sb">`</span>.
To<span class="w"> </span>learn<span class="w"> </span>more,<span class="w"> </span>run<span class="w"> </span>the<span class="w"> </span><span class="nb">command</span><span class="w"> </span>again<span class="w"> </span>with<span class="w"> </span>--verbose.
Execution<span class="w"> </span>failed:<span class="w"> </span>cargo<span class="w"> </span>build
You<span class="w"> </span>can<span class="w"> </span>fix<span class="w"> </span>the<span class="w"> </span>problem,<span class="w"> </span>and<span class="w"> </span><span class="k">then</span><span class="w"> </span>run
<span class="w"> </span>git<span class="w"> </span>rebase<span class="w"> </span>--continue
</pre></div>
<p>This will execute the command after <tt class="docutils literal"><span class="pre">-x</span></tt> for every commit and stop rebasing
if the command fails. We now can go on and fix this commit and continue
rebasing.</p>
<p>This little git feature allows us to not only have a nice looking, but also
<em>working</em> git history after rebasing!</p>
Setting up the Awesome Window Manager in Ubuntu 16.042016-10-19T00:00:00+02:002016-10-19T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2016-10-19:/setting-up-the-awesome-window-manager-in-ubuntu-1604.html<p class="first last">Setting up the awesome window manager under Ubuntu 16.04</p>
<p>My window manager of choice is the <a class="reference external" href="https://awesomewm.org/">awesome window manager</a>. On my private
laptop I have it setup together with the display manager <a class="reference external" href="https://wiki.archlinux.org/index.php/SLiM">SLiM</a> and a custom
<tt class="docutils literal">.xinitrc</tt> which starts a few helpers like the <a class="reference external" href="https://wiki.gnome.org/Projects/GnomeKeyring">gnome-keyring-daemon</a>.</p>
<p>On my work laptop I have Ubuntu 16.04 installed. Ubuntu uses <a class="reference external" href="https://freedesktop.org/wiki/Software/LightDM/">LightDM</a> (The
Light Display Manager) to manage logins. After installing awesome with <tt class="docutils literal">sudo
apt install awesome</tt> LightDM will allow you to start an awesome session. This
is due to the <tt class="docutils literal">/usr/share/xsessions/awesome.desktop</tt> file contained in the
awesome package.</p>
<p>Unfortunately this starts awesome directly and does not execute the
<tt class="docutils literal"><span class="pre">~/.xinitrc</span></tt> file. But it does load the various <tt class="docutils literal">/etc/X11/Xsession.d/</tt>
files which will then load the <tt class="docutils literal"><span class="pre">~/.xsessionrc</span></tt> file if it exists. When
<tt class="docutils literal">.xsessionrc</tt> gets loaded it will pass the session to be started as the first
argument (<tt class="docutils literal">$1</tt>). So to start any helpers we create it with the following
content:</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/sh</span>
<span class="c1">#</span>
<span class="c1"># ~/.xsessionrc</span>
<span class="c1">#</span>
<span class="k">case</span><span class="w"> </span><span class="nv">$1</span><span class="w"> </span><span class="k">in</span>
awesome<span class="o">)</span>
<span class="w"> </span><span class="nb">export</span><span class="w"> </span><span class="k">$(</span>gnome-keyring-daemon<span class="w"> </span>-s<span class="w"> </span>-c<span class="w"> </span>pkcs11,secrets,ssh,gpg<span class="k">)</span>
<span class="w"> </span><span class="p">;;</span>
<span class="k">esac</span>
</pre></div>
<p>This starts the gnome-keyring-daemon and export the <tt class="docutils literal">SSH_AUTH_SOCK</tt> variable,
but only if we are trying to start an awesome session.</p>
Debugging Rust code with vim and Conque-GDB2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2016-05-25:/debugging-rust-code-with-vim-and-conque-gdb.html<p class="first last">Using vim together with Conque-GDB to debug Rust and C/C++ code.</p>
<p>While I use debuggers quite a lot at work in IDEs such as VisualStudio, PyCharm
or QtCreator (of course all configured to use vim-like keybindings), I seldom
use them when working on my side projects.</p>
<p>This is maybe due to the fact, that for my side project I mainly use vim
together with make/cmake, python or Rust and cargo. My "debugging" then
revolves mostly around printing variables and getting stacktraces with gdb if
something goes very wrong.</p>
<p>Also, when programming in Rust, I never felt the need for a debugger, since one
hardly gets a segmentation fault.</p>
<p>Nevertheless I thought it would be a good idea to try to integrate gdb within
vim to be able to debug code if necessary. After some sophisticated research
with <a class="reference external" href="https://duckduckgo.com/?q=vim+gdb&ia=web">duckduckgo</a>, I found quite
some vim plugins for gdb support and <a class="reference external" href="https://stackoverflow.com/questions/6695410/gdb-front-end-to-use-with-vim">this stackoverflow entry</a>
which compares some of them. The one that stood out for me was Conque-GDB
because it looked very simple yet powerful.</p>
<div class="section" id="conque-gdb">
<h2>Conque-GDB</h2>
<p><a class="reference external" href="https://github.com/vim-scripts/Conque-GDB">Conque-GDB</a> is a very simple vim
plugin which provides a vim buffer that acts as a terminal emulator and runs
gdb in it.</p>
<p>Further it provides some keybindings to control the gdb instance like
<tt class="docutils literal"><Leader>r</tt> to run the process or <tt class="docutils literal"><Leader>b</tt> to set a breakpoint at the
current line and so on. There is a small <a class="reference external" href="https://www.youtube.com/watch?v=ZcSjaYSoqnc&feature=youtu.be">demonstration video</a> available on
youtube which shows some of the capabilities of the plugin.</p>
<p>If you use vundle to manage your vim plugins installing Conque-GDB is as easy
as adding</p>
<div class="highlight"><pre><span></span>Plugin <span class="s1">'vim-scripts/Conque-GDB'</span>
</pre></div>
<p>to your <tt class="docutils literal"><span class="pre">~/.vimrc</span></tt>. I found it quite useful since it allows you to do the
following things:</p>
<blockquote>
<ul class="simple">
<li>Set breakpoints from within vim</li>
<li>Show the current position of execution in vim</li>
<li>Examine the contents of variables from within vim</li>
<li>Some more stuff!</li>
</ul>
</blockquote>
</div>
<div class="section" id="using-it-with-rust">
<h2>Using it with Rust</h2>
<p>Conque-GDB allows to define your own gdb executable using the <tt class="docutils literal">:ConqueGdbExe</tt>
command. To debug Rust code one probably wants to use <tt class="docutils literal"><span class="pre">rust-gdb</span></tt> for pretty
printing support of Rust bindings.</p>
<p>To debug Rust code we first set <tt class="docutils literal">:ConqueGdbExe <span class="pre">rust-gdb</span></tt>. Then we start an
instance using <tt class="docutils literal">:ConqueGdb <span class="pre">target/debug/$name</span></tt> where <tt class="docutils literal">$name</tt> is the name of
the executable you want do debug. Then we may set some breakpoints using
<tt class="docutils literal"><Leader>b</tt> and finally run our program with <tt class="docutils literal"><Leader>r</tt>. When hitting a
breakpoint we can examine variables using <tt class="docutils literal"><Leader>p</tt> to print their content.</p>
<img alt="Vim screen shot using ConqueGdb" class="align-center" src="/images/vim_conque_gdb.png" style="width: 100%;" />
<p>For me this is quite a decent debugging experience while still being able to
stay in my favourite text editor!</p>
<p>Do you have any comments, found a bug or an error? Please leave a note on
<a class="reference external" href="https://www.reddit.com/r/rust/comments/4l226c/debugging_rust_code_with_vim_and_conquegdb/">Reddit</a>.</p>
</div>
C++ List of ScopeGuard2016-04-11T00:00:00+02:002016-04-11T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2016-04-11:/c-list-of-scopeguard.html<p class="first last">Implementing a easy to use list of ScopeGuard</p>
<p>Recently the developer of <a class="reference external" href="https://github.com/LibrePCB/LibrePCB">LibrePCB</a>
asked me about a C++ pattern to undo parts of an action if an exception gets
thrown in the middle of it.</p>
<p>Of course he basically described the main usage of a ScopeGuard. I went ahead
and <a class="reference external" href="https://github.com/LibrePCB/LibrePCB/pull/57">implemented one</a> based on
a <a class="reference external" href="https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C">talk by Andrei Alexandrescu</a>.</p>
<div class="section" id="basic-use-of-a-scopeguard">
<h2>Basic use of a ScopeGuard</h2>
<p>The ScopeGuard allows to write transactional code that will undo previous parts
if later code throws an exception.</p>
<div class="highlight"><pre><span></span><span class="n">myVector</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">item</span><span class="p">);</span>
<span class="k">auto</span><span class="w"> </span><span class="n">guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">scopeGuard</span><span class="p">([</span><span class="o">&</span><span class="p">]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">myVector</span><span class="p">.</span><span class="n">pop_back</span><span class="p">()</span><span class="w"> </span><span class="p">});</span>
<span class="c1">// Do stuff that may throw</span>
<span class="n">database</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">item</span><span class="p">);</span>
<span class="c1">// everything worked, so don't undo</span>
<span class="n">guard</span><span class="p">.</span><span class="n">dismiss</span><span class="p">();</span>
</pre></div>
<p>So if <tt class="docutils literal">database.add(item)</tt> throws, the item in myVector will be removed. For
more about the motivation behind ScopeGuard see the talk above or <a class="reference external" href="http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758">this drdobbs
article</a>.</p>
<p>Using C++11 and later the implementation is fairly simple:</p>
<pre class="code cpp literal-block">
<span class="k">struct</span><span class="w"> </span><span class="nc">ScopeGuardBase</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">ScopeGuardBase</span><span class="p">()</span><span class="o">:</span><span class="w">
</span><span class="n">mActive</span><span class="p">(</span><span class="nb">true</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="n">ScopeGuardBase</span><span class="p">(</span><span class="n">ScopeGuardBase</span><span class="o">&&</span><span class="w"> </span><span class="n">rhs</span><span class="p">)</span><span class="o">:</span><span class="w">
</span><span class="n">mActive</span><span class="p">(</span><span class="n">rhs</span><span class="p">.</span><span class="n">mActive</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="n">rhs</span><span class="p">.</span><span class="n">dismiss</span><span class="p">();</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="kt">void</span><span class="w"> </span><span class="n">dismiss</span><span class="p">()</span><span class="w"> </span><span class="k">noexcept</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="n">mActive</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="k">protected</span><span class="o">:</span><span class="w">
</span><span class="o">~</span><span class="n">ScopeGuardBase</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">default</span><span class="p">;</span><span class="w">
</span><span class="kt">bool</span><span class="w"> </span><span class="n">mActive</span><span class="p">;</span><span class="w">
</span><span class="p">};</span><span class="w">
</span><span class="k">template</span><span class="o"><</span><span class="k">class</span><span class="w"> </span><span class="nc">Fun</span><span class="o">></span><span class="w">
</span><span class="k">struct</span><span class="w"> </span><span class="nc">ScopeGuard</span><span class="o">:</span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">ScopeGuardBase</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">ScopeGuard</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">delete</span><span class="p">;</span><span class="w">
</span><span class="n">ScopeGuard</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">ScopeGuard</span><span class="o">&</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">delete</span><span class="p">;</span><span class="w">
</span><span class="n">ScopeGuard</span><span class="p">(</span><span class="n">Fun</span><span class="w"> </span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="k">noexcept</span><span class="o">:</span><span class="w">
</span><span class="n">ScopeGuardBase</span><span class="p">(),</span><span class="w">
</span><span class="n">mF</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">f</span><span class="p">))</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="n">ScopeGuard</span><span class="p">(</span><span class="n">ScopeGuard</span><span class="o">&&</span><span class="w"> </span><span class="n">rhs</span><span class="p">)</span><span class="w"> </span><span class="k">noexcept</span><span class="w"> </span><span class="o">:</span><span class="w">
</span><span class="n">ScopeGuardBase</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">rhs</span><span class="p">)),</span><span class="w">
</span><span class="n">mF</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">rhs</span><span class="p">.</span><span class="n">mF</span><span class="p">))</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="o">~</span><span class="n">ScopeGuard</span><span class="p">()</span><span class="w"> </span><span class="k">noexcept</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mActive</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">try</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">mF</span><span class="p">();</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="p">(...)</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="n">ScopeGuard</span><span class="o">&</span><span class="w"> </span><span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">ScopeGuard</span><span class="o">&</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">delete</span><span class="p">;</span><span class="w">
</span><span class="k">private</span><span class="o">:</span><span class="w">
</span><span class="n">Fun</span><span class="w"> </span><span class="n">mF</span><span class="p">;</span><span class="w">
</span><span class="p">};</span><span class="w">
</span><span class="k">template</span><span class="o"><</span><span class="k">class</span><span class="w"> </span><span class="nc">Fun</span><span class="o">></span><span class="w"> </span><span class="n">ScopeGuard</span><span class="o"><</span><span class="n">Fun</span><span class="o">></span><span class="w"> </span><span class="n">scopeGuard</span><span class="p">(</span><span class="n">Fun</span><span class="w"> </span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">return</span><span class="w"> </span><span class="n">ScopeGuard</span><span class="o"><</span><span class="n">Fun</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">f</span><span class="p">));</span><span class="w">
</span><span class="p">}</span>
</pre>
</div>
<div class="section" id="why-a-scopeguardlist">
<h2>Why a ScopeGuardList?</h2>
<p>If you have a transaction that consists of a lot of steps that may throw and
need to be undone it leads to code like the following:</p>
<div class="highlight"><pre><span></span><span class="n">doThing1</span><span class="p">();</span>
<span class="k">auto</span><span class="w"> </span><span class="n">guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">makeGuard</span><span class="p">([</span><span class="o">&</span><span class="p">]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">undoThing1</span><span class="p">();</span><span class="w"> </span><span class="p">});</span>
<span class="n">doThing2</span><span class="p">();</span>
<span class="k">auto</span><span class="w"> </span><span class="n">guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">makeGuard</span><span class="p">([</span><span class="o">&</span><span class="p">]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">undoThing2</span><span class="p">();</span><span class="w"> </span><span class="p">});</span>
<span class="n">doThing3</span><span class="p">();</span>
<span class="k">auto</span><span class="w"> </span><span class="n">guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">makeGuard</span><span class="p">([</span><span class="o">&</span><span class="p">]()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">undoThing3</span><span class="p">();</span><span class="w"> </span><span class="p">});</span>
<span class="c1">// Do stuff that may trow</span>
<span class="n">guard1</span><span class="p">.</span><span class="n">dismiss</span><span class="p">();</span>
<span class="n">guard2</span><span class="p">.</span><span class="n">dismiss</span><span class="p">();</span>
<span class="n">guard3</span><span class="p">.</span><span class="n">dismiss</span><span class="p">();</span>
</pre></div>
<p>Things get even worse when doing something in a loop:</p>
<div class="highlight"><pre><span></span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o"><</span><span class="mi">10</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">doStuff</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="w"> </span><span class="c1">// how do we create a guard for every operation?</span>
<span class="p">}</span>
</pre></div>
<p>To avoid that repetition and the potential error of a missing call to
<tt class="docutils literal">dismiss()</tt> we came up with a <tt class="docutils literal">ScopeGuardList</tt>.</p>
</div>
<div class="section" id="implementation-with-std-function">
<h2>Implementation with std::function<></h2>
<p>A simple implementation just contains a list of <tt class="docutils literal"><span class="pre">std::function<></span></tt>:</p>
<pre class="code cpp literal-block">
<span class="cp">#include</span><span class="w"> </span><span class="cpf">"scopeguard.h"</span><span class="cp">
#include</span><span class="w"> </span><span class="cpf"><vector></span><span class="cp">
#include</span><span class="w"> </span><span class="cpf"><utility></span><span class="cp">
#include</span><span class="w"> </span><span class="cpf"><functional></span><span class="cp">
</span><span class="w">
</span><span class="k">struct</span><span class="w"> </span><span class="nc">ScopeGuardList</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">ScopeGuardBase</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">ScopeGuardList</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">default</span><span class="p">;</span><span class="w">
</span><span class="n">ScopeGuardList</span><span class="p">(</span><span class="n">ScopeGuardList</span><span class="o">&&</span><span class="w"> </span><span class="n">rhs</span><span class="p">)</span><span class="o">:</span><span class="w">
</span><span class="n">ScopeGuardBase</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">rhs</span><span class="p">)),</span><span class="w">
</span><span class="n">mScopeGuards</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">rhs</span><span class="p">.</span><span class="n">mScopeGuards</span><span class="p">))</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="o">~</span><span class="n">ScopeGuardList</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mActive</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="k">auto</span><span class="o">&</span><span class="w"> </span><span class="n">scopeGuard</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mScopeGuards</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">scopeGuard</span><span class="p">();</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="k">template</span><span class="o"><</span><span class="k">class</span><span class="w"> </span><span class="nc">Fun</span><span class="o">></span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">add</span><span class="p">(</span><span class="n">Fun</span><span class="w"> </span><span class="n">f</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="n">mScopeGuards</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">f</span><span class="p">));</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="k">private</span><span class="o">:</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">function</span><span class="o"><</span><span class="kt">void</span><span class="p">()</span><span class="o">>></span><span class="w"> </span><span class="n">mScopeGuards</span><span class="p">;</span><span class="w">
</span><span class="p">};</span>
</pre>
<p>This implementation uses the type erasure of <tt class="docutils literal"><span class="pre">std::function</span></tt> to store several
undo functions. While being fairly simple it performs worse compared to the
above ScopeGuard implementation.</p>
<p>A quick benchmark showed that the <tt class="docutils literal">ScopeGuard</tt> performs ~14 times faster than
<tt class="docutils literal">ScopeGuardList</tt>:</p>
<pre class="code cpp literal-block">
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><chrono></span><span class="cp">
#include</span><span class="w"> </span><span class="cpf"><iostream></span><span class="cp">
</span><span class="w">
</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">"scopeguardlist.h"</span><span class="cp">
</span><span class="w">
</span><span class="kt">void</span><span class="w"> </span><span class="nf">testScopeGuard</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">time_point</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">></span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="n">end</span><span class="p">;</span><span class="w">
</span><span class="c1">// make volatile to avoid optimizations
</span><span class="w"> </span><span class="k">volatile</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span><span class="n">start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span><span class="w">
</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">n</span><span class="o"><</span><span class="mi">10000000</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">auto</span><span class="w"> </span><span class="n">guard0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">scopeGuard</span><span class="p">([</span><span class="o">&</span><span class="p">]{</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="p">});</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="n">end</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="kt">double</span><span class="o">></span><span class="w"> </span><span class="n">elapsed_seconds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">end</span><span class="o">-</span><span class="n">start</span><span class="p">;</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Needed "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">elapsed_seconds</span><span class="p">.</span><span class="n">count</span><span class="p">()</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"s for "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">" loops</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="kt">void</span><span class="w"> </span><span class="nf">testScopeGuardList</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">time_point</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">></span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="n">end</span><span class="p">;</span><span class="w">
</span><span class="c1">// make volatile to avoid optimizations
</span><span class="w"> </span><span class="k">volatile</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span><span class="n">start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span><span class="w">
</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">n</span><span class="o"><</span><span class="mi">10000000</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="k">auto</span><span class="w"> </span><span class="n">guardList</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ScopeGuardList</span><span class="p">();</span><span class="w">
</span><span class="n">guardList</span><span class="p">.</span><span class="n">add</span><span class="p">([</span><span class="o">&</span><span class="p">]{</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="p">});</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="n">end</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">duration</span><span class="o"><</span><span class="kt">double</span><span class="o">></span><span class="w"> </span><span class="n">elapsed_seconds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">end</span><span class="o">-</span><span class="n">start</span><span class="p">;</span><span class="w">
</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Needed "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">elapsed_seconds</span><span class="p">.</span><span class="n">count</span><span class="p">()</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"s for "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">setByGuard0</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">" loops</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="n">testScopeGuard</span><span class="p">();</span><span class="w">
</span><span class="n">testScopeGuardList</span><span class="p">();</span><span class="w">
</span><span class="p">}</span>
</pre>
<table border="1" class="docutils">
<caption>Benchmark with different optimization levels</caption>
<colgroup>
<col width="11%" />
<col width="41%" />
<col width="48%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">-O$N</th>
<th class="head">Time[s] ScopeGuard</th>
<th class="head">Time[s] ScopGuardList</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>0</td>
<td>0.178144</td>
<td>2.61144</td>
</tr>
<tr><td>1</td>
<td>0.0180427</td>
<td>0.286136</td>
</tr>
<tr><td>2</td>
<td>0.0170452</td>
<td>0.283548</td>
</tr>
<tr><td>3</td>
<td>0.0170423</td>
<td>0.289958</td>
</tr>
</tbody>
</table>
<p>Since the <tt class="docutils literal">ScopeGuardList</tt> isn't used in any performance critical part in
LibrePCB we didn't look further for a better performing way without type
erasure.</p>
<p>Do you have any comments, found a bug or an error? Please leave a note on
<a class="reference external" href="https://www.reddit.com/r/cpp/comments/4ecf5a/c_list_of_scopeguard/">Reddit</a>.</p>
</div>
Reading the SHTC1 smart gadget BLE device2015-08-16T00:00:00+02:002015-08-16T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2015-08-16:/reading-the-shtc1-smart-gadget-ble-device.html<p class="first last">Connection to a SHTC1 smart gadget and read its sensor values</p>
<div class="section" id="requirements">
<h2>Requirements</h2>
<p>First we need to install the bluez bluetooth stack:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>bluez<span class="w"> </span>bluez-utils
</pre></div>
<p>To be able to switch the bluetooth on and off I use the bluetooth command from
tlp:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>tlp
$<span class="w"> </span>sudo<span class="w"> </span>bluetooth<span class="w"> </span>on
</pre></div>
<p>Next we activate the bluetooth service:</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span>daemon-reload
$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span>start<span class="w"> </span>bluetooth.service
</pre></div>
</div>
<div class="section" id="connecting">
<h2>Connecting</h2>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>hcitool<span class="w"> </span>dev
Devices:
<span class="w"> </span>hci0<span class="w"> </span>F8:16:54:CD:5F:CC
$<span class="w"> </span>sudo<span class="w"> </span>hcitool<span class="w"> </span>lescan
LE<span class="w"> </span>Scan<span class="w"> </span>...
BC:6A:29:C1:A9:3B<span class="w"> </span>SHTC1<span class="w"> </span>smart<span class="w"> </span>gadget
$<span class="w"> </span>sudo<span class="w"> </span>gatttool<span class="w"> </span>-b<span class="w"> </span>BC:6A:29:C1:A9:3B<span class="w"> </span>-I
<span class="o">[</span>BC:6A:29:C1:A9:3B<span class="o">][</span>LE<span class="o">]</span>><span class="w"> </span>connect
Attempting<span class="w"> </span>to<span class="w"> </span>connect<span class="w"> </span>to<span class="w"> </span>BC:6A:29:C1:A9:3B
Connection<span class="w"> </span>successful
</pre></div>
</div>
<div class="section" id="reading-the-sensordata">
<h2>Reading the sensordata</h2>
<p>According to <a class="reference external" href="https://github.com/Sensirion/SmartGadget-iOS/blob/50dc0f36c0624f825f7637bceeb5a34da7c878f3/Classes/Peripheral/Services/Sensirion/Shtc1/Shtc1RhtService.m">the SmartGadget-iOS code</a>
The UUID to read the temperature is 0xAA21.
So we try to read it:</p>
<div class="highlight"><pre><span></span><span class="o">[</span>BC:6A:29:C1:A9:3B<span class="o">][</span>LE<span class="o">]</span>><span class="w"> </span>char-read-uuid<span class="w"> </span>0xAA21
handle:<span class="w"> </span>0x0025<span class="w"> </span>value:<span class="w"> </span><span class="m">66</span><span class="w"> </span>0b<span class="w"> </span>b9<span class="w"> </span><span class="m">14</span>
</pre></div>
<p>The first 16-bit value is the temperature and the second the humidity. Note
that the byte order of the values is big endian.</p>
<p>So to calculate the measured temperature in python we need to:</p>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="n">temperature</span> <span class="o">=</span> <span class="mh">0x0b66</span><span class="o">/</span><span class="mf">100.0</span>
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">temperature</span><span class="p">)</span><span class="o">+</span> <span class="s2">"°C"</span><span class="p">)</span>
<span class="mf">29.18</span><span class="err">°</span><span class="n">C</span>
<span class="o">>>></span> <span class="n">humidity</span> <span class="o">=</span> <span class="mh">0x14b9</span>
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">humidity</span><span class="p">)</span><span class="o">+</span> <span class="s2">"%RH"</span><span class="p">)</span>
<span class="mf">53.05</span><span class="o">%</span><span class="n">RH</span>
</pre></div>
</div>
Setting up airline-vim2015-07-03T00:00:00+02:002015-07-03T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2015-07-03:/setting-up-airline-vim.html<p class="first last">Setting up the airline-vim plug-in and configure the powerline fonts</p>
<p>Recently I noticed, that my Vim configuration is getting a bit outdated. The
configuration of one of my mate had a fancy status line, showed syntax errors
when saving a buffer and he used <a class="reference external" href="https://github.com/gmarik/Vundle.vim">vundle</a> to manage his Vim plug-ins. I used to
manage my Vim plug-ins with <a class="reference external" href="https://github.com/archlinuxfr/yaourt">yaourt</a>, a
package manager for <a class="reference external" href="https://aur4.archlinux.org/">user packages</a> in ArchLinux.</p>
<div class="section" id="installing-vundle">
<h2>Installing vundle</h2>
<p>First one needs to get the vundle plug-in via git:</p>
<div class="highlight"><pre><span></span>git<span class="w"> </span>clone<span class="w"> </span>https://github.com/VundleVim/Vundle.vim.git<span class="w"> </span>~/.vim/bundle/Vundle.vim
</pre></div>
<p>Then one needs to setup Vim to use it:</p>
<div class="highlight"><pre><span></span><span class="c">" ~/.vimrc</span>
<span class="k">set</span> <span class="nb">nocompatible</span>
<span class="k">filetype</span> off
<span class="k">set</span> <span class="nb">rtp</span><span class="p">+=~</span><span class="sr">/.vim/</span>bundle<span class="sr">/Vundle.vim/</span>
<span class="k">call</span> vundle#rc<span class="p">()</span>
Plugin <span class="s1">'gmarik/Vundle.vim'</span>
<span class="k">filetype</span> plugin indent <span class="k">on</span>
</pre></div>
<p>From there adding additional plug-ins is as easy as adding a <tt class="docutils literal">Plugin ...</tt> line
right after the vundle plug-in.</p>
<p>So adding <a class="reference external" href="https://github.com/bling/vim-airline">airline</a> for a fancy status
line, <a class="reference external" href="https://github.com/scrooloose/syntastic">syntastic</a> as a syntax checker
and git support with <a class="reference external" href="https://github.com/tpope/vim-fugitive">fugitive</a> is as
easy as this:</p>
<div class="highlight"><pre><span></span>Plugin <span class="s1">'scrooloose/syntastic'</span>
Plugin <span class="s1">'tpope/vim-fugitive'</span>
Plugin <span class="s1">'bling/vim-airline'</span>
</pre></div>
</div>
<div class="section" id="configuring-airline">
<h2>Configuring airline</h2>
<p>Out of the box airline does show the status bar only if at least one split is
active:</p>
<img alt="Vim screen shot with airline" class="align-center" src="/images/vim-airline0.png" style="width: 100%;" />
<p>Also the default symbols used in the statusline aren't that fancy. Adding <tt class="docutils literal">set
laststatus=2</tt> enables the statusline by default and <tt class="docutils literal">let
g:airline_powerline_fonts = 1</tt> lets one use the <a class="reference external" href="https://github.com/powerline/fonts">powerline fonts</a></p>
<p>Configuring my terminal emulator of choice, urxvt, turned out to be a bit of a
hassle.</p>
<p>Installing the fonts was easy:</p>
<div class="highlight"><pre><span></span>git<span class="w"> </span>clone<span class="w"> </span>https://github.com/powerline/fonts.git
<span class="nb">cd</span><span class="w"> </span>fonts
./install.sh
</pre></div>
<p>Then in <tt class="docutils literal"><span class="pre">~/.Xresources</span></tt> configure urxvt to use a powerline font:</p>
<div class="highlight"><pre><span></span>URxvt.font:<span class="w"> </span>xft:DejaVu<span class="w"> </span>Sans<span class="w"> </span>Mono<span class="w"> </span><span class="k">for</span><span class="w"> </span>Powerline:size<span class="o">=</span><span class="m">11</span>
</pre></div>
<p>Then reloading the configuration</p>
<div class="highlight"><pre><span></span>xrdb<span class="w"> </span>-merge<span class="w"> </span>~/.Xresources
</pre></div>
<p>The problem was that urxvt didn't like that at all and displayed the fonts with
the spacing all messed up. After an hour of googling and trying out different
stuff, it turned out I just needed to kill and restart the urxvtd daemon!</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>killall<span class="w"> </span>urxvtd
%<span class="w"> </span>urxvtd<span class="w"> </span>-q<span class="w"> </span>-o<span class="w"> </span>-f
</pre></div>
<p>After that it worked like a charm and the special symbols did show up nicely:</p>
<img alt="Vim screen shot with airline and powerline fonts" class="align-center" src="/images/vim-airline1.png" style="width: 100%;" />
</div>
Serialization in Rust2015-04-09T00:00:00+02:002015-04-09T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2015-04-09:/serialization-in-rust.html<p class="first last">Using the Rust JSON serialization to implement the Space API</p>
<p>One of my first projects with Rust is the <a class="reference external" href="https://spaceapi.net/">spaceapi</a>
implementation of my local <a class="reference external" href="https://coredump.ch">hackerspace</a>.</p>
<p>You can find the source for it on <a class="reference external" href="https://github.com/coredump-ch/spaceapi">github</a>.</p>
<div class="section" id="the-space-api">
<h2>The Space API</h2>
<p>The Space API is a rather simple JSON API used to expose information about a
hackerspace. It consist of some static data like the location or some contact
information and some dynamic data like the current state of the space.</p>
<p>Implementing JSON serialization in Rust is easy when using the <a class="reference external" href="https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html">rustc_serialize</a>
crate.</p>
<p>Using the <tt class="docutils literal">#[derive(RustcEncodable)]</tt> attribute on a type, serializing a
struct is as easy as calling <tt class="docutils literal"><span class="pre">json::encode(&status).unwrap()</span></tt>.</p>
<div class="highlight"><pre><span></span><span class="k">extern</span><span class="w"> </span><span class="k">crate</span><span class="w"> </span><span class="n">rustc_serialize</span><span class="p">;</span>
<span class="k">use</span><span class="w"> </span><span class="n">rustc_serialize</span>::<span class="n">json</span><span class="p">;</span>
<span class="cp">#[derive(RustcEncodable)]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Status</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">api</span>: <span class="nb">String</span><span class="p">,</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">space</span>: <span class="nb">String</span><span class="p">,</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">url</span>: <span class="nb">String</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">status</span>: <span class="nb">String</span> <span class="o">=</span><span class="w"> </span><span class="n">json</span>::<span class="n">encode</span><span class="p">(</span><span class="o">&</span><span class="n">Status</span><span class="p">{</span>
<span class="w"> </span><span class="n">api</span>: <span class="s">"0.13"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span>
<span class="w"> </span><span class="n">space</span>: <span class="s">"coredump"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span>
<span class="w"> </span><span class="n">url</span>: <span class="s">"https://www.coredump.ch/"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span>
<span class="w"> </span><span class="p">}).</span><span class="n">unwrap</span><span class="p">();</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">status</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This code will output:</p>
<div class="highlight"><pre><span></span><span class="p">{</span><span class="nt">"api"</span><span class="p">:</span><span class="s2">"0.13"</span><span class="p">,</span><span class="nt">"space"</span><span class="p">:</span><span class="s2">"coredump"</span><span class="p">,</span><span class="nt">"url"</span><span class="p">:</span><span class="s2">"https://www.coredump.ch/"</span><span class="p">}</span>
</pre></div>
<p>As you can see, the field names map directly to keys in the JSON output. That
way we can model the Space API objects with structs and have a simple typesafe
solution!</p>
</div>
<div class="section" id="the-type-property">
<h2>The 'type' property</h2>
<p>Unfortunately <a class="reference external" href="http://spaceapi.net/documentation#documentation-ref-13-root-feeds-blog-type">parts</a>
of the Space API contain the property <tt class="docutils literal">type</tt> which is a keyword in Rust.
Of course using it as an identifier for a Struct field yields a compile error:</p>
<div class="highlight"><pre><span></span><span class="cp">#[derive(RustcEncodable)]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Feed</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">type</span>: <span class="nb">String</span><span class="p">,</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">url</span>: <span class="nb">String</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
<pre class="literal-block">
main.rs:7:9: 7:13 error: expected identifier, found keyword `type`
main.rs:7 pub type: String,
^~~~
</pre>
<p>So we need to rename the field to something like <tt class="docutils literal">_type</tt> and change the
serialization.</p>
</div>
<div class="section" id="implementing-tojson">
<h2>Implementing ToJson</h2>
<p>My first idea was to implement the <a class="reference external" href="http://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/trait.ToJson.html">ToJson</a>
trait for Feed. Implementing <tt class="docutils literal">ToJson</tt> is easy, there is just one method
<tt class="docutils literal">to_json</tt> which returns the <tt class="docutils literal">Json</tt> object:</p>
<div class="highlight"><pre><span></span><span class="k">impl</span><span class="w"> </span><span class="n">json</span>::<span class="n">ToJson</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Feed</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">to_json</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Json</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">feed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BTreeMap</span>::<span class="n">new</span><span class="p">();</span>
<span class="w"> </span><span class="n">feed</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"type"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">_type</span><span class="p">.</span><span class="n">to_json</span><span class="p">());</span>
<span class="w"> </span><span class="n">feed</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"url"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">url</span><span class="p">.</span><span class="n">to_json</span><span class="p">());</span>
<span class="w"> </span><span class="n">Json</span>::<span class="n">Object</span><span class="p">(</span><span class="n">feed</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Sadly this means the <tt class="docutils literal">Feeds</tt> struct can't hold the Feed struct directly
anymore, but needs it as a <tt class="docutils literal">Json</tt> object:</p>
<div class="highlight"><pre><span></span><span class="cp">#[derive(RustcEncodable)]</span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Feeds</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">blog</span>: <span class="nc">Json</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
<p>Otherwise the Encodable trait can't be derived anymore, because it's not
implemented for the type Feed. Since this reduces type safety somewhat (we
could set <tt class="docutils literal">blog</tt> field to any Json string), I discarded this solution.</p>
</div>
<div class="section" id="implementing-encodable">
<h2>Implementing Encodable</h2>
<p>To regain type safety we need to implement the <a class="reference external" href="https://doc.rust-lang.org/rustc-serialize/rustc_serialize/trait.Encodable.html">Encodable trait</a>
for Feed.
The required method for Encodable may be a bit intimidating at the first look:</p>
<div class="highlight"><pre><span></span><span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">Encodable</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">encode</span><span class="o"><</span><span class="n">S</span>: <span class="nc">Encoder</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">s</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">S</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">S</span><span class="o">></span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Basically it takes a reference to self and an Encoder and returns an <a class="reference external" href="http://doc.rust-lang.org/nightly/core/result/enum.Result.html">Result</a> containing
either <tt class="docutils literal">OK()</tt> on success or <tt class="docutils literal">Err(S)</tt> on failure. But how does one use the
encoder?</p>
<div class="section" id="using-the-generated-code-as-base">
<h3>Using the generated code as base</h3>
<p>After some googleing I found out that one can show the macro expanded source
code. It's kinda like the pre-processor output when coming from the C/C++
world.</p>
<pre class="literal-block">
rustc -Z unstable-options src/spaceapi.rs --pretty expanded
</pre>
<p>The expanded code is pretty readable and it was easy to find the corresponding
trait implementation generated by the Rust compiler:</p>
<div class="highlight"><pre><span></span><span class="k">impl</span><span class="w"> </span>::<span class="n">rustc_serialize</span>::<span class="n">Encodable</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Feed</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">encode</span><span class="o"><</span><span class="n">__S</span>: ::<span class="n">rustc_serialize</span>::<span class="n">Encoder</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">__arg_0</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">__S</span><span class="p">)</span>
<span class="w"> </span>-> ::<span class="n">std</span>::<span class="n">result</span>::<span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">__S</span>::<span class="n">Error</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="bp">self</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Feed</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_type</span>: <span class="nc">ref</span><span class="w"> </span><span class="n">__self_0_0</span><span class="p">,</span><span class="w"> </span><span class="n">url</span>: <span class="nc">ref</span><span class="w"> </span><span class="n">__self_0_1</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=></span>
<span class="w"> </span><span class="n">__arg_0</span><span class="p">.</span><span class="n">emit_struct</span><span class="p">(</span><span class="s">"Feed"</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="k">usize</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">_e</span><span class="o">|</span><span class="w"> </span>-> <span class="nc">_</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">_e</span><span class="p">.</span><span class="n">emit_struct_field</span><span class="p">(</span><span class="s">"_type"</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="k">usize</span><span class="p">,</span>
<span class="w"> </span><span class="o">|</span><span class="n">_e</span><span class="o">|</span><span class="w"> </span>-> <span class="nc">_</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="w"> </span><span class="n">__self_0_0</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="n">_e</span><span class="p">)</span>
<span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span>::<span class="n">std</span>::<span class="n">result</span>::<span class="nb">Result</span>::<span class="nb">Ok</span><span class="p">(</span><span class="n">__try_var</span><span class="p">)</span><span class="w"> </span><span class="o">=></span>
<span class="w"> </span><span class="n">__try_var</span><span class="p">,</span>
<span class="w"> </span>::<span class="n">std</span>::<span class="n">result</span>::<span class="nb">Result</span>::<span class="nb">Err</span><span class="p">(</span><span class="n">__try_var</span><span class="p">)</span><span class="w"> </span><span class="o">=></span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span>::<span class="n">std</span>::<span class="n">result</span>::<span class="nb">Result</span>::<span class="nb">Err</span><span class="p">(</span><span class="n">__try_var</span><span class="p">),</span>
<span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">_e</span><span class="p">.</span><span class="n">emit_struct_field</span><span class="p">(</span><span class="s">"url"</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="k">usize</span><span class="p">,</span>
<span class="w"> </span><span class="o">|</span><span class="n">_e</span><span class="o">|</span><span class="w"> </span>-> <span class="nc">_</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="w"> </span><span class="n">__self_0_1</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="n">_e</span><span class="p">)</span>
<span class="w"> </span><span class="p">});</span><span class="w"> </span><span class="p">}),</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>So from there I tried to make the code a bit more readable which resulted in
the following:</p>
<div class="highlight"><pre><span></span><span class="k">impl</span><span class="w"> </span><span class="n">Encodable</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Feed</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">encode</span><span class="o"><</span><span class="n">S</span>: <span class="nc">Encoder</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">encoder</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">S</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">S</span>::<span class="n">Error</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="bp">self</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Feed</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_type</span>: <span class="nc">ref</span><span class="w"> </span><span class="n">p_type</span><span class="p">,</span><span class="w"> </span><span class="n">url</span>: <span class="nc">ref</span><span class="w"> </span><span class="n">p_url</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=></span>
<span class="w"> </span><span class="n">encoder</span><span class="p">.</span><span class="n">emit_struct</span><span class="p">(</span><span class="s">"Feed"</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="k">usize</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">enc</span><span class="o">|</span><span class="w"> </span>-> <span class="nc">_</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kr">try</span><span class="o">!</span><span class="p">(</span><span class="n">enc</span><span class="p">.</span><span class="n">emit_struct_field</span><span class="p">(</span><span class="w"> </span><span class="s">"type"</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="k">usize</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">enc</span><span class="o">|</span><span class="w"> </span><span class="n">p_type</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="n">enc</span><span class="p">)));</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">enc</span><span class="p">.</span><span class="n">emit_struct_field</span><span class="p">(</span><span class="s">"url"</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="k">usize</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">enc</span><span class="o">|</span><span class="w"> </span>-> <span class="nc">_</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="w"> </span><span class="n">p_url</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="n">enc</span><span class="p">)</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">}),</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>The final encoded String looks like this:</p>
<div class="highlight"><pre><span></span><span class="p">{</span><span class="nt">"type"</span><span class="p">:</span><span class="s2">"rss"</span><span class="p">,</span><span class="nt">"url"</span><span class="p">:</span><span class="s2">"https://www.coredump.ch/feed/"</span><span class="p">}</span>
</pre></div>
<p>Have comments? Discuss on <a class="reference external" href="https://news.ycombinator.com/item?id=9470475">Hacker News</a>.</p>
</div>
</div>
More Rust compared to C++2015-02-06T00:00:00+01:002015-02-06T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2015-02-06:/more-rust-compared-to-c.html<p class="first last">More about the programming language Rust</p>
<p>After <a class="reference external" href="http://rnestler.github.io/learning-rust.html">getting in touch with Rust</a>, the next thing I was looking
at were pointers and the concept of ownership and borrowing in Rust.</p>
<div class="section" id="pointers">
<h2>Pointers</h2>
<p>Rust has a lot of different pointer types, reminding me of the C++ references,
raw and smart pointers like <a class="reference external" href="http://en.cppreference.com/w/cpp/memory/unique_ptr">std::unique_ptr</a>, <a class="reference external" href="http://en.cppreference.com/w/cpp/memory/shared_ptr">std::shared_ptr</a>. For a nice comparison
see <a class="reference external" href="https://github.com/rust-lang/rust-wiki-backup/blob/master/Rust-for-CXX-programmers.rest">here</a>.</p>
<div class="section" id="references">
<h3>References</h3>
<p>One of the first pointer type you will meet in Rust is the reference type.</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"x = {}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"x = {}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">add_one</span><span class="p">(</span><span class="n">num</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>In C++ this would look something like this:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><cstdio></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">add_one</span><span class="p">(</span><span class="kt">int</span><span class="o">&</span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>What is think is nice in Rust is:</p>
<blockquote>
<ul class="simple">
<li>It's explicit that x will be modified (<tt class="docutils literal">&mut x</tt>)</li>
<li>It's guaranteed that x is neither dangling nor 0</li>
</ul>
</blockquote>
<p>In C++ references have value syntax. To avoid that I prefer the <a class="reference external" href="https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Reference_Arguments">style</a>
of using pointers for mutable and only <tt class="docutils literal">const</tt> reference for immutable data.</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><cstdio></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">add_one</span><span class="p">(</span><span class="kt">int</span><span class="o">*</span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="o">*</span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">x</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"x = %i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This way the syntax looks much more like the Rust example, but you can pass 0:</p>
<div class="highlight"><pre><span></span><span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="o">-></span><span class="w"> </span><span class="n">Segmentation</span><span class="w"> </span><span class="n">fault</span><span class="w"> </span><span class="p">(</span><span class="n">core</span><span class="w"> </span><span class="n">dumped</span><span class="p">)</span>
</pre></div>
<p>Trying the same with C++ references yields a compile error, because a non
<tt class="docutils literal">const</tt> reference can't bind to a temporary (rvalue)</p>
<div class="highlight"><pre><span></span>reference.cpp: In function 'int main()':
reference.cpp:12:11: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
add_one(0);
^
reference.cpp:3:6: note: in passing argument 1 of 'void add_one(int&)'
void add_one(int& num) {
^
</pre></div>
<p>Surprising to me, doing the same within Rust works</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">add_one</span><span class="p">(</span><span class="n">num</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="fm">print!</span><span class="p">(</span><span class="s">"adding one to {}"</span><span class="p">,</span><span class="w"> </span><span class="n">num</span><span class="p">);</span>
<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">" -> {}"</span><span class="p">,</span><span class="w"> </span><span class="n">num</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Output: <tt class="docutils literal">adding one to 0 <span class="pre">-></span> 1</tt>. Apparently one can bind mutable references
to temporaries in Rust.</p>
</div>
<div class="section" id="heap-pointers">
<h3>Heap pointers</h3>
<p>For managing data on the heap Rust has the <tt class="docutils literal">Box<T></tt> type</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Output: <tt class="docutils literal">5</tt></p>
<p>The equivalent in C++ would be</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><memory></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><cstdio></span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"%i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Note that the compiler takes care of freeing the used resources as soon as x
goes out of scope. In the C++ world this is called <a class="reference external" href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a>.</p>
</div>
</div>
<div class="section" id="ownership-borrowing-and-lifetime">
<h2>Ownership, Borrowing and Lifetime</h2>
<p>The Box type is an owning type. Meaning that it owns the resources it is
pointing to. The same is true for <tt class="docutils literal"><span class="pre">std::unique_ptr</span></tt>.</p>
<p>When passing a Box type to a function the ownership transfers to this function:</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">add_one</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">num</span>: <span class="nb">Box</span><span class="o"><</span><span class="kt">i32</span><span class="o">></span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>This will result in a compile error:</p>
<div class="highlight"><pre><span></span>boxed.rs:10:20: 10:22 error: use of moved value: `*x`
boxed.rs:10 println!("{}", * x);
^~
note: in expansion of format_args!
<std macros>:2:43: 2:76 note: expansion site
<std macros>:1:1: 2:78 note: in expansion of println!
boxed.rs:10:5: 10:24 note: expansion site
boxed.rs:9:13: 9:14 note: `x` moved here because it has type `Box<i32>`, which is non-copyable
boxed.rs:9 add_one(x);
</pre></div>
<p>Because a Box owns the resource, x will become invalid.
If we try same in C++</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><memory></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><cstdio></span>
<span class="kt">void</span><span class="w"> </span><span class="nf">add_one</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"%i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">add_one</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">x</span><span class="p">));</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"%i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>It will result in a segmentation fault:</p>
<div class="highlight"><pre><span></span>% g++ -Wall -std=c++14 cpp_smart_pointers.cpp -o cpp_smart_pointers
% ./cpp_smart_pointers
5
[1] 28585 segmentation fault (core dumped) ./cpp_smart_pointers
</pre></div>
<p>Because the unique_pointer moved from x into the function argument x remains
invalid and dereferencing it will leave it invalid. Note that <tt class="docutils literal">g++</tt> doesn't
even issue a warning even when compiling this code with <tt class="docutils literal"><span class="pre">-Wall</span></tt>.</p>
<p>What I think is nice in the C++ version is the explicit <tt class="docutils literal"><span class="pre">std::move</span></tt> which
makes it obvious to the reader, that <tt class="docutils literal">x</tt> shouldn't be used afterwards.</p>
<p>The compile errors Rust gives can be intimidating when learning Rust, since it
is not obvious from the code that <tt class="docutils literal">x</tt> just moved.</p>
<p>But Rust's lifetime concept doesn't stop here. It even tracks down usage of
invalidated references. Consider the following C++ code:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span><span class="cpf"><cstdio></span>
<span class="cp">#include</span><span class="cpf"><vector></span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class="w"> </span><span class="n">v</span><span class="p">;</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="kt">int</span><span class="o">&</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"%i, "</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">"%i</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Executing this code will output <tt class="docutils literal">5, 0</tt> on my machine. According to the <a class="reference external" href="http://en.cppreference.com/w/cpp/container/vector#Iterator_invalidation">C++
standard</a>
<tt class="docutils literal">push_back</tt> invalidates any reference to elements (iterators). So accessing
it triggers undefined behaviour.</p>
<p>Trying the same in Rust</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[];</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="w"> </span><span class="fm">print!</span><span class="p">(</span><span class="s">"{}, "</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Triggers a compile error:</p>
<div class="highlight"><pre><span></span>rust_dangling.rs:6:5: 6:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable
rust_dangling.rs:6 v.push(6);
^
rust_dangling.rs:4:14: 4:15 note: previous borrow of `v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `v` until the borrow ends
rust_dangling.rs:4 let x = &v[0];
^
rust_dangling.rs:8:2: 8:2 note: previous borrow ends here
rust_dangling.rs:1 fn main() {
...
rust_dangling.rs:8 }
^
</pre></div>
<p>Rust tries to tell us, that we can't change the vector, because there is still
a reference to it in scope, namely <tt class="docutils literal">x</tt>!
To fix the issue we need to limit the scope of <tt class="docutils literal">x</tt>:</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[];</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="w"> </span><span class="fm">print!</span><span class="p">(</span><span class="s">"{}, "</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Have comments? Discuss on <a class="reference external" href="https://news.ycombinator.com/item?id=9329506">Hacker News</a>.</p>
</div>
Learning Rust2015-02-04T00:00:00+01:002015-02-04T00:00:00+01:00rnestlertag:blog.rnstlr.ch,2015-02-04:/learning-rust.html<p class="first last">Learning the programming language rust</p>
<p>Reading the news that Rust reached <a class="reference external" href="http://blog.rust-lang.org/2015/01/09/Rust-1.0-alpha.html">1.0 Alpha</a> I decided to take
a deeper look at <a class="reference external" href="http://www.rust-lang.org/">it</a>.</p>
<div class="section" id="getting-rust">
<h2>Getting Rust</h2>
<p>Installing Rust under arch is as easy</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>rust
</pre></div>
<p>The above will install the latest version from the <a class="reference external" href="https://www.archlinux.org/packages/community/x86_64/rust/">community repo</a>. If you want the
latest and greatest version you could also try <a class="reference external" href="https://aur.archlinux.org/packages/rust-nightly/">the nightly build</a>.</p>
<p>The lazy people can try it <a class="reference external" href="https://play.rust-lang.org/?code=%2F%2F%20This%20code%20is%20editable%20and%20runnable!%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%20World!%22%3B%0A%7D">online</a>.</p>
</div>
<div class="section" id="hello-world">
<h2>Hello World!</h2>
<p>Here comes the obligatory "Hello World!" code in Rust</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Hello World!"</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="immutability">
<h2>Immutability</h2>
<p>Beeing a <a class="reference external" href="http://gamesfromwithin.com/wp-content/uploads/2010/07/const_nazi.mov">C++ const-nazi</a> I
really liked that by default all variable bindings are immutable.</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="n">x</span><span class="o">+=</span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>The example above will give you a compile error:</p>
<div class="highlight"><pre><span></span>mut.rs:4:5:<span class="w"> </span><span class="m">4</span>:9<span class="w"> </span>error:<span class="w"> </span>re-assignment<span class="w"> </span>of<span class="w"> </span>immutable<span class="w"> </span>variable<span class="w"> </span><span class="sb">`</span>x<span class="sb">`</span>
mut.rs:4<span class="w"> </span><span class="nv">x</span><span class="o">+=</span><span class="m">1</span><span class="p">;</span>
<span class="w"> </span>^~~~
mut.rs:3:9:<span class="w"> </span><span class="m">3</span>:10<span class="w"> </span>note:<span class="w"> </span>prior<span class="w"> </span>assignment<span class="w"> </span>occurs<span class="w"> </span>here
mut.rs:3<span class="w"> </span><span class="nb">let</span><span class="w"> </span><span class="nv">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<span class="w"> </span>^
error:<span class="w"> </span>aborting<span class="w"> </span>due<span class="w"> </span>to<span class="w"> </span>previous<span class="w"> </span>error
</pre></div>
<p>By using the "mut" keyword we mark the variable as mutable</p>
<div class="highlight"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="n">x</span><span class="o">+=</span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>So the code will print "2"</p>
<p>Rust will also emit a warning when not using variables or an error when trying
to use uninitialized variables.</p>
</div>
Run slock before going to sleep2013-10-25T00:00:00+02:002013-10-25T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2013-10-25:/run-slock-before-going-to-sleep.html<p class="first last">How to configure systemd to run slock when going to sleep</p>
<p>As noted in my previous post, I configured my system to run slock as soon as
the system enters sleep state. This is how its done.</p>
<p>First we create a new systemd unit in /etc/systemd/system called
suspend@.service</p>
<div class="highlight"><pre><span></span><span class="k">[Unit]</span>
<span class="na">Description</span><span class="o">=</span><span class="s">User suspend actions</span>
<span class="na">Before</span><span class="o">=</span><span class="s">sleep.target</span>
<span class="k">[Service]</span>
<span class="na">User</span><span class="o">=</span><span class="s">%I</span>
<span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
<span class="na">Environment</span><span class="o">=</span><span class="s">DISPLAY=:0</span>
<span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/slock</span>
<span class="k">[Install]</span>
<span class="na">WantedBy</span><span class="o">=</span><span class="s">sleep.target</span>
</pre></div>
<p>So what did we do? We created a unit that runs before sleep.target is reached.
This unit will run as a configurable user by enabling <cite>suspend@$USER.service</cite></p>
<div class="highlight"><pre><span></span><span class="gp"># </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>suspend@<span class="nv">$USER</span>.service
</pre></div>
<p>So the /usr/bin/slock runs as $USER. To be able to communicate with the
X-Server we need to set the DISPLAY variable to :0.</p>
<p>So now when your system is going to sleep systemd should start slock.</p>
<p>Sadly this works only for a one user system since the username is hardcoded
when enabling the unit file. To make it work with multible users one would
need to create a script which determines which user is running the X-Server
then change to this user and lock the screen.</p>
Creating this Blog2013-10-23T00:00:00+02:002013-10-23T00:00:00+02:00rnestlertag:blog.rnstlr.ch,2013-10-23:/creating-this-blog.html<p class="first last">How and why I created this blog.</p>
<p>Recently a friend of mine asked me how I configured my system so that <a class="reference external" href="http://tools.suckless.org/slock">slock</a> locks the screen when I close the lid.</p>
<p>Since I couldn't remember how I did it, I thought it's time to create a blog
where I can write down stuff like this.</p>
<p>The same friend recommended me to use <a class="reference external" href="http://getpelican.com/">pelican</a> to
create my blog.</p>
<div class="section" id="setting-up-pelican">
<h2>Setting up pelican</h2>
<p>Setting up pelican is quite straight forward. First I created a new developement environment with <a class="reference external" href="http://www.virtualenv.org/">virtualenv</a>.</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>virtualenv<span class="w"> </span>blogenv
$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>blogenv
$<span class="w"> </span>.<span class="w"> </span>bin/acivate
</pre></div>
<p>Then installing pelican</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pelican
</pre></div>
<p>The next step is to create the base structure with the interactive
pelican-quickstart</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>mkdir<span class="w"> </span>blog<span class="p">;</span><span class="w"> </span><span class="nb">cd</span><span class="w"> </span>blog
$<span class="w"> </span>pelican-quickstart
$<span class="w"> </span>ls
content/<span class="w"> </span>fabfile.py<span class="w"> </span>output/<span class="w"> </span>publishconf.py
develop_server.sh*<span class="w"> </span>Makefile<span class="w"> </span>pelicanconf.py
</pre></div>
<p>Thats it! Your pelican installation is finished! To generate your still empty blog is easy</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>make<span class="w"> </span>html
$<span class="w"> </span>make<span class="w"> </span>devserver
</pre></div>
<p>After that you can preview you blog on <a class="reference external" href="http://localhost:8000">http://localhost:8000</a></p>
</div>
<div class="section" id="integrating-with-github-pages">
<h2>Integrating with github pages</h2>
<p>Since I don't own any webspace I wanted to use the pages feature of <a class="reference external" href="https://help.github.com/articles/user-organization-and-project-pages">github</a></p>
<p>I created two repositories</p>
<blockquote>
<ul class="simple">
<li>username/username.github.io-source, where I host the pelican sources</li>
<li>username/username.github.io, where I host the generated output</li>
</ul>
</blockquote>
<p>Pelican supports this approach as seen in <a class="reference external" href="http://docs.getpelican.com/en/3.3.0/tips.html#user-pages">http://docs.getpelican.com/en/3.3.0/tips.html#user-pages</a></p>
<p>So all you need to do is to install ghp-import</p>
<div class="highlight"><pre><span></span>%<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>ghp-import
</pre></div>
<p>Then change SITEURL in publishconf.py to <a class="reference external" href="http://username.github.io">http://username.github.io</a> and edit the
github target in the Makefile to look like this</p>
<div class="highlight"><pre><span></span><span class="nf">github</span><span class="o">:</span><span class="w"> </span><span class="n">publish</span>
<span class="w"> </span>ghp-import<span class="w"> </span><span class="k">$(</span>OUTPUTDIR<span class="k">)</span>
<span class="w"> </span>git<span class="w"> </span>push<span class="w"> </span>git@github.com:username.username.io.git<span class="w"> </span>gh-pages:master
</pre></div>
<p>ghp-import will create a branch in the current git repository called gh-pages
and commit any changes in the output directory to it. Then we push this branch
to the master branch in our username.github.io repository.</p>
<p>So if you type</p>
<div class="highlight"><pre><span></span>$<span class="w"> </span>make<span class="w"> </span>github
</pre></div>
<p>The blog gets published under <a class="reference external" href="http://username.github.io">http://username.github.io</a></p>
</div>