Posts tagged tutorial


Genkernel in 2023

:: gentoo, kernel, linux, sysadmin, system, tutorial

By: Maciej Barć

I really wanted to look into the new kernel building solutions for Gentoo and maybe migrate to dracut, but last time I tried, ~1.5 years ago, the initreamfs was now working for me.

And now in 2023 I’m still running genkernel for my personal boxes as well as other servers running Gentoo.

I guess some short term solutions really become defined tools :P

So this is how I rebuild my kernel nowadays:

  1. Copy old config

    1
    2
    cd /usr/src
    cp linux-6.1.38-gentoo/.config linux-6.1.41-gentoo/
    
  2. Remove old kernel build directories

    1
    rm -r linux-6.1.31-gentoo
    
  3. Run initial preparation

    1
    ( eselect kernel set 1 && cd /usr/src/linux && make olddefconfig )
    
  4. Call genkernel

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    genkernel                                                       \
        --no-menuconfig                                             \
        --no-clean                                                  \
        --no-clear-cachedir                                         \
        --no-cleanup                                                \
        --no-mrproper                                               \
        --lvm                                                       \
        --luks                                                      \
        --mdadm                                                     \
        --nfs                                                       \
        --kernel-localversion="-$(hostname)-$(date '+%Y.%m.%d')"    \
        all
    
  5. Rebuild the modules

    If in your /etc/genkernel.conf you have MODULEREBUILD turned off, then also call emerge:

    1
    emerge -1 @module-rebuild
    

Debugging Frog blog with syntax macros

:: blog, language, lisp, macro, programming, racket, scheme, tutorial

By: Maciej Barć

Constructing debugging syntax

I wanted to echo parameter values when I set them in my blog’s frog.rkt config file.

Nothing simpler in Racket!

