aboutsummaryrefslogtreecommitdiffsponsor
diff options
context:
space:
mode:
authorSlack Coder <slackcoder@server.ky>2024-04-24 11:08:25 -0500
committerSlack Coder <slackcoder@server.ky>2024-04-25 18:22:22 -0500
commit7a67dff0e87fc117f1ae31ce38816b1108923011 (patch)
treeb598eba6df520d0fdb0e65b13630d9223a6587ee
downloadefi-sync-7a67dff0e87fc117f1ae31ce38816b1108923011.tar.xz
Initial commit
-rw-r--r--README.md39
-rw-r--r--efi-sync131
2 files changed, 170 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..dd1f1ad
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+# EFI Sync
+
+Automatically install your kernel and initrd into the EFI when your Slackware system is updated.
+
+```
+Usage: ./efi-sync {install|watch}
+
+ - install: install the kernel and initrd into your EFI.
+ - watch: install on updates to your kernel
+
+```
+
+`efi-sync` watches your kernel path for updates. Once one is detected and the
+package commands have completed, your EFI will be updated. `mkinitrd` to
+update your initial ram disk if its configuration file is present.
+
+## Installation
+
+Run the following are root to install this command:
+```
+cp efi-sync /usr/local/sbin/efi-sync
+chown root:root /usr/local/sbin/efi-sync
+chmod +x /usr/local/sbin/efi-sync
+```
+
+## Configuration
+
+The command looks for configuration at /etc/efi-sync.conf.
+
+Here is an example with the default values:
+```
+# The kernel path to watch.
+KERNEL=/boot/vmlinuz
+# The path to the EFI kernel.
+EFI_KERNEL=/boot/efi/Slackware/vmlinuz
+```
+
+If you want the initial ram disk updated, ensure /etc/mkinitrd.conf exists and
+'OUTPUT_IMAGE' is set to the initrd.gz path on your EFI.
diff --git a/efi-sync b/efi-sync
new file mode 100644
index 0000000..1129a16
--- /dev/null
+++ b/efi-sync
@@ -0,0 +1,131 @@
+#!/bin/bash
+
+trap graceful_exit QUIT TERM
+
+# Inofity events which signal something changed.
+MODIFICATION_EVENTS="CREATE,CLOSE_WRITE,MOVED_TO,MOVED_FROM,MOVE"
+
+# Signals if the watcher should stop.
+STOP=false
+
+graceful_exit () {
+ STOP=true
+
+ if [[ ! -z "$KPID" ]]; then
+ kill -TERM $KPID
+ fi
+ if [[ ! -z "$MPID" ]]; then
+ kill -TERM $MPID
+ fi
+}
+
+load_config() {
+ KERNEL=/boot/vmlinuz
+ EFI_KERNEL=/boot/efi/EFI/Slackware/vmlinuz
+
+ if [[ -f /etc/efi-sync.conf ]]; then
+ source /etc/efi-sync.conf || exit 1
+ fi
+
+ INSTALL_PROGRAMS="slackpkg,upgradepkg,installpkg,removepkg"
+ WAIT_TIME=5
+}
+
+log () {
+ echo "$(date --rfc-3339=seconds) $@"
+}
+
+require_efi () {
+ if ! mount | grep vfat >/dev/null; then
+ log "the efi partition must be mounted"
+ exit 1
+ fi
+}
+
+require_root () {
+ if [[ $USER != "root" ]]; then
+ log "command must be run as root"
+ exit 1
+ fi
+}
+
+efi_install () {
+ require_root
+ require_efi
+ load_config
+
+ KERNEL_VERSION="$(basename $(realpath "$KERNEL") | sed -E 's/vmlinuz-(.*)-(.*)/\2/')"
+
+ log "Installing $(realpath "$KERNEL")."
+ cp -H "$KERNEL" "${EFI_KERNEL}"|| log "Failed to copy '${KERNEL}' into your EFI at '${EFI_KERNEL}'."
+
+ if [[ -f /etc/mkinitrd.conf ]]; then
+ log "Installing the initial RAM disk for kernel version '${KERNEL_VERSION}'."
+ mkinitrd -F -c -k "${KERNEL_VERSION}" >/dev/null 2>&1 || log "mkinitrd failed to build and install your initial ramdisk."
+ fi
+}
+
+efi_watch () {
+ require_root
+ require_efi
+ load_config
+
+ while ! $STOP; do
+ log "Watching ${KERNEL} for updates."
+
+ inotifywait "$(dirname "$KERNEL")" --include "./$(basename $KERNEL)$" \
+ --event "$MODIFICATION_EVENTS" \
+ --quiet \
+ >/dev/null &
+ KPID="$!"
+
+ # Watching for directory updates is enough and helps avoid the system's watch limit.
+ find /lib/firmware /lib/modules -type d \
+ | xargs inotifywait \
+ --event "$MODIFICATION_EVENTS" \
+ --quiet \
+ --recursive \
+ >/dev/null &
+ MPID="$!"
+
+ if ! wait -n "$KPID" "$MPID"; then
+ kill -QUIT $KPID $MPID >/dev/null 2>&1
+ continue
+ fi
+ kill -QUIT $KPID $MPID >/dev/null 2>&1
+ unset KPID
+ unset MPID
+
+ if [[ -f /etc/mkinitrd.conf ]]; then
+ local count=0
+
+ while [[ $count -lt ${WAIT_TIME} ]]; do
+ while ps -C "${INSTALL_PROGRAMS}" >/dev/null; do
+ let "count = 0"
+ sleep 1
+ done
+
+ let "count = $count + 1"
+ done
+ fi
+
+ efi_install
+ done
+
+ log "Stopped watching ${KERNEL} for updates."
+}
+
+case "$1" in
+ 'install')
+ efi_install
+ ;;
+ 'watch')
+ efi_watch
+ ;;
+ *)
+ echo "Usage: $0 [install|watch]"
+ echo ""
+ echo -e "\t- install: install the kernel and initrd into your EFI."
+ echo -e "\t- watch: install on updates to your kernel"
+ echo ""
+esac