Today’s movie: Ex Machina

<INSERT APPROPRIATE QUOTE HERE>

This movie by Alex Garland was on my watchlist since quite some time. Bring together AI, consciousness, existentialism, deal with the singularity and stuff and you got me talking. There are so many ways that such a movie can go wrong. But that’s not a problem here. The narrative is well thought, and it gets to the point. The movie is also honest with itself. But that’s about just that. In the end there is nothing new to learn, no door opened on further reflection and this is what bugged us.

Spoiler alert! Warning! Spoiler ahead!

I guess there are several possible readings. But if you think it revolved around a robot passing the Turing test, my two cents are that you are probably wrong. Instead the whole purpose wasn’t a test of Ava’s ability to fake human behavior and consciousness as she could probably pass this test with ease (as did her preceding iterations), but whether an average human (Caleb) was still capable of seeing her as just a machine or at least not human. And obviously that test has failed.

My other guess is that Nathan, beside being a total drunk twat hypocritical misogynistic asshole, is actually on our side. This guy is genuinely scared by the consequences that a singularity just round the corner will have on humanity (beyond all ethical concerns). So his purpose was not to create the first human-like AI, but to get one step ahead and limit the damage. He wanted to draw the blurry line that would separate machines from humanity so that he could let those machines exist (which he sees as inevitable), but at the same time ensure that humanity thrives and stays true to itself.

Now being a smart guy, Nathan was capable of this assumption. Also forcing himself to make this distinction had a very negative impact on his personality (probably turning him into the boozer and asshole that he is). But he was truly aware of that which is why he designed Ava with such apparent robotic features and why he needed an external human factor (Caleb) to continue his tests.

OK so after some more explanations by Alex Garland that’s probably not what he meant at all. Instead it really is just a test of how smart she is and will she escape. But I tend to disagree, but that’s just my opinion.

Custom user Xsession with SDDM

Debian stretch is out, a lot of obsolete packages, a lot of major upgrades, which all in all resulted in quite a painful transition the last few days. But I’ll tell you more about that in the following posts.

I don’t really spend much time on Linux nowadays so KDE (along with KDM) has always been my goto solution for a jack all trade no-BS works-out-of-the-box desktop environment. And it worked like that just fine, until… well you know how software goes. KDE has been upgraded, KDM has been depreciated and replaced with SDDM.

I also use xsession so that I have a common way of starting session scripts and daemons (such as this one) and configuring stuff across different desktops. I generally selected custom session in the display manager and that was it. But SDDM does not seem to provide a way to do so, or at least that’s not so clear.

By default, it will execute /etc/sddm/xsession which itself sources /etc/X11/Xsession to which it will pass as argument the value of the Exec line in the desktop file (located in /usr/share/xsessions) describing the currently selected session.

If we want to bypass this, we need to scrap the argument passed to /etc/X11/Xsession no matter what SDDM thinks the current session should be. To do so create a wrapper for Xsession in /etc/X11/user-Xsession:

#!/bin/sh

export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

# Discard argument, we don't care about selecting the desktop environment.
/etc/X11/Xsession

And now configure SDDM to use this instead of its own version of it, in /etc/sddm.conf:

[X11]
SessionCommand=/etc/X11/user-Xsession

MSP430 and Contiki on FreeBSD

If you were trying to compile a Contiki application that targets an MSP430 platform (T-Mote Sky for example) on FreeBSD, you might have noticed that msp430-gcc was removed from the port tree and replaced by gcc-msp430-ti-toolchain. Contiki does not support this newer toolchain so you might find yourself a bit stuck there.

Fortunately you can still access the last version of the msp430-gcc packages from the FreeBSD archives:

Suspend on lid closed + battery

If you use FreeBSD 11 on the good ol’ ThinkPad X201, you’ve probably noticed now that suspend and resume work perfectly flawlessly with the latest FreeBSD release.

You probably wish to take advantage of this and suspend your laptop automatically when the lid is closed. Nothing could be easier:

sysctl hw.acpi.lid_switch_state=S3

Save this option /etc/sysctl.conf for it to be permanent.
Close the lid, the laptop goes to sleep, you’re done!
It’s that simple.

But, with this method it will go to sleep each time the lid is closed, completely ignoring whether the laptop is on battery or not. And if you’re like me you probably don’t want this. Instead you want it to suspend itself when the lid is closed and the laptop is on battery. Easy enough! We just have to invoke the mighty power of devd along with a very little shell script.

First we need to tell devd how to react when the lid is closed. Put this in /etc/devd/lid.conf, then restart (service devd restart):

# Notify lid close/open events.
notify 10 {
  match  "system"    "ACPI";
  match  "subsystem" "Lid";
  action "/etc/acpi/lid.sh $notify";
};

Now we will make a script that checks the lid and AC line states and chooses to suspend the laptop when both the lid is closed and AC line is disconnected. This goes in /etc/acpi/lid.sh:

#!/bin/sh

lid="$1" # 0x00 is closed, 0x01 is open (see devd.conf)
acline=$(sysctl -n hw.acpi.acline) # 0 is battery, 1 is online (man acpi)

if [ \( "$lid" = "0x00" \) -a \( "$acline" -eq 0 \) ]
then
  logger "Lid closed on battery. Going to sleep."
  acpiconf -s3
fi

Try it out! Disconnect the AC line, close the lid, it should go to sleep within seconds. However if it doesn’t work you might want to modify the script above a little to check whether lid events are received correctly or not.

Now you may use a modified version of this script to lock xscreensaver when the lid is closed and before the actual suspend. Well OK, I’ve done that for you:

#!/bin/sh
# XScreensaver should be called BEFORE going to sleep to avoid the desktop to be
# shown for a few seconds when the system resumes from sleep.
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