First I create this macro for echoing a single parameter value when it is set:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
(define-syntax-rule (verbose-set-parameter parameter-id parameter-value)
  (begin
    ;; Set the parameter.
    (parameter-id parameter-value)

    ;; Then call the parameter and print is's value.
    ;; The "'parameter-id" is special syntax
    ;; for turning a "parameter-id" identifier to a symbol.
    ;; We can also write it like:
    ;; > (quote parameter-id)
    ;; to be less confusing.
    (printf "[DEBUG] (~a ~v)\n" 'parameter-id (parameter-id))))

then, I create a wrapper for above macro that can take multiple parameter pairs:

1
2
3
4
5
(define-syntax-rule (verbose-set-parameters (parameter-id parameter-value) ...)
  (begin
    ;; Unpack a chain of "(parameter-id parameter-value)" pairs
    ;; using the "..." syntax.
    (verbose-set-parameter parameter-id parameter-value) ...))

Using the macro

Afterwards we can call it like so:

1
2
3
(verbose-set-parameters
 (current-title "XGQT's blog")
 (current-author "Maciej Barć"))

Notice that even the form of setting a parameter, that is (parameter-procedure "value"), remains the same, but in reality it is just similar to how the syntax macro pattern-matches on it.

Inspecting macro expansion

In racket-mode inside GNU Emacs we can inspect the macro expansion with racket-expand-region. Stepping through the expansion provided this result:

1
2
3
4
5
6
7
(begin
  (begin
    (current-title "XGQT's blog")
    (printf "[DEBUG] (~a ~v)\n" 'current-title (current-title)))
  (begin
    (current-author "Maciej Barć")
    (printf "[DEBUG] (~a ~v)\n" 'current-author (current-author))))

Comparing objects in Racket

:: lisp, programming language, racket, scheme, tutorial

By: Maciej Barć

Equality methods

By implementing a method for equality equal-to? and two extraction methods equal-hash-code-of and equal-secondary-hash-code-of we can define our own object comparison rules.

For more info see Object Equality and Hashing.

Consider the following example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
(define integer%
  (class* object% (equal<%>)
    (super-new)

    (init-field [value 0])

    (define/public (equal-to? other-object recur)
      (= value (get-field value other-object)))

    (define/public (equal-hash-code-of hash-code)
      (hash-code value))

    (define/public (equal-secondary-hash-code-of hash-code)
      (hash-code value))))

If we create a new integer% object we can notice that it is not transparent (we can not inspect values of any of it’s fields).

1
2
(new integer%)
;;  => (object:integer% ...)

But if we compare two fresh integer% objects they will be equal.

1
2
(equal? (new integer%) (new integer%))
;;  => #true

Transparent class

A transparent cvlass is a class with the inspect expression valuye se to #false.

From Racket documentation Creating Classes:

Just as for structure types, an inspector controls access to the class’s fields, including private fields, and also affects comparisons using equal?.

Consider the following example:

1
2
3
4
5
6
7
8
(define integer%
  (class object%

    (super-new)

    (inspect #false)

    (init-field [value 0])))

If we create a new integer% object we can see it’s field values.

1
2
(new integer%)
;;  => (object:integer% 0)

And if we compare two fresh integer% objects they will be equal.

1
2
(equal? (new integer%) (new integer%))
;;  => #true

Runing nginx under a local user

:: admin, http, network, nginx, server, tutorial

By: Maciej Barć

Config

First let’s prepare a suitable nginx configuration file.

This one is pretty bare but it works well for our case:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
worker_processes 1;
daemon off;
pid ./nginx/temp/nginx.pid;

error_log /dev/stdout info;

events {
    worker_connections 1024;
}

http {
    client_body_temp_path ./nginx/temp/client 1 2;
    proxy_temp_path ./nginx/temp/proxy;
    fastcgi_temp_path ./nginx/temp/fastcgi;
    uwsgi_temp_path ./nginx/temp/uwsgi;
    scgi_temp_path ./nginx/temp/scgi;

    server {
        listen 127.0.0.1:8080;
        server_name localhost;

        access_log /dev/stdout;
        error_log /dev/stdout info;

        root ./;

        location / {
            autoindex on;
        }
    }
}

Server config is set up for serving all static files from the current directory.

Startup

Preparation

Based on how you want to store _temp_path files it might be necessary to create (or clean up) additional directories, for example:

1
2
rm -r ./nginx/temp
mkdir -p ./nginx/temp

Run in current directory

1
nginx -c ./nginx.conf -p ./

BTW, you may want to replace ./ with "$(pwd)" and occurrences in the config with static paths.

Bonus: other simple servers

Some of no-dependency-except-itself http servers it’s good to know about:

Python http.server

1
python3 -m http.server -b 127.0.0.1 8080

Busybox

1
busybox httpd -f -p 127.0.0.1:8080 -v

You can read more about configuring busybox’s httpd on OpenWRT docs.

Bubblewrap cross-architecture chroot

:: chroot, emulation, gentoo, linux, sandbox, system, tutorial, virtualization, vm

By: Maciej Barć

System preparation

Qemu

Emerge qemu with static-user USE enabled and your wanted architectures.

1
2
3
4
5
6
7
8
app-emulation/qemu      QEMU_SOFTMMU_TARGETS: aarch64 arm x86_64
app-emulation/qemu      QEMU_USER_TARGETS: aarch64 arm x86_64

app-emulation/qemu      static-user
dev-libs/glib           static-libs
sys-apps/attr           static-libs
sys-libs/zlib           static-libs
dev-libs/libpcre2       static-libs

OpenRC

Enable qemu-binfmt:

1
rc-update add qemu-binfmt default

Start qemu-binfmt:

1
rc-service qemu-binfmt start

Chrooting

  • select chroot location (eg /chroots/gentoo-arm64-musl-stable)
  • unpack the desired rootfs
  • create needed directories
    • mkdir -p /chroots/gentoo-arm64-musl-stable/var/cache/distfiles
  • execute bwrap
    • with last ro-bind mount the qemu emulator binary (eg qemu-aarch64)
    • execute the mounted emulator binary giving it a shell program (eg bash)

Chroot with bwrap:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
bwrap                                                       \
    --bind /chroots/gentoo-arm64-musl-stable /              \
    --dev /dev                                              \
    --proc /proc                                            \
    --perms 1777 --tmpfs /dev/shm                           \
    --tmpfs /run                                            \
    --ro-bind /etc/resolv.conf /etc/resolv.conf             \
    --bind /var/cache/distfiles /var/cache/distfiles        \
    --ro-bind /usr/bin/qemu-aarch64 /usr/bin/qemu-aarch64   \
    /usr/bin/qemu-aarch64 /bin/bash -l