<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ivan Fraixedes</title>
    <description>The latest articles on Forem by Ivan Fraixedes (@ifraixedes).</description>
    <link>https://forem.com/ifraixedes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1392147%2F63bdc788-4dbb-4f80-b2f6-2b508c59d276.png</url>
      <title>Forem: Ivan Fraixedes</title>
      <link>https://forem.com/ifraixedes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ifraixedes"/>
    <language>en</language>
    <item>
      <title>Moved to the heap in Go standard pool</title>
      <dc:creator>Ivan Fraixedes</dc:creator>
      <pubDate>Wed, 15 Oct 2025 17:58:25 +0000</pubDate>
      <link>https://forem.com/ifraixedes/moved-to-the-heap-in-go-standard-pool-513i</link>
      <guid>https://forem.com/ifraixedes/moved-to-the-heap-in-go-standard-pool-513i</guid>
      <description>&lt;p&gt;The other day I was applying some changes to make a logic that was processing a list of "objects" sequentially to do it&lt;br&gt;
concurrently&lt;sup&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The logic itself doesn't matter for the purpose of this blog, what it only matters is that that to avoid a slice&lt;br&gt;
allocation of N element on each batch that was processing, the sequential logic was reusing a slice, so to reuse slices&lt;br&gt;
on the current implementation, I used the standard &lt;a href="https://pkg.go.dev/sync#Pool" rel="noopener noreferrer"&gt;sync.Pool&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I will use a slice of bytes as simple example, to make clear what my explanations and avoid confusion with&lt;br&gt;
the all the stuff that the original implementation entails.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use pointers
&lt;/h2&gt;

&lt;p&gt;Reading the documentation, one can realize (if you slide to the &lt;a href="https://pkg.go.dev/sync#example-Pool" rel="noopener noreferrer"&gt;example&lt;/a&gt;) that&lt;br&gt;
pool must use pointers to avoid allocations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bufPool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// The Pool's New function should generally only return pointer&lt;/span&gt;
        &lt;span class="c"&gt;// types, since a pointer can be put into the return interface&lt;/span&gt;
        &lt;span class="c"&gt;// value without an allocation:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pointers to slices
&lt;/h2&gt;

&lt;p&gt;Because the pool was storing slices, I started to mess with pointers to manipulate the slices gotten from it.&lt;/p&gt;

&lt;p&gt;Let's see in code, what I mean&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;// Reset the slice before use&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// you'll do something else here and  when you don't need this slice anymore&lt;/span&gt;
&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't seem that much, but if you account that, the current logic has to keep the gotten slice during iterations&lt;br&gt;
until the N elements configured in that batch is reached, you get in the call back function which is called for each&lt;br&gt;
element retrieved the following logic&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ranger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Some more logic goes here, and at some point under a conditional you&lt;/span&gt;
    &lt;span class="c"&gt;// capture `s2` into a goroutine and you put back the slice into the pool&lt;/span&gt;
    &lt;span class="c"&gt;// before exiting, and this callback get a new slice from the pool an&lt;/span&gt;
    &lt;span class="c"&gt;// assigned to `s`.&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, not to complex, but then I though, instead of using a temporary variable, use the pointer directly with some utility&lt;br&gt;
functions/wrappers, something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;put&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Evil allocations
&lt;/h2&gt;

&lt;p&gt;During the review of my changes, there was a comment to replace my utility functions/wrapper by others more ergonomic.&lt;/p&gt;

&lt;p&gt;That made me think, all these wrappers going to save the allocations saved because of using pointers in the pool?&lt;/p&gt;

&lt;p&gt;Myself response was: I don't know, let's write some &lt;strong&gt;dirty&lt;/strong&gt; benchmarks abstracting a pool usage, not from the real&lt;br&gt;
implementation, for simplicity and because I was only interested in finding out the pool behavior. Actually, the&lt;br&gt;
previous snippets of codes were extracted from these benchmarks.&lt;/p&gt;

&lt;p&gt;I started to write 3 different options, including using values in the pool instead of pointers, but when I saw that&lt;br&gt;
using values was doing the same allocations than using pointers with wrappers, I wrote a few more, some of them with a&lt;br&gt;
minimal changes that were expected not to provoke any allocation change because they were more about to reduce lines of&lt;br&gt;
code while eliminating intermediary variables by moving the operations into the same line.&lt;/p&gt;

&lt;p&gt;You can find it &lt;a href="https://gist.github.com/ifraixedes/912c6260ac5de02c649c05140b27f9bb" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you're interested in&lt;br&gt;
looking at it.&lt;/p&gt;

&lt;p&gt;Running the benchmarks with &lt;code&gt;go test -bench . -benchmem&lt;/code&gt;, I quickly saw which approach was fine because it didn't&lt;br&gt;
produce any allocation.&lt;/p&gt;

&lt;p&gt;Based on those results, it looked that it isn't a good idea to wrap anything in functions and just use directly the&lt;br&gt;
pointers to make sure that there isn't unexpected allocations.&lt;/p&gt;

&lt;p&gt;As a side note, the idea of having some wrappers was to avoid code repetition that was using intermediate variables to&lt;br&gt;
dereference the pointer to the slice to add elements and reset it, until my colleague mentioned that I could simplified&lt;br&gt;
with online just dereferencing when passed to &lt;code&gt;append&lt;/code&gt; and when resetting, but also dereferencing when assigning the&lt;br&gt;
result of those operations, so this ended up like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with that simplification, there weren't needed wrappers anymore because there was nothing to encapsulate, unless&lt;br&gt;
that seeing those many &lt;code&gt;*&lt;/code&gt; bothers you.&lt;/p&gt;
&lt;h2&gt;
  
  
  The culprit was "moved to heap"
&lt;/h2&gt;

&lt;p&gt;This could end up here, but I was curious about where those allocations where originated. I took 3 of the benchmarks and&lt;br&gt;
check the output of &lt;code&gt;go test -gcflags='-m' pool_test.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The output is quite verbose, but looking at it, I found that the important parts for this matter was the lines that&lt;br&gt;
contained &lt;code&gt;moved to heap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Following are the 3 benchmarks that I put in a single file to be easy to inspect the &lt;code&gt;moved to heap&lt;/code&gt; lines.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benchmark with 1 allocation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkPoolGetPut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;put&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;go test -gcflags='-m' bench_get_put_test.go 2&amp;gt;&amp;amp;1 | grep 'moved to heap'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bench_get_put_test.go:11:4: moved to heap: s
./bench_get_put_test.go:9:2: moved to heap: pool
./bench_get_put_test.go:30:5: moved to heap: s
./bench_get_put_test.go:21:14: moved to heap: s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can ignore line 9 and 11 for this one and for the rest, that's obvious that a new slice has to be allocated in the&lt;br&gt;
heap when it's created.&lt;/p&gt;

