Search Results: "tar"

13 March 2021

Enrico Zini: Decameron and content warnings

Giovanni Boccaccio's Decameron is a book in which there's a pandemic, and a group of seven young women and three young men decide to practice social distancing in a secluded villa just outside of Florence. During two weeks of lockdown, they structure their time wisely, and among other things they spend the evenings telling each other stories. The book is a collection of those stories. The stories vary from the erotic to the tragic, and may trigger some reader. Boccaccio is aware of that, so he starts each chapter with a one line summary that is explicitly intended as a content warning, to give the reader a choice in whether to read the story, or skip to the next one. Boccaccio explains this in the book itself:
However, those who read these tales can leave those they dislike and read those they like. I do not want to deceive anybody, and so all these tales bear written at the head a title explaining what they contain. (link to version in original language)
On top of the very relatable setting, the diversity of stories, the empathy in the narration, the gender inclusivity, and the respect for the reader, it's a pretty good book. It should even be out of copyright! It was written around year 1350.

Jonathan Dowland: Internal Gotek

This is the eleventh part in a series of blog posts. The previous post was FlashFloppy OLED display. The whole series is available here: Amiga.
It's still mostly all quiet on the Amiga project front. The last few months with both my kids at home have been too difficult and busy with no time for side projects. Primary Schools in the UK went back this week, and I've finally got around to installing the Gotek floppy emulator inside the Amiga A500's chassis. I followed A short "Internal Gotek Floppy" Installation Guide , which explains that you don't need to print (or buy) a special mount for it: Simply removing the Gotek's top plastic case is enough for it to fit inside, and you can support it with some nuts and bolts.
Gotek bolted into place Gotek bolted into place
Easy in theory, but it still took me a while, with plenty of trial and error to line it up just right. I ended up using some M4 bolts and smaller (the kind that you use in electrical sockets) to support the bottom part of the Gotek case in three places: one, at the front, re-using an original vertical support for the old floppy drive; and two at the back, screwing through two holes in the A500's outer case and mainboard. If I'd chosen short enough bolts, the back of the Gotek case could have probably just rested on the ends of those bolts, but the ones I had were another few cm longer, so I drilled holes in the Gotek case to run the bolts through, and secured it with nuts.
Knob, display and mount, external Knob, display and mount, external
In that guide, the author has an OLED display for their Gotek that they wanted on the top of the Amiga case, so they fed the four tiny wires through the grill. I had a go at that, but I've got the OLED display and a rotary encoder, so that's 8 wires total, and damn fiddly. Instead for now I've just routed them all out through the hole left behind by the floppy drive's Button. I'm going to try and tidy it up with some heat shrink or similar. So finally, my Amiga is one "unit" again, without dangly bits hanging off it (if you ignore those 8 tiny wires for now) that I can move around to store or use much more easily.

Louis-Philippe V ronneau: Preventing an OpenPGP Smartcard from caching the PIN eternally

While I'm overall very happy about my migration to an OpenPGP hardware token, the process wasn't entirely seamless and I had to hack around some issues, for example the PIN caching behavior in GnuPG. As described in this bug the cache-ttl parameter in GnuPG is not implemented and thus does nothing. This means once you type in your PIN, it is cached for as long as the token is plugged. Security-wise, this is not great. Instead of manually disconnecting the token frequently, I've come up with a script that restarts scdameon if the token hasn't been used during the last X minutes. It seems to work well and I call it using this cron entry: */5 * * * * my_user /usr/local/bin/restart-scdaemon To get a log from scdaemon, you'll need a ~/.gnupg/scdaemon.conf file that looks like this:
debug-level basic
log-file /var/log/scdaemon.log
Hopefully it can be useful to others!
 #!/usr/bin/python3
# Copyright 2021, Louis-Philippe V ronneau <pollo@debian.org>
#
# This script is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# 
# This script is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
# 
# You should have received a copy of the GNU General Public License along with
# this script. If not, see <http://www.gnu.org/licenses/>.
"""
This script restarts scdaemon after X minutes of inactivity to reset the PIN
cache. It is meant to be ran by cron each X/2 minutes.
This is needed because there is currently no way to set a cache time for
smartcards. See https://dev.gnupg.org/T3362#137811 for more details.
"""
import os
import sys
import subprocess
from datetime import datetime, timedelta
from argparse import ArgumentParser
p = ArgumentParser(description=__doc__)
p.add_argument('-l', '--log', default="/var/log/scdaemon.log",
               help='Path to the scdaemon log file.')
p.add_argument('-t', '--timeout', type=int, default="10",
               help=("Desired cache time in minutes."))
args = p.parse_args()
def get_last_line(scdaemon_log):
    """Returns the last line of the scdameon log file."""
    with open(scdaemon_log, 'rb') as f:
        f.seek(-2, os.SEEK_END)
        while f.read(1) != b'\n':
            f.seek(-2, os.SEEK_CUR)
        last_line = f.readline().decode()
    return last_line
def check_time(last_line, timeout):
    """Returns True if scdaemon hasn't been called since the defined timeout."""
    # We don't need to restart scdaemon if no gpg command has been run since
    # the last time it was restarted.
    should_restart = True
    if "OK closing connection" in last_line:
        should_restart = False
    else:
        last_time = datetime.strptime(last_line[:19], '%Y-%m-%d %H:%M:%S')
        now = datetime.now()
        delta = now - last_time
        if delta <= timedelta(minutes = timeout):
            should_restart = False
    return should_restart
def restart_scdaemon(scdaemon_log):
    """Restart scdaemon and verify the restart process was successful."""
    subprocess.run(['gpgconf', '--reload', 'scdaemon'], check=True)
    last_line = get_last_line(scdaemon_log)
    if "OK closing connection" not in last_line:
        sys.exit("Restarting scdameon has failed.")
def main():
    """Main function."""
    last_line = get_last_line(args.log)
    should_restart = check_time(last_line, args.timeout)
    if should_restart:
        restart_scdaemon(args.log)
if __name__ == "__main__":
    main()

12 March 2021

Ryan Kavanagh: Static Comments in Hugo

I switched from Jekyll to Hugo last week for a variety of reasons. One thing that was missing was a port of the jekyll-static-comments plugin that I used to use. I liked it because it saved readers from being tracked by Disqus or other comments solutions, and it required no javascript. To comment, users would email me their comment following a template attached to the bottom of each post. I then piped their email through a script to add it to the right post. As an added benefit, I could delegate comment spam detection to my mail server. I ve managed to reimplement this setup using Hugo. For those who are interested in a similar setup, here is what you need to do.

Pages with comments Instead of being single files, pages need to be leaf bundles. For example, this means that your blog post must be located at /content/blog/2021-03-12-static-comments-in-hugo/index.md instead of /content/blog/2021-03-12-static-comments-in-hugo.md. This lets you store the comments as page resources in the subdirectory /content/blog/2021-03-12-static-comments-in-hugo/comments/.

Partials You should create a comments.html partial and include it in the layout for the pages which should get comments:
<div class="post-comments">
  <p class="comment-notice"><b>Comments</b>: To comment on this post,
	send me an email following the template below. Your email address
	will not be posted, unless you choose to include it in
	the <span style="font-family: monospace;">link:</span> field.</p>
  <pre class="comment-notice">
To: Your Name &lt;your.email<span>@</span>example.org&gt;
Subject: [blog-comment]   .Page.RelPermalink  
post_id:   .Page.RelPermalink  
author: [How should you be identified? Usually your name or "Anonymous"]
link: [optional link to your website]
Your comments here. Markdown syntax accepted.</pre>
    $scratch := newScratch  
    $scratch.Set "comments" (.Resources.Match "comments/*yml")  
    if eq 1 (len ($scratch.Get "comments"))  
  <h2>1 Comment</h2>
    else  
  <h2>  len ($scratch.Get "comments")   Comments</h2>
    end  
    range ($scratch.Get "comments")  
  <div class="post-comment  % cycle 'odd', 'even' % ">
	  $comment := (.Content   transform.Unmarshal)  
	<span class="post-meta">
		 - $comment.date   dateFormat "Jan 2, 2006 at 15:04" - 
	</span>
	<h3 class="comment-header">
	    if $comment.link  
	  <a href="  $comment.link  ">  $comment.author  </a>
	    else  
	    $comment.author  
	    end  
	  <br />
	</h3>
	  $comment.comment   markdownify  
  </div>
    end  
</div>

