Skip to content
Henryk Paluch edited this page Sep 18, 2024 · 5 revisions

Alpine Linux

Alpine Linux is one of most lightweight Linux available to this days thanks to:

  • MUSL Runtime library (instead of glibc)
    • for example - Alpine /lib/ld-musl-x86_64.so.1 (linker and libc are same files) is just around 635KB long
    • openSUSE LEAP 15.6 glibc /lib64/libc.so.6 is around 2.4MB big (not counting locales that are memory mapped)
  • using OpenRC init system (no systemd)
  • basic system commands are provided by BusyBox

Homepage:

This document is very early draft...

Install via SSH

I plan to experiment with ZFS (but without encryption) - so I prefer to copy & paste commands on installation. To enable SSH I did this.

  • Booted alpine-extended-3.20.1-x86_64.iso from USB stick.
    apk update
    setup-interfaces
    # enter eth0 and confirm dhcp mode
    # replied 'done' for eth1
    # now you need to really activate network:
    /sbin/ifup eth0
    # now setup sshd - note: dropbear does not work - use default: openssh
    setup-sshd
    # set root password
    passwd root
    # use "ip a" or "ifconfig" to find IP address of Alpine Linux
  • now you can simply login from client machine using ssh root@ALPINE_IP

Now I plan to test ZFS setup from https://wiki.alpinelinux.org/wiki/Root_on_ZFS_with_native_encryption but skipping encryption:

First problem is that Alpine used crippled fdisk (actually busybox) which claims GPT support but it works in read-only mode for GPT - actually allows only MBR partitions editing. So we have to install something more usable, for example:

apk add parted

Now we have to prepare:

  • ext4 partition /boot (extlinux loader will be installed there)
  • another partition for ZFS root

Trying (I already have install FreeBSD on another ZFS partition):

parted /dev/sda

(parted) print                                                            
...
Number  Start   End     Size    File system  Name   Flags
 1      20.5kB  545kB   524kB
 2      1049kB  17.2GB  17.2GB               swap0
 3      17.2GB  125GB   107GB                disk0

Note: above 3 partitions are from FreeBSD 14.1 on ZFS - there is GPT+BIOS boot partition, FreeBSD swap partition and finally FreeBSD disk...

Trying to create /boot and / for Alpine

(parted) unit mb
(parted) print

Number  Start    End       Size      File system  Name   Flags
 1      0.02MB   0.54MB    0.52MB
 2      1.05MB   17181MB   17180MB                swap0
 3      17181MB  124555MB  107374MB               disk0

(parted) mkpart alpine-boot ext4 124555MB 124768MB
(parted) mkpart alpine-root ext4 124768MB 200000MB
(parted) mkpart alpine-swap linux-swap 200000MB 216000MB
(parted) print

Number  Start     End       Size      File system     Name         Flags
 1      0.02MB    0.54MB    0.52MB
 2      1.05MB    17181MB   17180MB                   swap0
 3      17181MB   124555MB  107374MB                  disk0
 4      124555MB  124768MB  213MB     ext4            alpine-boot
 5      124768MB  200000MB  75232MB   ext4            alpine-root
 6      200000MB  216000MB  16000MB   linux-swap(v1)  alpine-swap  swap

(parted) quit

Now let's continue:

mkswap -L alpine-swap /dev/sda6
swapon /dev/sda6
apk add e2fsprogs
mkfs.ext4 -L alpine-boot /dev/sda4

And now real stuff - ZFS:

apk add zfs sfdisk e2fsprogs syslinux

# replace /dev/sda5 with your ZFS partition !
zpool create -f -o ashift=12 \
-O acltype=posixacl -O canmount=off -O compression=lz4 \
-O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \
-O mountpoint=/ -R /mnt  zalpine /dev/sda5

mdev -s
zpool status
zfs create -o mountpoint=none -o canmount=off zalpine/ROOT
zfs create -o mountpoint=legacy zalpine/ROOT/alpine
mount -t zfs zalpine/ROOT/alpine /mnt/
mkdir /mnt/boot/
fdisk -l /dev/sda

# replace /dev/sda4 with your alpine-boot partition!
mount -t ext4 /dev/sda4 /mnt/boot/

WARNING! Now we diverge from original guide, we use just these commands:

DISKOPTS=/mnt setup-alpine
umount /mnt/boot
umount /mnt

Now disconnect reboot locally and pray :-)

Because I use FreeBSD loader as primary I have to do this to boot Alpine:

  • on BSD Loader go to console (press '3' to 'Escape to loader prompt')
  • issue lsdev to see partitions
  • to boot alpine I have to issue chain disk0p4: - including trailing colon !

Bugs:

  • Alpine Linux mercilessly import both its and also FreeBSD's pool - which may cause trouble (if it make some modification to it)
  • while FreeBSD works correctly and imports only its pool...

UEFI boot under LibVirt

If you create new VM under virt-manager in UEFI mode you have to select Firmware that that does NOT enforce "Secure" Boot, for example:

  • ovmf-x86_64-code

Only then will be Alpine able to boot under UEFI mode.

Here is example of correct firmware section in domain definition:

  <os firmware='efi'>
    <type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
    <firmware>
      <feature enabled='no' name='enrolled-keys'/>
      <feature enabled='no' name='secure-boot'/>
    </firmware>
    <loader readonly='yes' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader>
    <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/yourvmname_VARS.fd</nvram>
  </os>