&lt;p&gt;The important ones are 21 and 30, which is where a passed slice to the &lt;code&gt;put&lt;/code&gt; function makes the slice to be moved to the&lt;br&gt;
heap.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benchmark with 2 allocations
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkDoubleAllocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;appendByte&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;appendByte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;go test -gcflags='-m' bench_double_allocation_test.go  2&amp;gt;&amp;amp;1 | grep 'moved to heap'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bench_double_allocation_test.go:11:4: moved to heap: s
./bench_double_allocation_test.go:17:3: moved to heap: b
./bench_double_allocation_test.go:23:3: moved to heap: b
./bench_double_allocation_test.go:9:2: moved to heap: pool
./bench_double_allocation_test.go:32:11: moved to heap: b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important ones are the 17 and 23. My understanding is that 32 is moved to the heap, but because it's a pointer it&lt;br&gt;
doesn't allocate.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benchmark with 0 allocations
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;appendByte&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;appendByte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"returned slice doesn't have the expected number of elements"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;go test -gcflags='-m' bench_zero_allocation_test.go 2&amp;gt;&amp;amp;1 | grep 'moved to heap'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bench_zero_allocation_test.go:11:4: moved to heap: s
./bench_zero_allocation_test.go:9:2: moved to heap: pool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is nothing moved to the heap, hurray!&lt;/p&gt;

&lt;p&gt;Obviously, simplifying the wrappers to online dereferencing the pointers as commented above&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;appendByte&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces the same result, but it defeats the purpose of them, because we can place the one line wrappers where they are&lt;br&gt;
called.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When dealing with &lt;code&gt;sync.Pool&lt;/code&gt; use the same pointers that you get to put them into to avoid "moved to heap" and cause&lt;br&gt;
undesired allocations.&lt;/p&gt;

&lt;p&gt;If a function creates a variable and it returns a reference to it, it's moved to the heap. Although, I could expect&lt;br&gt;
this because of Rust learned lessons, I missed the point in Go.&lt;/p&gt;




&lt;p&gt;&lt;sup id="footnote-1"&gt;1&lt;/sup&gt; &lt;a href="https://review.dev.storj.tools/c/storj/storj/+/18859" rel="noopener noreferrer"&gt;https://review.dev.storj.tools/c/storj/storj/+/18859&lt;/a&gt;&lt;br&gt;
These are the changes that I worked and were I had to use &lt;code&gt;sync.Pool&lt;/code&gt; if it's your interest&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Arch Linux essential tweaks and applications</title>
      <dc:creator>Ivan Fraixedes</dc:creator>
      <pubDate>Fri, 27 Jun 2025 16:48:44 +0000</pubDate>
      <link>https://forem.com/ifraixedes/arch-linux-essential-tweaks-and-applications-54bh</link>
      <guid>https://forem.com/ifraixedes/arch-linux-essential-tweaks-and-applications-54bh</guid>
      <description>&lt;p&gt;This post is part of a series of posts about installing and configuring Arch Linux in a &lt;a href="https://slimbook.com/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt; Executive 14". I created them from a collection of personal notes, that I thought may be useful for others, so I published them through these series.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/base-arch-linux-installation-3299"&gt;Base Arch Linux installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-network-configuration-436i"&gt;Arch Linux network configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/tracking-dot-files-3emg"&gt;Tracking dot files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Arch Linux essential tweaks &amp;amp; applications&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This post and the next are related to personalize my recently installed Arch Linux. Although in the previous one, I already made some choices, they are not as personalized as the ones to come.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tweaking sudoers
&lt;/h2&gt;

&lt;p&gt;I wanted my user to be able to power off, reboot, etc, using &lt;code&gt;sudo&lt;/code&gt; but without having to type a password.&lt;/p&gt;

&lt;p&gt;To grant my user to do so, I created a new &lt;a href="https://man.archlinux.org/man/sudoers.5" rel="noopener noreferrer"&gt;&lt;em&gt;sudoers&lt;/em&gt;&lt;/a&gt; file &lt;code&gt;/etc/sudoers.d/10-common-operations-no-passwd&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ivan blacksmoke= NOPASSWD: /ur/bin/systemctl halt,/ur/bin/systemctl hibernate,/ur/bin/systemctl poweroff,/ur/bin/systemctl reboot,/ur/bin/systemctl suspend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I ensured that only root can access to it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# chown root:root /etc/sudoers.d/10-common-operations-no-passwd
# chmod -c 0660 /etc/sudoers.d/10-common-operations-no-passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sync the clock
&lt;/h2&gt;

&lt;p&gt;I wanted to sync the computer clock, so I enable the &lt;a href="https://wiki.archlinux.org/title/systemd-timesyncd" rel="noopener noreferrer"&gt;systemd-timesyncd&lt;/a&gt; daemon with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# timedatectl set-ntp true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  My default shell
&lt;/h2&gt;

&lt;p&gt;I wanted to use the &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;&lt;em&gt;fish shell&lt;/em&gt;&lt;/a&gt;, so I installed and set it as a default shell for my user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S fish
# chsh -s /usr/bin/fish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Changing my default editor
&lt;/h2&gt;

&lt;p&gt;If you have read the &lt;a href="https://dev.to{{&amp;lt;%20ref%20"&gt;}}"&amp;gt;base Arch Linux installation post&lt;/a&gt;, I installed NeoVim, but I never set it as my default editor.&lt;/p&gt;

&lt;p&gt;As a convention applications that requires to open an editor should read the &lt;code&gt;EDITOR&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/etc/environment&lt;/code&gt; file is a file that contains the environment variables thar are exported for all the sessions are created.&lt;/p&gt;

&lt;p&gt;I created the file because it didn't exist and I added&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EDITOR=/usr/bin/nvim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comfortable using the terminal without a desktop
&lt;/h2&gt;

&lt;p&gt;When you don't have a desktop environment (at least at this point, I didn't have any),  &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;&lt;em&gt;tmux&lt;/em&gt;&lt;/a&gt; is one of those tools that will be your friend, why? Because between many things, the two most important features for me is that I can have tabs and multiple panes (vertical and horizontal), so I convert a single terminal session in a full fledge environment where I can have several applications running at the same time and move from to another as I do in a desktop environment.&lt;/p&gt;