Comments To associate comments received by email to posts, I pipe them from mutt (using the keybinding) to the following (admittedly janky) shell script. It takes the comment, reformats it appropriately, and puts it in the post s comments subdirectory. Note that it determines which filename to use based on the email s contents, so make sure to check that the email doesn t contain anything nefarious before you pipe it into the script!
#!/bin/sh
# Copyright (C) 2016-2021 Ryan Kavanagh <rak@rak.ac>
# Distributed under the ISC license
BLOG_BASE="/media/t/work/blog"
MESSAGE=$(cat)
EMAIL=$(echo "$ MESSAGE "   grep "From:"   sed -e 's/From[^<]*<\?\([^>]*\)>\?.*/\1/g;s/@/-at-/g')
DATE=$(echo "$ MESSAGE "   grep "Date:"   sed -e 's/Date:\s*//g'   xargs -0 date -Iseconds -u -d)
POST_ID=$(echo "$ MESSAGE "   grep "post_id:"   sed -e 's/post_id: //g')
COMMENTS_DIR="$ BLOG_BASE /content/$ POST_ID /comments/"
COMMENT_FILE="$ COMMENTS_DIR /$ DATE _$ EMAIL .yml"
# Strip out the email headers and whitespace until the start of the comment
COMMENT_WHOLE=$(echo "$ MESSAGE "   sed -e '/^\s*$/,$!d;/^[^\s]/,$!d')
# Indent everything after the comment header
COMMENT_INDENTED=$(echo "$ COMMENT_WHOLE "   sed -e '/^\s*$/,$ s/.*/  &/g ')
# And add the comment header
COMMENT_PREFIXED=$(echo "$ COMMENT_INDENTED "   sed -e '0,/^\s*$/ s/^\s*$/comment:  / ')
[ -d "$ COMMENTS_DIR " ]   mkdir -p "$ COMMENTS_DIR "
echo "Saving the comment to $ COMMENT_FILE "
echo "date: $ DATE "   tee "$ COMMENT_FILE "
echo "$ COMMENT_PREFIXED "   tee -a "$ COMMENT_FILE "
For example, the following comment in an email body:
post_id: /blog/2021-03-12-static-comments-in-hugo/
author: Ryan Kavanagh
link: https://rak.ac/
Dear self,
Here is a test comment for your blog post.
It supports *markdown* **syntax** and  stuff .
Best,
Yourself
results in a file content/blog/2021-03-12-static-comments-in-hugo/comments/2021-03-12T18:47:25+00:00_rak-at-example.org.yml containing:
date: 2021-03-12T18:47:25+00:00
post_id: /blog/2021-03-12-static-comments-in-hugo/
author: Ryan Kavanagh
link: https://rak.ac/
comment:  
  Dear self,

  Here is a test comment for your blog post.
  It supports *markdown* **syntax** and  stuff .

  Best,
  Yourself  
You can see the rendered output at the bottom of this page.

Reproducible Builds (diffoscope): diffoscope 169 released

The diffoscope maintainers are pleased to announce the release of diffoscope version 169. This version includes the following changes:
[ Chris Lamb ]
* Optimisations:
  - Use larger buffer/block sizes when extracting files from libarchive-
    based archives.
  - Use a much-shorter CSS class (instead of "diffponct") to dramatically
    reduce uncompressed HTML output.
* Logging improvements:
  - Don't emit "Unable to stat file" warning/debug messages; we have
    entirely-artificial directory entries such as ELF sections which, of
    course, never exist as filesystem files.
  - Don't emit a "Returning a FooContainer" logging message - we already emit
    "Instantiating a FooContainer" one and are unlikely to fail in the
    middle.
  - Format the report size logging messages when generating HTML reports.
  - Add the target directory when logging which directory we are extracting
    containers to.
* Miscellaneous:
  - Ignore "--debug" and similar arguments when creating a (hopefully useful)
    temporary directory.
  - Ensure all internal temporary directories have useful names.
  - Clarify a comment regarding diffoscope not extracting excluded files.
[ Vagrant Cascadian ]
* Skip a DEX-related test if the "procyon" tool is unavailable.
You find out more by visiting the project homepage.

11 March 2021

Vincent Fourmond: All tips and tricks about QSoas

I've decided to post regular summaries of all the articles written here about QSoas; this is the first post of this kind. All the articles related to QSoas can be found here also. The articles written here can be separated into several categories. Tutorials to analyze real data These are posts about how to reproduce the data analysis of published articles, including links to the original data so you can fully reproduce our results. These posts all have the label tutorial. All about fits QSoas has a particularly powerful interface for non-linear least square minimisations (fits): Meta-data Meta data describe the conditions in which experiments were performed. Quiz and their solutions Quiz are small problems that take some skill to solve; they can teach you a lot about how to work with QSoas. Other tips and tricks Release annoucements These have generally lot of general information about the possibilities in QSoas:
About QSoas QSoas is a powerful open source data analysis program that focuses on flexibility and powerful fitting capacities. It is released under the GNU General Public License. It is described in Fourmond, Anal. Chem., 2016, 88 (10), pp 5050 5052. Current version is 3.0. You can download its source code there (or clone from the GitHub repository) and compile it yourself, or buy precompiled versions for MacOS and Windows there.

10 March 2021

Sean Whitton: consfigurator 0.3.1

I d like to briefly introduce my new project, Consfigurator:
Consfigurator is a system for declarative configuration management using Common Lisp. You can use it to configure hosts as root, deploy services as unprivileged users, build and deploy containers, and produce disc images. [not all of these are implemented yet, but the design permits them to be] Consfigurator s design gives you a great deal of flexibility about how to control the hosts you want to configure. If there is a command you can run which will obtain input and output streams attached to an interactive POSIX sh running on the target host/container, then with a little glue code, you can use much of Consfigurator s functionality to configure that host/container. But if it is possible to get an implementation of Common Lisp started up on the host, then Configurator can transparently execute your deployment code over on the remote side, rather than exchanging information via POSIX sh. This lets you use the full power of Common Lisp to deploy your configuration. Configurator has convenient abstractions for combining these different ways to execute your configuration on hosts with different ways of connecting to them. Connections can be arbitrarily nested. For example, to combine SSHing to a Debian machine as an unprivileged user, using sudo to become root, and then starting up a Lisp image to execute your deployment code, you would evaluate
    (deploy ((:ssh (:sudo :as "spwhitton@athena.example.com") :debian-sbcl)) athena.example.com)
Declarative configuration management systems like Consfigurator and Propellor share a number of goals with projects like the GNU Guix System and NixOS. However, tools like Consfigurator and Propellor try to layer the power of declarative and reproducible configuration on top of traditional, battle-tested unix system administration infrastructure like apt, dpkg, yum, and distro package archives, rather than seeking to replace any of those. Let s get as much as we can out of all that existing distro policy-compliant work!
Please check out the user s manual, which includes a tutorial/quick start guide, and come join us in #consfigurator on irc.oftc.net. It s early days but you can already do a fair few things with Consfigurator. It s a good time to come help get all the basic properties defined!

Mike Hommey: 5 years ago, Firefox (re)entered Debian

5 years ago today, I was declaring Iceweasel dead, and Firefox was making a come back in Debian. I hadn t planned to make this post, and in fact, I thought it had been much longer. But coincidentally, I was binge-watching Mr. Robot recently, which prominently featured Iceweasel. iceweasel command in a terminal Mr. Robot is set in the year 2015, and I was surprised that Iceweasel was being used, which led me to search for that post where I announced Firefox was back and realizing that we were close to the 5 years mark. Well, we are at the 5 years mark now. iceweasel start page I d normally say time flies, but it turns out it hasn t flown as much as I thought it did. I wonder if the interminable pandemic is to blame for that.

9 March 2021

Matthew Garrett: Unauthenticated MQTT endpoints on Linksys Velop routers enable local DoS

(Edit: this is CVE-2021-1000002)

Linksys produces a series of wifi mesh routers under the Velop line. These routers use MQTT to send messages to each other for coordination purposes. In the version I tested against, there was zero authentication on this - anyone on the local network is able to connect to the MQTT interface on a router and send commands. As an example:
mosquitto_pub -h 192.168.1.1 -t "network/master/cmd/nodes_temporary_blacklist" -m ' "data": "client": "f8:16:54:43:e2:0c", "duration": "3600", "action": "start" '
will ask the router to block the client with MAC address f8:16:54:43:e2:0c from the network for an hour. Various other MQTT topics pass parameters to shell scripts without quoting them or escaping metacharacters, so more serious outcomes may be possible.

The vendor has released two firmware updates since report - I have not verified whether either fixes this, but the changelog does not indicate any security issues were addressed.

Timeline:

2020-07-30: Submitted through the vendor's security vulnerability report form, indicating that I plan to disclose in either 90 days or after a fix is released. The form turns out to file a Bugcrowd submission.
2020-07-30: I claim the Bugcrowd submission.
2020-08-19: Vendor acknowledges the issue, is able to reproduce and assigns it a P3 priority.
2020-12-15: I ask if there's an update.
2021-02-02: I ask if there's an update.
2021-02-03: Bugcrowd raise a blocker on the issue, asking the vendor to respond.
2021-02-17: I ask for permission to disclose.
2021-03-09: In the absence of any response from the vendor since 2020-08-19, I violate Bugcrowd disclosure policies and unilaterally disclose.

comment count unavailable comments

Sylvestre Ledru: Debian running on Rust coreutils