You can also find that Cockit users have even to undergo more complicated ways to disable "Secure" Boot. See https://github.com/cockpit-project/cockpit-machines/issues/1220

Shell Edit keys

Shell (/bin/sh) is normally provided by BusyBox single binary, so some Bash hot keys do not work (for example ESC-. to repeat last argument from previous command).

You can see real list of editing keys in:

  • aports/main/busybox/src/busybox-1.36.1/libbb/lineedit.c

There are actually 2 possible shells in BusyBox:

  1. ash
  2. hush

One can find used shell with:

set | grep _VERSION
BB_ASH_VERSION='1.36.1'

(BB is common shortcut for "busybox"). So it is basically ash based shell.

Keys known to work (unless you turn on VI mode!):

  • Ctrl-R - backward search
  • Ctrl-A - (Home) begin of line
  • Ctrl-E - (End) end of line
  • Ctrl-F - (Right Arrow) - one character right
  • Ctrl-B - (Left Arrow) - one character left
  • Tab - completion
  • Ctrl-K - kill the text till end of line
  • Ctrl-L - clear/repaint screen - useful when some weird escape sequence clobbers prompt
  • Ctrl-N - (Down arrow) - next line in history
  • Ctrl-P - (Up Arrow) - prev line in history
  • Ctrl-U - clear line before cursor (inverse of Ctrl-K)
  • Ctrl-W - remove last word
  • Alt-D - delete word forward
  • Alt-backspace - delete work backward
  • Ctrl-Left or Alt-Left - jump one word back
  • Ctrl-Right or Alt-Right - jump one word forward

Ash and unsupported bash constructions:

  • curly brackets expansion:
    $ echo diff file.c{.orig,}
    
    # output under bash: diff file.c.orig file.c
    # output under ash:  diff file.c{.orig,}

Xen

I plan to play with Xen. I have to follow:

WARNING! Do NOT use GRUB with Xen Hypervisor - there are 2 bugs when using GRUB:

  1. incorrect kernel config detection (result: no Xen compatible kernel found, because GRUB expects kernel name with appended version, but current Alpine has only /boot/vmlinuz-lts without version suffix.
  2. Xen entries (generated with /etc/grub.d/20_linux_xen) will not extract root flags and/or modules from /etc/update-extlinux.conf (unlike regular GRUB entries generated by /etc/grub.d/10_linux). Adding them to /etc/default/grub will make them duplicate for regular entries.

So stick with syslinux - it should generate Xen configuration properly into /boot/extlinux.conf

Note: main "Xen standalone" command is xl - for example:

$ xl list

Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   384     2     r-----      36.8

$ xen-detect 

Running in PV context on Xen V4.18.

Domain-0 is special privileged VM (which you are on right-now) that has right to access hardware. Real VMs has to pass HW requests through Xen Hypervisor to this Domain-0 VM.

However we need to first create Bridge to be able to share single ethernet card with several Virtual Machines - follow:

To create real VM (called Domain-U - DomU in Xen) we can follow:

See also Xen wiki.

last (utmp) not working

Command last shows empty output. By defaults utmp defults to null. There is required special package utmps to make it work:

apk add utmps utmps-openrc
/sbin/setup-utmp
reboot

After reboot you should see login log with last command.

Extlinux limitations

Scenario - I installed Alpine as 2nd OS on disk with Windows in BIOS mode (so have to use MBR partitioning). I created ext4 partition from Extlinux boot media and installed Alpine usual way (formatting filesystem from Alpine boot media, mounted it under /mnt and install it with DISKOPTS=/mnt setup-alpine). But after reboot I got famous Extlinux error: Failed to load ldlinux.c32.

Here is my partition layout - note that I did NOT create /boot for extlinux because I would exhaust primary partitions (yes, I could use logical partitions, but I wanted to keep it simple):

evice  Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
/dev/sdb1 *  0,32,33     44,190,18         2048     718847     716800  350M  7 HPFS/NTFS
/dev/sdb2    44,190,19   1023,254,63     718848  835303087  834584240  397G  7 HPFS/NTFS
/dev/sdb3    1023,254,63 1023,254,63  835303424  925480959   90177536 43.0G 83 Linux
/dev/sdb4    1023,254,63 1023,254,63  925480960  937703087   12222128 5967M 82 Linux swap

There is single / filesystem on /dev/sdb3 that also contains /boot directory with extlinux.

Fortunately this Arch Linux forum post saved me:

Here is what I did (from Proxmox/Debian on other disk):

tune2fs -l /dev/sdb3

Filesystem features:      has_journal ext_attr resize_inode dir_index orphan_file filetype \
 extent 64bit flex_bg metadata_csum_seed sparse_super large_file huge_file dir_nlink extra_isize metadata_csum

e2fsck -f /dev/sdb3

tune2fs -l /dev/sdb3

Filesystem features:      has_journal ext_attr resize_inode dir_index orphan_file filetype \
 extent flex_bg metadata_csum_seed sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
  • Removing 64bit was enough to make this system bootable.
  • some sources mentions that even metadata_csum is problem, but in my case it works (so far).
Clone this wiki locally