Page MenuHomeFreeBSD

D54282.diff
No OneTemporary

D54282.diff

diff --git a/Makefile.inc1 b/Makefile.inc1
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -2146,10 +2146,12 @@
${_+_}@cd ${.CURDIR}; \
${MAKE} DESTDIR=${WSTAGEDIR} -DNO_ROOT stageworld
-stage-packages-kernel: .PHONY
- @mkdir -p ${KSTAGEDIR}
+${KSTAGEDIR}:
+ @mkdir -p "${KSTAGEDIR}"
+
+stage-packages-kernel: ${KSTAGEDIR} .PHONY
${_+_}@cd ${.CURDIR}; \
- ${MAKE} DESTDIR=${KSTAGEDIR} -DNO_ROOT stagekernel
+ ${MAKE} DESTDIR=${KSTAGEDIR} NO_INSTALLKERNEL=yes -DNO_ROOT stagekernel
stage-packages-source: .PHONY
@mkdir -p ${SSTAGEDIR};
@@ -2308,14 +2310,11 @@
|| exit 1; \
done
-_default_flavor= -default
-.if make(*package*) && exists(${KSTAGEDIR}/kernel.meta)
-. if ${MK_DEBUG_FILES} != "no"
-_debug=-dbg
-. endif
-
+# Create DTBs for systems that use them, mainly ARM. These are always
+# installed in /boot/dtb rather than a kernel-specific directory, so
+# we just take the files from the first kernel we built.
create-dtb-package: .PHONY
- @if [ -f ${KSTAGEDIR}/${DISTDIR}/dtb.plist ]; then \
+.if exists(${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]}/dtb.plist)
${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "dtb" \
PKGGENNAME "dtb" \
@@ -2325,102 +2324,91 @@
PKG_WWW "${PKG_WWW}" \
UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
- ${KSTAGEDIR}/${DISTDIR}/dtb.ucl ; \
+ ${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]}/dtb.ucl
awk -F\" ' \
/name/ { printf("===> Creating %s-", $$2); next } \
/version/ {print $$2; next } ' \
- ${KSTAGEDIR}/${DISTDIR}/dtb.ucl ; \
+ ${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]}/dtb.ucl
${PKG_CMD} -o ABI=${PKG_ABI} -o ALLOW_BASE_SHLIBS=yes \
-o OSVERSION="${SRCRELDATE}" \
create -f ${PKG_FORMAT} ${PKG_CLEVEL} -T${PKG_CTHREADS} \
- -M ${KSTAGEDIR}/${DISTDIR}/dtb.ucl \
- -p ${KSTAGEDIR}/${DISTDIR}/dtb.plist \
- -r ${KSTAGEDIR}/${DISTDIR} \
- -o ${REPODIR}/${PKG_ABI}/${PKG_OUTPUT_DIR} ; \
- fi
+ -M ${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]}/dtb.ucl \
+ -p ${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]}/dtb.plist \
+ -r ${KSTAGEDIR}/kernel.${BUILDKERNELS:[1]} \
+ -o ${REPODIR}/${PKG_ABI}/${PKG_OUTPUT_DIR}
+.endif # exists(dtb.plist)
+
+create-kernel-packages: .PHONY real-create-kernel-packages create-dtb-package
+real-create-kernel-packages: .PHONY
+.ORDER: real-create-kernel-packages create-dtb-package
+
+.for _kernel in ${BUILDKERNELS}
+# Generate the UCL plist for a kernel. This produces UCL for both the
+# kernel package itself and its companion -dbg package.
+create-kernel-plist-${_kernel}: .PHONY
+ rm -f ${KSTAGEDIR}/kernel.${_kernel}/kernel.plist
+ rm -f ${KSTAGEDIR}/kernel.${_kernel}/kernel-dbg.plist
+ cd ${KSTAGEDIR}/kernel.${_kernel} && \
+ ${METALOG_SORT_CMD} ${KSTAGEDIR}/kernel.${_kernel}.meta | \
+ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk -v kernel=yes
-create-kernel-packages: .PHONY create-kernel-flavored-packages create-dtb-package
-create-kernel-flavored-packages: .PHONY
-.ORDER: create-kernel-flavored-packages create-dtb-package
-
-. for flavor in "" ${_debug}
-create-kernel-flavored-packages: create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}
-create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap .PHONY
- @cd ${KSTAGEDIR}/${DISTDIR} ; \
- ${METALOG_SORT_CMD} ${KSTAGEDIR}/kernel.meta | \
- awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \
- -v kernel=yes -v _kernconf=${INSTALLKERNEL} ; \
+# Build a package for a single kernel, which has already been installed
+# into ${KSTAGEDIR}/kernel.${_kernel}.
+real-create-kernel-packages: real-create-kernel-packages-${_kernel}
+real-create-kernel-packages-${_kernel}: create-kernel-plist-${_kernel}
${SRCDIR}/release/packages/generate-ucl.lua \
- PKGNAME "kernel-${INSTALLKERNEL:tl}${flavor}" \
+ PKGNAME "kernel-${_kernel:tl}" \
PKGGENNAME "kernel" \
VERSION "${PKG_VERSION}" \
- KERNELDIR "kernel" \
- KERNEL_NAME "${INSTALLKERNEL}" \
- KERNEL_FLAVOR "${flavor}" \
+ KERNEL_NAME "${_kernel}" \
+ KERNELDIR "kernel.${_kernel}" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
- ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
+ ${KSTAGEDIR}/kernel.${_kernel}/kernel.ucl
awk -F\" ' \
- /name/ { printf("===> Creating %s-", $$2); next } \
- /version/ {print $$2; next } ' \
- ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \
+ /^name/ { printf("===> Creating %s-", $$2); next } \
+ /^version/ {print $$2; next } ' \
+ ${KSTAGEDIR}/kernel.${_kernel}/kernel.ucl
${PKG_CMD} -o ABI=${PKG_ABI} -o ALLOW_BASE_SHLIBS=yes \
-o OSVERSION="${SRCRELDATE}" \
create -f ${PKG_FORMAT} ${PKG_CLEVEL} -T${PKG_CTHREADS} \
- -M ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl \
- -p ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.plist \
- -r ${KSTAGEDIR}/${DISTDIR} \
+ -M ${KSTAGEDIR}/kernel.${_kernel}/kernel.ucl \
+ -p ${KSTAGEDIR}/kernel.${_kernel}/kernel.plist \
+ -r ${KSTAGEDIR}/kernel.${_kernel} \
-o ${REPODIR}/${PKG_ABI}/${PKG_OUTPUT_DIR}
-. endfor
-.else
-create-kernel-packages: .PHONY
-.endif
-.if !empty(INSTALLEXTRAKERNELS)
-.for _kernel in ${INSTALLEXTRAKERNELS}
-. if exists(${KSTAGEDIR}/kernel.${_kernel}.meta)
-. if ${MK_DEBUG_FILES} != "no"
-_debug=-dbg
-. endif
-. for flavor in "" ${_debug}
-create-kernel-packages: create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel}
-create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel}: _pkgbootstrap .PHONY
- @cd ${KSTAGEDIR}/kernel.${_kernel} ; \
- ${METALOG_SORT_CMD} ${KSTAGEDIR}/kernel.${_kernel}.meta | \
- awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \
- -v kernel=yes -v _kernconf=${_kernel} ; \
+.if ${MK_DEBUG_FILES} != "no"
+# Build the -dbg package which contains the debugging symbols for the kernel.
+real-create-kernel-packages: real-create-kernel-packages-${_kernel}-dbg
+real-create-kernel-packages-${_kernel}-dbg: create-kernel-plist-${_kernel}
${SRCDIR}/release/packages/generate-ucl.lua \
- PKGNAME "kernel-${_kernel:tl}${flavor}" \
- PKGGENNAME "kernel" \
- FORCEINCLUDE "kernel${flavor}" \
+ PKGNAME "kernel-${_kernel:tl}-dbg" \
+ PKGGENNAME "kernel-dbg" \
VERSION "${PKG_VERSION}" \
- KERNEL_NAME "${_kernel:tl}" \
- KERNEL_FLAVOR "${flavor}" \
+ KERNEL_NAME "${_kernel}" \
KERNELDIR "kernel.${_kernel}" \
PKG_NAME_PREFIX "${PKG_NAME_PREFIX}" \
PKG_MAINTAINER "${PKG_MAINTAINER}" \
PKG_WWW "${PKG_WWW}" \
UCLFILES "${SRCDIR}/release/packages/ucl" \
${SRCDIR}/release/packages/template.ucl \
- ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
+ ${KSTAGEDIR}/kernel.${_kernel}/kernel-dbg.ucl; \
awk -F\" ' \
/name/ { printf("===> Creating %s-", $$2); next } \
/version/ {print $$2; next } ' \
- ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \
+ ${KSTAGEDIR}/kernel.${_kernel}/kernel-dbg.ucl ; \
${PKG_CMD} -o ABI=${PKG_ABI} -o ALLOW_BASE_SHLIBS=yes \
-o OSVERSION="${SRCRELDATE}" \
create -f ${PKG_FORMAT} ${PKG_CLEVEL} -T${PKG_CTHREADS} \
- -M ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl \
- -p ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.plist \
+ -M ${KSTAGEDIR}/kernel.${_kernel}/kernel-dbg.ucl \
+ -p ${KSTAGEDIR}/kernel.${_kernel}/kernel-dbg.plist \
-r ${KSTAGEDIR}/kernel.${_kernel} \
-o ${REPODIR}/${PKG_ABI}/${PKG_OUTPUT_DIR}
-. endfor
-. endif
-. endfor
-.endif
+.endif # ${MK_DEBUG_FILES} != "no"
+.endfor # _kernel in ${BUILDKERNELS}
sign-packages: .PHONY
${_+_}@cd ${.CURDIR}; \
diff --git a/UPDATING b/UPDATING
--- a/UPDATING
+++ b/UPDATING
@@ -27,6 +27,20 @@
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20260106:
+ Packaged kernels will now always be installed in /boot/kernel.NAME,
+ rather than the first built kernel (usually GENERIC) being installed
+ in /boot/kernel. To avoid breaking existing bootloader configurations,
+ a symlink will be maintained at /boot/kernel pointing to an installed
+ kernel. After updating, you may want to check that the symlink looks
+ correct, and/or update explicitly set "kernel" in /boot/loader.conf.
+
+ For powerpc64le users, the symlink will not be created since /boot
+ is a FAT filesystem. Instead, you MUST edit /boot/etc/kboot.conf
+ to update the kernel filename.
+
+ This change only affects pkgbase users.
+
20260106:
Zstd has moved to the new "zstd" package. If you have set-minimal
installed, this package will be installed automatically, otherwise
diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist
--- a/etc/mtree/BSD.root.dist
+++ b/etc/mtree/BSD.root.dist
@@ -26,8 +26,6 @@
..
images
..
- kernel
- ..
loader.conf.d
..
lua
diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -843,6 +843,10 @@
..
..
..
+ pkg
+ triggers
+ ..
+ ..
security
..
sendmail
diff --git a/release/Makefile b/release/Makefile
--- a/release/Makefile
+++ b/release/Makefile
@@ -62,6 +62,12 @@
# installed on the target system, since fwget is supposed to handle that.
RELEASE_MEDIA_EXTRA_PACKAGES?= wifi-firmware-kmod-release
+# The default kernel to boot. This must be a kernel that was built as
+# part of the package repository being installed on the media.
+RELEASE_MEDIA_KERNEL?= kernel.GENERIC
+RELEASE_MEDIA_KERNEL.powerpc64?= kernel.GENERIC64
+RELEASE_MEDIA_KERNEL.powerpc64le?= kernel.GENERIC64LE
+
WORLDDIR?= ${.CURDIR:H}
PORTSDIR?= /usr/ports
@@ -303,6 +309,7 @@
. error INSTALL_SYSTEM_MEDIATYPE must be defined
. endif
+_INSTALL_SYSTEM_KERNEL=${RELEASE_MEDIA_KERNEL.${TARGET_ARCH}:U${RELEASE_MEDIA_KERNEL}}
_INSTALL_SYSTEM_SETS=${RELEASE_MEDIA_SETS.${INSTALL_SYSTEM_MEDIATYPE}:U${RELEASE_MEDIA_SETS}}
_INSTALL_SYSTEM_PKG=\
${PKG_CMD} \
@@ -323,6 +330,9 @@
${RELEASE_MEDIA_PACKAGES:S/^/${PKG_NAME_PREFIX}-/}
${_INSTALL_SYSTEM_PKG} clean -ay
+ # Make sure loader can find the kernel to boot.
+ echo 'kernel="${_INSTALL_SYSTEM_KERNEL}"' >>"${INSTALL_SYSTEM_ROOT}/boot/loader.conf"
+
# These files are created in post-install scripts and pkg doesn't
# currently support adding those to METALOG, so we need to do that
# ourselves.
diff --git a/release/packages/generate-ucl.lua b/release/packages/generate-ucl.lua
--- a/release/packages/generate-ucl.lua
+++ b/release/packages/generate-ucl.lua
@@ -111,7 +111,7 @@
if pkgname:match("%-lib$") ~= nil then
return false
end
- if pkggenname == "kernel" then
+ if pkggenname == "kernel" or pkggenname == "kernel-dbg" then
return false
end
diff --git a/release/packages/ucl/kernel-all.ucl b/release/packages/ucl/kernel-all.ucl
--- a/release/packages/ucl/kernel-all.ucl
+++ b/release/packages/ucl/kernel-all.ucl
@@ -1,9 +1,21 @@
-comment = "FreeBSD ${KERNEL_NAME} Kernel ${KERNEL_FLAVOR}"
+comment = "FreeBSD ${KERNEL_NAME} kernel"
desc = <<EOD
-FreeBSD ${KERNEL_NAME} Kernel ${KERNEL_FLAVOR}
+This package contains the operating system kernel, which is required to boot
+the system on physical and virtualised hardware. A kernel is not required
+in a jail(8) environment.
+
+This kernel was built from the configuration "${KERNEL_NAME}" and installs in
+/boot/${KERNELDIR}.
EOD
+deps {
+ # Make sure the kernel package triggers are installed.
+ "kernel-support": {
+ version = "${VERSION}"
+ },
+}
+
annotations {
set = kernels
}
diff --git a/release/packages/ucl/kernel-dbg-all.ucl b/release/packages/ucl/kernel-dbg-all.ucl
new file mode 100644
--- /dev/null
+++ b/release/packages/ucl/kernel-dbg-all.ucl
@@ -0,0 +1,11 @@
+comment = "FreeBSD ${KERNEL_NAME} kernel (debugging symbols)"
+
+desc = <<EOD
+This package contains debugging symbols for the operating system kernel,
+installed in /usr/lib/debug. This allows symbolic debugging of a kernel
+crash dump.
+EOD
+
+annotations {
+ set = kernels
+}
diff --git a/release/packages/ucl/kernel-support-all.ucl b/release/packages/ucl/kernel-support-all.ucl
new file mode 100644
--- /dev/null
+++ b/release/packages/ucl/kernel-support-all.ucl
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+comment = "Kernel packaging support"
+
+desc = <<EOD
+This package contains scripts to manage installed kernel packages.
+EOD
+
+annotations {
+ set = "base,base-jail"
+}
diff --git a/release/scripts/mtree-to-plist.awk b/release/scripts/mtree-to-plist.awk
--- a/release/scripts/mtree-to-plist.awk
+++ b/release/scripts/mtree-to-plist.awk
@@ -27,9 +27,6 @@
tags="package=dtb"
} else {
tags="package=kernel"
- if (_kernconf != "") {
- tags=tags""_kernconf
- }
}
}
if (length(tags) == 0)
@@ -68,9 +65,6 @@
}
if (kernel != "" && pkgname != "dtb") {
output="kernel"
- if (_kernconf != "") {
- output=output"."_kernconf
- }
if ($1 ~ /^\/usr\/lib\/debug\/boot/) {
output=output"-dbg.plist"
} else {
diff --git a/share/Makefile b/share/Makefile
--- a/share/Makefile
+++ b/share/Makefile
@@ -18,6 +18,7 @@
${_monetdef} \
${_msgdef} \
${_numericdef} \
+ pkg \
${_sendmail} \
skel \
${_snmp} \
diff --git a/share/man/man7/freebsd-base.7 b/share/man/man7/freebsd-base.7
--- a/share/man/man7/freebsd-base.7
+++ b/share/man/man7/freebsd-base.7
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd December 4, 2025
+.Dd December 25, 2025
.Dt FREEBSD-BASE 7
.Os
.Sh NAME
@@ -182,6 +182,30 @@
.It kernels
All available system kernels.
.El
+.Sh MANAGING PACKAGED KERNELS
+A packaged system kernel will be installed to a directory under
+.Pa /boot
+named after the kernel configuration.
+For example, the GENERIC kernel, which is the default kernel on most systems,
+will be installed to
+.Pa /boot/kernel.GENERIC .
+This behaviour differs from non-packaged kernels, and packaged kernels prior to
+.Fx 16.0 ,
+where the default kernel was typically installed in
+.Pa /boot/kernel .
+.Pp
+For compatibility with existing boot loader configurations, a symlink will be
+maintained at
+.Pa /boot/kernel
+which links to a currently installed kernel.
+If the symlink already exists and refers to a valid installed kernel, it will
+not be modified, so the administrator may change the symlink target if the
+automatically detected kernel is not correct.
+.Pp
+Alternatively, the default kernel may be changed by setting the
+.Sy kernel
+option in
+.Pa /boot/loader.conf .
.Sh EXAMPLES
Install the
.Xr vi 1
@@ -218,6 +242,7 @@
.Ed
.Sh SEE ALSO
.Xr build 7 ,
+.Xr loader.conf 5 ,
.Xr pkg 8 ,
.Xr src.conf 5
.Sh HISTORY
diff --git a/share/pkg/Makefile b/share/pkg/Makefile
new file mode 100644
--- /dev/null
+++ b/share/pkg/Makefile
@@ -0,0 +1,9 @@
+TRIGGERDIR= /usr/share/pkg/triggers
+
+FILESGROUPS= KERNSUP
+
+KERNSUP= kernel-link.ucl
+KERNSUPPACKAGE= kernel-support
+KERNSUPDIR= ${TRIGGERDIR}
+
+.include <bsd.prog.mk>
diff --git a/share/pkg/kernel-link.ucl b/share/pkg/kernel-link.ucl
new file mode 100644
--- /dev/null
+++ b/share/pkg/kernel-link.ucl
@@ -0,0 +1,197 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Kernel package handling. We maintain /boot/kernel as a symlink to
+ * an installed kernel as follows:
+ *
+ * (1) If /boot/kernel is a non-empty directory, do nothing. We assume
+ * the user is managing the default kernel themselves.
+ *
+ * (2) If /boot/kernel is an empty directory, remove it. This can happen
+ * when switching from old-style kernel naming to the new kernel.NAME
+ * style, and we need to handle this case to avoid breaking the system.
+ *
+ * If we are still running at this point, then /boot/kernel either does
+ * not exist, or is a symlink.
+ *
+ * (3) If it is a symlink, and the symlink target exists, do nothing.
+ * This allows the user to manually change which kernel the symlink
+ * points at.
+ *
+ * (4) If it doesn't exist, or it's a symlink and the symlink target
+ * doesn't exist, create it as a symlink to an installed kernel.
+ */
+
+path_glob: [
+ "/boot/kernel.*",
+]
+
+trigger: {
+ type: lua
+ sandbox: false
+ script: <<EOD
+
+BOOT_DIR = "/boot" -- Where kernels live.
+KERNEL_LINK = BOOT_DIR.."/kernel" -- Where the symlink lives.
+
+-- Check if an installed kernel seems valid.
+local is_valid_kernel = function(name)
+ local path = BOOT_DIR.."/kernel."..name.."/kernel"
+ local f = io.open(path, "r")
+
+ if not f then
+ return false
+ end
+
+ io.close(f)
+ return true
+end
+
+-- Determine the default kernel we would use to update the symlink.
+-- This is a GENERIC kernel if we can find one, otherwise just pick
+-- the first one we find.
+local get_default_kernel = function()
+ local kernels = {}
+
+ ret = pkg.readdir(BOOT_DIR)
+ if ret == nil then
+ -- /boot doesn't exist or something strange happened,
+ -- signal an error.
+ return nil
+ end
+
+ for _,dir in ipairs(ret) do
+ local kname = dir:match("^kernel%.(.*)$")
+ if kname ~= nil and is_valid_kernel(kname) then
+ table.insert(kernels, kname)
+ end
+ end
+
+ -- Did we find any kernels?
+ if #kernels == 0 then
+ return nil
+ end
+
+ -- If we have one of the default GENERIC kernels we know
+ -- about, pick that as the default kernel.
+ local generic_kernels = {
+ ["GENERIC"] = true,
+ ["GENERIC64"] = true,
+ ["GENERIC64LE"] = true,
+ }
+
+ for _,kernel in ipairs(kernels) do
+ if generic_kernels[kernel] then
+ return "kernel."..kernel
+ end
+ end
+
+ -- If not, just return the first kernel we found.
+ return "kernel."..kernels[1]
+end
+
+-- Determine if we should do anything with /boot/kernel.
+local should_update_kernel = function()
+ kstat = pkg.stat(KERNEL_LINK)
+
+ -- If /boot/kernel doesn't exist at all, we want to create it.
+ if kstat == nil then
+ return true
+ end
+
+ -- If it's a directory, we're dealing with one of two legacy
+ -- cases: if it's empty, we want to remove it and create the
+ -- symlink in its place; if not, it probably already contains
+ -- a kernel and we should do nothing.
+ if kstat.type == "dir" then
+ return (os.remove(KERNEL_LINK) ~= nil)
+ end
+
+ -- At this point, it should be a symlink. If it's not, something
+ -- strange is going on, so just abort.
+ if kstat.type ~= "lnk" then
+ return false
+ end
+
+ -- Check if the target directory exists.
+ ret = pkg.readdir(KERNEL_LINK)
+
+ -- If we couldn't readdir(), then it's an invalid link and we
+ -- should update it.
+ if ret == nil then
+ return (os.remove(KERNEL_LINK) ~= nil)
+ end
+
+ -- If the symlink target exists but is an empty directory, we also
+ -- want to update it.
+ if #ret == 0 then
+ return (os.remove(KERNEL_LINK) ~= nil)
+ end
+
+ -- Otherwise, it's not empty, so do nothing.
+ return false
+end
+
+-- Perform the symlink update.
+do_update_kernel = function(kname)
+ if not os.remove(KERNEL_LINK) then
+ return false
+ end
+
+ ret = pkg.symlink(kname, KERNEL_LINK)
+ if not ret then
+ return false
+ end
+
+ return true
+end
+
+local main = function()
+ if not should_update_kernel() then
+ return
+ end
+
+ -- Find a suitable default kernel.
+ local default_kernel = get_default_kernel()
+ if not default_kernel then
+ return
+ end
+
+ if not do_update_kernel(default_kernel) then
+ print("WARNING: Failed to update the /boot/kernel symlink.")
+ print(" The system may fail to reboot correctly.")
+ return
+ end
+
+ -- Make sure we very clearly inform the user of what we did, since
+ -- choosing the wrong kernel will render the system unbootable.
+ print("")
+ print("NOTE: The default kernel symlink at "..KERNEL_LINK.." has been updated to point at")
+ print(" "..BOOT_DIR.."/"..default_kernel..".")
+ print("")
+ print(" If this is not correct, either update the symlink to point at the correct")
+ print(" kernel, or manually set 'kernel' in "..BOOT_DIR.."/loader.conf. For more details,")
+ print(" refer to freebsd-base(7).")
+ print("")
+end
+
+main()
+
+EOD
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 25, 1:00 AM (6 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27918661
Default Alt Text
D54282.diff (21 KB)

Event Timeline