tldr: Rust/coreutils ( https://github.com/uutils/coreutils/ ) is now available in Debian, good enough to boot a Debian with GNOME, install the top 1000 packages, build Firefox, the Linux Kernel and LLVM/Clang. Even if I wrote more than 100 patches to achieve that, it will probably be a bumpy ride for many other use cases.
It is also a terrific project to learn Rust. See the list of good first bugs. Even if I see Rust code every day at Mozilla, I was looking for an actual personal project (i.e. this isn't a Mozilla project) to learn Rust during the various COVID lockdowns. I started contributing to the alternative Coreutils developed in Rust. The project aims at proposing a drop-in replacement of the C-based GNU Coreutils, and I wanted to evaluate if this could be used to run a regular Debian. Similar to what I have done with clang.debian.net a few years ago (rebuilding the Debian archive using clang instead of gcc). I expect that most of the readers know what is the Coreutils. It is a set of programs performing simple operations (copy/move file, change permissions/ownership, etc). Even if some commands are from the 70s, they are at the base of Linux, Unix and macOS. While different implementations can be found, they are trying to remain compatible in terms of arguments, options, etc. This implementation of Coreutils isn t different! If you want to learn more about the history of Unix, I recommend this great Corecursive podcast with Brian Kernighan. While a lot of people contributed to this project, much was left to be done: To start easy, I defined 4 goals for this work:
  1. Package Coreutils in Debian/Ubuntu
  2. Boot a Debian system with a Rust-based coreutils
  3. Install the top 1000 packages in Debian - including GNOME
  4. Build Firefox, the Linux Kernel and LLV/Clang

Packaging of Coreutils in Debian Packaging in Debian isn't a trivial or even simple task. It requires uploading independently all the dependencies in the archive. Rust, with its new ecosystem and small crates, is making this task significantly harder. The package is called rust-coreutils - https://tracker.debian.org/pkg/rust-coreutils For Debian/Ubuntu users, to have an idea of the complexity of packaging such applications, just run
debtree --build-dep rust-coreutils dot -Tsvg > coreutils.svg (should be around 1M). Since it isn't production ready, the rust-coreutils is installable in parallel with coreutils. This package does NOT replace the GNU/coreutils files (yet?), the new files are installed in /usr/lib/cargo/bin/. They can be used with: export PATH=/usr/lib/cargo/bin/:$PATH Or, uglier, overriding the files with the new ones.

Booting Debian with rust-coreutils To achieve this, because I knew I would likely break the image a few times, I created a new project to quickly install a full Debian with PXE and preseed. The project is available here: https://github.com/opencollab/qemu-debian-install-pxe-preseed/ A script to create the full qemu image: build_qemu_debian_image.sh A second script to boot on the newly created image: boot.sh Then, building and installing coreutils on the system (yeah, it is ugly - don t do that at home): apt install rust-coreutils
cd /usr/lib/cargo/bin/
for f in *; do
cp -f $f /usr/bin/
done
First surprise, unlike the old init.d init system, as systemd is not relying on a series of scripts (it is mostly written in C), replacing the coreutils did not have an impact. Therefore, I didn't experience any issue during the boot process

Implementing missing options A significant number of problems could be easily identified as a lack of support for some options. Here is a list of most of the fixes I had to implement to make this plan work:

Different behavior Most of the programs behaved as expected. Here is a list of differences:
  • install doesn't support using /dev/null as source file
    Setting up libreoffice-common (1:6.1.5-3+deb10u6) ...
    install: error: install: cannot install /dev/null to /etc/apparmor.d/local/usr.lib.libreoffice.program.oosplash : the source path is not an existing regular file
    A limitation of rust itself https://github.com/rust-lang/rust/issues/79390

Compile Firefox, Clang and the Linux Kernel Build systems can vary significantly one from the other. To verify their usage of coreutils, I built these three major projects

Firefox As Firefox relies mostly on Python as a build system, it went smoothly. I didn t encounter any issue. The only unrelated issue that I noticed working on it was apt-key was broken because the script relied on a buggy option of mktemp.

Linux Kernel I identified only two issues compared to GNU Coreutils:
  • The chown command on a non-existing symlink target doesn t fail on the GNU version, the Rust one was triggering an error.
    https://github.com/uutils/coreutils/pull/1694
  • Linux kernel
    ln -fsn ../../x86/boot/bzImage ./arch/x86_64/boot/bzImage
    ln: error: Unrecognized option: 'n'

LLVM/Clang The llvm toolchain relies on Cmake. Just like for Firefox, I didn t face any issue.

Comparing with GNU coreutils using its testsuite Recently, James Robson added a new test to run the GNU testsuite on the Rust/coreutils.

# TOTAL: 611
# PASS: 144
# SKIP: 86
# XFAIL: 0
# FAIL: 342
# XPASS: 0
# ERROR: 39
compared to 546 test passing with the GNU version. Even if a bunch of errors are just different outputs, it demonstrates that there is still a long road ahead.

Next steps & contribute First, we will need more motivated contributors to work on this project. Many features remain to be implemented, optimizations to be done (e.g. decreasing the memory usage), etc.
I started to create a list of good first bugs for newcomers: https://github.com/uutils/coreutils/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+bug%22
I will update this list of there is some interest for this project.
Helping improve the support of the GNU coreutils testsuite would be a huge step while being a great way to learn Rust! Then, once it is in a better state, we will be able to make it a reliable alternative in Debian/Ubuntu to the GNU/Coreutils. This might be also interesting for other folks who prefer a BSD license over a GPL.

7 March 2021

Enrico Zini: Women in science

Timeline of women in science - Wikipedia
this is a timeline of women in science, spanning from ancient history up to the 21st century. While the timeline primarily focuses on women involved with natural sciences such as astronomy, biology, chemistry and physics, it also includes women from the social sciences (e.g. sociology, psychology) and the formal sciences (e.g. mathematics, computer science), as well as notable science educators and medical scientists. The chronological events listed in the timeline relate to both scientific achievements and gender equality within the sciences.
List of women's firsts - Wikipedia
This is a list of women's firsts noting the first time that a woman or women achieved a given historical feat. A shorthand phrase for this development is "breaking the gender barrier" or "breaking the glass ceiling." Other terms related to the glass ceiling can be used for specific fields related to those terms, such as "breaking the brass ceiling" for women in the military and "breaking the stained glass ceiling" for women clergy. Inclusion on the list is reserved for achievements by women that have significant historical impact.
List of Women in Technology International Hall of Fame inductees - Wikipedia
The Women in Technology International Hall of Fame was established in 1996 by Women in Technology International (WITI) to honor women who contribute to the fields of science and technology.
Women in Chemistry Compound Interest
8 March is International Women s Day. As in previous years, I ve put together another edition of this series looking at underappreciated women from chemistry history.
And some men, too:

Thorsten Alteholz: My Debian Activities in February 2021

FTP master This month I accepted 162 and rejected 28 packages, which is again a small increase compared to last month. The overall number of packages that got accepted was 291. Debian LTS This was my eightieth month that I did some work for the Debian LTS initiative, started by Raphael Hertzog at Freexian. This month my all in all workload has been 30h. During that time I did LTS and normal security uploads of: I also prepared debdiffs for golang-github-appc-cni, wpa and libbsd, which for one reason or another did not result in a DLA yet. Moreover I did some NEW processing and other stuff on security-master. Last but not least I did some days of frontdesk duties. Debian ELTS This month was the thirty-second ELTS month. During my allocated time I uploaded: Last but not least I did some days of frontdesk duties. Other stuff This month I uploaded new upstream versions of:

Shirish Agarwal: Task-based menus for a file

XDG Just throwing this out for wider talk perhaps. I have been silently watching a list called xdg@lists.freedesktop.org. Now the list talks about freedesktop standards which basically is trying to have some sort of standards that all desktop environments can follow. One of the discussions on the specific list shared above is and was about New MimeType fields in .desktop . It is a fascinating thread with many people giving loads of interesting view points. If you are into desktops even casually, you would enjoy the discussions thoroughly. Seriously thinking, I shared the below on the list Hi all, I read quite a bit of the fascinating thread. As a user I have often had to fix the same at my end and at times had to re-fix it again. For me it s the mkv and related media file types. Now I have different applications which are for different things, For e.g. mpv is exclusively the player (followed at times by vlc) for playing the content. Mediainfo to have technical knowledge/bits about the content. ffmpeg for doing some basic stuff (extracting subtitles or adding subtitles etc.) to the content, re-encoding into smaller resolution etc etc. Sadly, none of the solutions as of date tell me if I hover or even go into properties of a mkv file which application does what. I do know this is perhaps a bit outside the discussion having, but does anybody have any ideas? At the very least, it should make the user more aware of what he can do with particular applications perhaps. One way is to perhaps have a database so if I ask in a way that the system understands which are the editors which can be used to manipulate or edit mkv files, it should give me a list available from debian database. I do know that apt, aptitude etc. do try to do something on those lines but it has many shortcomings. And as somebody else mentioned, don t think the solution would be done tomorrow but at least sometime in future. While I stopped at the above on the list, allow me to extrapolate or share a bit more where I am coming from. Somebody did share that this should be actually done by the desktop provider, and GNOME 1 did provide a solution in the early days, now then they have moved to being a more dumb desktop or in their words simplifying. In any case, while I haven t hadn t had the opportunity to see the new MAC desktop, Windows 10 desktop interface is nothing to write home about. All our DE s starting from GNOME, MATE, XFCE, could and should be giving us much more than it has, making users having richer and better experiences than they have today. And while I shared about .mkv (the Matroska Multimedia Container), the above applies and can apply to any file format which can be manipulated in different ways using different tools. I just shared the one I use most often as a use-case scenario. And this should be made easier now that we have processors have multiple cores (for e.g. Intel and AMD quad cores are now there at decent prices) . So would it be too much of an ask to have something which helps people be more productive. As of today, for anybody who is new to either Debian or any X desktop, there is still such a substantial learning curve and more so applications and how they fit in the puzzle and what can be done and what cannot be done. A much screwy thing to add to the mix is file format and which file format version can a particular app. read. The biggest and the most common culprit here is pdf. A good webpage which shares the versions and the comments which tell how people are still having issues with various versions of pdf. Most of the foss tools I use top out at pdf 1.4 which is quite an old format  . I am open to testing and debugging if somebody does try decoding the new versions. For me, this is also an issue as most I.T. notices and what not we get, at times I have to try and figure out things, at times go to MS and use an acrobat reader and that is dumb.

Banking There are also lot of banking stuff that we cannot do on free software, especially in India as lot of powerful proprietary interests are there which make sure that no public API s are available, or even if there is, it would be something half-done or after back and forth, they say, this is just for show, as had shared last year. I would probably add another section later to talk about it. From what little I know, in Europe the law mandates that there are public API s not only for banking but wherever public money (read taxpayer money) is involved. Again, not all countries, but some more than others. At least, that is what I had seen over the years. Till later.

Louis-Philippe V ronneau: New Year, New OpenPGP Key

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Sun, 07 Mar 2021 13:00:17 -0500
I've recently set up a new OpenPGP key and will be transitioning away from my
old one.
It is a chance for me to start using a OpenPGP hardware token and to transition
to a new personal email address (my main public contact is still my
 @debian.org  address).
Please note that I've partially redacted some email addresses from this
statement to minimise the amount of spam I receive. It shouldn't be hard for
actual humans to follow the instructions below to find the complete addresses.
The old key will continue to be valid for a few months, but will eventually be
revoked.
You might know my old OpenPGP certificate as:
pub   rsa4096/0x7AEAC4EC6AAA0A97 2014-12-22 [expires: 2021-06-02]
      Key fingerprint = 677F 54F1 FA86 81AD 8EC0  BCE6 7AEA C4EC 6AAA 0A97
uid       Louis-Philippe V ronneau <REDACTED@riseup.net>
uid       Louis-Philippe V ronneau (alias) <REDACTED@riseup.net>
uid       Louis-Philippe V ronneau (debian) <REDACTED@debian.org>
My new OpenPGP certificate is:
pub   ed25519/0xE1E5457C8BAD4113 2021-03-06 [expires: 2022-03-06]
      Key fingerprint = F64D 61D3 21F3 CB48 9156  753D E1E5 457C 8BAD 4113
uid       Louis-Philippe V ronneau <REDACTED@veronneau.org>
uid       Louis-Philippe V ronneau <REDACTED@debian.org>
These days, I mostly use my key for Debian and to sign git commit. I don't
really expect you to sign my new key if you had signed my old one.
I've published the new certificate on keys.openpgp.org as well as on my
personal website. You can fetch it like this:
    $ wget -O- https://veronneau.org/media/openpgp.key   gpg --import
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEZ39U8fqGga2OwLzmeurE7GqqCpcFAmBFFM8ACgkQeurE7Gqq
CpcuchAAscAeszdtA+TlCI4YvK5nlk+nJnCnNBSnl7Et+jiNjq8kB/Fud+dWMTXC
Zag8oJkalbbxub0BT0bEAn+BiBunu58E0gd0Xq4syTbqZ5o5IN17S/tfxCD0k1hf
ewrnYZ2l0i5g4YvHGKC+Xv4D+Z84BylnIRaXHqlUdluOVfVYDfLybOAqoktO/KUH
I+vQBwXj0Fr/QAtgiz5Nwh/YHFiU9xMSvr5ozRwAFs6+xfIqFHuVPRRkEN5iVo4D
kkMIz+kFfkoh4aWIP4dgAu39XnEgxwTR9J+4yE8TzCCMzO7xCK0X6vqgPAxYMPvb
RuP4FnGWOnGnlcudCUAUkOaryrwRi+dPQTnNICHTYsvVc7dg+W0EhVUkwEuuEwpI
qtcB/Y5AGhqK0Cc11uXiFjIQwLTgwcUez4F0xrGeqsTtAM5gyRup2w0jbocTuYSh
ZRv/2zwrq/S3xVrUYGqdT+L5odmkBzz9zOwY5WlU2H9CMFOdh71XOv9wWQXan9ou
hLRodeOQ8MinIBP+sX36ol1zg/aP7mCHvRRSBzWt7l3WhVxgZFpNwIfp/RZqU0R4
IEq48mntFhPvHJjFmAKLKK/ckzNMtSn+HWQPJV3HTInKCTu5PTNMU3SAvPHOHEps
V6WWSOPB+1Lm/tlIULDc+0SopWoiWO4NObCSs8zMZHlYPBk5x/KIdQQBFgoAHRYh
BMqnQAcHqBawIC/DzfQlelCyHPqFBQJgRRTPAAoJEPQlelCyHPqFFVEA/1qScaAk
O+eBEE4q0BaJDsqweCS1XCcuQGkQCKi5Zv6kAQChQ96Ve7cKbN/wRkT9pdIhmx01
+CmIsnp3k6N0ZYLLCg==
=onl0
-----END PGP SIGNATURE-----

6 March 2021

Shirish Agarwal: Making life difficult

Freedom house puts India in partly free Just couple of days ago, freedom house published its 2020 rankings for all countries including India. While freedom house shared how democracy in the world has weakened, India chose to take offense about it being called partly free .
India, leader in Internet shutdowns Access Now (copyright)
The above illustration is shared by accessnow . The next big ones who have Internet shutdowns are Yemen 6 and Ethiopia 4. Such internet shutdowns have and will have sad repercussions as would share in another story as well.

Color-coding journalists A story was broken by caravan magazine yesterday and which was followed by newslaundry which shows how the Govt. is looking to just drive some narrative, does not matter whether it s true or false, it should just show that the Govt. is right and others are all wrong. As can be seen, almost all reporters barring a few have kept silent rather than refuting statements attributed to them or happenings which didn t happen. And this goes to a much larger narrative and disinformation route taken by the Govt. which doesn t have any semblance to the truth or reality as people know it. I would illustrate couple of examples below which shares that. In all my young and even adult-life I hadn t seen a Govt. this much against its own people.

Omega Seiki puts a manufacturing plant in Bangladesh Now Omega Seiki is an Indian vendor who chose or had to go to manufacture their electric vehicles in Bangladesh. Now while this is a slightly old story this was broken on social media recently. Everybody starting blaming both the vendor and saying we should break FTA (Free Trade Agreement) with Bangladesh, not knowing that despite the FTA, India has put tariff barriers between India and Bangladesh. I had to share research from Brookings to show where India has been losing. Of course, those who don t want to see, wouldn t see anything wrong in the picture.

Teen raped, asked to marry the accused when she turns 18 Now you may see the above headlines and feel it is ridiculous, but the fact is that these orders were put or given by Madras High Court couple of months back. This was then reported by both Livelaw and BarandBench respectively. Now to be truthful, this news didn t make much noise as it should have, probably as I had shared previously that the Govt. wants to lower the marriageable age to 15 or even less. And this is despite all the medical evidence on the contrary, because it assuages this Govt s masculinity. There is also the very recent case where the SC CJI asked the rapist if he is willing to marry a girl who was underage when she reaches maturity. Another one in which it seems martial rape is not a crime according to the CJI. So it seems these are the state of things in which India finds itself today. There are judges like Vrinda Grover who do question CJI but they are few and there are costs to them who ask questions. Although, as shared this news was overtaken by other news and would have remained so, if not one of the leaders of the present Govt. , a Ramesh Jarkiholi, who hails from Belagavi region of north Karnataka was caught in a sex CD scandal basically asking sexual favors for a permanent Govt. job. He had made statements after the Madras High Court case applauding the judgement given by the judge. While, due to public pressure he had to resign, but not before stating that he had everybody blue films including the Chief Minister of the State. And sad to report that six Karnataka Ministers rushed today or rather yesterday to put a petition in the civil court to restrain media from airing/printing/publishing any defamatory content against them. The court has granted a media gag against 68 media houses for the same. Sadly, the recent happening only reinforce what has been happening in Karnataka since a decade. Update 07/03/2021 Seems yesterday another 10 odd ministers rushed to get the same order. Seems different laws apply to politicians vis-a-vis others. A recent example of Rhea Chakravarthy, an actress and girlfriend of Sushant Singh who was hounded in his suicide case and many accusations made on TV but no evidence till date. From what we know as facts, Sushant committed suicide as he was not getting work due to cronyism in Bollywood. In fact, those who were behind it have white-washed themselves, deleted their tweets etc. and while the public knows, no accountability on them. In fact, there is and was so much that I wanted to share as to what has been happening to women, sadly and thankfully arre did the needful for me. They wrote an entire article which tells what the situation for women in India today is. And if you are wondering why I said, that is because when a site which was made exclusively for people to laugh and have a good time and get relief, when they start writing serious articles, you can be sure that things have gone horribly wrong

Asking Tesla to come to India and at the same time ambivalent on battery Recently, Mr. Nitin Gadkari, a prominent minister of the present Govt. invited Tesla and gave all sorts of incentives to start a manufacturing plant here in India. And while it seems that Tesla has accepted, looking at the Vodafone case, hopefully Tesla does make such contracts where if something goes wrong and they need to sue the Govt. they can do it in States or elsewhere. The way the Govt. acted in the Vodafone case had been a dampener to any MNC investments so far. Although to be fair to both Tesla and GOI, the basic models even if they are manufactured in India will go to less than 1% of the population. The cheapest Tesla Model Y which retails in the U.S. for USD 40k would be around INR 30 lakh. And this is their cheapest car to date. I do know there are rumors of the 25k but that is probably 2-3 years away as shared by Tesla China President Tom Zhu in an interview shared on YT.

https://www.youtube.com/watch?v=aH5leMWFBxI There are couple of interesting comments being made. The fact that China is going to fully open its automobile market to western companies shows how confident China feels about their own vendors. And I m not much impressed about Tesla as I am about the tiny car revolution happening in China. India, if it wanted to, could learn many lessons from China. Even the electric buses they had started in 2010 itself where people in our auto industry thought it was all a fad. Sadly, we are missing most of the technology and if and by the time Tesla starts a production line, dunno where we could get our lithium. India hasn t been as aggressive as other countries when it comes to securing raw natural resources in other countries, as some other countries have.  Even besides that, it has been tough when you have so many people who still believe that ICE vehicles (Internal Combustion Engines) are better than EV s and even if they know they choose to believe the propaganda. Couple of months ago a young UK girl who had died due to asthma, an inquest found that air pollution was a factor. The girl s name was Ella Adoo-Kissi-Debrah. This is the first case where the doctor ruled air pollution as a chief factor in a person s death. Probably first of its kind of ruling anywhere in the world. I also shared TCO studies between BEV and ICE vehicles done by people who are considering an electric vehicle but those studies seem to fall on deaf ears.

Starlink This is another of Elon Musk s ventures and would be a money spinner for sure in around the globe. While Starlink has asked TRAI for permission, I don t think they will get it. There is also Bharti Global s Oneweb which probably has a better chance of getting permissions. The reason is censorship. As shared above, India is now a leader in Internet shutdowns and do see this trend only accelerate rather than go the other way around. For people who don t remember, remember how satellite phones were made illegal even though only businessmen could afford it. And this was just 5 years ago. As shared Oneweb would have better shot as they would accept all Government directives without a second thought. Unless Starlink gives a binding to the Govt. to be a willing partner when it wants to have internet shutdowns, it will not work. Now how Elon approaches that is to be seen and known. FWIW, you can t access Starlink webpage on BSNL broadband. My broadband provider gives at the most 300 kbps and sometimes, at late nights or early mornings, around 500 kbps.

Farmer Protests
Lastly, farmer protests have entered 100 days. In the interim, Vivek Kaul, an economist took stock of the Bihar APMC to see if things have really worked as the Govt. supporters were telling. The investigation and the results didn t inspire the confidence as the Govt. said. The sad part is though, that nowadays nobody, at least those in power as well as those who are supporters are keen to read, understand and even argue otherwise. They are all happy with whatsapp knowledge. Till date 200+ people have died in the farmer protests. All mainstream media houses have stopped talking about farmers in the hope that they will disappear. At the end of the day the Govt. wants that the corporates should win at whatever the cost.

Michael Stapelberg: Debian Code Search: OpenAPI now available

Debian Code Search now offers an OpenAPI-based API! Various developers have created ad-hoc client libraries based on how the web interface works. The goal of offering an OpenAPI-based API is to provide developers with automatically generated client libraries for a large number of programming languages, that target a stable interface independent of the web interface s implementation details.

Getting started
  1. Visit https://codesearch.debian.net/apikeys/ to download your personal API key. Login via Debian s GitLab instance salsa.debian.org; register there if you have no account yet.
  2. Find the Debian Code Search client library for your programming language. If none exists yet, auto-generate a client library on editor.swagger.io: click Generate Client .
  3. Search all code in Debian from your own analysis tool, migration tracking dashboard, etc.

curl example
curl \
  -H "x-dcs-apikey: $(cat dcs-apikey-stapelberg.txt)" \
  -X GET \
  "https://codesearch.debian.net/api/v1/search?query=i3Font&match_mode=regexp" 

Web browser example You can try out the API in your web browser in the OpenAPI documentation.

Code example (Go) Here s an example program that demonstrates how to set up an auto-generated Go client for the Debian Code Search OpenAPI, run a query, and aggregate the results:
func burndown() error  
	cfg := openapiclient.NewConfiguration()
	cfg.AddDefaultHeader("x-dcs-apikey", apiKey)
	client := openapiclient.NewAPIClient(cfg)
	ctx := context.Background()
	// Search through the full Debian Code Search corpus, blocking until all
	// results are available:
	results, _, err := client.SearchApi.Search(ctx, "fmt.Sprint(err)", &openapiclient.SearchApiSearchOpts 
		// Literal searches are faster and do not require escaping special
		// characters, regular expression searches are more powerful.
		MatchMode: optional.NewString("literal"),
	 )
	if err != nil  
		return err
	 
	// Print to stdout a CSV file with the path and number of occurrences:
	wr := csv.NewWriter(os.Stdout)
	header := []string "path", "number of occurrences" 
	if err := wr.Write(header); err != nil  
		return err
	 
	occurrences := make(map[string]int)
	for _, result := range results  
		occurrences[result.Path]++
	 
	for _, result := range results  
		o, ok := occurrences[result.Path]
		if !ok  
			continue
		 
		// Print one CSV record per path:
		delete(occurrences, result.Path)
		record := []string result.Path, strconv.Itoa(o) 
		if err := wr.Write(record); err != nil  
			return err
		 
	 
	wr.Flush()
	return wr.Error()
 
The full example can be found under burndown.go.

Feedback? File a GitHub issue on github.com/Debian/dcs please!

Migration status I m aware of the following third-party projects using Debian Code Search:
Tool Migration status
Debian Code Search CLI tool Updated to OpenAPI
identify-incomplete-xs-go-import-path Update pending
gnome-codesearch makes no API queries
If you find any others, please point them to this post in case they are not using Debian Code Search s OpenAPI yet.

5 March 2021

Arturo Borrero Gonz lez: Openstack Neutron L3 failover issues

Networking In the Cloud Services team at the Wikimedia Foundation we use Openstack Neutron to build our virtual network, and in particular, we rely on the neutron-l3-agent for implementing all the L3 connectivity, topology and policing. This includes basic packet firewalling and NAT. As of this writing, we are using Openstack version Train. We run the neutron-l3-agent on standard linux hardware servers with 10G NICs, and in general it works really well. Our setup is rather simple: we have a couple of servers for redundancy (note: upstream recommends having 3) and each server runs an instance of neutron-l3-agent. We don t use DVR, so all ingress/egress network traffic (or north-south traffic) flows using these servers. Today we use a flat network topology in our cloud. This means that all of our virtual machines share the same router gateway. Therefore, we only have one software-defined router. Neutron does a very smart thing: each software-defined router is implemented on a linux network namespace (netns). Each router living on its own netns, the namespace contains all IP addresses, routes, interfaces, netfilter firewalling rules, NAT configuration, etc. Additionally, we configure the agents and software-defined routers to be deployed on an high availability fashion. Neutron implements this by running an instance of keepalived (VRRP) inside each router netns. The gateway IP is therefore a virtual address that can move between the two instances of the neutron-l3-agent. In our setup we rely very heavily on IPv4 NAT, we use it for the egress traffic (SNAT) and also for Openstack floating IPs (SNAT/DNAT). Neutron uses Netfilter rules for configuring the whole NAT setup. There is, however, no apparent mechanism in the neutron-l3-agent to ensure continuity of NATed TCP connections when a failover happens. If all NATed TCP connections are flowing using neutron-l3-agent node A, and a failover happens, node B wont be able to pick up the opened TCP streams and therefore all connections will need to be re-established. This happens because the conntrack information that Netfilter uses to perform NAT is not present in node B when the failover happens. NAT is, in general, a stateful thing and should be treated that way. It seems some folks upstream are aware of this, and there are even some blueprints to introduce conntrackd alongside keepalived. The actual implementation didn t happen so far, apparently. I wonder, are we the only cloud deployment suffering this issue? Our users have been experiencing annoying connection cuts every time we failover the neutron-l3-agent for whatever reason: an upgrade, server reboot, etc. After numerous incidents I opened a ticket in our phabricator instance and started working on it. I ve been trying to improve this situation by following a couple of strategies: To help the conntrack engine deal with NATed TCP connections I decided to try setting the sysctl key net.netfilter.nf_conntrack_tcp_be_liberal=1. But it turns out this sysctl key is not inherited from the main netns when the software-defined netns is created (i.e, is per-netns). I needed a mechanism to detect netns events (creation) and then inject the sysctl setting. Neutron apparently doesn t have any facility to hook/call commands at netns creation time. This felt like a very fun coding challenge, so I did it! I learned that netns have a /var/run/netns/<netns> entry, so I thought it would be easy to listen to file system events and react to them. I wanted to use some python, so I decided to go with the pyinotify library. I ended up creating a simple netns-events.py daemon/script. By using regexes it allows matching on netns names and running arbitrary commands on certain situations: The daemon reads a yaml configuration file like this:
---
# $NETNS env var is provided by the runner daemon
- netns_regex: ^qrouter-.*
  daemon_startup_actions:
    - ip netns exec $NETNS sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
    - ip netns exec $NETNS sysctl net.netfilter.nf_conntrack_tcp_loose=1
  inotify_actions:
    - IN_CREATE:
        - ip netns exec $NETNS sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
        - ip netns exec $NETNS sysctl net.netfilter.nf_conntrack_tcp_loose=1
We run this daemon as a systemd service, side by side with the neutron-l3-agent systemd service. Apparently the nf_conntrack_tcp_be_liberal sysctl key is only read either at module load time or netns creation time, so it is really important the netns-events.py daemon runs before neutron-l3-agent starts doing its thing. Anyway, this won t probably solve all of our problems. I m still on a massive rabbit hole with conntrackd, that I ll leave for another day. Other than this small script to set the sysctl keys I have more questions than answers. Again, I wonder what others do, or if there is something fundamentally wrong with our cloud network architecture. I ll keep researching how to deploy neutron-l3-agent in a more realiable fashion. If you have more hints, are in the same situation, or have any other insight, please let me know!

Sergio Durigan Junior: A debuginfod service for Debian

Hi there. Long time no write! On Tuesday, February 23, 2021, I made an announcement at debian-devel-announce about a new service that I configured for Debian: a debuginfod server. This post serves two purposes: pay the promise I made to Jonathan Carter that I would write a blog post about the service, and go into a bit more detail about it. What's debuginfod? From the announcement above:
debuginfod is a new-ish project whose purpose is to serve
ELF/DWARF/source-code information over HTTP.  It is developed under the
elfutils umbrella.  You can find more information about it here:
  https://sourceware.org/elfutils/Debuginfod.html
In a nutshell, by using a debuginfod service you will not need to
install debuginfo (a.k.a. dbgsym) files anymore; the symbols will be
served to GDB (or any other debuginfo consumer that supports debuginfod)
over the network.  Ultimately, this makes the debugging experience much
smoother (I myself never remember the full URL of our debuginfo
repository when I need it).
Perhaps not everybody knows this, but until last year I was a Debugger Engineer (a.k.a. GDB hacker) at Red Hat. I was not involved with the creation of debuginfod directly, but I witnessed discussions about "having way to serve debug symbols over the internet" multiple times during my tenure at the company. So this is not a new idea, and it's not even the first implementation, but it's the first time that some engineers actually got their hands dirty enough to have something concrete to show. The idea to set up a debuginfod server for Debian started to brew after 2019's GNU Tools Cauldron, but as usual several things happened in $LIFE (including a global pandemic and leaving Red Hat and starting a completely different job at Canonical) which had the effect of shuffling my TODO list "a little". Benefits for Debian Debian unfortunately is lagging behind when it comes to offer its users a good debugging experience. Before the advent of our debuginfod server, if you wanted to debug a package in Debian you would need to:
  1. Add the debian-debug apt repository to your /etc/apt/sources.list.
  2. Install the dbgsym package that contains the debug symbols for the package you are debugging. Note that the version of the dbgsym package needs to be exactly the same as the version of the package you want to debug.
  3. Figure out which shared libraries your package uses and install the dbgsym packages for all of them. Arguably, this step is optional but recommended if you would like to perform a more in-depth debugging.
  4. Download the package source, possibly using apt source or some equivalent command.
  5. Open GDB, and make sure you adjust the source paths properly (more below). This can be non-trivial.
  6. Finally, debug the program.
Now, with the new service, you will be able to start from step 4, without having to mess with sources.list, dbgsym packages and version mismatches. The package source It is important to mention an existing (but perhaps not well-known) limitation of our debugging experience in Debian: the need to manually download the source packages and adjust GDB to properly find them (see step 4 above). debuginfod is able to serve source code as well, but our Debian instance is not doing that at the moment. Debian does not provide a patched source tree that is ready to be consumed by GDB or debuginfod (for a good example of a distribution that does this, see Fedora's debugsource packages). Let me show you an example of debugging GDB itself (using debuginfod) on Debian:
$ HOME=/tmp DEBUGINFOD_URLS=https://debuginfod.debian.net gdb -q gdb
Reading symbols from gdb...
Downloading separate debug info for /tmp/gdb...
Reading symbols from /tmp/.cache/debuginfod_client/02046bac4352940d19d9164bab73b2f5cefc8c73/debuginfo...
(gdb) start
Temporary breakpoint 1 at 0xd18e0: file /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c, line 28.
Starting program: /usr/bin/gdb 
Downloading separate debug info for /lib/x86_64-linux-gnu/libreadline.so.8...
Downloading separate debug info for /lib/x86_64-linux-gnu/libz.so.1...
Downloading separate debug info for /lib/x86_64-linux-gnu/libncursesw.so.6...
Downloading separate debug info for /lib/x86_64-linux-gnu/libtinfo.so.6...
Downloading separate debug info for /tmp/.cache/debuginfod_client/d6920dbdd057f44edaf4c1fbce191b5854dfd9e6/debuginfo...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Downloading separate debug info for /lib/x86_64-linux-gnu/libexpat.so.1...
Downloading separate debug info for /lib/x86_64-linux-gnu/liblzma.so.5...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libbabeltrace.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libbabeltrace-ctf.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libipt.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libmpfr.so.6...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libsource-highlight.so.4...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libxxhash.so.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libdebuginfod.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libstdc++.so.6...
Downloading separate debug info for /lib/x86_64-linux-gnu/libgcc_s.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0...
Downloading separate debug info for /tmp/.cache/debuginfod_client/dbfea245d26065975b4084f4e9cd2d83c65973ee/debuginfo...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libdw.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libelf.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libuuid.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libgmp.so.10...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.74.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4...
Downloading separate debug info for /lib/x86_64-linux-gnu/libbz2.so.1.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libicui18n.so.67...
Downloading separate debug info for /tmp/.cache/debuginfod_client/acaa831dbbc8aa70bb2131134e0c83206a0701f9/debuginfo...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libicuuc.so.67...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libnghttp2.so.14...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libidn2.so.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/librtmp.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libssh2.so.1...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libpsl.so.5...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libnettle.so.8...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libgnutls.so.30...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/liblber-2.4.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libbrotlidec.so.1...
Downloading separate debug info for /tmp/.cache/debuginfod_client/39739740c2f8a033de95c1c0b1eb8be445610b31/debuginfo...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libunistring.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libhogweed.so.6...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libgcrypt.so.20...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libp11-kit.so.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libtasn1.so.6...
Downloading separate debug info for /lib/x86_64-linux-gnu/libcom_err.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libsasl2.so.2...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libbrotlicommon.so.1...
Downloading separate debug info for /lib/x86_64-linux-gnu/libgpg-error.so.0...
Downloading separate debug info for /usr/lib/x86_64-linux-gnu/libffi.so.7...
Downloading separate debug info for /lib/x86_64-linux-gnu/libkeyutils.so.1...
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffebf8) at /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c:28
28      /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c: Directory not empty.
(gdb) list
23      in /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c
(gdb) 
(See all those Downloading separate debug info for... lines? Nice!) As you can see, when we try to list the contents of the file we're in, nothing shows up. This happens because GDB doesn't know where the file is. So you have to tell it. In this case, it's relatively easy: you see that the GDB package's build directory is /build/gdb-Nav6Es/gdb-10.1/. When you apt source gdb, you will end up with a directory called $PWD/gdb-10.1/ containing the full source of the package. Notice that the last directory's name in both paths is the same, so in this case we can use GDB's set substitute-path command do the job for us (in this example $PWD is /tmp/):
$ HOME=/tmp DEBUGINFOD_URLS=https://debuginfod.debian.net gdb -q gdb
Reading symbols from gdb...
Reading symbols from /tmp/.cache/debuginfod_client/02046bac4352940d19d9164bab73b2f5cefc8c73/debuginfo...
(gdb) set substitute-path /build/gdb-Nav6Es/ /tmp/
(gdb) start
Temporary breakpoint 1 at 0xd18e0: file /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c, line 28.
Starting program: /usr/bin/gdb 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffebf8) at /build/gdb-Nav6Es/gdb-10.1/gdb/gdb.c:28
warning: Source file is more recent than executable.
28        memset (&args, 0, sizeof args);
(gdb) list
23      int
24      main (int argc, char **argv)
25       
26        struct captured_main_args args;
27
28        memset (&args, 0, sizeof args);
29        args.argc = argc;
30        args.argv = argv;
31        args.interpreter_p = INTERP_CONSOLE;
32        return gdb_main (&args);
(gdb)
Much better, huh? The problem is that this process is manual, and changes depending on how the package you're debugging was built. What can we do to improve this? What I personally would like to see is something similar to what the Fedora project already does: create a new debug package which will contain the full, patched source package. This would mean changing our building infrastructure and possibly other somewhat complex things. Using the service (by default) At the time of this writing, I am working on an elfutils Merge Request whose purpose is to implement a debconf question to ask the user whether she wants to use our service by default. If you would like to start using the service right now, all you have to do is set the following environment variable in your shell:
DEBUGINFOD_URLS="https://debuginfod.debian.net"
More information You can find more information about our debuginfod service here. Try to keep an eye on the page as it's being constantly updated. If you'd like to get in touch with me, my email is my domain at debian dot org. I sincerely believe that this service is a step in the right direction, and hope that it can be useful to you :-).

