blog.8-p.info

My OnePlus 5T is having a chipmunk sound issue. Interestingly Nokia phones are having the same issue.

While killing VoLTE and WiFi calling fixed the issue for me, it is sad to see that such a fundamental feature can be broken in 2021. Modern software is weird.

Last week, I’ve been working on firecracker-containerd’s pipe issue. My pull request is still a messy draft but seems it fixes the issue finally.

What is the issue?

When you run a container in a micro VM, you have FIFO files on both the micro VM and its host. These FIFO files are not connected, but firecracker-containerd is reading bytes from one and writing the bytes to another (or vice versa), so they look connected from clients.

Inside firecracker-containerd, IOProxy is responsible for connecting them. However, the proxy would stop when it has an error. So errors like EPIPE would stop the proxy completely.

My fix here is detecting a stopped IOProxy and creating a new one instead. Sounds simple. Right? But I was really struggling.

Concurrency is hard

Goroutines and channels make the problem difficult. I had multiple strange timeouts. In hindsight, they were deadlocks. In Go, reading more than what a channel has will block the reader, and writing more than what a channel can hold will block the writer. And when things block, I really cannot see why.

I may need to use debuggers like Delve, or build a mechanism that dumps all goroutines.

Slow build

Another part that makes me unproductive is the slowness of firecracker-containerd’s build, especially around the in-VM agent. Building the agent is fast, but putting the agent in a new root filesystem image is slow.

The root filesystem is currently all squashfs. I probably should create an ext4 variant. So that I can mount a pre-built image and replace the agent.

Meta: Blub Studies

Both Chris Krycho’s note and Hillel Wayne’s TLA+ Action Properties led me to Ben Kuhn’s In defense of blub studies.

How IOProxy works inside firecracker-containerd is “blub” knowledge. How do I keep the knowledge and pass it around? Right now, I’m writing that on this personal blog, but there may be more official places. Maybe ARCHITECTURE.md? Isn’t it too specific?

I believed that git grep shows the lack of Unix’s composability. It could be git + grep, but git grep is written in C and simply has a grep-equivalent inside.

But there is a caveat. In September 2005, Linus Torvalds has added git grep, 20-lines shell script. So, it was git + xargs + grep in the beginning! Then, in April 2006, Junio C Hamano has added a C version of git grep to reduce Git’s dependence on the shell.

This attempts to set up built-in “git grep” to further reduce our dependence on the shell, while at the same time optionally allowing to run grep against object database.

(…)

But this is going in the right direction. The shell script version is one of the worst Portability offender in the git barebone Porcelainish; it uses xargs -0 to pass paths around and shell arrays to sift flags and parameters.

So, it was actually showing Unix’s composability in the beginning, and later replaced due to the lack of portability.

Firecracker v0.24.2 has been released which handles SIGPIPE. I was working on that this week.

TCP/IP, Sockets, and SIGPIPE (2018) is a good read. The author mostly focuses the fact that TCP socket APIs were based on pipes, so pipes’ behaviors were automatically inherited.

But, even regarding pipes, SIGPIPE is weird. Writing to files would fail but it won’t kill a program. Why do we want to kill a program only for pipes?

There is a Stack Overflow question with some answers. The most accepted one is;

I believe the reason SIGPIPE exists is much simpler: establishing sane default behavior for pure “filter” programs that continuously read input, transform it somehow, and write output.

Which, somewhat makes sense.

In terms of history, Unix v6 had signal(2) with 13 – “write on a pipe with no one to read it”. At that time, all signals didn’t have names and only defined as numbers. Unix v1 didn’t have any signals. man.cat-v.org doesn’t have Unix v5’s man pages, but the Unix Heritage Society has Unix Programmer’s Manual’s scanned PDF. According to the PDF, page 159, Unix v5 had signal(2) but didn’t have 13. So SIGPIPE was introduced as the part of Unix v6.

Interestingly Rust ignores SIGPIPE due to the fact it had green threads before. The ship has sailed and people don’t want to change the behavior anymore. Go ignores SIGPIPE too only if the file descriptor is neither stdout nor stderr.

This is the end of my 100 Days To Offload challenge. It technically took two years, but still within 365 days. I started the challenge at May 21st, 2020 after reading Guillermo Garron’s Blogging is not dead.

Blogging is not dead, as Tim Bray has written in 2020.

Um, nope. For every discipline-with-depth that I care about (software/Internet, politics, energy economics, physics), if you want to find out what’s happening and you want to find out from first-person practitioners, you end up reading a blog.

They’re pretty hard to monetize, which means that the people who write them usually aren’t primarily bloggers, they’re primarily professional economists or physicists or oil analysts or Internet geeks. Since most of us don’t even try to monetize ’em, they’re pretty ad-free and thus a snappy reading experience.

I would disagree regarding the monetization part though. It is great to see makers like Laura Kampf can do her stuff and make a living.

But I do agree blogging is not dead. Writing from from first-person practitioners is great. Twitter is too short and centralized.

What’s next?

I would slow down a bit, but the act of aiming only high quality, meaningful, lengthy posts is the way to kill good blogs. I would still write short “what I’ve learned recently” posts.