lid="$1" # 0x00 is closed, 0x01 is open (see devd.conf)
acline=$(sysctl -n hw.acpi.acline) # 0 is battery, 1 is online (man acpi)

lock_display() (
  socket="$1"
  display=$(echo "$socket" | tr "X" ":")

  # Temporary pid file for the watching command
  tpid=$(mktemp)

  # Wait until the display is actually locked.
  (timeout 2s xscreensaver-command -display "$display" -watch & echo $! > $tpid) | (
    # Issue the lock command only when we know that
    # the watching pipe is ready.
    xscreensaver-command -display "$display" -lock

    while read line
    do
      line=$(echo $line | cut -d' ' -f 1)

      if [ "$line" = LOCK ]
      then
        # We have to kill the watching command manually before breaking.
        kill -TERM $(cat $tpid)
        break
      fi
    done
  )

  rm $tpid
)

# The X server may not be running
if [ ! -d /tmp/.X11-unix ]
then
  exit 0
fi

# Lock each available display
for socket in $(ls /tmp/.X11-unix)
do
  # Lock the display
  logger "Locking xscreensaver on $socket"
  lock_display $socket &
done

# Wait until every displays are locked
wait

# Now we can suspend if needed
if [ \( "$lid" = "0x00" \) -a \( "$acline" -eq 0 \) ]
then
  logger "Lid closed on battery. Going to sleep."
  acpiconf -s3
fi

Today’s movie: The Wind Rises

風立ちぬ

The Wind Rises by Hayao Miyazaki. Almost saw this movie in 2013 when I lived for some time in Tokyo. We planned to see it at the cinema but for some reason we didn’t (there was so much to do back then). Finally didn’t got to see it until today.

All that we’d ever aspire from life, yet it’s nothing but a dream.

Disk failure happens

So my not-so-trusty-anymore 5 years old HDD crashed unexpectedly this morning. That happened on my working laptop. But thank god I do backups! I still probably lost some documents but it could have been much worse.

Coincidentally I was just saying to myself that it would be a good idea to reinstall it just to force me to clean this old setup a little bit. Well that providential failure forced my hand. Thanks for that!

This also prompted me to start building a NAS, an idea that I have in my mind since quite a few months now. So you will probably read more of that in a few weeks.

Using NAT64 locally

NAT64 is a translation mechanism that allows IPv6 addresses to be transparently mapped to IPv4 addresses. The principle if very simple. In a NAT64 address, the IPv4 address is embedded into the 32 least significant bits of the IPv6 address. When you send an IPv6 packet to a NAT64 router, it will extract the IPv4 address embedded into the NAT64 IPv6 destination address and send the packet using this IPv4 instead. The source IPv4 address used is chosen within a provided pool of IPv4 addresses (which can be SNATed, in which case you can use a private network reserverd for the NAT64 pool). The NAT64 router will also do the reverse mapping and translate the reply from the IPv4 remote address to your original IPv6 address.

This is very convenient for IPv6 only hosts (such as IoT smart objects) that need to contact a very sparse IPv6 Internet. Even if a remote host is only accessible via IPv4, it can still be accessed from IPv6 using its NAT64 address. Also since the majority of addresses are resolved using DNS, there are some servers (unbound is one of them) that provide a DNS64 module which will automatically construct a NAT64 AAAA record when no other IPv6 records are found for a specific domain. This way your IPv6 only hosts using DNS believe that all domains have an AAAA record, and that all the Internet is IPv6 enabled.

In my case I use Tayga NAT64 router along with Unbound DNS64 module. There are several posts out there that explain how to configure these two and this is not my intent here. Instead I want to focus on a problem that I had using Tayga’s NAT64 locally. That is trying to ping a non-IPv6 domain from the host that is running Tayga:

$ ping6 ipv4.google.com

This command worked fine from outside the host running Tayga (for packets routed through the NAT64 router), but didn’t work at all when issued on the host running Tayga.

Using tcpdump, I found that when issued locally, Tayga used its own IPv4 address (its ipv4-addr option) as source address for the translated IPv6 packets. Since this address was not mapped in Tayga IPv4 source address pool, it did not translate the reply back to the original IPv6 address and so the ping6 command never got any reply.

What I also found was that the source address used by the ping6 command was also Tayga’s own IPv6 address (its ipv6-address option). Since the NAT64 address that ping6 tries to use is routed through the nat64 interface, it defaulted to the nat64 interface IPv6 address (that is Tayga’s IPv6 address) for its source address.

This is what triggered Tayga to use its own IPv4 address which is outside its pool resulting in the reply not being translated back to its own IPv6 address. So we need a way to avoid choosing Tayga’s own IPv6 address when trying to reach a NAT64 address locally. We know that Tayga configures its own IPv4 and IPv6 addresses on its nat64 interface. All we have to do is to add another IPv6 address to the interface so that it will be used instead as the source address for local packets destinated to the nat64 router interface.

Suppose we have:

  • Internet routed prefix: 2001:db8:1::/64
  • NAT64 IPv6 prefix: 2001:db8:64::/96
  • NAT64 IPv6 address: 2001:db8:1::64
  • NAT64 IPv4 address: 192.168.1.64

Then the nat64 interface will have the 2001:db8:1::64 IPv6 address. Just add another IPv6 address to this interface with:

ifconfig nat64 inet6 add 2001:db8:1::46 netmask 128

Tadaaa! Now when you try to reach a NAT64 address locally, the address you just added to nat64 will be used instead as the source address. Since this is not Tayga’s own IPv6 address, it will dutifully map the NAT64 using its IPv4 address pool and translate the reply back to the new IPv6 address. In other words NAT64 addresses now work on the host running the NAT64 router.