4 March 2021

Sean Whitton: waylandmar21

While struggling with Pfizer second dose side effects yesterday, with little ability to do anything serious so surreal to have a fever yet also certainty you re not actually ill[1] I thought I d try building the branch of Emacs with native Wayland support, and try starting up Sway instead of i3. I recently upgraded my laptop to Debian bullseye, as I usually do at this stage of our pre-release freeze, and was wondering whether bullseye would be the release which would enable me to switch to Wayland. Why might I want to do this? I don t care about screen tearing and don t have any fancy monitors with absurd numbers of pixels. Previously, I had been hoping to cling on to my X11 setup for as long as possible, and switch to Wayland only once things I want to use started working worse on X11, because all the developers of those things have stopped using X11. But then after upgrading to bullseye, I found I had to forward-port an old patch to xfce4-session to prevent it from resetting SSH_AUTH_SOCK to the wrong value, and I thought to myself, maybe I could cut out some of the layers here, and maybe it ll be a bit less annoying. I have a pile of little scripts trying to glue together xfce4 and i3 to get all the functionality I need, but since there have been people who use their computers for similar purposes to me trying to make Sway useful for quite some time now, maybe there are more integrated solutions available. I have also been getting tired of things which have only ever half-worked under X, like toggling autolock off when there isn t fullscreen video playing (when I m video conferencing on another device, I often want to prevent my laptop s screen from locking, and it works most of the time, but sometimes still locks, sigh). I have a normalise desktop keybinding which tries to fix recurrent issues by doing things like restarting ibus, and it would be nice to drop something so hackish. And indeed, a lot of basic things do work way better under Sway. swayidle is clean and sane, and I was easily able to add a keybinding which inhibits locking the screen when a certain window is visible. I could bind brightness up/down keys without having to invoke xfce4-power-manager never managed that before and, excitingly, I could have those keys bound such that they still work when the screen is locked. I still need two old scripts which interact with the i3/sway IPC, but those two are reasonable ways to extend functionality, rather than bad hacks. The main thing that I could not figure out is IME various people claim online to have got typing their Asian languages working natively under Sway, not just into Xwayland windows, but I couldn t, and there is no standard way to do it yet, it would seem. Also, it seems Qt in Debian doesn t support Wayland natively, so far as I could tell. And there isn t really a drop-in replacement for dmenu yet, so you have to run that under Xwayland. A lot of this is probably going to be fixed during 2021, but the thing is, I ll be on Debian bullseye, so how it works now is probably as good as it is going to get for the next two years or so. So, wanting to get back to doing something more useful today, I reluctantly booted back into X11. I m really looking forward to switching to Sway, and getting rid of some of my hacks, but I think I am probably going to have to wait for Debian bookworm unless I completely run out of patience with the various X11 annoyances described above, and start furiously backporting things. Update, later that afternoon Newer versions of fcitx5 packages hit Debian testing within the past few days, it turns out, and the IME problem is solved! So looks like I am slowly going to be able to migrate to Sway during the Debian bullseye lifecycle after all. How nice. Many thanks to various upstreams and those who have been working on these packages in Debian. [1] Okay, I suppose I could have caught the disease a few days ago and it became symptomatic at the same time I was experiencing the side effects.