&lt;p&gt;Nowadays, there are similar terminal emulator that may be for some people a better choice, however, this isn't a debate if Tmux is the best, the worse, or the average. I use  &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;&lt;em&gt;tmux&lt;/em&gt;&lt;/a&gt; because I used for long time, remotely and locally, and it works good for me, so I haven't invested my time on learning another one.&lt;/p&gt;

&lt;p&gt;So, yes,  &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;&lt;em&gt;tmux&lt;/em&gt;&lt;/a&gt; is what I wanted&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S tmux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A few essential tools
&lt;/h2&gt;

&lt;p&gt;The last missing tools at this point were&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;man&lt;/code&gt; because I need to read documentation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;less&lt;/code&gt; because I need to paginate outputs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;extfat-utils&lt;/code&gt; because I need to mount external ExtFat disks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bat&lt;/code&gt; because syntax coloring to cat certain files is helpful in certain situations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vimfm&lt;/code&gt; because is used for certain applications to show file differences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;so they were in with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S man-db extfat-utils less bat vifm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Welcome Arch User Repository
&lt;/h2&gt;

&lt;p&gt;Some good tools aren't in the official Arch linux official package repository, but they are in &lt;a href="https://aur.archlinux.org/" rel="noopener noreferrer"&gt;AUR (Arch User Repository)&lt;/a&gt;, the package repository manage by the community.&lt;/p&gt;

&lt;p&gt;You cannot install &lt;a href="https://wiki.archlinux.org/title/Arch_User_Repository" rel="noopener noreferrer"&gt;AUR packages&lt;/a&gt; with &lt;code&gt;pacman&lt;/code&gt;, buy you can do it manually which isn't that bad, but it's a bit tedious due to the process boilerplate and you have also to repeat it manually to update each installation that you installed from AUR. Fortunately, there are tools that simplify the process and make our busy life easier.&lt;/p&gt;

&lt;p&gt;There are many tools to install &lt;a href="https://wiki.archlinux.org/title/Arch_User_Repository" rel="noopener noreferrer"&gt;AUR packages&lt;/a&gt;. I chose to install &lt;a href="https://github.com/Morganamilo/paru" rel="noopener noreferrer"&gt;Paru&lt;/a&gt;, however, I don't have a strong argument for it, which is I liked what I read and it's implemented in &lt;a href="https://rust-lang.org" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's install it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paru
&lt;/h3&gt;

