惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
Last Week in AI
Last Week in AI
The Cloudflare Blog
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
S
SegmentFault 最新的问题
量子位
大猫的无限游戏
大猫的无限游戏
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
I
InfoQ
人人都是产品经理
人人都是产品经理
G
Google Developers Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Engineering at Meta
Engineering at Meta

Rc-2020 on Julia Evans

Day 57: Trying to set up GitHub Actions Day 56: A little WebAssembly Day 53: a little nginx, IPv6, and wireguard Day 52: testing how many Firecracker VMs I can run Day 51: Fixed my logging and made a couple of puzzles Day 49: making the VMs boot faster Day 48: Another Go program, and a little vim configuration Day 47: Using device mapper to manage Firecracker images Day 46: debugging an iptables problem Day 44: Building my VMs with Docker Day 43: Building VM images Day 42: Writing a Go program to manage Firecracker VMs Day 41: Trying to understand what a bridge is Day 40: screen flickering & a talk about containers Day 39: Customizing gotty's terminal Day 38: Modifying gotty to serve many different terminal applications at once Day 37: A new laptop and a little Vue Day 35: Launching my VMs more reliably Day 34: Learning about qemu Day 33: pairing is magic and beautiful git diffs Day 32: A Rails model that doesn't use the database with ActiveHash Day 24: a short talk about blogging myths, and a debugging tip Day 23: a little Rails testing Day 22: getting OAuth to work in Rails Day 21: wrangling systemd & setting up git deploys to a VM Day 19: Clustering faces (poorly) using an autoencoder Day 20: trying to figure out how Google Cloud IAM works Day 18: an answer to an autoencoder question Day 17: trying to wrap my head around autoencoders Day 13: BPTT, and debugging why a model isn't training is hard
Day 50: Building some tarballs for puzzles, and trying to...
Julia Evans · 2021-01-30 · via Rc-2020 on Julia Evans

On Friday I made progress on 3 things:

  1. getting my 5.8 kernel to boot faster in Firecracker
  2. built some puzzle tarballs (which I’ll explain in a bit)
  3. loaded the puzzle tarballs into my Firecracker VMs

the mystery of the slow kernel boot

I noticed that I had 2 pauses when I started my kernel with Firecracker (here’s the complete log).

one for 0.3 seconds:

[    0.142205] i8042: If AUX port is really absent please use the 'i8042.noaux' option
2021-01-29T09:14:10.315589518 [anonymous-instance:WARN:src/devices/src/legacy/i8042.rs:126] Failed to trigger i8042 kbd interrupt (disabled by guest OS)
[    0.424261] serio: i8042 KBD port at 0x60,0x64 irq 1

and one for 0.5 seconds:

[    0.442595] Key type encrypted registered
[    0.936675] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input0

I asked about this in the Firecracker Slack and got a reply suggesting to use the i8042.noaux option for the first delay. (which I hadn’t noticed, even though it says it right there :)). That fixed it!

I still don’t understand why the second delay is happening or how to fix it. Someone suggested it might be related to secure boot, but I spent a while poking at my kernel config and tried compiling with 6 different configurations and didn’t get anywhere, so I gave up for the day and moved onto something else.

building tarballs of each puzzle

I wrote a little Python script to do this. It basically runs a build.sh script that I write to build the puzzle inside a Docker container, and then makes a tarball of the Docker container’s current working directory.

Basically I took advantage of the fact that I know how Docker uses overlayfs internally and just took a tarball of the upper part of the overlay directly.

I did this because I couldn’t find a good way to do it using the normal Docker interfaces – I tried some things using a Docker experimental feature called docker build --squash but didn’t really get anywhere.

import os
import subprocess
import json
import time


pwd = os.getcwd()

container_id = subprocess.check_output(["docker", "run", "-v", f"{pwd}:/puzzle", "-td",  "my-base-image", "/bin/bash"])
container_id = container_id.decode("utf-8").strip()
container_json = subprocess.check_output(["docker", "inspect", container_id])
properties = json.loads(container_json)

upperdir = properties[0]['GraphDriver']['Data']['UpperDir']

subprocess.check_call(["docker", "exec", container_id, "bash", "/puzzle/build.sh"])
subprocess.check_call(["sudo", "tar", "-C", upperdir, "--exclude=puzzle", "--xattrs", "-cf", "puzzle.tar", '.'])

subprocess.check_call(["docker", "kill", container_id])

loading the puzzle tarball when I start a puzzle

I then wrote a little Go function to load in these tarballs when I start a VM. It’s really dumb, it just mounts the image, extracts the tarball into the mounted directory, and unmounts.

func (opts *options) copyPuzzleFiles(imagePath string) error {
	if opts.Request.Tarball == "" {
		return nil
	}
	mountDir := filepath.Join(ImageDir, pseudo_uuid())
	err := os.Mkdir(mountDir, 0755)
	defer os.Remove(mountDir)
	if err != nil {
		return fmt.Errorf("Failed creating dir: %s", mountDir, err)
	}

	if err := exec.Command("mount", imagePath, mountDir).Run(); err != nil {
		return fmt.Errorf("Failed mounting path %s: %s", imagePath, err)
	}

	if err := exec.Command("tar", "-C", mountDir, "-xf", opts.Request.Tarball).Run(); err != nil {
		return fmt.Errorf("Failed to extract tarball %s: %s", opts.Request.Tarball, err)
	}

	if err := exec.Command("umount", mountDir).Run(); err != nil {
		return fmt.Errorf("Failed umounting path %s: %s", imagePath, err)
	}
	return nil
}

One thing I’ve been thinking about with code like this is whether it makes sense to shell out to tools or whether it would be better to – for example, Go has a tarball. Right now I don’t really see any benefit to using Go’s tar code because I feel like these command line tools (mount/umount/tar) are really a known quantity and if I tried to reimplement them in Go I would just write a buggy version that I’d then have to maintain.

filesystems!

I also had a really delightful conversation with my friend Dave about filesystems where we talked about my problems with using device mapper and how Firecracker doesn’t support qcow2 and ideas for different ways to get Firecracker to support overlay images.

There’s an interesting discussion on the Firecracker GitHub about implementing a virtio backend to let the VM share a directory from the host.