nanobsd: Add a NO_ROOT build option

Add a -U option to build NanoBSD images without root privileges.  It
relies on makefs/mkimg and metalog (mtree) files, similar to what
release engineering uses to build images.

Keep the current way to build NanoBSD images untouched.  Once this
method gets battle tested, it may be used to build images as root as
well.

Reviewed by:	imp, emaste
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D48793
This commit is contained in:
Jose Luis Duran
2026-01-17 18:10:48 +00:00
parent 8832f767d6
commit ecc039be7f
3 changed files with 151 additions and 9 deletions
+34 -6
View File
@@ -192,9 +192,11 @@ NANO_CPUTYPE=""
# Directory to populate /cfg from # Directory to populate /cfg from
NANO_CFGDIR="" NANO_CFGDIR=""
NANO_METALOG_CFG=""
# Directory to populate /data from # Directory to populate /data from
NANO_DATADIR="" NANO_DATADIR=""
NANO_METALOG_DATA=""
# We don't need SRCCONF or SRC_ENV_CONF. NanoBSD puts everything we # We don't need SRCCONF or SRC_ENV_CONF. NanoBSD puts everything we
# need for the build in files included with __MAKE_CONF. Override in your # need for the build in files included with __MAKE_CONF. Override in your
@@ -356,6 +358,10 @@ make_conf_build() {
nano_global_make_env nano_global_make_env
echo "${CONF_WORLD}" echo "${CONF_WORLD}"
echo "${CONF_BUILD}" echo "${CONF_BUILD}"
if [ -n "${NANO_NOPRIV_BUILD}" ]; then
echo NO_ROOT=true
echo METALOG="${NANO_METALOG}"
fi
) > ${NANO_MAKE_CONF_BUILD} ) > ${NANO_MAKE_CONF_BUILD}
} }
@@ -595,15 +601,28 @@ setup_nanobsd() {
# link /$d under /conf # link /$d under /conf
# we use hard links so we have them both places. # we use hard links so we have them both places.
# the files in /$d will be hidden by the mount. # the files in /$d will be hidden by the mount.
mkdir -p conf/base/$d conf/default/$d tgt_dir conf/base/$d conf/default/$d
find $d -print | cpio ${CPIO_SYMLINK} -dumpl conf/base/ find $d -print | cpio ${CPIO_SYMLINK} -dumpl conf/base/
if [ -n "$NANO_METALOG" ]; then
grep "^.\/${d}\/" "${NANO_METALOG}" |
sed -e "s=^./${d}=./conf/base/${d}=g" |
sort | uniq >> "${NANO_METALOG}.conf"
fi
done done
if [ -n "$NANO_METALOG" ]; then
cat "${NANO_METALOG}.conf" >> "${NANO_METALOG}"
rm -f "${NANO_METALOG}.conf"
fi
echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size
echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size
tgt_touch conf/base/etc/md_size
tgt_touch conf/base/var/md_size
# pick up config files from the special partition # pick up config files from the special partition
echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > conf/default/etc/remount echo "mount -o ro /dev/${NANO_DRIVE}${NANO_SLICE_CFG}" > conf/default/etc/remount
tgt_touch conf/default/etc/remount
# Put /tmp on the /var ramdisk (could be symlink already) # Put /tmp on the /var ramdisk (could be symlink already)
tgt_dir2symlink tmp var/tmp 1777 tgt_dir2symlink tmp var/tmp 1777
@@ -660,13 +679,15 @@ EOF
# save config file for scripts # save config file for scripts
echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf
tgt_touch etc/nanobsd.conf
echo "/dev/${NANO_DRIVE}${NANO_ROOT} / ufs ro 1 1" > etc/fstab echo "/dev/${NANO_DRIVE}${NANO_ROOT} / ufs ro 1 1" > etc/fstab
echo "/dev/${NANO_DRIVE}${NANO_SLICE_CFG} /cfg ufs rw,noauto 2 2" >> etc/fstab echo "/dev/${NANO_DRIVE}${NANO_SLICE_CFG} /cfg ufs rw,noauto 2 2" >> etc/fstab
mkdir -p cfg tgt_touch etc/fstab
tgt_dir cfg
# Create directory for eventual /usr/local/etc contents # Create directory for eventual /usr/local/etc contents
mkdir -p etc/local tgt_dir etc/local
) )
} }
@@ -883,6 +904,8 @@ cust_install_files() (
if [ -n "${NANO_CUST_FILES_MTREE}" -a -f ${NANO_CUST_FILES_MTREE} ]; then if [ -n "${NANO_CUST_FILES_MTREE}" -a -f ${NANO_CUST_FILES_MTREE} ]; then
CR "mtree -eiU -p /" <${NANO_CUST_FILES_MTREE} CR "mtree -eiU -p /" <${NANO_CUST_FILES_MTREE}
fi fi
tgt_touch $(find * -type f)
) )
####################################################################### #######################################################################
@@ -995,7 +1018,7 @@ pprint() {
usage() { usage() {
( (
echo "Usage: $0 [-BbfhIiKknpqvWwX] [-c config_file]" echo "Usage: $0 [-BbfhIiKknpqUvWwX] [-c config_file]"
echo " -B suppress installs (both kernel and world)" echo " -B suppress installs (both kernel and world)"
echo " -b suppress builds (both kernel and world)" echo " -b suppress builds (both kernel and world)"
echo " -c specify config file" echo " -c specify config file"
@@ -1008,6 +1031,7 @@ usage() {
echo " -n add -DNO_CLEAN to buildworld, buildkernel, etc" echo " -n add -DNO_CLEAN to buildworld, buildkernel, etc"
echo " -p suppress preparing the image" echo " -p suppress preparing the image"
echo " -q make output more quiet" echo " -q make output more quiet"
echo " -U add -DNO_ROOT to build without root privileges"
echo " -v make output more verbose" echo " -v make output more verbose"
echo " -W suppress installworld" echo " -W suppress installworld"
echo " -w suppress buildworld" echo " -w suppress buildworld"
@@ -1039,6 +1063,9 @@ set_defaults_and_export() {
if ! $do_clean; then if ! $do_clean; then
NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN" NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN"
fi fi
if ! $do_root; then
NANO_PMAKE="${NANO_PMAKE} -DNO_ROOT"
fi
NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
@@ -1049,8 +1076,9 @@ set_defaults_and_export() {
[ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \ [ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \
NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" || true NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" || true
[ -n "${NANO_NOPRIV_BUILD}" ] && [ -z "${NANO_METALOG}" ] && \ if [ -n "${NANO_NOPRIV_BUILD}" ] && [ -z "${NANO_METALOG}" ]; then
NANO_METALOG=${NANO_OBJ}/_.metalog || true NANO_METALOG=${NANO_OBJ}/_.metalog
fi
NANO_STARTTIME=`date +%s` NANO_STARTTIME=`date +%s`
: ${NANO_TIMESTAMP:=${NANO_STARTTIME}} : ${NANO_TIMESTAMP:=${NANO_STARTTIME}}
+100
View File
@@ -155,6 +155,33 @@ create_code_slice() {
) > ${NANO_OBJ}/_.cs 2>&1 ) > ${NANO_OBJ}/_.cs 2>&1
} }
_create_code_slice ( ) (
pprint 2 "build code slice"
pprint 3 "log: ${NANO_OBJ}/_.cs"
(
IMG=${NANO_DISKIMGDIR}/_.disk.image
CODE_SIZE=$(head -n 1 "${NANO_LOG}/_.partitioning" | awk '{ print $2 }')
CODE_SIZE=$(_xxx_adjust_code_size "$CODE_SIZE")
echo "Writing code image..."
if [ -f "${NANO_WORLDDIR}/boot/boot" ]; then
echo "Making bootable partition"
bootcode="-b ${NANO_WORLDDIR}/boot/boot"
else
echo "Partition will not be bootable"
fi
nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "${CODE_SIZE}" "${NANO_OBJ}/_.disk.part" \
"${NANO_WORLDDIR}"
mkimg -s bsd \
${bootcode} \
-p freebsd-ufs:="${NANO_OBJ}/_.disk.part" \
-o "${NANO_DISKIMGDIR}/_.disk.image"
rm -f "${NANO_OBJ}/_.disk.part"
) > ${NANO_OBJ}/_.cs 2>&1
)
create_diskimage() { create_diskimage() {
pprint 2 "build diskimage" pprint 2 "build diskimage"
@@ -255,3 +282,76 @@ create_diskimage() {
) > ${NANO_LOG}/_.di 2>&1 ) > ${NANO_LOG}/_.di 2>&1
} }
_create_diskimage() {
pprint 2 "build diskimage"
pprint 3 "log: ${NANO_OBJ}/_.di"
(
local altroot bootloader cfgimage dataimage diskimage
CODE_SIZE=$(head -n 1 "${NANO_LOG}/_.partitioning" | awk '{ print $2 }')
CODE_SIZE=$(_xxx_adjust_code_size "$CODE_SIZE")
IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
if [ -f "${NANO_WORLDDIR}/${NANO_BOOTLOADER}" ]; then
bootloader="-b ${NANO_WORLDDIR}/${NANO_BOOTLOADER}"
else
echo "Image will not be bootable"
fi
diskimage="-p freebsd:=${NANO_DISKIMGDIR}/_.disk.image"
if [ "$NANO_IMAGES" -gt 1 ] && [ "$NANO_INIT_IMG2" -gt 0 ] ; then
echo "Duplicating to second image..."
tgt_switch_root_fstab "${NANO_SLICE_ROOT}" "${NANO_SLICE_ALTROOT}"
nano_makefs "-DxZ ${NANO_MAKEFS} -o minfree=0,optimization=space" \
"${NANO_METALOG}" "${CODE_SIZE}" "${NANO_OBJ}/_.altroot.part" \
"${NANO_WORLDDIR}"
tgt_switch_root_fstab "${NANO_SLICE_ALTROOT}" "${NANO_SLICE_ROOT}"
if [ -f "${NANO_WORLDDIR}/boot/boot" ]; then
bootcode="-b ${NANO_WORLDDIR}/boot/boot"
fi
mkimg -s bsd \
${bootcode} \
-p freebsd-ufs:="${NANO_OBJ}/_.altroot.part" \
-o "${NANO_OBJ}/_.altroot.image"
altroot="-p freebsd:=${NANO_OBJ}/_.altroot.image"
rm -f "${NANO_OBJ}/_.altroot.part"
else
altroot="-p-"
fi
if [ "${NANO_INIT_IMG2}" -eq 0 ]; then
altroot="-p freebsd::${CODE_SIZE}b"
fi
# Create Config slice
_populate_cfg_part "${NANO_OBJ}/_.cfg.part" "${NANO_CFGDIR}" \
"${NANO_SLICE_CFG}" "${NANO_CONFSIZE}" "${NANO_METALOG_CFG}"
cfgimage="-p freebsd:=${NANO_OBJ}/_.cfg.part"
# Create Data slice, if any.
if [ -n "${NANO_SLICE_DATA}" ] &&
[ "${NANO_SLICE_CFG}" = "${NANO_SLICE_DATA}" ] &&
[ "${NANO_DATASIZE}" -ne 0 ]; then
pprint 2 "NANO_SLICE_DATA is the same as NANO_SLICE_CFG, fix."
exit 2
fi
if [ "${NANO_DATASIZE}" -ne 0 ] && [ -n "${NANO_SLICE_DATA}" ] ; then
_populate_data_part "${NANO_OBJ}/_.data.part" "${NANO_DATADIR}" \
"${NANO_SLICE_DATA}" "${NANO_DATASIZE}" "${NANO_METALOG_DATA}"
dataimage="-p freebsd:=${NANO_OBJ}/_.data.part"
fi
echo "Writing out ${NANO_IMGNAME}..."
mkimg -s mbr \
${bootloader} \
${diskimage} \
${altroot} \
${cfgimage} \
${dataimage} \
-o ${IMG}
exit
) > ${NANO_LOG}/_.di 2>&1
}
+17 -3
View File
@@ -36,6 +36,7 @@ topdir=`dirname ${nanobsd_sh}`
# Parse arguments # Parse arguments
do_clean=true do_clean=true
do_root=true
do_kernel=true do_kernel=true
do_installkernel=true do_installkernel=true
do_world=true do_world=true
@@ -49,7 +50,7 @@ do_prep_image=true
. "${topdir}/legacy.sh" . "${topdir}/legacy.sh"
set +e set +e
args=`getopt BKXWbc:fhiIknpqvw $*` args=`getopt BKXWbc:fhiIknpqUvw $*`
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
usage usage
exit 2 exit 2
@@ -133,6 +134,11 @@ do
PPLEVEL=$(($PPLEVEL + 1)) PPLEVEL=$(($PPLEVEL + 1))
shift shift
;; ;;
-U)
do_root=false
NANO_NOPRIV_BUILD=true
shift
;;
-w) -w)
do_world=false do_world=false
shift shift
@@ -221,9 +227,17 @@ else
fi fi
if $do_code ; then if $do_code ; then
calculate_partitioning calculate_partitioning
create_code_slice if [ -z "${NANO_NOPRIV_BUILD}" ]; then
create_code_slice
else
_create_code_slice
fi
if $do_image ; then if $do_image ; then
create_diskimage if [ -z "${NANO_NOPRIV_BUILD}" ]; then
create_diskimage
else
_create_diskimage
fi
else else
pprint 2 "Skipping image build (as instructed)" pprint 2 "Skipping image build (as instructed)"
fi fi