&lt;p&gt;First we have to make sure that we have installed and up to date the &lt;em&gt;basic tools to build Arch Linux Pacakges&lt;/em&gt; (a.k.a. &lt;code&gt;base-devel&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# sudo pacman -S --needed base-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Paru&lt;/em&gt; is in the AUR packages, so we have to &lt;a href="https://wiki.archlinux.org/title/Arch_User_Repository" rel="noopener noreferrer"&gt;install it manually&lt;/a&gt;. After it, we shouldn't recur very often or even never to manually install and update AUR packages, because that's what it will do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cd .local/makepgk/sources
# git clone https://aur.archlinux.org/paru.git
# cd paru
# makepkg -sirc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;makepkg&lt;/code&gt; will ask for installing &lt;em&gt;Rust&lt;/em&gt; via the &lt;a href="https://archlinux.org/packages/?name=rust" rel="noopener noreferrer"&gt;rust&lt;/a&gt; or &lt;a href="https://archlinux.org/packages/?name=rustup" rel="noopener noreferrer"&gt;rustup&lt;/a&gt;, I chose &lt;em&gt;rust&lt;/em&gt;, &lt;em&gt;rustup&lt;/em&gt; didn't work because it couldn't select which &lt;em&gt;Rust&lt;/em&gt; version to use.&lt;/p&gt;

&lt;p&gt;Anyway, the dependency will be deleted after the installation, that's what the &lt;code&gt;-r&lt;/code&gt; flag does in the &lt;code&gt;makepkg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After the installation, I also deleted &lt;code&gt;.cargo&lt;/code&gt; and &lt;code&gt;.rustup&lt;/code&gt; directories that were created in my &lt;em&gt;home&lt;/em&gt; directory.&lt;/p&gt;

&lt;p&gt;Finally, I wanted to apply &lt;a href="https://github.com/Morganamilo/paru?tab=readme-ov-file#general-tips" rel="noopener noreferrer"&gt;its general tips&lt;/a&gt; at the time that I installed.&lt;/p&gt;

&lt;p&gt;To apply them and other recommended options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I enabled the &lt;em&gt;pacman's&lt;/em&gt; &lt;code&gt;Color&lt;/code&gt;  uncommenting it from &lt;code&gt;/etc/pacman.conf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;/etc/paru.conf&lt;/code&gt;, I enabled the file manager viewer to use &lt;em&gt;vifm&lt;/em&gt; uncommenting &lt;code&gt;FileManager&lt;/code&gt; option and making sure that it's set to &lt;em&gt;vifm&lt;/em&gt;  (i.e. &lt;code&gt;FileManager = vifm&lt;/code&gt;). Remember to uncomment the &lt;code&gt;[bin]&lt;/code&gt; section if it's commented because this options belongs to that section.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;/etc/paru.conf&lt;/code&gt;, I enabled the search results to start at the bottom and go upwards, uncommenting the option &lt;code&gt;BottomUp&lt;/code&gt;.  Remember to uncomment the &lt;code&gt;[options]&lt;/code&gt; section if it's commented because this options belongs to that section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that was all for the day.&lt;/p&gt;

</description>
      <category>archlinux</category>
    </item>
    <item>
      <title>Tracking dot files</title>
      <dc:creator>Ivan Fraixedes</dc:creator>
      <pubDate>Sat, 21 Jun 2025 14:41:58 +0000</pubDate>
      <link>https://forem.com/ifraixedes/tracking-dot-files-3emg</link>
      <guid>https://forem.com/ifraixedes/tracking-dot-files-3emg</guid>
      <description>&lt;p&gt;This post is part of a series of posts about installing and configuring Arch Linux in a &lt;a href="https://slimbook.com/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt; Executive 14". I created them from a collection of personal notes, that I thought may be useful for others, so I published them through these series.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/base-arch-linux-installation-3299"&gt;Base Arch Linux installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-network-configuration-436i"&gt;Arch Linux network configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tracking dot files&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-essential-tweaks-and-applications-54bh"&gt; Arch Linux essential tweaks &amp;amp; applications&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This post isn't specifically related to Arch Linux, however, I dit it before I started to add and modify more configuration files on my home directory (a.k.a &lt;em&gt;dotfiles&lt;/em&gt;) , I wanted to start tracking them in a Git repository.&lt;/p&gt;

&lt;p&gt;Through the years, I've become more disciplined in how to manage my personal computers, one of those things is to track my configurations files (a.k.a &lt;em&gt;dotfiles&lt;/em&gt;). Nowadays, when I set up a new one, I start to track them in a Git repository.&lt;/p&gt;

&lt;p&gt;One purpose is restoring them or take some of them for other installations when they are different ones (not the same OS, or the same one with other applications, etc.), but, the other purposes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To see when new configuration files appear, disappear (i.e. delete) or are modified without being aware.&lt;/li&gt;
&lt;li&gt;Track the changes with useful commit messages, so I can use them to remember how to configure or change certain files to achieve something.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE I don't share this Git repository with anybody. Although it shouldn't contain any secret, I don't want to publicly share it, in case that one slides on it. &lt;/p&gt;

&lt;p&gt;Bear in mind that the commands in this post&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are all executed from my user home directory.&lt;/li&gt;
&lt;li&gt;They are executed on &lt;a href="https://archlinux.org/" rel="noopener noreferrer"&gt;Arch Linux&lt;/a&gt; or a distribution based on it, although the most of them should work in other common Linux distributions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The starting point is obvious :P&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# git init -b main .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GPG
&lt;/h2&gt;

&lt;p&gt;Before doing any other thing, I want to set up my GPG keys because I want all my commits to be signed with my &lt;em&gt;keybase&lt;/em&gt; signature.&lt;/p&gt;

&lt;p&gt;I ensure that that &lt;code&gt;gnupg&lt;/code&gt; is installed and up to date&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# sudo pacman -S --needed gnupg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have exported my &lt;em&gt;keybase&lt;/em&gt; private key, with the &lt;em&gt;uid&lt;/em&gt; that reference to &lt;em&gt;&lt;a href="mailto:ifraixedes@keybase.io"&gt;ifraixedes@keybase.io&lt;/a&gt;&lt;/em&gt; removed, and with &lt;em&gt;uid&lt;/em&gt; referencing to my email account under my personal domain, and that's the one that I importing below.&lt;/p&gt;

&lt;p&gt;Let's import the key, but before, I list them to see that I don't have any, then import it, and I list them again to see that it was imported as expected, obviously for importing you only need to execute the command in the middle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# gpg --list-keys
# gpg --import /mnt/usbstick/personal-gpg.priv.key
# gpg --list-keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git
&lt;/h2&gt;

&lt;p&gt;I wanted to have some &lt;em&gt;Git&lt;/em&gt; global configuration to start using it with this repository. The content of my initial &lt;code&gt;.gitconfig&lt;/code&gt; file is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[alias]
  amend = commit --amend --no-edit
  brdel = "!f() { git push $1 :$2; }; f"
  graph = log --color --graph --pretty=format:\"%h | %ad | %an | %s%d\" --date=short
  hist = log --color --pretty=format:\"%C(yellow)%h%C(reset) %s%C(bold red)%d%C(reset) %C(green)%ad%C(reset) %C(blue)[%an]%C(reset)\" --relative-date --decorate
  lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset' --abbrev-commit --date=relative
  trdel = "!f() { git push $1 :refs/tags/$2; }; f"
  wdiff = diff --color-words
  wip = for-each-ref --sort='authordate:iso8601' --format=' %(color:green)%(authordate:relative)%09%(color:white)%(refname:short)' refs/heads

[commit]
  gpgSign = true

[core]
  whitepace = blank-at-eol,space-before-tab,blank-at-eol

[init]
  defaultBranch = main

[merge]
  conflictstyle = diff3

[pull]
  ff = only

[push]
  default = current
  followTags = true

[user]
  email = &amp;lt;redacted&amp;gt;
  name = Ivan Fraixedes
  signingkey = B5CB5AD5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However the only settings that matters for the signature are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[commit]
  gpgSign = true

[user]
  email = &amp;lt;redacted&amp;gt;
  name = Ivan Fraixedes
  signingkey = B5CB5AD5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I  also create a &lt;code&gt;.gitignore&lt;/code&gt; file to start ignoring what I don't want to track. I could ignore some entire directories, for example &lt;code&gt;.local&lt;/code&gt;, however, I don't do it because I want to know when new directories appear there, despite of the extra work that brings in having to update &lt;code&gt;.gitignore&lt;/code&gt; from time to time.&lt;/p&gt;

&lt;p&gt;Last, but not least, I have to define the &lt;code&gt;GPG_TTY&lt;/code&gt; environment variable, otherwise git commit fails with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: gpg failed to sign the data:
[GNUPG:] KEY_CONSIDERED 2CFC97FB943CDD6F5DD1B8ECFB6101AFB5CB5AD5 2
[GNUPG:] BEGIN_SIGNING H8
[GNUPG:] PINENTRY_LAUNCHED 1117 curses 1.2.1 - linux - - 1000/1000 0
gpg: signing failed: Inappropriate ioctl for device
[GNUPG:] FAILURE sign 83918950
gpg: signing failed: Inappropriate ioctl for device

fatal: failed to write commit object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? well &lt;a href="https://man.archlinux.org/man/gpg-agent.1" rel="noopener noreferrer"&gt;&lt;code&gt;gpg-agent&lt;/code&gt;&lt;/a&gt; is a daemon which starts automatically to mange secret (a.k.a private) keys. You can read in its documentation it requires &lt;code&gt;GPG_TTY&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;p&gt;Because I use &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;fishell&lt;/a&gt;, I declare it into a new file under &lt;code&gt;.config/fish/conf.d/env-vars.fish&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set -gx GPG_TTY (tty)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and apply it to my session with &lt;code&gt;source ./config/fish/conf.d/env-vars.fish&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point I created my first commits with the home files that I want to track and I move on from this point creating separated commits for new files, files deletions, and file modifications.&lt;/p&gt;

</description>
      <category>archlinux</category>
    </item>
    <item>
      <title>Arch Linux network configuration</title>
      <dc:creator>Ivan Fraixedes</dc:creator>
      <pubDate>Wed, 30 Oct 2024 18:28:46 +0000</pubDate>
      <link>https://forem.com/ifraixedes/arch-linux-network-configuration-436i</link>
      <guid>https://forem.com/ifraixedes/arch-linux-network-configuration-436i</guid>
      <description>&lt;p&gt;This post is part of a series of posts about installing and configuring Arch Linux in a &lt;a href="https://slimbook.com/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt; Executive 14". I created them from a collection of personal notes, that I thought may be useful for others, so I published them through these series.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/base-arch-linux-installation-3299"&gt;Base Arch Linux installation &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Arch Linux network configuration&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/tracking-dot-files-3emg"&gt;Tracking dot files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-essential-tweaks-and-applications-54bh"&gt; Arch Linux essential tweaks &amp;amp; applications&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;NOTE because all the operations require root permissions, I logged as root with &lt;code&gt;sudo su&lt;/code&gt;, so all the commands in this post don't execute with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I decided to use &lt;a href="https://wiki.archlinux.org/title/systemd-networkd" rel="noopener noreferrer"&gt;&lt;code&gt;systemd-networkd&lt;/code&gt;&lt;/a&gt; to deal with the network configuration, and I decided to fully commit to it, so I used &lt;a href="https://wiki.archlinux.org/title/Systemd-resolved" rel="noopener noreferrer"&gt;&lt;code&gt;systemd-resolved&lt;/code&gt;&lt;/a&gt; for configuration the &lt;em&gt;network name resolution&lt;/em&gt; (a.k.a DNS). Bear in mind that my laptop only has one network interface (apart of the loopback interface).&lt;/p&gt;

&lt;p&gt;Both services are part of the base Arch Linux installation.&lt;/p&gt;

&lt;p&gt;I enable the &lt;code&gt;systemd-networkd&lt;/code&gt;, so it automatically starts at boot (i.e. &lt;code&gt;systemctl enable systemd-networkd.service&lt;/code&gt;). After executing it, you'll see a list of created &lt;em&gt;symlinks&lt;/em&gt; in &lt;code&gt;/etc/systemd/system&lt;/code&gt; and sub-directories to &lt;code&gt;/usr/lib/systemd/system&lt;/code&gt; directory, not important, but I wanted to point it out.  &lt;/p&gt;

&lt;p&gt;I configured the &lt;a href="https://wiki.archlinux.org/title/systemd-networkd#systemd-networkd-wait-online" rel="noopener noreferrer"&gt;&lt;code&gt;systemd-networkd-wait-online.service&lt;/code&gt;&lt;/a&gt; which is a oneshot system service that waits for the network to be configured. I edited the file &lt;code&gt;/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service&lt;/code&gt; which is a &lt;em&gt;symlink&lt;/em&gt; to &lt;code&gt;/usr/lib/systemd/system/systemd-networkd-network-wait-online.service&lt;/code&gt;, adding the &lt;code&gt;--any&lt;/code&gt; flag to the following line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --any
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To configure the &lt;a href="https://wiki.archlinux.org/title/systemd-networkd#Wireless_adapter" rel="noopener noreferrer"&gt;wireless adapter&lt;/a&gt;, I created a new file, &lt;code&gt;/etc/systemd/network/25-wireless.network&lt;/code&gt;, with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Match]
Name=wlan0