2 March 2021

Russ Allbery: Review: The Lion, the Witch and the Wardrobe

Review: The Lion, the Witch and the Wardrobe, by C.S. Lewis
Illustrator: Pauline Baynes
Series: Chronicles of Narnia #1
Publisher: Collier Books
Copyright: 1950
Printing: 1978
ISBN: 0-02-044220-3
Format: Mass market
Pages: 186
Although it's been more than 20 years since I last read it, I believe I have read The Lion, the Witch and the Wardrobe more times than any other book. The count is certainly in double digits. As you might guess, I also have strong opinions about it, some of which are unorthodox, and I've been threatening to write this review for years. It seemed a fitting choice for my 1000th review. There is quite a lot that can and has been said about this book and this series, and this review is already going to be much too long, so I'm only going to say a fraction of it. I'm going to focus on my personal reactions as someone raised a white evangelical Christian but no longer part of that faith, and the role this book played in my religion. I'm not going to talk much about some of its flaws, particularly Lewis's treatment of race and gender. This is not because I don't agree they're there, but only that I don't have much to say that isn't covered far better in other places. Unlike my other reviews, this one will contain major spoilers. If you have managed to remain unspoiled for a 70-year-old novel that spawned multiple movies and became part of the shared culture of evangelical Christianity, and want to stay that way, I'll warn you in ALL CAPS when it's time to go. But first, a few non-spoiler notes. First, reading order. Most modern publications of The Chronicles of Narnia will list The Magician's Nephew as the first book. This follows internal chronological order and is at C.S. Lewis's request. However, I think Lewis was wrong. You should read this series in original publication order, starting with The Lion, the Witch and the Wardrobe (which I'm going to abbreviate as TLtWatW like everyone else who writes about it). I will caveat this by saying that I have a bias towards reading books in the order an author wrote them because I like seeing the development of the author's view of their work, and I love books that jump back in time and fill in background, so your experience may vary. But the problem I see with the revised publication order is that The Magician's Nephew explains the origins of Narnia and, thus, many of the odd mysteries of TLtWatW that Lewis intended to be mysterious. Reading it first damages both books, like watching a slow-motion how-to video for a magic trick before ever seeing it performed. The reader is not primed to care about the things The Magician's Nephew is explaining, which makes it less interesting. And the bits of unexpected magic and mystery in TLtWatW that give it so much charm (and which it needs, given the thinness of the plot) are already explained away and lose appeal because of it. I have read this series repeatedly in both internal chronological order and in original publication order. I have even read it in strict chronological order, wherein one pauses halfway through the last chapter of TLtWatW to read The Horse and His Boy before returning. I think original publication order is the best. (The Horse and His Boy is a side story and it doesn't matter that much where you read it as long as you read it after TLtWatW. For this re-read, I will follow original publication order and read it fifth.) Second, allegory. The common understanding of TLtWatW is that it's a Christian allegory for children, often provoking irritated reactions from readers who enjoyed the story on its own terms and later discovered all of the religion beneath it. I think this view partly misunderstands how Lewis thought about the world and there is a more interesting way of looking at the book. I'm not as dogmatic about this as I used to be; if you want to read it as an allegory, there are plenty of carefully crafted parallels to the gospels to support that reading. But here's my pitch for a different reading. To C.S. Lewis, the redemption of the world through the death of Jesus Christ is as foundational a part of reality as gravity. He spent much of his life writing about religion and Christianity in both fiction and non-fiction, and this was the sort of thing he constantly thought about. If somewhere there is another group of sentient creatures, Lewis's theology says that they must fit into that narrative in some way. Either they would have to be unfallen and thus not need redemption (roughly the position taken by The Space Trilogy), or they would need their own version of redemption. So yes, there are close parallels in Narnia to events of the Christian Bible, but I think they can be read as speculating how Christian salvation would play out in a separate creation with talking animals, rather than an attempt to disguise Christianity in an allegory for children. It's a subtle difference, but I think Narnia more an answer to "how would Christ appear in this fantasy world?" than to "how do I get children interested in the themes of Christianity?", although certainly both are in play. Put more bluntly, where other people see allegory, I see the further adventures of Jesus Christ as an anthropomorphic lion, which in my opinion is an altogether more delightful way to read the books. So much for the preamble; on to the book. The Pevensie kids, Peter, Susan, Edmund, and Lucy, have been evacuated to a huge old house in the country due to the air raids (setting this book during World War II, something that is passed over with barely a mention and not a hint of trauma in a way that a modern book would never do). While exploring this house, which despite the scant description is still stuck in my mind as the canonical huge country home, Lucy steps into a wardrobe because she wants to feel the fur of the coats. Much to her surprise, the wardrobe appears not to have a back, and she finds herself eventually stepping into a snow-covered pine forest where she meets a Fawn named Mr. Tumnus by an unlikely lamp-post. MAJOR SPOILERS BELOW, so if you don't want to see those, here's your cue to stop reading. Two things surprised me when re-reading TLtWatW. The first, which I remember surprising me every time I read it, is how far into this (very short) book one has to go before the plot kicks into gear. It's not until "What Happened After Dinner" more than a third in that we learn much of substance about Narnia, and not until "The Spell Begins to Break" halfway through the book that things start to happen. The early chapters are concerned primarily with the unreliability of the wardrobe portal, with a couple of early and brief excursions by Edmund and Lucy, and with Edmund being absolutely awful to Lucy. The second thing that surprised me is how little of what happens is driven by the kids. The second half of TLtWatW is about the fight between Aslan and the White Witch, but this fight was not set off by the children and their decisions don't shape it in any significant way. They're primarily bystanders; the few times they take action, it's either off-camera or they're told explicitly what to do. The arguable exception is Edmund, who provides the justification for the final conflict, but he functions more as plot device than as a character with much agency. When that is combined with how much of the story is also on rails via its need to recapitulate part of the gospels (more on that in a moment), it makes the plot feel astonishingly thin and simple. Edmund is the one protagonist who gets to make some decisions, all of them bad. As a kid, I hated reading these parts because Edmund is an ass, the White Witch is obviously evil, and everyone knows not to eat the food. Re-reading now, I have more appreciation for how Lewis shows Edmund's slide into treachery. He starts teasing Lucy because he thinks it's funny (even though it's not), has a moment when he realizes he was wrong and almost apologizes, but then decides to blame his discomfort on the victim. From that point, he is caught, with some help from the White Witch's magic, in a spiral of doubling down on his previous cruelty and then feeling unfairly attacked. Breaking the cycle is beyond him because it would require admitting just how badly he behaved and, worse, that he was wrong and his little sister was right. He instead tries to justify himself by spreading poisonous bits of doubt, and looks for reasons to believe the friends of the other children are untrustworthy. It's simplistic, to be sure, but it's such a good model of how people slide into believing conspiracy theories and joining hate groups. The Republican Party is currently drowning in Edmunds. That said, Lewis does one disturbing thing with Edmund that leaped out on re-reading. Everyone in this book has a reaction when Aslan's name is mentioned. For the other three kids, that reaction is awe or delight. For Edmund, it's mysterious horror. I know where Lewis is getting this from, but this is a nasty theological trap. One of the problems that religion should confront directly is criticism that questions the moral foundations of that religion. If one postulates that those who have thrown in with some version of the Devil have an instinctual revulsion for God, it's a free intellectual dodge. Valid moral criticism can be hand-waved away as Edmund's horrified reaction to Aslan: a sign of Edmund's guilt, rather than a possible flaw to consider seriously. It's also, needless to say, not the effect you would expect from a god who wants universal salvation! But this is only an odd side note, and once Edmund is rescued it's never mentioned again. This brings us to Aslan himself, the Great Lion, and to the heart of why I think this book and series are so popular. In reinterpreting Christianity for the world of Narnia, Lewis created a far more satisfying and relatable god than Jesus Christ, particularly for kids. I'm not sure I can describe, for someone who didn't grow up in that faith, how central the idea of a personal relationship with Jesus is to evangelical Christianity. It's more than a theological principle; it's the standard by which one's faith is judged. And it is very difficult for a kid to mentally bootstrap themselves into a feeling of a personal relationship with a radical preacher from 2000 years ago who spoke in gnomic parables about subtle points of adult theology. It's hard enough for adults with theological training to understand what that phrase is intended to mean. For kids, you may as well tell them they have a personal relationship with Aristotle. But a giant, awe-inspiring lion with understanding eyes, a roar like thunder, and a warm mane that you can bury your fingers into? A lion who sacrifices himself for your brother, who can be comforted and who comforts you in turn, and who makes a glorious surprise return? That's the kind of god with which one can imagine having a personal relationship. Aslan felt physical and embodied and present in the imagination in a way that Jesus never did. I am certain I was not the only Christian kid for whom Aslan was much more viscerally real than Jesus, and who had a tendency to mentally substitute Aslan for Jesus in most thoughts about religion. I am getting ahead of myself a bit because this is a review of TLtWatW and not of the whole series, and Aslan in this book is still a partly unformed idea. He's much more mundanely present here than he is later, more of a field general than a god, and there are some bits that are just wrong (like him clapping his paws together). But the scenes with Susan and Lucy, the night at the Stone Table and the rescue of the statues afterwards, remain my absolute favorite parts of this book and some of the best bits of the whole series. They strike just the right balance of sadness, awe, despair, and delight. The image of a lion also lets Lewis show joy in a relatable way. Aslan plays, he runs, he wrestles with the kids, he thrills in the victory over evil just as much as Susan and Lucy do, and he is clearly having the time of his life turning people back to flesh from stone. The combination of translation, different conventions, and historical distance means the Bible has none of this for the modern reader, and while people have tried to layer it on with Bible stories for kids, none of them (and I read a lot of them) capture anything close to the sheer joy of this story. The trade-off Lewis makes for that immediacy is that Aslan is a wonderful god, but TLtWatW has very little religion. Lewis can have his characters interact with Aslan directly, which reduces the need for abstract theology and difficult questions of how to know God's will. But even when theology is unavoidable, this book doesn't ask for the type of belief that Christianity demands. For example, there is a crucifixion parallel, because in Lewis's world view there would have to be. That means Lewis has to deal with substitutionary atonement (the belief that Christ died for the sins of the world), which is one of the hardest parts of Christianity to justify. How he does this is fascinating. The Narnian equivalent is the Deep Magic, which says that the lives of all traitors belong to the White Witch. If she is ever denied a life, Narnia will be destroyed by fire and water. The Witch demands Edmund's life, which sets up Aslan to volunteer to be sacrificed in Edmund's place. This triggers the Deeper Magic that she did not know about, freeing Narnia from her power. You may have noticed the card that Lewis is palming, and to give him credit, so do the kids, leading to this exchange when the White Witch is still demanding Edmund:
"Oh, Aslan!" whispered Susan in the Lion's ear, "can't we I mean, you won't, will you? Can't we do something about the Deep Magic? Isn't there something you can work against it?" "Work against the Emperor's magic?" said Aslan, turning to her with something like a frown on his face. And nobody ever made that suggestion to him again.
The problem with substitutionary atonement is why would a supposedly benevolent god create such a morally abhorrent rule in the first place? And Lewis totally punts. Susan is simply not allowed to ask the question. Lewis does try to tackle this problem elsewhere in his apologetics for adults (without, in my opinion, much success). But here it's just a part of the laws of this universe, which all of the characters, including Aslan, have to work within. That leads to another interesting point of theology, which is that if you didn't already know about the Christian doctrine of the trinity, you would never guess it from this book. The Emperor-Beyond-the-Sea and Aslan are clearly separate characters, with Aslan below the Emperor in the pantheon. This makes rules like the above work out more smoothly than they do in Christianity because Aslan is bound by the Emperor's rules and the Emperor is inscrutable and not present in the story. (The Holy Spirit is Deity Not-appearing-in-this-book, but to be fair to Lewis, that's largely true of the Bible as well.) What all this means is that Aslan's death is presented straightforwardly as a magic spell. It works because Aslan has the deepest understanding of the fixed laws of the Emperor's magic, and it looks nothing like what we normally think of as religion. Faith is not that important in this book because Aslan is physically present, so it doesn't require any faith for the children to believe he exists. (The Beavers, who believed in him from prophecy without having seen him, are another matter, but this book never talks about that.) The structure of religion is therefore remarkably absent despite the story's Christian parallels. All that's expected of the kids is the normal moral virtues of loyalty and courage and opposition to cruelty. I have read this book so many times that I've scrutinized every word, so I have to resist the temptation to dig into every nook and cranny: the beautiful description of spring, the weird insertion of Lilith as Adam's first wife, how the controversial appearance of Santa Claus in this book reveals Lewis's love of Platonic ideals... the list is endless, and the review is already much longer than normal. But I never get to talk about book endings in reviews, so one more indulgence. The best thing that can be said about the ending of TLtWatW is that it is partly redeemed by the start of Prince Caspian. Other than that, the last chapter of this book has always been one of my least favorite parts of The Chronicles of Narnia. For those who haven't read it (and who by this point clearly don't mind spoilers), the four kids are immediately and improbably crowned Kings and Queens of Narnia. Apparently, to answer the Professor from earlier in the book, ruling magical kingdoms is what they were teaching in those schools? They then spend years in Narnia, never apparently giving a second thought to their parents (you know, the ones who are caught up in World War II, which prompted the evacuation of the kids to the country in the first place). This, for some reason, leaves them talking like medieval literature, which may be moderately funny if you read their dialogue in silly voices to a five-year-old and is otherwise kind of tedious. Finally, in a hunt for the white stag, they stumble across the wardrobe and tumble back into their own world, where they are children again and not a moment has passed. I will give Lewis credit for not doing a full reset and having the kids not remember anything, which is possibly my least favorite trope in fiction. But this is almost as bad. If the kids returned immediately, that would make sense. If they stayed in Narnia until they died, that arguably would also make sense (their poor parents!). But growing up in Narnia and then returning as if nothing happened doesn't work. Do they remember all of their skills? How do you readjust to going to school after you've lived a life as a medieval Queen? Do they remember any of their friends after fifteen years in Narnia? Argh. It's a very "adventures are over, now time for bed" sort of ending, although the next book does try to patch some of this up. As a single book taken on its own terms, TLtWatW is weirdly slight, disjointed, and hits almost none of the beats that one would expect from a children's novel. What saves it is a sense of delight and joy that suffuses the descriptions of Narnia, even when locked in endless winter, and Aslan. The plot is full of holes, the role of the children in that plot makes no sense, and Santa Claus literally shows up in the middle of the story to hand out plot devices and make an incredibly sexist statement about war. And yet, I memorized every gift the children received as a kid, I can still feel the coziness of the Beaver's home while Mr. Beaver is explaining prophecy, and the night at the Stone Table remains ten times more emotionally effective for me than the description of the analogous event in the Bible. And, of course, there's Aslan.
"Safe?" said Mr. Beaver. "Don't you hear what Mrs. Beaver tells you? Who said anything about safe? 'Course he isn't safe. But he's good. He's the king, I tell you."
Aslan is not a tame lion, to use the phrase that echos through this series. That, I think, is the key to the god that I find the most memorable in all of fantasy literature, even in this awkward, flawed, and decidedly strange introduction. Followed by Prince Caspian, in which the children return to a much-changed Narnia. Lewis has gotten most of the obligatory cosmological beats out of the way in this book, so subsequent books can tell more conventional stories. Rating: 7 out of 10

Next.

Previous.