aboutsummaryrefslogtreecommitdiff
path: root/public/running-golang-application-as-pid1.html
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2023-11-01 22:54:27 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2023-11-01 22:54:27 +0100
commit2417a6b7603524dc5cd30d29b153f91024b9443d (patch)
tree9be5ea8e5baba96dd9159217da6badf6157fb595 /public/running-golang-application-as-pid1.html
parent89ba3497f07a8ea43d209b583f39fcc286acc923 (diff)
downloadmitjafelicijan.com-2417a6b7603524dc5cd30d29b153f91024b9443d.tar.gz
Move to Jekyll
Diffstat (limited to 'public/running-golang-application-as-pid1.html')
-rwxr-xr-xpublic/running-golang-application-as-pid1.html222
1 files changed, 0 insertions, 222 deletions
diff --git a/public/running-golang-application-as-pid1.html b/public/running-golang-application-as-pid1.html
deleted file mode 100755
index e276887..0000000
--- a/public/running-golang-application-as-pid1.html
+++ /dev/null
@@ -1,222 +0,0 @@
1<!doctype html><html lang=en-us><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=generator content="JBMAFP - github.com/mitjafelicijan/jbmafp"><link href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL69vf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv76+/8LBwQkAAAAAAAAAAAAAAAC+vb3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+9vf/Bv78JAAAAAAAAAAAAAAAAu7q6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7ubr/vr29CAAAAAAAAAAAy8nJAZ6foP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnqGj/6GipAoAAAAAHLjU/xcXHf/BwsL/I8XY/yPK3v8XGiD/IbjL/yPF2f8XGiD/Fxkf/yLF2f8gnK3/Fxog/62ztv8fwNf/FRcd/x271v8mz93/GRsi/xkXHf8p097/GiIp/xobIv8p0t3/KdPe/xocIv8fYmr/KNPe/xoZH/8aHCL/J87c/xy81/8VFxz/IsPZ/8zS0/8XGiD/Ir/R/yPH2/8XGiD/Fxkf/yPH2/8dd4T/GBog/yPJ3f8jyNr/uru9/xcUGv8cudb/EhITDKi5vRKlvMP/RUpOERwcHRAdOj4QHTk8EBwdHRAdNTgQHTo/EBwcHRAcHB0QSGduEKW4vf+koqQfHzg+EBqz0ewSFRv7EyMr/xq51vsTERb7ExUb+xq41fsau9j7ExUb+xiPp/sZudb7ExUb+xMVG/sZuNX/GKvI/BIUGfMdvdn/IrfL/xcaIP8n1eb/J9Dh/xkcIf8ZGR7/J8/f/xxCSv8ZGyH/J9Dg/ybQ4P8ZHCL/FSQs/yPK3/8UExj/GE1b/ybS5P8ZGB7/Ghwj/ynW5P8p2Ob/Ghwi/yWrtv8p1eH/Ghwi/xocIv8p1uT/J8XT/xkcIv8m1un/Hb7d/xUYH/8hzOr/HtHu/xcaIf8XGB//I8vi/xgxOv8XGSD/I8rg/yPK4P8XGiD/GUFL/yPP6f8SERj/Fhkh/x3A4f8AAAAAJ2f9/ydr//8mZPH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlYu38J2v//ydo/f8AAAAAAAAAAAd8/fkFqf//Iob8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMY39awWr//8FfP3/AAAAAAAAAAAFm/7/SfD//wR+/f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOB/f9B7v//BaX+/wAAAAAAAAAAQ878SAyZ/v9n1v4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu9v8DDJb+/z3N/XgAAAAA3/sAAN/7AADf+wAA3/sAAAAAAAAAAAAAAAAAAN/7AAAAAAAAAAAAAAAAAAAAAAAAj/EAAI/5AACP8QAA3/sAAA==" rel=icon type=image/x-icon><title>Running Golang application as PID 1 with Linux kernel</title><meta name=description content="Unikernels, kernels, and alikeI have been reading a lot aboutunikernernels lately and found themvery intriguing."><meta name=author content="Mitja Felicijan"><link rel=alternate type=application/rss+xml title="Mitja Felicijan's posts" href=https://mitjafelicijan.com/index.xml><link rel=alternate type=application/rss+xml title="Mitja Felicijan's notes" href=https://mitjafelicijan.com/notes.xml><style>:root{--border-color:gainsboro;--border-size:2px;--link-color:blue;--bg-color:#eee}*::selection{background:var(--link-color);color:#fff}*::-moz-selection{background:var(--link-color);color:#fff}*::-webkit-selection{background:var(--link-color);color:#fff}body{padding:2.5rem;max-width:1900px;background:#fff;font-family:sans-serif;line-height:1.35rem;font-size:16px}hr{border:0;border-bottom:var(--border-size)solid var(--border-color);margin-block-start:1.5rem}a{color:var(--link-color);text-decoration:none}h1,h2,h3{line-height:initial}h1{font-size:xx-large}footer{margin-block-start:2rem}cap{text-transform:capitalize}blockquote{font-style:italic}table{max-width:100%;border:var(--border-size)solid var(--border-color);border-collapse:separate;border-spacing:0}table thead tr th{border-bottom:var(--border-size)solid var(--border-color);text-align:left}table th,table td{padding:.5em .8em}ul.list li{padding:.2em 0}ul{line-height:1.35em}pre{text-wrap:nowrap;overflow-x:auto;padding:0 1em;border:var(--border-size)solid var(--border-color)}code{padding:0 3px;font-size:14px;border:0;background:var(--bg-color)}pre code{line-height:1.3em;background:#fff}pre,code,pre *,code *{font-family:monospace}figure{margin-inline-start:0;margin-inline-end:0}figcaption{width:800px;max-width:100%;text-align:center}figcaption p{margin:.3em 0 1.5em;font-style:italic}img,video,audio{width:800px;max-width:100%;border:var(--border-size)solid var(--border-color);padding:.5em}header nav{display:flex;gap:.9rem}article iframe{margin:0!important}audio::-webkit-media-controls-enclosure{border-radius:0}@media only screen and (max-width:600px){body{padding:.5em;word-wrap:break-word}header nav{gap:.7rem}header nav .hob{display:none}a{word-wrap:break-word}img,video,audio{padding:0}}</style><header><nav class=main itemscope itemtype=http://schema.org/SiteNavigationElement role=navigation aria-label="Main navigation"><a href=/>Home</a>
2<a href=/#posts>Posts</a>
3<a href=/#notes>Notes</a>
4<a href=/#sideprojects class=hob>Side Projects</a>
5<a href=/vault.html>Vault</a>
6<a href=https://github.com/mitjafelicijan target=_blank>Code</a>
7<a href=/mitjafelicijan.pgp.pub.txt target=_blank class=hob>PGP</a>
8<a href=/curriculum-vitae.html>CV</a>
9<a href=/index.xml target=_blank class=hob>RSS</a></nav></header><main role=main><article itemtype=http://schema.org/Article><h1 itemtype=headline>Running Golang application as PID 1 with Linux kernel</h1><p><cap>post</cap>, Dec 25, 2021 on <a href=https://mitjafelicijan.com>Mitja Felicijan's blog</a><div><h2 id=unikernels-kernels-and-alike>Unikernels, kernels, and alike</h2><p>I have been reading a lot about
10<a href=https://en.wikipedia.org/wiki/Unikernel>unikernernels</a> lately and found them
11very intriguing. When you push away all the marketing speak and look at the
12idea, it makes a lot of sense.<blockquote><p>A unikernel is a specialized, single address space machine image constructed
13by using library operating systems. (<a href=https://en.wikipedia.org/wiki/Unikernel>Wikipedia</a>)</blockquote><p>I really like the explanation from the article
14<a href="https://queue.acm.org/detail.cfm?id=2566628">Unikernels: Rise of the Virtual Library Operating System</a>.
15Really worth a read.<p>If we compare a normal operating system to a unikernel side by side, they would
16look something like this.<figure><img src=/posts/pid1/unikernels.webp alt="Virtual machines vs Containers vs Unikernels"></figure><p>From this image, we can see how the complexity significantly decreases with
17the use of Unikernels. This comes with a price, of course. Unikernels are hard
18to get running and require a lot of work since you don't have an actual proper
19kernel running in the background providing network access and drivers etc.<p>So as a half step to make the stack simpler, I started looking into using
20Linux kernel as a base and going from there. I came across this
21<a href="https://www.youtube.com/watch?v=Sk9TatW9ino">Youtube video talking about Building the Simplest Possible Linux System</a>
22by <a href=https://landley.net>Rob Landley</a> and apart from statically compiling the
23application to be run as PID1 there was really no other obstacles.<h2 id=what-is-pid-1>What is PID 1?</h2><p>PID 1 is the first process that Linux kernel starts after the boot process.
24It also has a couple of unique properties that are unique to it.<ul><li>When the process with PID 1 dies for any reason, all other processes are
25killed with KILL signal.<li>When any process having children dies for any reason, its children are
26re-parented to process with PID 1.<li>Many signals which have default action of Term do not have one for PID 1.<li>When the process with PID 1 dies for any reason, kernel panics, which
27result in system crash.</ul><p>PID 1 is considered as an Init application which takes care of running other
28and handling services like:<ul><li>sshd,<li>nginx,<li>pulseaudio,<li>etc.</ul><p>If you are on a Linux machine, you can check what your process is with PID 1
29by running the following.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ cat /proc/1/status
30</span></span><span style=display:flex><span>Name: systemd
31</span></span><span style=display:flex><span>Umask: 0000
32</span></span><span style=display:flex><span>State: S (sleeping)
33</span></span><span style=display:flex><span>Tgid: 1
34</span></span><span style=display:flex><span>Ngid: 0
35</span></span><span style=display:flex><span>Pid: 1
36</span></span><span style=display:flex><span>PPid: 0
37</span></span><span style=display:flex><span>...
38</span></span></code></pre><p>As we can see on my machine the process with id of 1 is <a href=https://systemd.io/>systemd</a>
39which is a software suite that provides an array of system components for Linux
40operating systems. If you look closely you can also see that the <code>PPid</code>
41(process id of the parent process) is <code>0</code> which additionally confirms that
42this process doesn't have a parent.<h2 id=so-why-even-run-application-as-pid-1-instead-of-just-using-a-container>So why even run application as PID 1 instead of just using a container?</h2><p>Containers are wonderful, but they come with a lot of baggage. And because they
43are in their nature layered, the images require quite a lot of space and also a
44lot of additional software to handle them. They are not as lightweight as they
45seem, and many popular images require 500 MB plus disk space.<p>The idea of running this as PID 1 would result in a significantly smaller footprint,
46as we will see later in the post.<blockquote><p>You could run a simple init system inside Docker container described more
47in this article <a href=https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/>Docker and the PID 1 zombie reaping problem</a>.</blockquote><h2 id=the-master-plan>The master plan</h2><ol><li>Compile Linux kernel with the default definitions.<li>Prepare a Hello World application in Golang that is statically compiled.<li>Run it with <a href=https://www.qemu.org/>QEMU</a> and providing Golang application
48as init application / PID 1.</ol><p>For the sake of simplicity we will not be cross-compiling any of it and just
49use the 64bit version.<h2 id=compiling-linux-kernel>Compiling Linux kernel</h2><pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.7.tar.xz
50</span></span><span style=display:flex><span>$ tar xf linux-5.15.7.tar.xz
51</span></span><span style=display:flex><span>
52</span></span><span style=display:flex><span>$ cd linux-5.15.7
53</span></span><span style=display:flex><span>
54</span></span><span style=display:flex><span>$ make clean
55</span></span><span style=display:flex><span>
56</span></span><span style=display:flex><span><span style=color:green># read more about this https://stackoverflow.com/a/41886394</span>
57</span></span><span style=display:flex><span>$ make defconfig
58</span></span><span style=display:flex><span>
59</span></span><span style=display:flex><span>$ time make -j <span style=color:#a31515>`</span>nproc<span style=color:#a31515>`</span>
60</span></span><span style=display:flex><span>
61</span></span><span style=display:flex><span>$ cd ..
62</span></span></code></pre><p>At this point we have kernel image that is located in <code>arch/x86_64/boot/bzImage</code>.
63We will use this in QEMU later.<p>To make our lives a bit easier lets move the kernel image to another place.
64Lets create a folder <code>bin/</code> in the root of our project with <code>mkdir -p bin</code>.<p>At this point we can copy <code>bzImage</code> to <code>bin/</code> folder with
65<code>cp linux-5.15.7/arch/x86_64/boot/bzImage bin/bzImage</code>.<p>The folder structure of this experiment should look like this.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>pid1/
66</span></span><span style=display:flex><span> bin/
67</span></span><span style=display:flex><span> bzImage
68</span></span><span style=display:flex><span> linux-5.15.7/
69</span></span><span style=display:flex><span> linux-5.15.7.tar.xz
70</span></span></code></pre><h2 id=preparing-pid-1-application-in-golang>Preparing PID 1 application in Golang</h2><p>This step is relatively easy. The only thing we must have in mind that we will
71need to compile the binary as a static one.<p>Let's create <code>init.go</code> file in the root of the project.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span><span style=color:#00f>package</span> main
72</span></span><span style=display:flex><span>
73</span></span><span style=display:flex><span><span style=color:#00f>import</span> (
74</span></span><span style=display:flex><span> <span style=color:#a31515>&#34;fmt&#34;</span>
75</span></span><span style=display:flex><span> <span style=color:#a31515>&#34;time&#34;</span>
76</span></span><span style=display:flex><span>)
77</span></span><span style=display:flex><span>
78</span></span><span style=display:flex><span><span style=color:#00f>func</span> main() {
79</span></span><span style=display:flex><span> <span style=color:#00f>for</span> {
80</span></span><span style=display:flex><span> fmt.Println(<span style=color:#a31515>&#34;Hello from Golang&#34;</span>)
81</span></span><span style=display:flex><span> time.Sleep(1 * time.Second)
82</span></span><span style=display:flex><span> }
83</span></span><span style=display:flex><span>}
84</span></span></code></pre><p>If you notice, we have a forever loop in the main, with a simple sleep of 1
85second to not overwhelm the CPU. This is because PID 1 should never complete
86and/or exit. That would result in a kernel panic. Which is BAD!<p>There are two ways of compiling Golang application. Statically and dynamically.<p>To statically compile the binary, use the following command.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ go build -ldflags=<span style=color:#a31515>&#34;-extldflags=-static&#34;</span> init.go
87</span></span></code></pre><p>We can also check if the binary is statically compiled with:<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ file init
88</span></span><span style=display:flex><span>init: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=Ypu8Zw_4NBxm1Yxg2OYO/H5x721rQ9uTPiDVh-VqP/vZN7kXfGG1zhX_qdHMgH/9vBfmK81tFrygfOXDEOo, not stripped
89</span></span><span style=display:flex><span>
90</span></span><span style=display:flex><span>$ ldd init
91</span></span><span style=display:flex><span>not a dynamic executable
92</span></span></code></pre><p>At this point, we need to create <a href=https://www.linuxfromscratch.org/blfs/view/svn/postlfs/initramfs.html>initramfs</a>
93(abbreviated from "initial RAM file system", is the successor of initrd. It
94is a cpio archive of the initial file system that gets loaded into memory
95during the Linux startup process).<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ echo init | cpio -o --format=newc &gt; initramfs
96</span></span><span style=display:flex><span>$ mv initramfs bin/initramfs
97</span></span></code></pre><p>The projects at this stage should look like this.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>pid1/
98</span></span><span style=display:flex><span> bin/
99</span></span><span style=display:flex><span> bzImage
100</span></span><span style=display:flex><span> initramfs
101</span></span><span style=display:flex><span> linux-5.15.7/
102</span></span><span style=display:flex><span> linux-5.15.7.tar.xz
103</span></span><span style=display:flex><span> init.go
104</span></span></code></pre><h2 id=running-all-of-it-with-qemu>Running all of it with QEMU</h2><p><a href=https://www.qemu.org/>QEMU</a> is a free and open-source hypervisor. It emulates
105the machine's processor through dynamic binary translation and provides a set
106of different hardware and device models for the machine, enabling it to run a
107variety of guest operating systems.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ qemu-system-x86_64 -serial stdio -kernel bin/bzImage -initrd bin/initramfs -append <span style=color:#a31515>&#34;console=ttyS0&#34;</span> -m 128
108</span></span></code></pre><pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ qemu-system-x86_64 -serial stdio -kernel bin/bzImage -initrd bin/initramfs -append <span style=color:#a31515>&#34;console=ttyS0&#34;</span> -m 128
109</span></span><span style=display:flex><span>[ 0.000000] Linux version 5.15.7 (m@khan) (gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7), GNU ld version 2.37-10.fc35) <span style=color:green>#7 SMP Mon Dec 13 10:23:25 CET 2021</span>
110</span></span><span style=display:flex><span>[ 0.000000] Command line: console=ttyS0
111</span></span><span style=display:flex><span>[ 0.000000] x86/fpu: x87 FPU will use FXSAVE
112</span></span><span style=display:flex><span>[ 0.000000] signal: max sigframe size: 1440
113</span></span><span style=display:flex><span>[ 0.000000] BIOS-provided physical RAM map:
114</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
115</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
116</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
117</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x0000000007fdffff] usable
118</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x0000000007fe0000-0x0000000007ffffff] reserved
119</span></span><span style=display:flex><span>[ 0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
120</span></span><span style=display:flex><span>[ 0.000000] NX (Execute Disable) protection: active
121</span></span><span style=display:flex><span>[ 0.000000] SMBIOS 2.8 present.
122</span></span><span style=display:flex><span>[ 0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-6.fc35 04/01/2014
123</span></span><span style=display:flex><span>[ 0.000000] tsc: Fast TSC calibration failed
124</span></span><span style=display:flex><span>...
125</span></span><span style=display:flex><span>[ 2.016106] ALSA device list:
126</span></span><span style=display:flex><span>[ 2.016329] No soundcards found.
127</span></span><span style=display:flex><span>[ 2.053176] Freeing unused kernel image (initmem) memory: 1368K
128</span></span><span style=display:flex><span>[ 2.056095] Write protecting the kernel read-only data: 20480k
129</span></span><span style=display:flex><span>[ 2.058248] Freeing unused kernel image (text/rodata gap) memory: 2032K
130</span></span><span style=display:flex><span>[ 2.058811] Freeing unused kernel image (rodata/data gap) memory: 500K
131</span></span><span style=display:flex><span>[ 2.059164] Run /init as init process
132</span></span><span style=display:flex><span>Hello from Golang
133</span></span><span style=display:flex><span>[ 2.386879] tsc: Refined TSC clocksource calibration: 3192.032 MHz
134</span></span><span style=display:flex><span>[ 2.387114] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2e02e31fa14, max_idle_ns: 440795264947 ns
135</span></span><span style=display:flex><span>[ 2.387380] clocksource: Switched to clocksource tsc
136</span></span><span style=display:flex><span>[ 2.587895] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input3
137</span></span><span style=display:flex><span>Hello from Golang
138</span></span><span style=display:flex><span>Hello from Golang
139</span></span><span style=display:flex><span>Hello from Golang
140</span></span></code></pre><p>The whole <a href=/posts/pid1/qemu.log>log file here</a>.<h2 id=size-comparison>Size comparison</h2><p>The cool thing about this approach is that the Linux kernel and the application
141together only take around 12 MB, which is impressive as hell. And we need to
142also know that the size of bzImage (Linux kernel) could be greatly decreased
143by going into <code>make menuconfig</code> and removing a ton of features from the kernel,
144making the size even smaller. I managed to get kernel size down to 2 MB and
145still working properly.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>total 12M
146</span></span><span style=display:flex><span>-rw-r--r--. 1 m m 9.3M Dec 13 10:24 bzImage
147</span></span><span style=display:flex><span>-rw-r--r--. 1 m m 1.9M Dec 27 01:19 initramfs
148</span></span></code></pre><h2 id=creating-iso-image-and-running-it-with-gnome-boxes>Creating ISO image and running it with Gnome Boxes</h2><p>First we need to create proper folder structure with <code>mkdir -p iso/boot/grub</code>.<p>Then we need to download the <a href=https://github.com/littleosbook/littleosbook/raw/master/files/stage2_eltorito>grub binary</a>.
149You can read more about this program on <a href=https://github.com/littleosbook/littleosbook>https://github.com/littleosbook/littleosbook</a>.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ wget -O iso/boot/grub/stage2_eltorito https://github.com/littleosbook/littleosbook/raw/master/files/stage2_eltorito
150</span></span></code></pre><pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ tree iso/boot/
151</span></span><span style=display:flex><span>iso/boot/
152</span></span><span style=display:flex><span>├── bzImage
153</span></span><span style=display:flex><span>├── grub
154</span></span><span style=display:flex><span>│   ├── menu.lst
155</span></span><span style=display:flex><span>│   └── stage2_eltorito
156</span></span><span style=display:flex><span>└── initramfs
157</span></span></code></pre><p>Let's copy files into proper folders.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>$ cp stage2_eltorito iso/boot/grub/
158</span></span><span style=display:flex><span>$ cp bin/bzImage iso/boot/
159</span></span><span style=display:flex><span>$ cp bin/initramfs iso/boot/
160</span></span></code></pre><p>Lets create a GRUB config file at <code>nano iso/boot/grub/menu.lst</code> with contents.<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>default=<span style=color:#a31515>0</span>
161</span></span><span style=display:flex><span>timeout=<span style=color:#a31515>5</span>
162</span></span><span style=display:flex><span>
163</span></span><span style=display:flex><span>title GoAsPID1
164</span></span><span style=display:flex><span>kernel /boot/bzImage
165</span></span><span style=display:flex><span>initrd /boot/initramfs
166</span></span></code></pre><p>Let's create iso file by using genisoimage:<pre tabindex=0 style=background-color:#fff><code><span style=display:flex><span>genisoimage -R <span style=color:#a31515>\
167</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -b boot/grub/stage2_eltorito <span style=color:#a31515>\
168</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -no-emul-boot <span style=color:#a31515>\
169</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -boot-load-size 4 <span style=color:#a31515>\
170</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -A os <span style=color:#a31515>\
171</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -input-charset utf8 <span style=color:#a31515>\
172</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -quiet <span style=color:#a31515>\
173</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -boot-info-table <span style=color:#a31515>\
174</span></span></span><span style=display:flex><span><span style=color:#a31515></span> -o GoAsPID1.iso <span style=color:#a31515>\
175</span></span></span><span style=display:flex><span><span style=color:#a31515></span> iso
176</span></span></code></pre><p>This will produce <code>GoAsPID1.iso</code> which you can use with <a href=https://www.virtualbox.org/>Virtualbox</a>
177or <a href=https://apps.gnome.org/app/org.gnome.Boxes/>Gnome Boxes</a>.<p><video src=/posts/pid1/boxes.mp4 controls></video><h2 id=is-running-applications-as-pid-1-even-worth-it>Is running applications as PID 1 even worth it?</h2><p>Well, the answer to this is not as simple as one would think. Sometimes it is
178and sometimes it's not. For embedded systems and very specialized applications
179it is worth for sure. But in normal uses, I don't think so. It was an interesting
180exercise in compiling kernels and looking at the guts of the Linux kernel,
181but sticking to containers for most of the things is a better option in my
182opinion.<p>An interesting experiment would be creating an image that supports networking
183and could be deployed to AWS as an EC2 instance and observing how it fares.
184But in that case, we would need to write some sort of supervisor that would
185run on a separate EC2 that would check if other EC2 instances are running
186properly. Remember that if your application fails, kernel panics and the
187whole machine is inoperable in this case.</div></article></main><section><hr><h2>Posts from blogs I follow around the net</h2><ul><li><a href=https://utcc.utoronto.ca/~cks/space/blog/linux/NFSv4ServerLockClients target=_blank rel=noopener>Finding which NFSv4 client owns a lock on a Linux NFS(v4) server</a> — <a href=https://utcc.utoronto.ca/~cks/space/blog/>Chris's Wiki :: blog</a><div>A while back I wrote an entry about finding which NFS client owns
188a lock on a Linux NFS server, which turned
189out to be specific to NFS v3 (which I really should have seen coming,
190since it involved NLM and lockd). Finding the NFS v4 client that
191owns a lock is, depending on your perspective, either simpl…<li><a href=http://www.landley.net/notes-2023.html#28-10-2023 target=_blank rel=noopener>October 28, 2023</a> — <a href=http://www.landley.net/notes-2023.html>Rob Landley's Blog Thing for 2023</a><div>Oh good grief, two of my least favorite licensing people, Larry Rosen
192and Bradley Kuhn, are interacting on the OSI's license-discuss
193list where the're doing
194bad computer history and insisting that a guy Larry Rosen
195coincidentally interviewed for a book years ago is clearly the origin of
196somethin…<li><a href="http://offbeatpursuit.com:80/blog/?id=25" target=_blank rel=noopener>A fix by any other name</a> — <a href=http://offbeatpursuit.com:80/blog/>WLOG - blog</a><div>tags:
197i2c, plan9
198Another month, another file system.
199Well, if you can’t fix it in software, fix it in hardware (looking at
200you, bme680, we’re not
201done yet). The show must go on, as they say, and I would like my
202experiments to go on.
203So a “new” addition to the environmental sensor family connected to
204the h…<li><a href=https://mirzapandzo.com/next-image-url-parameter-is-valid-but-upstream-response-is-invalid target=_blank rel=noopener>Next/Image "url" parameter is valid but upstream response is invalid</a> — <a href=https://mirzapandzo.com/>Mirza Pandzo's Blog</a><div>Getting "url" parameter is valid but upstream response is invalid error with Next/Image on WSL2<li><a href=https://drewdevault.com/2023/10/13/Going-off-script.html target=_blank rel=noopener>Going off-script</a> — <a href=https://drewdevault.com>Drew DeVault's blog</a><div>There is a phenomenon in society which I find quite bizarre. Upon our entry to
205this mortal coil, we are endowed with self-awareness, agency, and free will.
206Each of the 8 billion members of this human race represents a unique person, a
207unique worldview, and a unique agency. Yet, many of us have the sam…<li><a href=https://szymonkaliski.com/writing/2023-10-02-building-a-diy-pen-plotter/ target=_blank rel=noopener>Building a DIY Pen Plotter</a> — <a href=http://github.com/dylang/node-rss>Szymon Kaliski</a><div>This article documents my learnings from designing and building a DIY Pen Plotter during the summer of 2023.
208My ultimate goal is to build my…<li><a href=https://neil.computer/notes/chart-of-accounts-for-startups-and-saas-companies/ target=_blank rel=noopener>Chart of Accounts for Startups and SaaS Companies</a> — <a href=https://neil.computer/>Neil Panchal</a><div>Accounting is fundamental to starting a business. You need to have a basic understanding of accounting principles and essential bookkeeping. I had to learn it. There was no choice. For filing taxes, your CPA is going to ask you for an Income Statement (also known as P/L statement). If<li><a href=https://journal.valeriansaliou.name/deploy-a-nomad-cluster-on-alpine-linux-with-vultr/ target=_blank rel=noopener>Deploy a Nomad Cluster on Alpine Linux with Vultr</a> — <a href=https://journal.valeriansaliou.name/>Valerian Saliou</a><div>After spending countless hours trying to understand how to deploy my apps on Kubernetes for the first time to host Mirage, an AI API service that I run, I ended up making myself a promise that the next app I work on would be using a more productive & simpler<li><a href=https://jcs.org/2023/10/25/wifi_da target=_blank rel=noopener>BlueSCSI Wi-Fi Desk Accessory 1.0 Released</a> — <a href=https://jcs.org/>joshua stein</a><div>BlueSCSI Wi-Fi Desk Accessory
2091.0 has been released:
210wifi_da-1.0.sit
211(StuffIt 3 archive)
212SHA256: ccfc9d27dd5da7412d10cef73b81119a1fec3848e4d1d88ff652a07ffdc6a69aSHA1: ff124972f202ceda6d7fa4788110a67ccda6a13a
213This is the initial public release of my BlueSCSI Wi-Fi Desk Accessory for
214classic MacOS.<li><a href=https://michael.stapelberg.ch/posts/2023-10-25-my-all-flash-zfs-network-storage-build/ target=_blank rel=noopener>My 2023 all-flash ZFS NAS (Network Storage) build</a> — <a href=https://michael.stapelberg.ch/>Michael Stapelbergs Website</a><div>For over 10 years now, I run two self-built NAS (Network Storage) devices which serve media (currently via Jellyfin) and run daily backups of all my PCs and servers.
215In this article, I describe my goals, which hardware I picked for my new build (and why) and how I set it up.
216Design Goals
217I use my netw…</ul><p>Generated with <a href=https://git.sr.ht/~sircmpwn/openring target=_blank rel=noopener>openring</a>.</section><footer><hr><p><big><strong>Want to comment or have something to add?</strong></big><p>You can write me an email
218at <a href=mailto:mitja.felicijan@gmail.com>mitja.felicijan@gmail.com</a> or
219catch up with me <a href=https://telegram.me/mitjafelicijan target=_blank>on Telegram</a>.<hr><p>This website does not track you. Content is made available under the <a href=https://creativecommons.org/licenses/by/4.0/ target=_blank rel=noreferrer>CC BY 4.0 license</a> unless
220specified otherwise. Blog is also available as <a href=/index.xml target=_blank>RSS feed</a>.</footer><script>
221 window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
222 </script><script defer src=/_vercel/insights/script.js></script> \ No newline at end of file