[Network]
DHCP=yes
IgnoreCarrierLoss=3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To obtain the name of the wireless adapter, I executed &lt;code&gt;ip link&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Everything should be fine at this point, so I started the service &lt;code&gt;systemd start systemd-netword.service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next is to configure name resolution service (TODO review if name resolution service is correct) through the &lt;code&gt;systemd-resolved&lt;/code&gt; service.&lt;/p&gt;

&lt;p&gt;I started enabling &lt;code&gt;systemctl enable systemd-resolved.service&lt;/code&gt; which, as before it created some &lt;code&gt;symlinks&lt;/code&gt; . Right after, I started it &lt;code&gt;systemctl start systemd-resolved.service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wiki.archlinux.org/title/Systemd-resolved#DNS" rel="noopener noreferrer"&gt;I replaced the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; by a &lt;em&gt;symlink&lt;/em&gt; &lt;code&gt;ln -sf ../run/systemd/resolve/stub-resolve.conf /etc/resolv.conf&lt;/code&gt;&lt;/a&gt;, the service had to be active, otherwise the runtime configuration (the file &lt;code&gt;/run/systemd/resolve/stub-resolve.conf&lt;/code&gt;) didn't exist and the &lt;em&gt;symlink&lt;/em&gt; creating would have failed.&lt;/p&gt;

&lt;p&gt;I checked the DNS currently in use with &lt;code&gt;resolvectl status&lt;/code&gt; and it was great, it gave me the DNS servers configured on my router.&lt;/p&gt;

&lt;p&gt;Last, I configured the Wi-FI through the &lt;code&gt;iwd&lt;/code&gt;, which I already installed in the &lt;a href="//./arch-linux-base-installation.md"&gt;base installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, &lt;a href="https://wiki.archlinux.org/title/Iwd#WPA-PSK" rel="noopener noreferrer"&gt;I created the &lt;code&gt;iwd&lt;/code&gt; network configuration file&lt;/a&gt; &lt;code&gt;/var/lib/iwd/foo.psk&lt;/code&gt;, where &lt;code&gt;foo&lt;/code&gt; is the SSID of my home Wi-FI network.&lt;/p&gt;

&lt;p&gt;I opened the file with the editor and wrote&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Security]
Passphrase=I typed here for you to know it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I started the service (&lt;code&gt;systemctl start iwd.service&lt;/code&gt;) and confirmed that I could ping some external sites.&lt;/p&gt;

&lt;p&gt;After this, I edited the above file to remove the passphrase because the pre-shared key was written it, so it doesn't need to be there anymore.&lt;/p&gt;

&lt;p&gt;Because, &lt;a href="https://wiki.archlinux.org/title/Iwd#Disable_periodic_scan_for_available_networks" rel="noopener noreferrer"&gt;I didn't want &lt;code&gt;iwd&lt;/code&gt; to scan periodically for networks when it's in a disconnected state&lt;/a&gt;, I created the &lt;code&gt;/etc/iwd/main.conf&lt;/code&gt; file, opened with the editor, and wrote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Scan]
DisablePeriodicScan=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least, I want the service to automatically start at boot, hence I enabled the service (&lt;code&gt;systemctl enable iwd.service&lt;/code&gt;), which created some &lt;em&gt;symlinks&lt;/em&gt; as before.&lt;/p&gt;

&lt;p&gt;This is all, I rebooted my computer and I could verify that it connects automatically to my home Wi-Fi network.&lt;/p&gt;

