<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dju92</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dju92"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Dju92"/>
	<updated>2026-05-05T13:26:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:ZFS&amp;diff=26715</id>
		<title>Talk:ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:ZFS&amp;diff=26715"/>
		<updated>2024-05-13T17:45:15Z</updated>

		<summary type="html">&lt;p&gt;Dju92: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Autotrim ==&lt;br /&gt;
&lt;br /&gt;
In the [[ZFS_scrub_and_trim#Definition_2|Definition]] section:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting. See the &amp;lt;b&amp;gt;documentation&amp;lt;/b&amp;gt; for the autotrim property &amp;lt;b&amp;gt;above&amp;lt;/b&amp;gt; for the types of vdev devices which can be trimmed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The documentation needs to be linked to. It&#039;s not above. 🤔&amp;lt;br&amp;gt;&lt;br /&gt;
Thanks, &amp;amp;ndash;[[User:zcrayfish|zcrayfish]] &amp;lt;small&amp;gt;([[User talk:zcrayfish|talk]]•[[Special:Contributions/zcrayfish|contribs]]•[[Special:EmailUser/zcrayfish|send email]])&amp;lt;/small&amp;gt; 01:17, 12 May 2024 (UTC)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
-----&lt;br /&gt;
Indeed, nice catch.&amp;lt;br&amp;gt;&lt;br /&gt;
i updated the page to correct it, and add the link to the autotrim documentation ;)&amp;lt;br&amp;gt;&lt;br /&gt;
Dju92&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=26714</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=26714"/>
		<updated>2024-05-13T17:40:54Z</updated>

		<summary type="html">&lt;p&gt;Dju92: Correction + link to autotrim documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine Linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other Linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.&lt;br /&gt;
&lt;br /&gt;
Also see [https://blogs.oracle.com/oracle-systems/post/disk-scrub-why-and-when Oracle - Disk Scrub - Why and When?]&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in {{path|/usr/libexec/zfs/scrub}}&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
{{cat|/usr/libexec/zfs/scrub|&amp;lt;nowiki&amp;gt;#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
{{cmd|# chmod +x /usr/libexec/zfs/scrub}}&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
{{cmd|# crontab -e}}&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
{{cmd|# rc-update}}&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
{{cmd|# rc-update add crond}}&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
{{cmd|# rc-service crond start}}&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
Initiates an immediate on-demand TRIM operation for all of the free space in a pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space.&amp;lt;br&amp;gt;&lt;br /&gt;
A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting.&lt;br /&gt;
See the [https://openzfs.github.io/openzfs-docs/man/v2.2/7/zpoolprops.7.html#autotrim documentation for the autotrim property] for the types of vdev devices which can be trimmed.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, build only with NVME ssd drive(s) and no trim is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in {{path|/usr/libexec/zfs/trim}}&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
{{cat|/usr/libexec/zfs/trim|&amp;lt;nowiki&amp;gt;#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-trim&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trim_if_not_already_trimming () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;trimming&amp;quot;; then&lt;br /&gt;
                # Ignore errors (i.e. HDD pools),&lt;br /&gt;
                # and continue with trimming other pools.&lt;br /&gt;
                zpool trim &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
zpool_is_nvme_only () {&lt;br /&gt;
        zpool=$1&lt;br /&gt;
        # get a list of devices attached to the specified zpool&lt;br /&gt;
        zpool list -vHPL &amp;quot;${zpool}&amp;quot; |&lt;br /&gt;
                awk -F&#039;\t&#039; &#039;$2 ~ /^\/dev\// {&lt;br /&gt;
                        if($2 !~ /^\/dev\/nvme/)&lt;br /&gt;
                                exit 1&lt;br /&gt;
                }&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# TRIM all healthy pools that are not already trimming as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                if zpool_is_nvme_only &amp;quot;${pool}&amp;quot;; then&lt;br /&gt;
                        trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
                fi&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
{{cmd|# chmod +x /usr/libexec/zfs/trim}}&lt;br /&gt;
&lt;br /&gt;
== Launching the trim script with cron ==&lt;br /&gt;
&lt;br /&gt;
Here, the trim will be launched once a month, on the 1st sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
{{cmd|# crontab -e}}&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs trim the first sunday of every month&lt;br /&gt;
24      0       1-7    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/trim ]; then /usr/libexec/zfs/trim; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
{{cmd|# rc-update}}&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
{{cmd|# rc-update add crond}}&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
{{cmd|# rc-service crond start}}&lt;br /&gt;
&lt;br /&gt;
[[Category:File systems]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=26701</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=26701"/>
		<updated>2024-05-10T20:25:05Z</updated>

		<summary type="html">&lt;p&gt;Dju92: typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine Linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other Linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.&lt;br /&gt;
&lt;br /&gt;
Also see [https://blogs.oracle.com/oracle-systems/post/disk-scrub-why-and-when Oracle - Disk Scrub - Why and When?]&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in {{path|/usr/libexec/zfs/scrub}}&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
{{cat|/usr/libexec/zfs/scrub|&amp;lt;nowiki&amp;gt;#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
{{cmd|# chmod +x /usr/libexec/zfs/scrub}}&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
{{cmd|# crontab -e}}&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
{{cmd|# rc-update}}&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
{{cmd|# rc-update add crond}}&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
{{cmd|# rc-service crond start}}&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
Initiates an immediate on-demand TRIM operation for all of the free space in a pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space.&amp;lt;br&amp;gt;&lt;br /&gt;
A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting. See the documentation for the autotrim property above for the types of vdev devices which can be trimmed.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, build only with NVME ssd drive(s) and no trim is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in {{path|/usr/libexec/zfs/trim}}&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
{{cat|/usr/libexec/zfs/trim|&amp;lt;nowiki&amp;gt;#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-trim&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trim_if_not_already_trimming () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;trimming&amp;quot;; then&lt;br /&gt;
                # Ignore errors (i.e. HDD pools),&lt;br /&gt;
                # and continue with trimming other pools.&lt;br /&gt;
                zpool trim &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
zpool_is_nvme_only () {&lt;br /&gt;
        zpool=$1&lt;br /&gt;
        # get a list of devices attached to the specified zpool&lt;br /&gt;
        zpool list -vHPL &amp;quot;${zpool}&amp;quot; |&lt;br /&gt;
                awk -F&#039;\t&#039; &#039;$2 ~ /^\/dev\// {&lt;br /&gt;
                        if($2 !~ /^\/dev\/nvme/)&lt;br /&gt;
                                exit 1&lt;br /&gt;
                }&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# TRIM all healthy pools that are not already trimming as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                if zpool_is_nvme_only &amp;quot;${pool}&amp;quot;; then&lt;br /&gt;
                        trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
                fi&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
{{cmd|# chmod +x /usr/libexec/zfs/trim}}&lt;br /&gt;
&lt;br /&gt;
== Launching the trim script with cron ==&lt;br /&gt;
&lt;br /&gt;
Here, the trim will be launched once a month, on the 1st sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
{{cmd|# crontab -e}}&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs trim the first sunday of every month&lt;br /&gt;
24      0       1-7    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/trim ]; then /usr/libexec/zfs/trim; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
{{cmd|# rc-update}}&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
{{cmd|# rc-update add crond}}&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
{{cmd|# rc-service crond start}}&lt;br /&gt;
&lt;br /&gt;
[[Category:File systems]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24445</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24445"/>
		<updated>2023-08-25T01:34:54Z</updated>

		<summary type="html">&lt;p&gt;Dju92: small typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine Linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other Linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.&lt;br /&gt;
&lt;br /&gt;
Also see [https://blogs.oracle.com/oracle-systems/post/disk-scrub-why-and-when Oracle - Disk Scrub - Why and When?]&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/scrub&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/scrub&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
Initiates an immediate on-demand TRIM operation for all of the free space in a pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space.&amp;lt;br&amp;gt;&lt;br /&gt;
A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting. See the documentation for the autotrim property above for the types of vdev devices which can be trimmed.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, build only with NVME ssd drive(s) and no trim is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/trim&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-trim&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trim_if_not_already_trimming () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;trimming&amp;quot;; then&lt;br /&gt;
                # Ignore errors (i.e. HDD pools),&lt;br /&gt;
                # and continue with trimming other pools.&lt;br /&gt;
                zpool trim &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
zpool_is_nvme_only () {&lt;br /&gt;
        zpool=$1&lt;br /&gt;
        # get a list of devices attached to the specified zpool&lt;br /&gt;
        zpool list -vHPL &amp;quot;${zpool}&amp;quot; |&lt;br /&gt;
                awk -F&#039;\t&#039; &#039;$2 ~ /^\/dev\// {&lt;br /&gt;
                        if($2 !~ /^\/dev\/nvme/)&lt;br /&gt;
                                exit 1&lt;br /&gt;
                }&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# TRIM all healthy pools that are not already trimming as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                if zpool_is_nvme_only &amp;quot;${pool}&amp;quot;; then&lt;br /&gt;
                        trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
                fi&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/trim&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
Here, the scrub will be launched once a month, on the 1st sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs trim the first sunday of every month&lt;br /&gt;
24      0       1-7    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/trim ]; then /usr/libexec/zfs/trim; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24419</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24419"/>
		<updated>2023-08-24T22:25:09Z</updated>

		<summary type="html">&lt;p&gt;Dju92: /* Definition */ added oracle explanation on scrub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine Linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other Linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.&lt;br /&gt;
&lt;br /&gt;
Alo see [https://blogs.oracle.com/oracle-systems/post/disk-scrub-why-and-when Oracle - Disk Scrub - Why and When?]&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/scrub&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/script&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
Initiates an immediate on-demand TRIM operation for all of the free space in a pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space.&amp;lt;br&amp;gt;&lt;br /&gt;
A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting. See the documentation for the autotrim property above for the types of vdev devices which can be trimmed.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, build only with NVME ssd drive(s) and no trim is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/trim&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-trim&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trim_if_not_already_trimming () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;trimming&amp;quot;; then&lt;br /&gt;
                # Ignore errors (i.e. HDD pools),&lt;br /&gt;
                # and continue with trimming other pools.&lt;br /&gt;
                zpool trim &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
zpool_is_nvme_only () {&lt;br /&gt;
        zpool=$1&lt;br /&gt;
        # get a list of devices attached to the specified zpool&lt;br /&gt;
        zpool list -vHPL &amp;quot;${zpool}&amp;quot; |&lt;br /&gt;
                awk -F&#039;\t&#039; &#039;$2 ~ /^\/dev\// {&lt;br /&gt;
                        if($2 !~ /^\/dev\/nvme/)&lt;br /&gt;
                                exit 1&lt;br /&gt;
                }&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# TRIM all healthy pools that are not already trimming as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                if zpool_is_nvme_only &amp;quot;${pool}&amp;quot;; then&lt;br /&gt;
                        trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
                fi&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/trim&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
Here, the scrub will be launched once a month, on the 1st sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs trim the first sunday of every month&lt;br /&gt;
24      0       1-7    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/trim ]; then /usr/libexec/zfs/trim; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24418</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24418"/>
		<updated>2023-08-24T22:17:19Z</updated>

		<summary type="html">&lt;p&gt;Dju92: added the trim part, corrected a few typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine Linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other Linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/scrub&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/script&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommended to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
Initiates an immediate on-demand TRIM operation for all of the free space in a pool. This operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space.&amp;lt;br&amp;gt;&lt;br /&gt;
A manual on-demand TRIM operation can be initiated irrespective of the autotrim pool property setting. See the documentation for the autotrim property above for the types of vdev devices which can be trimmed.&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, build only with NVME ssd drive(s) and no trim is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/trim&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-trim&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
trim_if_not_already_trimming () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;trimming&amp;quot;; then&lt;br /&gt;
                # Ignore errors (i.e. HDD pools),&lt;br /&gt;
                # and continue with trimming other pools.&lt;br /&gt;
                zpool trim &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
zpool_is_nvme_only () {&lt;br /&gt;
        zpool=$1&lt;br /&gt;
        # get a list of devices attached to the specified zpool&lt;br /&gt;
        zpool list -vHPL &amp;quot;${zpool}&amp;quot; |&lt;br /&gt;
                awk -F&#039;\t&#039; &#039;$2 ~ /^\/dev\// {&lt;br /&gt;
                        if($2 !~ /^\/dev\/nvme/)&lt;br /&gt;
                                exit 1&lt;br /&gt;
                }&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# TRIM all healthy pools that are not already trimming as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                if zpool_is_nvme_only &amp;quot;${pool}&amp;quot;; then&lt;br /&gt;
                        trim_if_not_already_trimming &amp;quot;${pool}&amp;quot;&lt;br /&gt;
                fi&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/trim&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
Here, the scrub will be launched once a month, on the 1st sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs trim the first sunday of every month&lt;br /&gt;
24      0       1-7    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/trim ]; then /usr/libexec/zfs/trim; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a line saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=24417</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=24417"/>
		<updated>2023-08-24T21:58:11Z</updated>

		<summary type="html">&lt;p&gt;Dju92: /* Storage */ added zfs scrub/trim&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Todo|This material has been re-organized..., but grouping should be checked: &#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; and &#039;&#039;&#039;tutorials are more detailed document&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
[[Image:package_edutainment.svg|right|link=]]&lt;br /&gt;
{{TOC left}}&lt;br /&gt;
&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The tutorials are hands-on&#039;&#039;&#039; and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good example. The output in one step is the starting point for the following step.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; explaining how to perform a particular task with Alpine Linux, that expects a minimal knowledge from reader to perform actions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; contributions on those pages must be complete articles as well as requesting topics to be covered, don&#039;t override already made contributions. If you want to request a topic, please add your request in this page&#039;s [[Talk:Tutorials_and_Howtos|Discussion]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
= Howtos =&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[Ansible]] &#039;&#039;(Configuration management)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Monitoring ===&lt;br /&gt;
&lt;br /&gt;
* [[Awstats]] &#039;&#039;(Free log file analyzer)&#039;&#039;&lt;br /&gt;
* [[Cacti: traffic analysis and monitoring network]] &#039;&#039;(Front-end for rrdtool networking monitor)&#039;&#039;&lt;br /&gt;
* [[Cvechecker]] &#039;&#039;(Compare installed packages for Common Vulnerabilities Exposure)&#039;&#039; &amp;lt;!-- Monitoring and Security --&amp;gt;&lt;br /&gt;
* [[Dglog]] &#039;&#039;(Log analyzer for the web content filter DansGuardian)&#039;&#039;&lt;br /&gt;
* [[Linfo]]&lt;br /&gt;
* [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[PhpSysInfo]] &#039;&#039;(A simple application that displays information about the host it&#039;s running on)&#039;&#039;&lt;br /&gt;
* [[Piwik]] &#039;&#039;(A real time web analytics software program)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft, solution, Networking and Monitoring and Server --&amp;gt;&lt;br /&gt;
** [[Setting up NRPE daemon]] &#039;&#039;(Performs remote Nagios checks)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting Up Fprobe And Ntop|Ntop]] &#039;&#039;(NetFlow collection and analysis using a remote fprobe instance)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
* [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Traffic monitoring]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
** [[Setting up monitoring using rrdtool (and rrdcollect)]]&lt;br /&gt;
** [[Setting up traffic monitoring using rrdtool (and snmp)]] &amp;lt;!-- Monitoring --&amp;gt;&lt;br /&gt;
* [[Zabbix|Zabbix - the professional complete manager]] &#039;&#039;(Monitor and track the status of network services and hardware)&#039;&#039;&lt;br /&gt;
* [[ZoneMinder video camera security and surveillance]]&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
&lt;br /&gt;
* Alpine Wall &#039;&#039;(a new firewall management framework)&#039;&#039;&lt;br /&gt;
** [[Alpine Wall]]&lt;br /&gt;
** [[Alpine Wall User&#039;s Guide]] &lt;br /&gt;
** [[How-To Alpine Wall]]&lt;br /&gt;
* [[Freeradius Active Directory Integration]]&lt;br /&gt;
* [[GNUnet]]&lt;br /&gt;
* [[Setting up a OpenVPN server|OpenVPN server]] &#039;&#039;(Allowing single users or devices to remotely connect to your network)&#039;&#039;&lt;br /&gt;
* [[OpenVSwitch]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
* [[Configure a Wireguard interface (wg)|Wireguard]]&lt;br /&gt;
&lt;br /&gt;
=== Telephony ===&lt;br /&gt;
&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[FreePBX V3]] &#039;&#039;(FreeSWITCH, Asterisk GUI web acces tool)&#039;&#039;&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
* [[Kamailio]] &#039;&#039;(SIP Server, formerly OpenSER)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Backup and data migration ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]]&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
* [[Migrating data]]&lt;br /&gt;
* [[Rsnapshot]] - setting up periodic backups&lt;br /&gt;
&lt;br /&gt;
== Desktop ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine and UEFI]]&lt;br /&gt;
* [[Default applications]]&lt;br /&gt;
* Desktop cloud&lt;br /&gt;
** [[Nextcloud]] &#039;&#039;(Self hostable cloud suite - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
** [[OwnCloud]] &#039;&#039;(Installing OwnCloud)&#039;&#039;&lt;br /&gt;
** [[Seafile: setting up your own private cloud]]&lt;br /&gt;
* [[Desktop environments and Window managers]] (overall information only)&lt;br /&gt;
* [[Printer Setup]]&lt;br /&gt;
* [[Remote Desktop Server]]&lt;br /&gt;
* [[Sound Setup]]&lt;br /&gt;
** [[PipeWire]]&lt;br /&gt;
* [[Suspend on LID close]]&lt;br /&gt;
* [[Alpine setup scripts#setup-xorg-base|Xorg Setup]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
* [[Bluetooth]] - Instructions for installing and configuring Bluetooth&lt;br /&gt;
* [[Bonding]] - Bond (or aggregate) multiple ethernet interfaces&lt;br /&gt;
* [[Bridge]] - Configuring a network bridge&lt;br /&gt;
** [[Bridge wlan0 to eth0]]&lt;br /&gt;
* [[Configure Networking]]&lt;br /&gt;
* [[How to configure static routes]]&lt;br /&gt;
* Modem&lt;br /&gt;
** [[Using HSDPA modem]]&lt;br /&gt;
** [[Using serial modem]]&lt;br /&gt;
* [[Multi ISP]] &#039;&#039;(Dual-ISP setup with load-balancing and automatic failover)&#039;&#039;&lt;br /&gt;
* [[PXE boot]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection|Satellite Internet Connection setup]]&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
** [[Wi-Fi|Connecting to a wireless access point]]&lt;br /&gt;
** [[How to setup a wireless access point]] &#039;&#039;(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)&#039;&#039;&lt;br /&gt;
* [[Vlan]]&lt;br /&gt;
&lt;br /&gt;
== Other Architectures ==&lt;br /&gt;
&lt;br /&gt;
=== ARM ===&lt;br /&gt;
&lt;br /&gt;
* [[Alpine on ARM]]&lt;br /&gt;
&lt;br /&gt;
==== Raspberry Pi ====&lt;br /&gt;
&lt;br /&gt;
* [[Raspberry Pi Bluetooth Speaker|Raspberry Pi - Bluetooth Speaker]]&lt;br /&gt;
* [[Raspberry Pi|Raspberry Pi - Installation]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi|Raspberry Pi - Router with VPN]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi (IPv6)|Raspberry Pi - Router with VPN (IPv6)]]&lt;br /&gt;
* [[Classic install or sys mode on Raspberry Pi|Raspberry Pi - Sys mode install]]&lt;br /&gt;
* [[RPI Video Receiver|Raspberry Pi - Video Receiver]] &#039;&#039;(network video decoder using Rasperry Pi and omxplayer)&#039;&#039;&lt;br /&gt;
* [[Raspberry Pi 3 - Browser Client]] - kiosk or digital sign&lt;br /&gt;
* [[Raspberry Pi 3 - Configuring it as wireless access point -AP Mode]]&lt;br /&gt;
* [[Raspberry Pi 3 - Setting Up Bluetooth]]&lt;br /&gt;
* [[Raspberry Pi 4 - Persistent system acting as a NAS and Time Machine]]&lt;br /&gt;
* [[How to set up Alpine as a wireless router|Raspberry Pi Zero W - Wireless router]] &#039;&#039;(Setting up a firewalled, Wireless AP with wired network on a Pi Zero W)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IBM Z (IBM z Systems) ===&lt;br /&gt;
&lt;br /&gt;
* [[s390x|s390x - Installation]]&lt;br /&gt;
&lt;br /&gt;
=== PowerPC ===&lt;br /&gt;
&lt;br /&gt;
* [[Ppc64le|Powerpc64le - Installation]]&lt;br /&gt;
&lt;br /&gt;
== Post-Install ==&lt;br /&gt;
&lt;br /&gt;
* [[CPU frequency scaling]]&lt;br /&gt;
* [[Repositories#Enabling_the_community_repository|Enable Community repository]] &#039;&#039;(Providing additional packages)&#039;&#039;&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
* [[Alpine Linux Init System|Init System (OpenRC)]] &#039;&#039;(Configure a service to automatically boot at next reboot)&#039;&#039;&lt;br /&gt;
** [[Multiple Instances of Services|Init System - Multiple Instances of Services]]&lt;br /&gt;
** [[Writing Init Scripts|Init System - Writing Init Scripts]]&lt;br /&gt;
* [[Installing Oracle Java|Oracle Java (installation)]]&lt;br /&gt;
* [[IGMPproxy]]&lt;br /&gt;
* [[Alpine Linux package management|Package Management (apk)]] &#039;&#039;(How to add/remove packages on your Alpine)&#039;&#039;&lt;br /&gt;
** [[Comparison with other distros|Package Management - Comparison with other distros]]&lt;br /&gt;
* [[Running glibc programs]]&lt;br /&gt;
* [[Setting up a new user]]&lt;br /&gt;
* [[Upgrading Alpine]]&lt;br /&gt;
&lt;br /&gt;
== Remote Administration ==&lt;br /&gt;
&lt;br /&gt;
* ACF&lt;br /&gt;
** [[Changing passwords for ACF|ACF - changing passwords]]&lt;br /&gt;
** [[Generating SSL certs with ACF]] &amp;lt;!-- Generating SSL certs with ACF 1.9 --&amp;gt;&lt;br /&gt;
** [[setup-acf| ACF - setup]] &#039;&#039;(Configures ACF (webconfiguration/webmin) so you can manage your box through https)&#039;&#039;&lt;br /&gt;
* [[Setting up a SSH server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
** [[HOWTO OpenSSH 2FA with password and Google Authenticator |OpenSSH 2FA]] &#039;&#039;(A simple two factor setup for OpenSSH)&#039;&#039;&lt;br /&gt;
* [[OpenVCP]] &#039;&#039;(VServer Control Panel)&#039;&#039;&lt;br /&gt;
* [[PhpMyAdmin]] &#039;&#039;(Web-based administration tool for MYSQL)&#039;&#039;&lt;br /&gt;
* [[PhpPgAdmin]] &#039;&#039;(Web-based administration tool for PostgreSQL)&#039;&#039;&lt;br /&gt;
* [[Webmin]] &#039;&#039;(A web-based interface for Linux system)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(Hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
* [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
&lt;br /&gt;
* [[DNSCrypt-Proxy]] &#039;&#039;Encrypt and authenticate DNS calls from your system&#039;&#039;&lt;br /&gt;
* [[Setting up nsd DNS server]]&lt;br /&gt;
* [[Setting up unbound DNS server]]&lt;br /&gt;
* [[TinyDNS Format]]&lt;br /&gt;
&lt;br /&gt;
=== HTTP ===&lt;br /&gt;
&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
** [[Apache with php-fpm]]&lt;br /&gt;
** [[Setting Up Apache with PHP]]&lt;br /&gt;
** [[Apache authentication: NTLM Single Signon]]&lt;br /&gt;
* [[Darkhttpd]]&lt;br /&gt;
* [[Lighttpd]]&lt;br /&gt;
** [[Lighttpd Advanced security]]&lt;br /&gt;
** [[Setting Up Lighttpd With FastCGI]]&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
** [[Nginx as reverse proxy with acme (letsencrypt)]]&lt;br /&gt;
** [[Nginx with PHP]]&lt;br /&gt;
* Squid Proxy&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
** [[Setting up Explicit Squid Proxy]]&lt;br /&gt;
** [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
* [[Tomcat]]&lt;br /&gt;
&lt;br /&gt;
==== Hostable Content ====&lt;br /&gt;
&lt;br /&gt;
* [[DokuWiki]]&lt;br /&gt;
* [[Drupal]] &#039;&#039;(Content Management System (CMS) written in PHP)&#039;&#039;&lt;br /&gt;
* [[Kopano]] &#039;&#039;(Microsoft Outlook compatible Groupware)&#039;&#039;&lt;br /&gt;
* [[Mahara]] &#039;&#039;(E-portfolio and social networking system)&#039;&#039;&lt;br /&gt;
* [[MediaWiki]] &#039;&#039;(Free web-based wiki software application)&#039;&#039;&lt;br /&gt;
* [[Pastebin]] &#039;&#039;(Pastebin software application)&#039;&#039;&lt;br /&gt;
* [[Phpizabi]] &#039;&#039;(Social Networking Platform)&#039;&#039;&lt;br /&gt;
* [[Statusnet]] &#039;&#039;(Microblogging Platform)&#039;&#039;&lt;br /&gt;
* [[WordPress]] &#039;&#039;(Web software to create website or blog)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== IRC ===&lt;br /&gt;
&lt;br /&gt;
* [[How To Setup Your Own IRC Network]] &#039;&#039;(Using {{Pkg|charybdis}} and {{Pkg|atheme-iris}})&#039;&#039;&lt;br /&gt;
* [[NgIRCd]] &#039;&#039;(Server for Internet Relay Chat/IRC)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
&lt;br /&gt;
* Exim/Dovecot&lt;br /&gt;
** [[Small-Time Email with Exim and Dovecot]] &#039;&#039;(A simple configuration for your home network.)&lt;br /&gt;
** [[Setting up dovecot with imap and ssl]]&lt;br /&gt;
* [[relay email to gmail (msmtp, mailx, sendmail]]&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Setting up postfix with virtual domains]]&lt;br /&gt;
* Server protection&lt;br /&gt;
** [[Protecting your email server with Alpine]]&lt;br /&gt;
** [[Setting up clamsmtp]]&lt;br /&gt;
&lt;br /&gt;
=== Other Servers ===&lt;br /&gt;
&lt;br /&gt;
* [[Chrony and GPSD | Chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]&lt;br /&gt;
* [[Glpi]] &#039;&#039;(Manage inventory of technical resources)&#039;&#039;&lt;br /&gt;
* [[How to setup a Alpine Linux mirror]]&lt;br /&gt;
* [[Setting up a nfs-server|nfs-server]]&lt;br /&gt;
* [[Odoo]]&lt;br /&gt;
* [[Configure OpenLDAP | OpenLDAP]] &#039;&#039;(Installing and configuring the Alpine package for OpenLDAP)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-ad-dc|samba-ad-dc]] &#039;&#039;(Active Directory compatible domain controller)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-server|samba-server]] &#039;&#039;(standard file sharing)&#039;&#039;&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
* [[UniFi Controller]]&lt;br /&gt;
&lt;br /&gt;
=== Software development ===&lt;br /&gt;
&lt;br /&gt;
* [[Cgit]]&lt;br /&gt;
* [[OsTicket]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Patchwork]] &#039;&#039;(Patch review management system)&#039;&#039;&lt;br /&gt;
* [[Redmine]] &#039;&#039;(Project management system)&#039;&#039;&lt;br /&gt;
* [[Request Tracker]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Setting up trac wiki|Trac]] &#039;&#039;(Enhanced wiki and issue tracking system for software development projects)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up disks manually|Disk setup (manual)]]&lt;br /&gt;
* [[Disk Replication with DRBD|DRBD: Disk Replication]]&lt;br /&gt;
* [[Filesystems]]&lt;br /&gt;
** [[Burning ISOs]]&lt;br /&gt;
* [[Setting up iSCSI|iSCSI Setup]]&lt;br /&gt;
** [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
** [[Linux iSCSI Target (TCM)|iSCSI Target (TCM)/LinuxIO (LIO)]]&lt;br /&gt;
** [[Linux iSCSI Target (tgt)|User space iSCSI Target (tgt)]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM|LVM Setup]]&lt;br /&gt;
** [[Setting up LVM on GPT-labeled disks|LVM on GPT-labeled disks]]&lt;br /&gt;
** [[Installing on GPT LVM|LVM on GPT-labeled disks (updated)]]&lt;br /&gt;
** [[LVM on LUKS]]&lt;br /&gt;
* RAID&lt;br /&gt;
** [[Raid Administration]]&lt;br /&gt;
** [[Setting up a software RAID array]]&lt;br /&gt;
* ZFS&lt;br /&gt;
** [[Root on ZFS with native encryption]]&lt;br /&gt;
** [[Setting up ZFS on LUKS]]&lt;br /&gt;
** [[Setting up ZFS with native encryption]]&lt;br /&gt;
** [[ZFS scrub and trim]]&lt;br /&gt;
&lt;br /&gt;
== Virtualization ==&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
* [[Installing Alpine in a virtual machine]]&lt;br /&gt;
** [[Install Alpine on VMware ESXi]]&lt;br /&gt;
* [[KVM]] &#039;&#039;(Setting up Alpine as a KVM hypervisor)&#039;&#039;&lt;br /&gt;
* [[LXC]] &#039;&#039;(Setting up a Linux container in Alpine Linux)&#039;&#039;&lt;br /&gt;
* [[QEMU]]&lt;br /&gt;
* Xen&lt;br /&gt;
** [[Xen Dom0]] &#039;&#039;(Setting up Alpine as a dom0 for Xen hypervisor)&#039;&#039;&lt;br /&gt;
** [[Xen Dom0 on USB or SD]]&lt;br /&gt;
** [[Create Alpine Linux PV DomU|Xen DomU (paravirtualized)]]&lt;br /&gt;
** [[Xen LiveCD]]&lt;br /&gt;
** [[Xen PCI Passthrough]]&lt;br /&gt;
&lt;br /&gt;
= Tutorials =&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small Office Services]]&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Experiences with OpenVPN-client on ALIX.2D3]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039;&lt;br /&gt;
* [[High performance SCST iSCSI Target on Linux software Raid]]&lt;br /&gt;
* [[ISP Mail Server HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)&#039;&#039;&lt;br /&gt;
** [[ISP Mail Server Upgrade 2.x]]&lt;br /&gt;
** [[ISP Mail Server 2.x HowTo]] &#039;&#039;(Beta, please test)&#039;&#039;&lt;br /&gt;
** [[ISP Mail Server 3.x HowTo]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft --&amp;gt;&lt;br /&gt;
* [[Streaming Security Camera Video with VLC]]&lt;br /&gt;
&lt;br /&gt;
== Newbie corner ==&lt;br /&gt;
&lt;br /&gt;
* [[How to get regular stuff working]] &#039;&#039;some notes on need-to-know topics&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Servers ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine production deploy]]&lt;br /&gt;
** [[Production Web server: Lighttpd|Production web server: Lighttpd‎‎]]&lt;br /&gt;
** [[Production DataBases : mysql|Production database: MySql]]&lt;br /&gt;
** [[Production LAMP system: Lighttpd + PHP + MySQL‎‎]]&lt;br /&gt;
* Alpine production monitoring&lt;br /&gt;
** [[Cacti: traffic analysis and monitoring network]]&lt;br /&gt;
** [[Zabbix|Zabbix - the professional complete manager]]&lt;br /&gt;
* Kubernetes&lt;br /&gt;
** [[K8s]] Building a K8s Cluster on Alpine Linux&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24416</id>
		<title>ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZFS&amp;diff=24416"/>
		<updated>2023-08-24T21:39:24Z</updated>

		<summary type="html">&lt;p&gt;Dju92: Created page with &amp;quot;= Introduction =  On alpine linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other linux distributions.&amp;lt;br&amp;gt; Setting it up is easy and can be done in a few minutes.  = Scrub =  == Definition ==  {{Note|The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt; Wh...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
On alpine linux, there in no cron/script provided to scrub (and eventually trim) your pool(s) on a regular basis, like in other linux distributions.&amp;lt;br&amp;gt;&lt;br /&gt;
Setting it up is easy and can be done in a few minutes.&lt;br /&gt;
&lt;br /&gt;
= Scrub =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
{{Note|The scrub examines all data in the specified pools to verify that it checksums correctly. For replicated (mirror, raidz, or draid) devices, ZFS automatically repairs any damage discovered during the scrub&amp;lt;br&amp;gt;&lt;br /&gt;
When scrubbing a pool with encrypted filesystems the keys do not need to be loaded. However, if the keys are not loaded and an unrepairable checksum error is detected the file name cannot be included in the zpool status -v verbose error report.&amp;lt;br&amp;gt;&lt;br /&gt;
A scrub is split into two parts: metadata scanning and block scrubbing. The metadata scanning sorts blocks into large sequential ranges which can then be read much more efficiently from disk when issuing the scrub I/O.}}&lt;br /&gt;
&lt;br /&gt;
== Creating the script ==&lt;br /&gt;
&lt;br /&gt;
This script is used to list the pools, make sure they are online, and no scrub is being done at the time.&amp;lt;br&amp;gt;&lt;br /&gt;
We will write it in &#039;&#039;&#039;/usr/libexec/zfs/scrub&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It&#039;s taken from debian zfs scripts&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh -eu&lt;br /&gt;
&lt;br /&gt;
# directly exit successfully when zfs module is not loaded&lt;br /&gt;
if ! [ -d /sys/module/zfs ]; then&lt;br /&gt;
        exit 0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# [auto] / enable / disable&lt;br /&gt;
PROPERTY_NAME=&amp;quot;org.alpine:periodic-scrub&amp;quot;&lt;br /&gt;
&lt;br /&gt;
get_property () {&lt;br /&gt;
        # Detect the ${PROPERTY_NAME} property on a given pool.&lt;br /&gt;
        # We are abusing user-defined properties on the root dataset,&lt;br /&gt;
        # since they&#039;re not available on pools https://github.com/openzfs/zfs/pull/11680&lt;br /&gt;
        # TODO: use zpool user-defined property when such feature is available.&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        zfs get -H -o value &amp;quot;${PROPERTY_NAME}&amp;quot; &amp;quot;${pool}&amp;quot; 2&amp;gt;/dev/null || return 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
scrub_if_not_scrub_in_progress () {&lt;br /&gt;
        pool=&amp;quot;$1&amp;quot;&lt;br /&gt;
        if ! zpool status &amp;quot;${pool}&amp;quot; | grep -q &amp;quot;scrub in progress&amp;quot;; then&lt;br /&gt;
                # Ignore errors and continue with scrubbing other pools.&lt;br /&gt;
                zpool scrub &amp;quot;${pool}&amp;quot; || true&lt;br /&gt;
        fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Scrub all healthy pools that are not already scrubbing as per their configs.&lt;br /&gt;
zpool list -H -o health,name 2&amp;gt;&amp;amp;1 | \&lt;br /&gt;
        awk -F&#039;\t&#039; &#039;$1 == &amp;quot;ONLINE&amp;quot; {print $2}&#039; | \&lt;br /&gt;
while read pool&lt;br /&gt;
do&lt;br /&gt;
        # read user-defined config&lt;br /&gt;
        ret=$(get_property &amp;quot;${pool}&amp;quot;)&lt;br /&gt;
        if [ $? -ne 0 ] || [ &amp;quot;disable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                :&lt;br /&gt;
        elif [ &amp;quot;-&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;auto&amp;quot; = &amp;quot;${ret}&amp;quot; ] || [ &amp;quot;enable&amp;quot; = &amp;quot;${ret}&amp;quot; ]; then&lt;br /&gt;
                scrub_if_not_scrub_in_progress &amp;quot;${pool}&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
                cat &amp;gt; /dev/stderr &amp;lt;&amp;lt;EOF&lt;br /&gt;
$0: [WARNING] illegal value &amp;quot;${ret}&amp;quot; for property &amp;quot;${PROPERTY_NAME}&amp;quot; of ZFS dataset &amp;quot;${pool}&amp;quot;.&lt;br /&gt;
$0: Acceptable choices for this property are: auto, enable, disable. The default is auto.&lt;br /&gt;
EOF&lt;br /&gt;
        fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make the script executable&lt;br /&gt;
 # chmod +x /usr/libexec/zfs/script&lt;br /&gt;
&lt;br /&gt;
== Launching the scrub script with cron ==&lt;br /&gt;
&lt;br /&gt;
It is recommanded to launch a scrub regularly to assure your pool(s) and datas are in good shape.&amp;lt;br&amp;gt;&lt;br /&gt;
Here, the scrub will be launched once a month, on the 2nd sunday of the month.&lt;br /&gt;
&lt;br /&gt;
In root, edit your crontabs&lt;br /&gt;
 # crontab -e&lt;br /&gt;
&lt;br /&gt;
and add these 2 lines&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zfs scrub the second sunday of every month&lt;br /&gt;
24      0       8-14    *       *       if [ $(date +\%w) -eq 0 ] &amp;amp;&amp;amp; [ -x /usr/libexec/zfs/scrub ]; then /usr/libexec/zfs/scrub; fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, make sure cron is launched:&lt;br /&gt;
 # rc-update&lt;br /&gt;
&lt;br /&gt;
There should be a ligne saying&lt;br /&gt;
&amp;lt;pre&amp;gt;crond |      default&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If not, add it to the boot sequence&lt;br /&gt;
 # rc-update add crond&lt;br /&gt;
&lt;br /&gt;
then start the crond daemon&lt;br /&gt;
 # rc-service crond start&lt;br /&gt;
&lt;br /&gt;
= Trim =&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24188</id>
		<title>Bootloaders</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24188"/>
		<updated>2023-08-09T13:15:20Z</updated>

		<summary type="html">&lt;p&gt;Dju92: added details for grub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page shows the basic steps you need to perform, if you for any reason want to switch bootloaders or apply some manual configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rEFInd&amp;lt;/code&amp;gt; is an easy to use EFI boot menu that allows booting different operating systems.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Syslinux&amp;lt;/code&amp;gt; is the default light-weight bootloader used in Alpine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Grub&amp;lt;/code&amp;gt; is a standard linux boot loader.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EFI Boot Stub&amp;lt;/code&amp;gt; allows booting linux directly from a motherboard supporting UEFI or another bootloader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= rEFIind =&lt;br /&gt;
&lt;br /&gt;
For (U)EFI systems, the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package can provide a graphical EFI boot menu that allows to boot operating systems that are found on the available partitions.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; is not yet available in the used alpine release, it may be installed in another dual/multi-booted linux distribution.&lt;br /&gt;
&lt;br /&gt;
For example, with a Debian based distribution, it can be installed to the EFI partition like this:&lt;br /&gt;
 &lt;br /&gt;
 apt install refind             # installs the debian package&lt;br /&gt;
 refind-install --alldrivers    # installs refind to the EFI partition&lt;br /&gt;
&lt;br /&gt;
(The --alldrivers option includes all filesystem drivers instead of only the one needed to load the currently running kernel, to allow finding and booting operating systems from more partitions.)&lt;br /&gt;
&lt;br /&gt;
And a first (default) boot menu line needs to be configured with Alpine&#039;s default boot parameters. Assuming the bootable partition is mounted at &amp;lt;code&amp;gt;/media/sdXY&amp;lt;/code&amp;gt; it can be done like this (at time of writing):&lt;br /&gt;
 echo &#039;&amp;quot;Alpine&amp;quot; &amp;quot;modules=loop,squashfs,sd-mod,usb-storage quiet initrd=\boot\intel-ucode.img initrd=\boot\amd-ucode.img initrd=\boot\initramfs-lts&amp;quot;&#039; &amp;gt; /media/sdXY/boot/refind_linux.conf&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&lt;br /&gt;
# At the time of writing, it was still needed to use backslashes in the .conf file. &lt;br /&gt;
# The path in the config file needs to be relative to the partition that the kernel resides on. If &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; resides on its own separate partition, then &amp;lt;code&amp;gt;\boot&amp;lt;/code&amp;gt; needs to be removed from the paths.                                                                                               }}&lt;br /&gt;
&lt;br /&gt;
= Installing Syslinux =&lt;br /&gt;
&lt;br /&gt;
If you want to switch from another bootloader back to Syslinux, or if you for some reason want to install Syslinux manually, the following steps are required.&lt;br /&gt;
&lt;br /&gt;
Install the &amp;lt;code&amp;gt;syslinux&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add syslinux&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using GPT partitions, install the GPT MBR onto the drive you want to install the bootloader on (in this case &amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or if you&#039;re using DOS partitions, install the DOS MBR instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- See also: http://www.syslinux.org/wiki/index.php?title=Mbr --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the required Syslinux binaries. Despite being called &amp;lt;code&amp;gt;extlinux&amp;lt;/code&amp;gt;, Syslinux supports booting from FAT12/16/32, NTFS, ext2/3/4, [[Btrfs|btrfs]], XFS, and UFS/FFS filesystems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;extlinux --install /boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The configuration file is located in &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
Alpine ships with a script called &amp;lt;code&amp;gt;update-extlinux&amp;lt;/code&amp;gt; which automatically (re)generates this file, for example on updates to Syslinux.&lt;br /&gt;
The settings for this script can be found in &amp;lt;code&amp;gt;/etc/update-extlinux.conf&amp;lt;/code&amp;gt;, including the option to disable automatic overwriting of &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
You can also place additional menu entries in the &amp;lt;code&amp;gt;/etc/update-extlinux.d/&amp;lt;/code&amp;gt; directory, e.g. for dual booting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== EFI ===&lt;br /&gt;
&lt;br /&gt;
{{Todo|Work in progress. This should at least get you started.}}&lt;br /&gt;
&lt;br /&gt;
Assuming &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt; is a FAT32 partition of type EF00 and &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; belongs to the rootfs created after running &amp;lt;code&amp;gt;setup-disk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /mnt/EFI/syslinux&lt;br /&gt;
cp /usr/share/syslinux/efi64/* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/extlinux.conf /mnt/EFI/syslinux/syslinux.cfg&lt;br /&gt;
cp /boot/vmlinuz* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/initramfs* /mnt/EFI/syslinux/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may need to modify &amp;lt;code&amp;gt;/mnt/EFI/syslinux/syslinux.cfg&amp;lt;/code&amp;gt; to change the paths to absolute paths (just add a / in front of the vmlinuz/initramfs entries),&lt;br /&gt;
or copy the files to &amp;lt;code&amp;gt;/mnt/EFI/syslinux&amp;lt;/code&amp;gt; instead (XXX: untested).&lt;br /&gt;
&lt;br /&gt;
At the end, the file /mnt/EFI/syslinux/syslinux.cfg should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEFAULT menu.c32&lt;br /&gt;
PROMPT 0&lt;br /&gt;
MENU TITLE Alpine/Linux Boot Menu&lt;br /&gt;
MENU HIDDEN&lt;br /&gt;
MENU AUTOBOOT Alpine will be booted automatically in # seconds&lt;br /&gt;
TIMEOUT 10&lt;br /&gt;
LABEL lts&lt;br /&gt;
  MENU DEFAULT&lt;br /&gt;
  MENU LABEL Linux lts&lt;br /&gt;
  LINUX /vmlinuz-lts&lt;br /&gt;
  INITRD /initrd-lts&lt;br /&gt;
  APPEND root=/dev/sda3 modules=sd-load,usb-storage,ext4 quiet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally, add syslinux to EFI boot menu (assuming /dev/sda is your hard drive)&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add efibootmgr&lt;br /&gt;
efibootmgr -c -d /dev/sda -p 1 -l \\EFI\\syslinux\\syslinux.efi -L &amp;quot;ALPINE-SYSLINUX&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now verify that the boot entry has been added&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;efibootmgr&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BootCurrent: 0001&lt;br /&gt;
Timeout: 0 seconds&lt;br /&gt;
BootOrder: 0001,0000,0002,...&lt;br /&gt;
Boot001* ALPINE-SYSLINUX HD(1,GPT,xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)/FILE(\EFI\syslinux\syslinux.efi)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= GRUB =&lt;br /&gt;
&lt;br /&gt;
To install GRUB in BIOS mode, (optionally) remove the Syslinux package and install the required GRUB packages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk del syslinux&lt;br /&gt;
apk add grub grub-bios&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI, install Grub&#039;s EFI package instead. Note that &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; has to be an EFI compatible filesystem like FAT32.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add grub-efi efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the MBR and GRUB binaries to disk for BIOS mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install /dev/vda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install --target=x86_64-efi --efi-directory=/boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then add this line to /etc/default/grub:&lt;br /&gt;
&amp;lt;pre&amp;gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;quiet rootfstype=ext4 modules=sd-mod,usb-storage,ext4&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GRUB ships with an automatic config generator, including some automatic detection of other operating systems installed on the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script can be configured via the &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file.&lt;br /&gt;
See [https://www.gnu.org/software/grub/manual/html_node/Simple-configuration.html] for a list of available options.&lt;br /&gt;
&lt;br /&gt;
= EFI Boot Stub =&lt;br /&gt;
&lt;br /&gt;
To boot directly from your motherboard&#039;s UEFI boot menu, a boot entry needs&lt;br /&gt;
to be created with either a UEFI shell or &#039;&#039;efibootmgr&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== efibootmgr ==&lt;br /&gt;
&lt;br /&gt;
Install efibootmgr:&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a boot entry. It&#039;s recommended to do this in a script, as efibootmgr&lt;br /&gt;
does not allow editing entries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
params=&amp;quot;root=/dev/sdXZ rootfstype=ext4 rw \&lt;br /&gt;
  initrd=\intel-ucode.img \&lt;br /&gt;
  initrd=\initramfs-lts&amp;quot;&lt;br /&gt;
&lt;br /&gt;
efibootmgr --create --label &amp;quot;Alpine Linux&amp;quot; \&lt;br /&gt;
  --disk /dev/sdX --part Y \&lt;br /&gt;
  --loader /vmlinuz-lts \&lt;br /&gt;
  --unicode &amp;quot;${params}&amp;quot; \&lt;br /&gt;
  --verbose&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;/dev/sdXY&amp;lt;/code&amp;gt; contains the EFI partition and &amp;lt;code&amp;gt;/dev/sdXZ&amp;lt;/code&amp;gt; contains the root partition. If you are using {{Pkg|linux-edge}}, replace &amp;lt;code&amp;gt;lts&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;edge&amp;lt;/code&amp;gt; in the script&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The kernel contains the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/do_mounts.c#n254 exhaustive list] of ways to specify the block device. For a more robust boot entry, it is recommended to use a persistent name such as the PARTUUID.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Optionally, set the newly created entry as the default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;efibootmgr -n XXXX&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;XXXX&amp;lt;/code&amp;gt; is the boot number of the new entry.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The loader and initrd file arguments are relative to the EFI partition. In a default installation, alpine places these files in &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, while EFI is mounted to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;. You can either update fstab to mount EFI at &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, or manually copy them to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;.                                                                                           }}&lt;br /&gt;
&lt;br /&gt;
= Using a UKI (UEFI only) =&lt;br /&gt;
&lt;br /&gt;
It is possible to boot directly into a &#039;&#039;&#039;Unified Kernel Image&#039;&#039;&#039; (UKI). A UKI is a single file which contains the initfs, kernel and cmdline. While this is typically done in order to enable [https://en.wikipedia.org/wiki/UEFI SecureBoot], it is perfectly feasible to skip enrolling the custom keys and leave SecureBoot off.&lt;br /&gt;
&lt;br /&gt;
The page [[UEFI Secure Boot]] contains the instructions for setting an a UKI. Additionally, it is possible to install the UKI in the default fallback path used by most UEFI implementations. By installing the UKI into this path, the system will automatically boot into it if no other entries are defined. This can be automated as part of the kernel hook by adding the following to &amp;lt;code&amp;gt;/etc/kernel-hooks.d/secureboot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For the edge kernel, install the UKI into the default UEFI path.&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; == &amp;quot;edge&amp;quot; ]; then&lt;br /&gt;
  output_dir=&amp;quot;/efi/EFI/Boot/&amp;quot;&lt;br /&gt;
  output_name=&amp;quot;bootx64.efi&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;bootx64.efi&amp;lt;/code&amp;gt; is only correct for &amp;lt;code&amp;gt;x86_64&amp;lt;/code&amp;gt; systems. For other architectures the exact name will vary.&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
* [https://www.denx.de/wiki/U-Boot/ReleaseCycle U-Boot Release Cycle]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Booting]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24187</id>
		<title>Bootloaders</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24187"/>
		<updated>2023-08-08T23:58:47Z</updated>

		<summary type="html">&lt;p&gt;Dju92: efibootmgr needed by grub-efi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page shows the basic steps you need to perform, if you for any reason want to switch bootloaders or apply some manual configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rEFInd&amp;lt;/code&amp;gt; is an easy to use EFI boot menu that allows booting different operating systems.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Syslinux&amp;lt;/code&amp;gt; is the default light-weight bootloader used in Alpine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Grub&amp;lt;/code&amp;gt; is a standard linux boot loader.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EFI Boot Stub&amp;lt;/code&amp;gt; allows booting linux directly from a motherboard supporting UEFI or another bootloader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= rEFIind =&lt;br /&gt;
&lt;br /&gt;
For (U)EFI systems, the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package can provide a graphical EFI boot menu that allows to boot operating systems that are found on the available partitions.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; is not yet available in the used alpine release, it may be installed in another dual/multi-booted linux distribution.&lt;br /&gt;
&lt;br /&gt;
For example, with a Debian based distribution, it can be installed to the EFI partition like this:&lt;br /&gt;
 &lt;br /&gt;
 apt install refind             # installs the debian package&lt;br /&gt;
 refind-install --alldrivers    # installs refind to the EFI partition&lt;br /&gt;
&lt;br /&gt;
(The --alldrivers option includes all filesystem drivers instead of only the one needed to load the currently running kernel, to allow finding and booting operating systems from more partitions.)&lt;br /&gt;
&lt;br /&gt;
And a first (default) boot menu line needs to be configured with Alpine&#039;s default boot parameters. Assuming the bootable partition is mounted at &amp;lt;code&amp;gt;/media/sdXY&amp;lt;/code&amp;gt; it can be done like this (at time of writing):&lt;br /&gt;
 echo &#039;&amp;quot;Alpine&amp;quot; &amp;quot;modules=loop,squashfs,sd-mod,usb-storage quiet initrd=\boot\intel-ucode.img initrd=\boot\amd-ucode.img initrd=\boot\initramfs-lts&amp;quot;&#039; &amp;gt; /media/sdXY/boot/refind_linux.conf&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&lt;br /&gt;
# At the time of writing, it was still needed to use backslashes in the .conf file. &lt;br /&gt;
# The path in the config file needs to be relative to the partition that the kernel resides on. If &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; resides on its own separate partition, then &amp;lt;code&amp;gt;\boot&amp;lt;/code&amp;gt; needs to be removed from the paths.                                                                                               }}&lt;br /&gt;
&lt;br /&gt;
= Installing Syslinux =&lt;br /&gt;
&lt;br /&gt;
If you want to switch from another bootloader back to Syslinux, or if you for some reason want to install Syslinux manually, the following steps are required.&lt;br /&gt;
&lt;br /&gt;
Install the &amp;lt;code&amp;gt;syslinux&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add syslinux&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using GPT partitions, install the GPT MBR onto the drive you want to install the bootloader on (in this case &amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or if you&#039;re using DOS partitions, install the DOS MBR instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- See also: http://www.syslinux.org/wiki/index.php?title=Mbr --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the required Syslinux binaries. Despite being called &amp;lt;code&amp;gt;extlinux&amp;lt;/code&amp;gt;, Syslinux supports booting from FAT12/16/32, NTFS, ext2/3/4, [[Btrfs|btrfs]], XFS, and UFS/FFS filesystems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;extlinux --install /boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The configuration file is located in &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
Alpine ships with a script called &amp;lt;code&amp;gt;update-extlinux&amp;lt;/code&amp;gt; which automatically (re)generates this file, for example on updates to Syslinux.&lt;br /&gt;
The settings for this script can be found in &amp;lt;code&amp;gt;/etc/update-extlinux.conf&amp;lt;/code&amp;gt;, including the option to disable automatic overwriting of &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
You can also place additional menu entries in the &amp;lt;code&amp;gt;/etc/update-extlinux.d/&amp;lt;/code&amp;gt; directory, e.g. for dual booting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== EFI ===&lt;br /&gt;
&lt;br /&gt;
{{Todo|Work in progress. This should at least get you started.}}&lt;br /&gt;
&lt;br /&gt;
Assuming &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt; is a FAT32 partition of type EF00 and &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; belongs to the rootfs created after running &amp;lt;code&amp;gt;setup-disk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /mnt/EFI/syslinux&lt;br /&gt;
cp /usr/share/syslinux/efi64/* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/extlinux.conf /mnt/EFI/syslinux/syslinux.cfg&lt;br /&gt;
cp /boot/vmlinuz* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/initramfs* /mnt/EFI/syslinux/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may need to modify &amp;lt;code&amp;gt;/mnt/EFI/syslinux/syslinux.cfg&amp;lt;/code&amp;gt; to change the paths to absolute paths (just add a / in front of the vmlinuz/initramfs entries),&lt;br /&gt;
or copy the files to &amp;lt;code&amp;gt;/mnt/EFI/syslinux&amp;lt;/code&amp;gt; instead (XXX: untested).&lt;br /&gt;
&lt;br /&gt;
At the end, the file /mnt/EFI/syslinux/syslinux.cfg should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEFAULT menu.c32&lt;br /&gt;
PROMPT 0&lt;br /&gt;
MENU TITLE Alpine/Linux Boot Menu&lt;br /&gt;
MENU HIDDEN&lt;br /&gt;
MENU AUTOBOOT Alpine will be booted automatically in # seconds&lt;br /&gt;
TIMEOUT 10&lt;br /&gt;
LABEL lts&lt;br /&gt;
  MENU DEFAULT&lt;br /&gt;
  MENU LABEL Linux lts&lt;br /&gt;
  LINUX /vmlinuz-lts&lt;br /&gt;
  INITRD /initrd-lts&lt;br /&gt;
  APPEND root=/dev/sda3 modules=sd-load,usb-storage,ext4 quiet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally, add syslinux to EFI boot menu (assuming /dev/sda is your hard drive)&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add efibootmgr&lt;br /&gt;
efibootmgr -c -d /dev/sda -p 1 -l \\EFI\\syslinux\\syslinux.efi -L &amp;quot;ALPINE-SYSLINUX&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now verify that the boot entry has been added&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;efibootmgr&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BootCurrent: 0001&lt;br /&gt;
Timeout: 0 seconds&lt;br /&gt;
BootOrder: 0001,0000,0002,...&lt;br /&gt;
Boot001* ALPINE-SYSLINUX HD(1,GPT,xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)/FILE(\EFI\syslinux\syslinux.efi)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= GRUB =&lt;br /&gt;
&lt;br /&gt;
To install GRUB in BIOS mode, (optionally) remove the Syslinux package and install the required GRUB packages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk del syslinux&lt;br /&gt;
apk add grub grub-bios&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI, install Grub&#039;s EFI package instead. Note that &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; has to be an EFI compatible filesystem like FAT32.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add grub-efi efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the MBR and GRUB binaries to disk for BIOS mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install /dev/vda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install --target=x86_64-efi --efi-directory=/boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GRUB ships with an automatic config generator, including some automatic detection of other operating systems installed on the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script can be configured via the &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file.&lt;br /&gt;
See [https://www.gnu.org/software/grub/manual/html_node/Simple-configuration.html] for a list of available options.&lt;br /&gt;
&lt;br /&gt;
= EFI Boot Stub =&lt;br /&gt;
&lt;br /&gt;
To boot directly from your motherboard&#039;s UEFI boot menu, a boot entry needs&lt;br /&gt;
to be created with either a UEFI shell or &#039;&#039;efibootmgr&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== efibootmgr ==&lt;br /&gt;
&lt;br /&gt;
Install efibootmgr:&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a boot entry. It&#039;s recommended to do this in a script, as efibootmgr&lt;br /&gt;
does not allow editing entries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
params=&amp;quot;root=/dev/sdXZ rootfstype=ext4 rw \&lt;br /&gt;
  initrd=\intel-ucode.img \&lt;br /&gt;
  initrd=\initramfs-lts&amp;quot;&lt;br /&gt;
&lt;br /&gt;
efibootmgr --create --label &amp;quot;Alpine Linux&amp;quot; \&lt;br /&gt;
  --disk /dev/sdX --part Y \&lt;br /&gt;
  --loader /vmlinuz-lts \&lt;br /&gt;
  --unicode &amp;quot;${params}&amp;quot; \&lt;br /&gt;
  --verbose&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;/dev/sdXY&amp;lt;/code&amp;gt; contains the EFI partition and &amp;lt;code&amp;gt;/dev/sdXZ&amp;lt;/code&amp;gt; contains the root partition. If you are using {{Pkg|linux-edge}}, replace &amp;lt;code&amp;gt;lts&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;edge&amp;lt;/code&amp;gt; in the script&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The kernel contains the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/do_mounts.c#n254 exhaustive list] of ways to specify the block device. For a more robust boot entry, it is recommended to use a persistent name such as the PARTUUID.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Optionally, set the newly created entry as the default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;efibootmgr -n XXXX&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;XXXX&amp;lt;/code&amp;gt; is the boot number of the new entry.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The loader and initrd file arguments are relative to the EFI partition. In a default installation, alpine places these files in &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, while EFI is mounted to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;. You can either update fstab to mount EFI at &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, or manually copy them to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;.                                                                                           }}&lt;br /&gt;
&lt;br /&gt;
= Using a UKI (UEFI only) =&lt;br /&gt;
&lt;br /&gt;
It is possible to boot directly into a &#039;&#039;&#039;Unified Kernel Image&#039;&#039;&#039; (UKI). A UKI is a single file which contains the initfs, kernel and cmdline. While this is typically done in order to enable [https://en.wikipedia.org/wiki/UEFI SecureBoot], it is perfectly feasible to skip enrolling the custom keys and leave SecureBoot off.&lt;br /&gt;
&lt;br /&gt;
The page [[UEFI Secure Boot]] contains the instructions for setting an a UKI. Additionally, it is possible to install the UKI in the default fallback path used by most UEFI implementations. By installing the UKI into this path, the system will automatically boot into it if no other entries are defined. This can be automated as part of the kernel hook by adding the following to &amp;lt;code&amp;gt;/etc/kernel-hooks.d/secureboot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For the edge kernel, install the UKI into the default UEFI path.&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; == &amp;quot;edge&amp;quot; ]; then&lt;br /&gt;
  output_dir=&amp;quot;/efi/EFI/Boot/&amp;quot;&lt;br /&gt;
  output_name=&amp;quot;bootx64.efi&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;bootx64.efi&amp;lt;/code&amp;gt; is only correct for &amp;lt;code&amp;gt;x86_64&amp;lt;/code&amp;gt; systems. For other architectures the exact name will vary.&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
* [https://www.denx.de/wiki/U-Boot/ReleaseCycle U-Boot Release Cycle]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Booting]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24186</id>
		<title>Bootstrapping Alpine Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24186"/>
		<updated>2023-08-08T11:31:18Z</updated>

		<summary type="html">&lt;p&gt;Dju92: setup network before setting up repos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
= VPS =&lt;br /&gt;
This section is to provide a means to bootstrap Alpine Linux on any VPS.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
 &lt;br /&gt;
=== Prepare ===&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Download apk-tools-static for your architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.0/x86_64/apk.static&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Unpack .apk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tar zxf apk-tools-static-*.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Assuming your alpine rootfs is mounted in &#039;&#039;&#039;/tmp/target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo ./sbin/apk.static --arch $(arch) -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ -U --allow-untrusted --root /tmp/target --initdb add alpine-base&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit /tmp/target/etc/fstab&lt;br /&gt;
* edit /tmp/target/etc/inittab&lt;br /&gt;
* edit /tmp/target/etc/resolv.conf&lt;br /&gt;
* mount proc/sys/dev&lt;br /&gt;
&amp;lt;pre&amp;gt;for a in proc sys dev; do mount -o bind /$a /tmp/target/$a; done&amp;lt;/pre&amp;gt;&lt;br /&gt;
* chroot into your new installation&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /tmp/target /bin/sh&amp;lt;/pre&amp;gt;&lt;br /&gt;
* setup hostname&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-hostname&amp;lt;/pre&amp;gt;&lt;br /&gt;
* setup network&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-interfaces&amp;lt;/pre&amp;gt;&lt;br /&gt;
* setup repos&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-apkrepos -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
* add a few base packages&lt;br /&gt;
&amp;lt;pre&amp;gt;apk update&lt;br /&gt;
apk add linux-lts linux-firmware-none acpi mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
* add services to boot&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add acpid default&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add crond default&lt;br /&gt;
rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add networking boot&lt;br /&gt;
rc-update add savecache shutdown&lt;br /&gt;
rc-update add seedrng boot&lt;br /&gt;
rc-update add swap boot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloader ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/running-a-custom-linux-distro-on-a-linode-vps Running a Custom Linux Distribution on a Linode]&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-custom-compiled-kernel-with-pvgrub Run a Custom Compiled Kernel with PV-GRUB]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Install Alpine on Amazon EC2]]&lt;br /&gt;
* [[Install Alpine on coLinux]]&lt;br /&gt;
* [[Install Alpine on Rackspace]]&lt;br /&gt;
* [[Alpine setup scripts]]&lt;br /&gt;
* [https://serverfault.com/questions/98950/how-do-i-chain-boot-from-grub-to-syslinux How do I chain boot from grub to syslinux?]&lt;br /&gt;
* [https://web.archive.org/web/20151008232205/http://uggedal.com/journal/alpine-linux-on-linode/ Alpine Linux on Linode]&lt;br /&gt;
* [[Installing Alpine Linux in a chroot]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24185</id>
		<title>Bootstrapping Alpine Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24185"/>
		<updated>2023-08-08T11:22:52Z</updated>

		<summary type="html">&lt;p&gt;Dju92: better formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
= VPS =&lt;br /&gt;
This section is to provide a means to bootstrap Alpine Linux on any VPS.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
 &lt;br /&gt;
=== Prepare ===&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Download apk-tools-static for your architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.0/x86_64/apk.static&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Unpack .apk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tar zxf apk-tools-static-*.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Assuming your alpine rootfs is mounted in &#039;&#039;&#039;/tmp/target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo ./sbin/apk.static --arch $(arch) -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ -U --allow-untrusted --root /tmp/target --initdb add alpine-base&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit /tmp/target/etc/fstab&lt;br /&gt;
* edit /tmp/target/etc/inittab&lt;br /&gt;
* edit /tmp/target/etc/resolv.conf&lt;br /&gt;
* mount proc/sys/dev&lt;br /&gt;
&amp;lt;pre&amp;gt;for a in proc sys dev; do mount -o bind /$a /tmp/target/$a; done&amp;lt;/pre&amp;gt;&lt;br /&gt;
* chroot into your new installation&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /tmp/target /bin/sh&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* setup repos&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-apkrepos -f&amp;lt;/pre&amp;gt;&lt;br /&gt;
* add a few base packages&lt;br /&gt;
&amp;lt;pre&amp;gt;apk update&lt;br /&gt;
apk add linux-lts linux-firmware-none acpi mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
* setup hostname&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-hostname&amp;lt;/pre&amp;gt;&lt;br /&gt;
* setup network&lt;br /&gt;
&amp;lt;pre&amp;gt;setup-interfaces&amp;lt;/pre&amp;gt;&lt;br /&gt;
* add services to boot&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add acpid default&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add crond default&lt;br /&gt;
rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add networking boot&lt;br /&gt;
rc-update add savecache shutdown&lt;br /&gt;
rc-update add seedrng boot&lt;br /&gt;
rc-update add swap boot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloader ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/running-a-custom-linux-distro-on-a-linode-vps Running a Custom Linux Distribution on a Linode]&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-custom-compiled-kernel-with-pvgrub Run a Custom Compiled Kernel with PV-GRUB]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Install Alpine on Amazon EC2]]&lt;br /&gt;
* [[Install Alpine on coLinux]]&lt;br /&gt;
* [[Install Alpine on Rackspace]]&lt;br /&gt;
* [[Alpine setup scripts]]&lt;br /&gt;
* [https://serverfault.com/questions/98950/how-do-i-chain-boot-from-grub-to-syslinux How do I chain boot from grub to syslinux?]&lt;br /&gt;
* [https://web.archive.org/web/20151008232205/http://uggedal.com/journal/alpine-linux-on-linode/ Alpine Linux on Linode]&lt;br /&gt;
* [[Installing Alpine Linux in a chroot]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24184</id>
		<title>Bootstrapping Alpine Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24184"/>
		<updated>2023-08-08T11:19:53Z</updated>

		<summary type="html">&lt;p&gt;Dju92: added linux-firmware-none to not install ~1G of useless firmwares on a vm/vps&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
= VPS =&lt;br /&gt;
This section is to provide a means to bootstrap Alpine Linux on any VPS.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
 &lt;br /&gt;
=== Prepare ===&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Download apk-tools-static for your architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.0/x86_64/apk.static&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Unpack .apk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tar zxf apk-tools-static-*.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Assuming your alpine rootfs is mounted in &#039;&#039;&#039;/tmp/target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo ./sbin/apk.static --arch $(arch) -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ -U --allow-untrusted --root /tmp/target --initdb add alpine-base&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit /tmp/target/etc/fstab&lt;br /&gt;
* edit /tmp/target/etc/inittab&lt;br /&gt;
* edit /tmp/target/etc/resolv.conf&lt;br /&gt;
* mount proc/sys/dev&lt;br /&gt;
&amp;lt;pre&amp;gt;for a in proc sys dev; do mount -o bind /$a /tmp/target/$a; done&amp;lt;/pre&amp;gt;&lt;br /&gt;
* chroot into your new installation&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /tmp/target /bin/sh&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* setup repos (setup-apkrepos -f)&lt;br /&gt;
* add a few base packages (apk update &amp;amp;&amp;amp; apk add linux-lts linux-firmware-none acpi mkinitfs)&lt;br /&gt;
* setup hostname (setup-hostname)&lt;br /&gt;
* setup network (setup-interfaces)&lt;br /&gt;
* add services&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add acpid default&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add crond default&lt;br /&gt;
rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add networking boot&lt;br /&gt;
rc-update add savecache shutdown&lt;br /&gt;
rc-update add seedrng boot&lt;br /&gt;
rc-update add swap boot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloader ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/running-a-custom-linux-distro-on-a-linode-vps Running a Custom Linux Distribution on a Linode]&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-custom-compiled-kernel-with-pvgrub Run a Custom Compiled Kernel with PV-GRUB]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Install Alpine on Amazon EC2]]&lt;br /&gt;
* [[Install Alpine on coLinux]]&lt;br /&gt;
* [[Install Alpine on Rackspace]]&lt;br /&gt;
* [[Alpine setup scripts]]&lt;br /&gt;
* [https://serverfault.com/questions/98950/how-do-i-chain-boot-from-grub-to-syslinux How do I chain boot from grub to syslinux?]&lt;br /&gt;
* [https://web.archive.org/web/20151008232205/http://uggedal.com/journal/alpine-linux-on-linode/ Alpine Linux on Linode]&lt;br /&gt;
* [[Installing Alpine Linux in a chroot]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24183</id>
		<title>Bootstrapping Alpine Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24183"/>
		<updated>2023-08-08T11:15:55Z</updated>

		<summary type="html">&lt;p&gt;Dju92: edit for mkinitfs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
= VPS =&lt;br /&gt;
This section is to provide a means to bootstrap Alpine Linux on any VPS.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
 &lt;br /&gt;
=== Prepare ===&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Download apk-tools-static for your architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.0/x86_64/apk.static&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Unpack .apk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tar zxf apk-tools-static-*.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Assuming your alpine rootfs is mounted in &#039;&#039;&#039;/tmp/target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo ./sbin/apk.static --arch $(arch) -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ -U --allow-untrusted --root /tmp/target --initdb add alpine-base&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit /tmp/target/etc/fstab&lt;br /&gt;
* edit /tmp/target/etc/inittab&lt;br /&gt;
* edit /tmp/target/etc/resolv.conf&lt;br /&gt;
* mount proc/sys/dev&lt;br /&gt;
&amp;lt;pre&amp;gt;for a in proc sys dev; do mount -o bind /$a /tmp/target/$a; done&amp;lt;/pre&amp;gt;&lt;br /&gt;
* chroot into your new installation&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /tmp/target /bin/sh&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* setup repos (setup-apkrepos -f)&lt;br /&gt;
* add a few base packages (apk update &amp;amp;&amp;amp; apk add linux-lts acpi mkinitfs)&lt;br /&gt;
* setup hostname (setup-hostname)&lt;br /&gt;
* setup network (setup-interfaces)&lt;br /&gt;
* add services&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add acpid default&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add crond default&lt;br /&gt;
rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add networking boot&lt;br /&gt;
rc-update add savecache shutdown&lt;br /&gt;
rc-update add seedrng boot&lt;br /&gt;
rc-update add swap boot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloader ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/running-a-custom-linux-distro-on-a-linode-vps Running a Custom Linux Distribution on a Linode]&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-custom-compiled-kernel-with-pvgrub Run a Custom Compiled Kernel with PV-GRUB]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Install Alpine on Amazon EC2]]&lt;br /&gt;
* [[Install Alpine on coLinux]]&lt;br /&gt;
* [[Install Alpine on Rackspace]]&lt;br /&gt;
* [[Alpine setup scripts]]&lt;br /&gt;
* [https://serverfault.com/questions/98950/how-do-i-chain-boot-from-grub-to-syslinux How do I chain boot from grub to syslinux?]&lt;br /&gt;
* [https://web.archive.org/web/20151008232205/http://uggedal.com/journal/alpine-linux-on-linode/ Alpine Linux on Linode]&lt;br /&gt;
* [[Installing Alpine Linux in a chroot]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24171</id>
		<title>Bootstrapping Alpine Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootstrapping_Alpine_Linux&amp;diff=24171"/>
		<updated>2023-08-07T14:29:10Z</updated>

		<summary type="html">&lt;p&gt;Dju92: added main guideline&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
= VPS =&lt;br /&gt;
This section is to provide a means to bootstrap Alpine Linux on any VPS.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
 &lt;br /&gt;
=== Prepare ===&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Download apk-tools-static for your architecture.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;wget https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.0/x86_64/apk.static&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Unpack .apk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tar zxf apk-tools-static-*.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Assuming your alpine rootfs is mounted in &#039;&#039;&#039;/tmp/target&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo ./sbin/apk.static --arch $(arch) -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ -U --allow-untrusted --root /tmp/target --initdb add alpine-base&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit /tmp/target/etc/fstab&lt;br /&gt;
* edit /tmp/target/etc/inittab&lt;br /&gt;
* edit /tmp/target/etc/mkinitfs/mkinitfs.conf&lt;br /&gt;
* edit /tmp/target/etc/resolv.conf&lt;br /&gt;
* mount proc/sys/dev&lt;br /&gt;
&amp;lt;pre&amp;gt;for a in proc sys dev; do mount -o bind /$a /tmp/target/$a; done&amp;lt;/pre&amp;gt;&lt;br /&gt;
* chroot into your new installation&lt;br /&gt;
&amp;lt;pre&amp;gt;chroot /tmp/target /bin/sh&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* setup repos (setup-apkrepos -f)&lt;br /&gt;
* add a few base packages (apk update &amp;amp;&amp;amp; apk add linux-lts acpi)&lt;br /&gt;
* setup hostname (setup-hostname)&lt;br /&gt;
* setup network (setup-interfaces)&lt;br /&gt;
* add services&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rc-update add acpid default&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add crond default&lt;br /&gt;
rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add networking boot&lt;br /&gt;
rc-update add savecache shutdown&lt;br /&gt;
rc-update add seedrng boot&lt;br /&gt;
rc-update add swap boot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloader ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/running-a-custom-linux-distro-on-a-linode-vps Running a Custom Linux Distribution on a Linode]&lt;br /&gt;
* [https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-custom-compiled-kernel-with-pvgrub Run a Custom Compiled Kernel with PV-GRUB]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[Install Alpine on Amazon EC2]]&lt;br /&gt;
* [[Install Alpine on coLinux]]&lt;br /&gt;
* [[Install Alpine on Rackspace]]&lt;br /&gt;
* [[Alpine setup scripts]]&lt;br /&gt;
* [https://serverfault.com/questions/98950/how-do-i-chain-boot-from-grub-to-syslinux How do I chain boot from grub to syslinux?]&lt;br /&gt;
* [https://web.archive.org/web/20151008232205/http://uggedal.com/journal/alpine-linux-on-linode/ Alpine Linux on Linode]&lt;br /&gt;
* [[Installing Alpine Linux in a chroot]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Virtualization]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24112</id>
		<title>Bootloaders</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=24112"/>
		<updated>2023-08-07T09:21:49Z</updated>

		<summary type="html">&lt;p&gt;Dju92: /* EFI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page shows the basic steps you need to perform, if you for any reason want to switch bootloaders or apply some manual configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rEFInd&amp;lt;/code&amp;gt; is an easy to use EFI boot menu that allows booting different operating systems.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Syslinux&amp;lt;/code&amp;gt; is the default light-weight bootloader used in Alpine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Grub&amp;lt;/code&amp;gt; is a standard linux boot loader.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EFI Boot Stub&amp;lt;/code&amp;gt; allows booting linux directly from a motherboard supporting UEFI or another bootloader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= rEFIind =&lt;br /&gt;
&lt;br /&gt;
For (U)EFI systems, the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package can provide a graphical EFI boot menu that allows to boot operating systems that are found on the available partitions.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; is not yet available in the used alpine release, it may be installed in another dual/multi-booted linux distribution.&lt;br /&gt;
&lt;br /&gt;
For example, with a Debian based distribution, it can be installed to the EFI partition like this:&lt;br /&gt;
 &lt;br /&gt;
 apt install refind             # installs the debian package&lt;br /&gt;
 refind-install --alldrivers    # installs refind to the EFI partition&lt;br /&gt;
&lt;br /&gt;
(The --alldrivers option includes all filesystem drivers instead of only the one needed to load the currently running kernel, to allow finding and booting operating systems from more partitions.)&lt;br /&gt;
&lt;br /&gt;
And a first (default) boot menu line needs to be configured with Alpine&#039;s default boot parameters. Assuming the bootable partition is mounted at &amp;lt;code&amp;gt;/media/sdXY&amp;lt;/code&amp;gt; it can be done like this (at time of writing):&lt;br /&gt;
 echo &#039;&amp;quot;Alpine&amp;quot; &amp;quot;modules=loop,squashfs,sd-mod,usb-storage quiet initrd=\boot\intel-ucode.img initrd=\boot\amd-ucode.img initrd=\boot\initramfs-lts&amp;quot;&#039; &amp;gt; /media/sdXY/boot/refind_linux.conf&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&lt;br /&gt;
# At the time of writing, it was still needed to use backslashes in the .conf file. &lt;br /&gt;
# The path in the config file needs to be relative to the partition that the kernel resides on. If &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; resides on its own separate partition, then &amp;lt;code&amp;gt;\boot&amp;lt;/code&amp;gt; needs to be removed from the paths.                                                                                               }}&lt;br /&gt;
&lt;br /&gt;
= Installing Syslinux =&lt;br /&gt;
&lt;br /&gt;
If you want to switch from another bootloader back to Syslinux, or if you for some reason want to install Syslinux manually, the following steps are required.&lt;br /&gt;
&lt;br /&gt;
Install the &amp;lt;code&amp;gt;syslinux&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add syslinux&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using GPT partitions, install the GPT MBR onto the drive you want to install the bootloader on (in this case &amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or if you&#039;re using DOS partitions, install the DOS MBR instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- See also: http://www.syslinux.org/wiki/index.php?title=Mbr --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the required Syslinux binaries. Despite being called &amp;lt;code&amp;gt;extlinux&amp;lt;/code&amp;gt;, Syslinux supports booting from FAT12/16/32, NTFS, ext2/3/4, [[Btrfs|btrfs]], XFS, and UFS/FFS filesystems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;extlinux --install /boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The configuration file is located in &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
Alpine ships with a script called &amp;lt;code&amp;gt;update-extlinux&amp;lt;/code&amp;gt; which automatically (re)generates this file, for example on updates to Syslinux.&lt;br /&gt;
The settings for this script can be found in &amp;lt;code&amp;gt;/etc/update-extlinux.conf&amp;lt;/code&amp;gt;, including the option to disable automatic overwriting of &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
You can also place additional menu entries in the &amp;lt;code&amp;gt;/etc/update-extlinux.d/&amp;lt;/code&amp;gt; directory, e.g. for dual booting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== EFI ===&lt;br /&gt;
&lt;br /&gt;
{{Todo|Work in progress. This should at least get you started.}}&lt;br /&gt;
&lt;br /&gt;
Assuming &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt; is a FAT32 partition of type EF00 and &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; belongs to the rootfs created after running &amp;lt;code&amp;gt;setup-disk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /mnt/EFI/syslinux&lt;br /&gt;
cp /usr/share/syslinux/efi64/* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/extlinux.conf /mnt/EFI/syslinux/syslinux.cfg&lt;br /&gt;
cp /boot/vmlinuz* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/initramfs* /mnt/EFI/syslinux/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may need to modify &amp;lt;code&amp;gt;/mnt/EFI/syslinux/syslinux.cfg&amp;lt;/code&amp;gt; to change the paths to absolute paths (just add a / in front of the vmlinuz/initramfs entries),&lt;br /&gt;
or copy the files to &amp;lt;code&amp;gt;/mnt/EFI/syslinux&amp;lt;/code&amp;gt; instead (XXX: untested).&lt;br /&gt;
&lt;br /&gt;
At the end, the file /mnt/EFI/syslinux/syslinux.cfg should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEFAULT menu.c32&lt;br /&gt;
PROMPT 0&lt;br /&gt;
MENU TITLE Alpine/Linux Boot Menu&lt;br /&gt;
MENU HIDDEN&lt;br /&gt;
MENU AUTOBOOT Alpine will be booted automatically in # seconds&lt;br /&gt;
TIMEOUT 10&lt;br /&gt;
LABEL lts&lt;br /&gt;
  MENU DEFAULT&lt;br /&gt;
  MENU LABEL Linux lts&lt;br /&gt;
  LINUX /vmlinuz-lts&lt;br /&gt;
  INITRD /initrd-lts&lt;br /&gt;
  APPEND root=/dev/sda3 modules=sd-load,usb-storage,ext4 quiet&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally, add syslinux to EFI boot menu (assuming /dev/sda is your hard drive)&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;pre&amp;gt;&lt;br /&gt;
apk add efibootmgr&lt;br /&gt;
efibootmgr -c -d /dev/sda -p 1 -l \\EFI\\syslinux\\syslinux.efi -L &amp;quot;ALPINE-SYSLINUX&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now verify that the boot entry has been added&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;efibootmgr&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BootCurrent: 0001&lt;br /&gt;
Timeout: 0 seconds&lt;br /&gt;
BootOrder: 0001,0000,0002,...&lt;br /&gt;
Boot001* ALPINE-SYSLINUX HD(1,GPT,xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)/FILE(\EFI\syslinux\syslinux.efi)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= GRUB =&lt;br /&gt;
&lt;br /&gt;
To install GRUB in BIOS mode, (optionally) remove the Syslinux package and install the required GRUB packages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk del syslinux&lt;br /&gt;
apk add grub grub-bios&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI, install Grub&#039;s EFI package instead. Note that &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; has to be an EFI compatible filesystem like FAT32.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add grub-efi&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the MBR and GRUB binaries to disk for BIOS mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install /dev/vda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install --target=x86_64-efi --efi-directory=/boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GRUB ships with an automatic config generator, including some automatic detection of other operating systems installed on the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script can be configured via the &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file.&lt;br /&gt;
See [https://www.gnu.org/software/grub/manual/html_node/Simple-configuration.html] for a list of available options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= EFI Boot Stub =&lt;br /&gt;
&lt;br /&gt;
To boot directly from your motherboard&#039;s UEFI boot menu, a boot entry needs&lt;br /&gt;
to be created with either a UEFI shell or &#039;&#039;efibootmgr&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== efibootmgr ==&lt;br /&gt;
&lt;br /&gt;
Install efibootmgr:&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a boot entry. It&#039;s recommended to do this in a script, as efibootmgr&lt;br /&gt;
does not allow editing entries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
params=&amp;quot;root=/dev/sdXZ rootfstype=ext4 rw \&lt;br /&gt;
  initrd=\intel-ucode.img \&lt;br /&gt;
  initrd=\initramfs-lts&amp;quot;&lt;br /&gt;
&lt;br /&gt;
efibootmgr --create --label &amp;quot;Alpine Linux&amp;quot; \&lt;br /&gt;
  --disk /dev/sdX --part Y \&lt;br /&gt;
  --loader /vmlinuz-lts \&lt;br /&gt;
  --unicode &amp;quot;${params}&amp;quot; \&lt;br /&gt;
  --verbose&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;/dev/sdXY&amp;lt;/code&amp;gt; contains the EFI partition and &amp;lt;code&amp;gt;/dev/sdXZ&amp;lt;/code&amp;gt; contains the root partition. If you are using {{Pkg|linux-edge}}, replace &amp;lt;code&amp;gt;lts&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;edge&amp;lt;/code&amp;gt; in the script&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The kernel contains the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/do_mounts.c#n254 exhaustive list] of ways to specify the block device. For a more robust boot entry, it is recommended to use a persistent name such as the PARTUUID.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Optionally, set the newly created entry as the default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;efibootmgr -n XXXX&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;XXXX&amp;lt;/code&amp;gt; is the boot number of the new entry.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The loader and initrd file arguments are relative to the EFI partition. In a default installation, alpine places these files in &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, while EFI is mounted to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;. You can either update fstab to mount EFI at &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, or manually copy them to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;.                                                                                           }}&lt;br /&gt;
&lt;br /&gt;
= Using a UKI (UEFI only) =&lt;br /&gt;
&lt;br /&gt;
It is possible to boot directly into a &#039;&#039;&#039;Unified Kernel Image&#039;&#039;&#039; (UKI). A UKI is a single file which contains the initfs, kernel and cmdline. While this is typically done in order to enable [https://en.wikipedia.org/wiki/UEFI SecureBoot], it is perfectly feasible to skip enrolling the custom keys and leave SecureBoot off.&lt;br /&gt;
&lt;br /&gt;
The page [[UEFI Secure Boot]] contains the instructions for setting an a UKI. Additionally, it is possible to install the UKI in the default fallback path used by most UEFI implementations. By installing the UKI into this path, the system will automatically boot into it if no other entries are defined. This can be automated as part of the kernel hook by adding the following to &amp;lt;code&amp;gt;/etc/kernel-hooks.d/secureboot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For the edge kernel, install the UKI into the default UEFI path.&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; == &amp;quot;edge&amp;quot; ]; then&lt;br /&gt;
  output_dir=&amp;quot;/efi/EFI/Boot/&amp;quot;&lt;br /&gt;
  output_name=&amp;quot;bootx64.efi&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;bootx64.efi&amp;lt;/code&amp;gt; is only correct for &amp;lt;code&amp;gt;x86_64&amp;lt;/code&amp;gt; systems. For other architectures the exact name will vary.&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
* [https://www.denx.de/wiki/U-Boot/ReleaseCycle U-Boot Release Cycle]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Booting]]&lt;/div&gt;</summary>
		<author><name>Dju92</name></author>
	</entry>
</feed>