</description>
      <category>archlinux</category>
    </item>
    <item>
      <title>Base Arch Linux installation</title>
      <dc:creator>Ivan Fraixedes</dc:creator>
      <pubDate>Thu, 28 Mar 2024 09:45:23 +0000</pubDate>
      <link>https://forem.com/ifraixedes/base-arch-linux-installation-3299</link>
      <guid>https://forem.com/ifraixedes/base-arch-linux-installation-3299</guid>
      <description>&lt;p&gt;This post is part of a series of posts about installing and configuring Arch Linux in a &lt;a href="https://slimbook.com/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt; Executive 14". I created them from a collection of personal notes, that I thought may be useful for others, so I published them through these series.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Base Arch Linux installation&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-network-configuration-436i"&gt;Arch Linux network configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/tracking-dot-files-3emg"&gt;Tracking dot files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ifraixedes/arch-linux-essential-tweaks-and-applications-54bh"&gt; Arch Linux essential tweaks &amp;amp; applications&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I installed Arch Linux in my new laptop, an &lt;a href="https://slimbook.com/en/" rel="noopener noreferrer"&gt;Slimbook&lt;/a&gt; Executive 14".&lt;br&gt;
I followed the &lt;a href="https://wiki.archlinux.org/title/Installation_guide" rel="noopener noreferrer"&gt;official installation guide&lt;/a&gt;, however, I had to dig through different pages to install it how I wanted.&lt;/p&gt;

&lt;p&gt;My requirements were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypt the full disk with &lt;a href="https://en.wikipedia.org/wiki/Dm-crypt" rel="noopener noreferrer"&gt;dm-crypt&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://sourceware.org/lvm2/" rel="noopener noreferrer"&gt;LVM&lt;/a&gt; to manage disk partitions.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://en.wikipedia.org/wiki/Ext4" rel="noopener noreferrer"&gt;ext4&lt;/a&gt; file system.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating disk partitions
&lt;/h2&gt;

&lt;p&gt;I've mostly followed &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Overview" rel="noopener noreferrer"&gt;dm-crypt/Encrypting an entire system&lt;/a&gt;, but I summarize here my process with the options that I chose.&lt;/p&gt;

&lt;p&gt;The laptop has 1 TB of NVMe (Non-Volatile Memory Express) and I deliberately want to encrypt the full disk.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;dm-crypt&lt;/code&gt; scenario that I've chosen is &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Encrypted_boot_partition_(GRUB)" rel="noopener noreferrer"&gt;LVM on LUKS with encrypted boot partition&lt;/a&gt; over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The cool &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LUKS_on_a_partition_with_TPM2_and_Secure_Boot" rel="noopener noreferrer"&gt;Secure Boot and the Trusted Platform Module option&lt;/a&gt; because, despite, I have to annoyingly type a password every time that I boot the machine, it will be protected from boot &lt;a href="https://en.wikipedia.org/wiki/Cold_boot_attack" rel="noopener noreferrer"&gt;cool boot attacks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS" rel="noopener noreferrer"&gt;LVM on LUKS&lt;/a&gt; because I want to have everything encrypted, included the boot partition (which contains the &lt;a href="https://wiki.archlinux.org/title/Arch_boot_process#initramfs" rel="noopener noreferrer"&gt;initramfs&lt;/a&gt; and the kernel).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used  the ancient &lt;a href="https://www.man7.org/linux/man-pages/man8/fdisk.8.html" rel="noopener noreferrer"&gt;&lt;code&gt;fdisk&lt;/code&gt;&lt;/a&gt; to create in the only disk that the laptop has, which is mapped to the device &lt;code&gt;/dev/nvme0n1&lt;/code&gt;, all the partitions indicated in &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Preparing_the_disk_6" rel="noopener noreferrer"&gt;the "preparing the disk" section of LVM on LUKS with encrypted boot partition&lt;/a&gt;. The partitions ended up as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: Samsung SSD 980 PRO 1TB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: &amp;lt;redacted&amp;gt;

Device           Start        End    Sectors   Size Type
/dev/nvme0n1p1    2048       4095       2048     1M BIOS boot
/dev/nvme0n1p2    4096    2101247    2097152     1G EFI System
/dev/nvme0n1p3 2101248 1953523711 1951422464 930.5G Linux filesystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's encrypt the second partition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cyptsetup luksFormat --type luks1 /dev/nvme0n1p3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's mount it on &lt;code&gt;/dev/mapper/cyrptlvm&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cryptsetup open /dev/nvme0n1p3 cryptlvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we start with the LVM ceremony&lt;/p&gt;

&lt;p&gt;First of all, I create a  physical volume because I only have one hard disk&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pvcreate /dev/mapper/cryptlvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondly, one logical groups because I don't need an extra degree of isolation between volumes and it's more storage efficient than having multiples groups&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# vgcreate main /dev/mapper/cryptlvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And last, but not least, three logical volumes, one for swap, one for the root partition, and one for the home directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lvcreate -L 64G main -n swap
# lvcreate -L 430G main -n root
# lvcreate -l 100%FREE main -n home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may wonder why I'm booking 64 Gb for memory swap. It isn't because I'm scared of running short of RAM, this laptop has exactly 64 Gb. In the past I ran into hibernating issues because the swap partition was smaller than the size of the RAM, although nowadays, &lt;a href="https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation" rel="noopener noreferrer"&gt;the memory image for the hibernation can be store in a file and not only in a swap partition&lt;/a&gt; I preferred to keep it simple and use the swap partition for hibernating because I can afford to lose 64 Gb of disk from the other two partitions and, anyway, if I need to pull up that space, I could do it resizing the LVM volumes.&lt;/p&gt;

&lt;p&gt;Time to format the partitions, for the swap partition is a snap. For the other two, I decided to be conservative and use ext4, despite of the cool features that btrfs, I went for ensuring maturity and stability over better data integrity and error recovering and I don't need btrfs RAID, volume management, snapshots, and rollbacks because I already have LVM for them.&lt;/p&gt;

&lt;p&gt;So the boring stuff for that is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkfs.ext4 /dev/main/root
# mkfs.ext4 /dev/main/home
# mkswap /dev/main/swap
# mount /dev/main/root /mnt
# mount --mkdir /dev/main/home /mnt/home
# swapon /dev/main/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I chose to boot in UEFI mode, so mounted the partition in &lt;code&gt;/efi&lt;/code&gt; for compatibility with &lt;code&gt;grup-install&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkfs.fat -F32 -n EFI /dev/nvme0n1p2
# mount --mkdir /dev/nvme0n1p2 /mnt/efi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparation before installing
&lt;/h2&gt;

&lt;p&gt;First of all, we need an internet connection. The Arch Linux installation image comes with &lt;a href="https://wiki.archlinux.org/title/Iwd" rel="noopener noreferrer"&gt;iwd&lt;/a&gt;, and after I ensured that the Wi-FI network card was detected with &lt;code&gt;ip link&lt;/code&gt;, I followed the &lt;code&gt;iwctl&lt;/code&gt; commands  in the &lt;a href="https://wiki.archlinux.org/title/Iwd#Connect_to_a_network" rel="noopener noreferrer"&gt;connect to a network&lt;/a&gt; section.&lt;/p&gt;

&lt;p&gt;I ensured that the system clock is accurate with &lt;code&gt;timedateclt&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing essential packages
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacstrap -K /mnt base linux linux-firmware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Essential configurations
&lt;/h2&gt;

&lt;p&gt;I generate the &lt;code&gt;fstab&lt;/code&gt; file from the current mounted volumes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# genfstab -U /mnt &amp;gt;&amp;gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I changed the root directory to the root mounted volume, where we are installing Arch Linux.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I installed Neovim, which is the editor that I usually use, and I need one to be able to modify and create some configuration files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S neovim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the timezone&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ln -sf /usr/share/zoneinfo/Europe/Madrid /etc/localtime
# hwclock --systohc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I uncommented the &lt;code&gt;ca_ES.UTF-8 UTF-8&lt;/code&gt;, &lt;code&gt;es_ES.UTF-8 UTF-8&lt;/code&gt;, and &lt;code&gt;en_US.UTF-8 UTF-8&lt;/code&gt; from &lt;code&gt;/etc/locale.gen&lt;/code&gt; and generated the locales with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# locale-gen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created the file &lt;code&gt;/etc/locale.conf&lt;/code&gt; and write inside &lt;code&gt;LANG=en_US.UTF-8&lt;/code&gt; to set the &lt;code&gt;LANG&lt;/code&gt; variable accordingly.&lt;/p&gt;

&lt;p&gt;I configured the hostname writing &lt;code&gt;blacksmoke&lt;/code&gt; in &lt;code&gt;/etc/hostname&lt;/code&gt;, yes the laptop is called &lt;code&gt;blacksmoke&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I installed the &lt;code&gt;iwd&lt;/code&gt; network manager&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S iwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've decided to use a &lt;em&gt;systemd-based initramfs&lt;/em&gt;, so I  changed the &lt;a href="https://wiki.archlinux.org/title/Mkinitcpio#Configuration" rel="noopener noreferrer"&gt;&lt;code&gt;mkinitcpio.conf&lt;/code&gt;&lt;/a&gt;  (&lt;code&gt;/etc/mkinitcpio.conf&lt;/code&gt;)  from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOOKS=(base systemd autodetect microcode modconf kms keyboard block sd-encrypt lvm2 filesystems fsck)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; I swapped &lt;code&gt;udev&lt;/code&gt; by &lt;code&gt;systemd&lt;/code&gt;, added &lt;code&gt;sd-encrypt&lt;/code&gt; and &lt;code&gt;lvm2&lt;/code&gt; and removed &lt;code&gt;keymap&lt;/code&gt; and &lt;code&gt;consolefont&lt;/code&gt; because I'm fine with the US console keymap and the default console font.&lt;/p&gt;

&lt;p&gt;and I installed LVM because it's obviously needed due to my partitions are on top of LVM volumes, besides that &lt;code&gt;mkinitcpio&lt;/code&gt; needs is as you can see above that I added the &lt;code&gt;lvm2&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S lvm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right after, I regenerated the &lt;em&gt;initramfs&lt;/em&gt; running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkinitcpio -P
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I saw through the warnings printed in the console that Im missing a few firmwares. As commented in &lt;a href="https://wiki.archlinux.org/title/Mkinitcpio#Possibly_missing_firmware_for_module_XXXX" rel="noopener noreferrer"&gt;Mkinitcpio wiki page about "possible missing firmware for module XXXX&lt;/a&gt;, I had to install the Linux firmwares package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S linux-firmware linux-firmware-qlogic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it wasn't enough, and I had to install other firmwares from AUR packages, so let's go for them.&lt;/p&gt;

&lt;p&gt;As you may know, &lt;a href="https://wiki.archlinux.org/title/Arch_User_Repository" rel="noopener noreferrer"&gt;installing package from AUR repositories&lt;/a&gt; is totally different story than doing from main stream repositories, they are several tools that simplify the process by automating several manual steps, however, and I like them, but I want to decide which one to use, once I have the OS working, not at the installation time, so I installed them manually.&lt;/p&gt;

&lt;p&gt;First, I installed the required packages to build AUR packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S base-devel sudo git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I authorized all the users in the &lt;code&gt;wheel&lt;/code&gt; group creating the following file &lt;code&gt;/etc/sudoers.d/00-wheel-users&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%wheel ALL=(ALL:ALL) ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I ensured that only root can access to it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  chmod -c 0660 /etc/sudoers.d/00-wheel-users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://wiki.archlinux.org/title/Makepkg#Usage" rel="noopener noreferrer"&gt;&lt;code&gt;makepkg&lt;/code&gt; requires &lt;code&gt;sudo&lt;/code&gt;&lt;/a&gt;, so it was the time to create my regular user and set it's password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# useradd -c "Ivan Fraixedes" -m -U -G wheel ivan
# passwd ivan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I adjusted &lt;code&gt;/etc/makepkg.conf&lt;/code&gt; following the &lt;a href="https://wiki.archlinux.org/title/Makepkg#Tips_and_tricks" rel="noopener noreferrer"&gt;tips &amp;amp; trics&lt;/a&gt;, creating &lt;code&gt;/etc/makepkg.conf.d/makepkg.conf&lt;/code&gt; with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MAKEFLAGS="-j$(nproc)"

PKGDEST=~/.local/makepkg/packages
SRCDEST=~/.local/makepkg/sources
SRCPKGDEST=~/.local/makepkg/srcpackages
LOGDEST=~/.local/makepkg/logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I logged with my user and created the directories that I configured for &lt;code&gt;makepkg&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# su ivan
# cd ~
# mkdir -p .local/makepkg
# cd .local/makepkg
# mkdir logs packages sources srcpackages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I installed the following firmware from AUR doing (as &lt;code&gt;ivan&lt;/code&gt; user)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkdir -p tmp/aur
# cd tmp/aur
# git clone https://aur.archlinux.org/upd72020x-fw.git
# cd upd72020x-fw
# makepkg -sirc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same package installation call &lt;code&gt;mkinitcpio&lt;/code&gt; and I saw that there isn't a warning anymore for the &lt;code&gt;xhci-pci&lt;/code&gt; firmware, yup!&lt;br&gt;
I repeated the same process for the following AUR firmwares &lt;a href="https://aur.archlinux.org/packages/ast-firmware/" rel="noopener noreferrer"&gt;&lt;code&gt;ast&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://aur.archlinux.org/packages/aic94xx-firmware" rel="noopener noreferrer"&gt;&lt;code&gt;aic94xxx&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://aur.archlinux.org/packages/wd719x-firmware" rel="noopener noreferrer"&gt;&lt;code&gt;wd719x&lt;/code&gt;&lt;/a&gt;. Cha-ching no more warning when building the &lt;em&gt;initramfs&lt;/em&gt; with &lt;code&gt;mkinitcpio&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I installed the &lt;a href="https://wiki.archlinux.org/title/GRUB" rel="noopener noreferrer"&gt;GRUB&lt;/a&gt; boot loader and the &lt;a href="https://linux.die.net/man/8/efibootmgr" rel="noopener noreferrer"&gt;&lt;code&gt;efibootmgr&lt;/code&gt;&lt;/a&gt; which is required by GRUB for UEFI systems&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pacman -S grub efibootmgr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And configure it (&lt;code&gt;/etc/default/grub&lt;/code&gt;) to allow booting from &lt;code&gt;/boot&lt;/code&gt; on the encrypted partition and set the kernel parameters to allow &lt;em&gt;initramfs&lt;/em&gt; to unlock the encrypted root partition using the &lt;code&gt;sd-encrypt&lt;/code&gt; mkinitcpio's hook.&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt; these lines may not be together, some may be commented, and some may have other values that you may need to keep, in any case they will ended up with these values in a different machine (e.g. the disk UUID won't be the same), hence, check the &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Configuring_GRUB_2" rel="noopener noreferrer"&gt;configuring GRUB&lt;/a&gt; section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRUB_ENABLE_CRYPTODISK=y
GRUB_CMDLINE_LINUX="rd.luks.name=a199a1d7-acc0-4910-babb-e0059dec293b=cryptlvm"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What disk UUID should you add in the above GRUB's configuration? I think that's quite obvious, but I didn't think that much at that moment and I set to the UUID of the wrong one and, for obvious reasons, GRUB wasn't able to decrypt the volumen and boot the OS :(. It took me several hours to find out  my mistake  and with a lot of rebooting to try to see if I was fixing the issues for every change that I was making in &lt;code&gt;mkinitcpio.conf&lt;/code&gt;, &lt;code&gt;grub&lt;/code&gt;, etc., so pay attention and don't waste marvelous hours with this stupid mistake.&lt;/p&gt;

&lt;p&gt;It has to be the UUID of the LUKS partition where the &lt;code&gt;/boot&lt;/code&gt; is placed, NOT the LVM one! In my case is &lt;code&gt;/dev/nvme0n1p3&lt;/code&gt; and to find out UUID, you can do &lt;code&gt;ls -l /dev/disk/by-uuid&lt;/code&gt; and the link name that points to it is the UUID.&lt;/p&gt;

&lt;p&gt;I installed GRUB to be mounted ESP for UEFI booting and generated the GRUB's configuration file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck
# grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, at this point, I rebooted the computer and yes, after booting from its disk, it asked me for the LUKS password, then GRUB menu showed up, and, after selecting boot Arch, it asked me again for LUKS password. Brilliant, everything finally worked.&lt;/p&gt;

&lt;p&gt;Last, but not least and before finishing this blog post, I want to include here 2 things as an initial setup.&lt;/p&gt;

&lt;p&gt;I did a couple of more things which I consider that they are part of the base installation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set a password for the &lt;code&gt;root&lt;/code&gt; user, otherwise you cannot login with it. Yes, I want a password for it, I found sometimes useful in the past to be able to login as &lt;code&gt;root&lt;/code&gt; rather than my regular user.&lt;/li&gt;
&lt;li&gt;Add a &lt;em&gt;keyfile&lt;/em&gt; to the LUKS partition, so it can be used to decrypted automatically by GRUB and not having to type the LUKS passphrase twice.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After booting up, I login with my regular user &lt;code&gt;ivan&lt;/code&gt; and then, I access as root and change its password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# sudo su
# passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the root login, I set up the &lt;em&gt;keyfile&lt;/em&gt; for the LUKS volume following the &lt;a href="https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#With_a_keyfile_embedded_in_the_initramfs" rel="noopener noreferrer"&gt;"With a keyfile embedded in the initramfs" section of "dm-crypt/Device encryption" page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, I created the &lt;em&gt;keyfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# dd bs=512 count=4 if=/dev/random of=/root/cryptlvm.keyfile iflag=fullblock
# chmod 000 /root/cryptlvm.keyfile
# cryptsetup -v luksAddKey /dev/nvme0n1p3 /root/cryptlvm.keyfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added the &lt;em&gt;keyfile&lt;/em&gt; to the &lt;em&gt;initramfs&lt;/em&gt; image, that's just updating the &lt;code&gt;/etc/mkinicpio.conf&lt;/code&gt;, adding the file path to the &lt;code&gt;FILES&lt;/code&gt; list, in my case, &lt;code&gt;FILES&lt;/code&gt; was empty, so it changed from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FILES=()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FILES=(/root/cryptlvm.keyfile)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recreate the &lt;em&gt;initramfs&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkinitcpio -P
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secure the access to the embedded &lt;em&gt;keyfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# chmod 600 /boot/initramfs-linux*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update GRUB's configuration (i.e. &lt;code&gt;/etc/default/grub&lt;/code&gt;) to point to the &lt;em&gt;keyfile&lt;/em&gt;. Remember, that in my case, I'm using &lt;em&gt;systemd-based initramfs&lt;/em&gt; (i.e. &lt;code&gt;sd-encrypt&lt;/code&gt; hook). I my case, I added &lt;code&gt;rd.luks.key=a199a1d7-acc0-4910-babb-e0059dec293b=/root/cryptlvm.key&lt;/code&gt; to the &lt;code&gt;GRUB_CMDLINE_LINUX&lt;/code&gt;, so it changed from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRUB_CMDLINE_LINUX="rd.luks.name=a199a1d7-acc0-4910-babb-e0059dec293b=cryptlvm"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRUB_CMDLINE_LINUX="rd.luks.name=a199a1d7-acc0-4910-babb-e0059dec293b=cryptlvm rd.luks.key=a199a1d7-acc0-4910-babb-e0059dec293b=/root/cryptlvm.key"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And regenerate the GRUB's configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it for today, in future posts, I will cover what tools I'm installing and certain configurations that I tweaked to make my machine more comfortably usable.&lt;/p&gt;

</description>
      <category>archlinux</category>
    </item>
  </channel>
</rss>
