diff --git a/Dockerfile b/Dockerfile
index 2a5d8fe..673f756 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,7 @@ RUN apt-get -y update && \
git vim parted \
quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \
libarchive-tools libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc\
- binfmt-support ca-certificates qemu-utils kpartx fdisk gpg pigz\
+ binfmt-support ca-certificates fdisk gpg pigz\
&& rm -rf /var/lib/apt/lists/*
COPY . /pi-gen/
diff --git a/README.md b/README.md
index e19b2b3..3529770 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ To install the required dependencies for `pi-gen` you should run:
```bash
apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
-qemu-utils kpartx gpg pigz
+gpg pigz
```
The file `depends` contains a list of tools needed. The format of this
@@ -63,27 +63,6 @@ The following environment variables are supported:
The release name to use in `/etc/issue.txt`. The default should only be used
for official Raspberry Pi builds.
- * `USE_QCOW2` **EXPERIMENTAL** (Default: `0` )
-
- Instead of using traditional way of building the rootfs of every stage in
- single subdirectories and copying over the previous one to the next one,
- qcow2 based virtual disks with backing images are used in every stage.
- This speeds up the build process and reduces overall space consumption
- significantly.
-
- Additional optional parameters regarding qcow2 build:
-
- * `BASE_QCOW2_SIZE` (Default: 12G)
-
- Size of the virtual qcow2 disk.
- Note: This is a maximum size - not a guaranteed allocation size. You may need
- to increase the default size if you are building a particularly full image, containing
- many packages or pre-built artefacts.
-
- **CAUTION:** Although the qcow2 build mechanism will run inside Docker, there is a known issue
- where the network block device is not disconnected correctly after the Docker process has
- ended abnormally. In that case see [Disconnect an image if something went wrong](#Disconnect-an-image-if-something-went-wrong)
-
* `RELEASE` (Default: bookworm)
The release version to build images against. Valid values are any supported
@@ -423,71 +402,6 @@ follows:
* Once you're happy with the image you can remove the SKIP_IMAGES files and
export your image to test
-# Regarding Qcow2 image building
-
-### Get infos about the image in use
-
-If you issue the two commands shown in the example below in a second command shell while a build
-is running you can find out, which network block device is currently being used and which qcow2 image
-is bound to it.
-
-Example:
-
-```bash
-root@build-machine:~/$ lsblk | grep nbd
-nbd1 43:32 0 10G 0 disk
-├─nbd1p1 43:33 0 10G 0 part
-└─nbd1p1 253:0 0 10G 0 part
-
-root@build-machine:~/$ ps xa | grep qemu-nbd
- 2392 pts/6 S+ 0:00 grep --color=auto qemu-nbd
-31294 ? Ssl 0:12 qemu-nbd --discard=unmap -c /dev/nbd1 image-stage4.qcow2
-```
-
-Here you can see, that the qcow2 image `image-stage4.qcow2` is currently connected to `/dev/nbd1` with
-the associated partition map `/dev/mapper/nbd1p1`. Don't worry that `lsblk` shows two entries. It is totally fine, because the device map is accessible via `/dev/mapper/nbd1p1` and also via `/dev/dm-0`. This is all part of the device mapper functionality of the kernel. See `dmsetup` for further information.
-
-### Mount a qcow2 image
-
-If you want to examine the content of a a single stage, you can simply mount the qcow2 image found in the `WORK_DIR` directory with the tool `./imagetool.sh`.
-
-See `./imagetool.sh -h` for further details on how to use it.
-
-### Disconnect an image if something went wrong
-
-It can happen, that your build stops in case of an error. Normally `./build.sh` should handle image disconnection appropriately, but in rare cases, especially during a Docker build, this may not work as expected. If that happens, starting a new build will fail and you may have to disconnect the image and/or device yourself.
-
-A typical message indicating that there are some orphaned device mapper entries is this:
-
-```
-Failed to set NBD socket
-Disconnect client, due to: Unexpected end-of-file before all bytes were read
-```
-
-If that happens go through the following steps:
-
-1. First, check if the image is somehow mounted to a directory entry and umount it as you would any other block device, like i.e. a hard disk or USB stick.
-
-2. Second, to disconnect an image from `qemu-nbd`, the QEMU Disk Network Block Device Server, issue the following command (be sure to change the device name to the one actually used):
-
- ```bash
- sudo qemu-nbd -d /dev/nbd1
- ```
-
- Note: if you use Docker build, normally no active `qemu-nbd` process exists anymore as it will be terminated when the Docker container stops.
-
-3. To disconnect a device partition map from the network block device, execute:
-
- ```bash
- sudo kpartx -d /dev/nbd1
- or
- sudo ./imagetool.sh --cleanup
- ```
-
- Note: The `imagetool.sh` command will cleanup any /dev/nbdX that is not connected to a running `qemu-nbd` daemon. Be careful if you use network block devices for other tasks utilizing NBDs on your build machine as well.
-
-Now you should be able to start a new build without running into troubles again. Most of the time, especially when using Docker build, you will only need no. 3 to get everything up and running again.
-
# Troubleshooting
## `64 Bit Systems`
diff --git a/build-docker.sh b/build-docker.sh
index 83e76a5..41e341f 100755
--- a/build-docker.sh
+++ b/build-docker.sh
@@ -144,9 +144,6 @@ time ${DOCKER} run \
$DOCKER_CMDLINE_PRE \
--name "${DOCKER_CMDLINE_NAME}" \
--privileged \
- --cap-add=ALL \
- -v /dev:/dev \
- -v /lib/modules:/lib/modules \
${PIGEN_DOCKER_OPTS} \
--volume "${CONFIG_FILE}":/config:ro \
-e "GIT_HASH=${GIT_HASH}" \
diff --git a/build.sh b/build.sh
index 7d7bc40..f34adfc 100755
--- a/build.sh
+++ b/build.sh
@@ -23,11 +23,6 @@ EOF
on_chroot << EOF
apt-get -o Acquire::Retries=3 install --no-install-recommends -y $PACKAGES
EOF
- if [ "${USE_QCOW2}" = "1" ]; then
- on_chroot << EOF
-apt-get clean
-EOF
- fi
fi
log "End ${SUB_STAGE_DIR}/${i}-packages-nr"
fi
@@ -38,11 +33,6 @@ EOF
on_chroot << EOF
apt-get -o Acquire::Retries=3 install -y $PACKAGES
EOF
- if [ "${USE_QCOW2}" = "1" ]; then
- on_chroot << EOF
-apt-get clean
-EOF
- fi
fi
log "End ${SUB_STAGE_DIR}/${i}-packages"
fi
@@ -99,16 +89,7 @@ run_stage(){
STAGE_WORK_DIR="${WORK_DIR}/${STAGE}"
ROOTFS_DIR="${STAGE_WORK_DIR}"/rootfs
- if [ "${USE_QCOW2}" = "1" ]; then
- if [ ! -f SKIP ]; then
- load_qimage
- fi
- else
- # make sure we are not umounting during export-image stage
- if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
- unmount "${WORK_DIR}/${STAGE}"
- fi
- fi
+ unmount "${WORK_DIR}/${STAGE}"
if [ ! -f SKIP_IMAGES ]; then
if [ -f "${STAGE_DIR}/EXPORT_IMAGE" ]; then
@@ -116,7 +97,7 @@ run_stage(){
fi
fi
if [ ! -f SKIP ]; then
- if [ "${CLEAN}" = "1" ] && [ "${USE_QCOW2}" = "0" ] ; then
+ if [ "${CLEAN}" = "1" ]; then
if [ -d "${ROOTFS_DIR}" ]; then
rm -rf "${ROOTFS_DIR}"
fi
@@ -133,14 +114,7 @@ run_stage(){
done
fi
- if [ "${USE_QCOW2}" = "1" ]; then
- unload_qimage
- else
- # make sure we are not umounting during export-image stage
- if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
- unmount "${WORK_DIR}/${STAGE}"
- fi
- fi
+ unmount "${WORK_DIR}/${STAGE}"
PREV_STAGE="${STAGE}"
PREV_STAGE_DIR="${STAGE_DIR}"
@@ -184,10 +158,7 @@ do
done
term() {
- if [ "${USE_QCOW2}" = "1" ]; then
- log "Unloading image"
- unload_qimage
- fi
+ true; #TODO: Cleanup
}
trap term EXIT INT TERM
@@ -270,18 +241,6 @@ source "${SCRIPT_DIR}/common"
# shellcheck source=scripts/dependencies_check
source "${SCRIPT_DIR}/dependencies_check"
-export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
-export USE_QCOW2="${USE_QCOW2:-0}"
-export BASE_QCOW2_SIZE=${BASE_QCOW2_SIZE:-12G}
-source "${SCRIPT_DIR}/qcow2_handling"
-if [ "${USE_QCOW2}" = "1" ]; then
- NO_PRERUN_QCOW2=1
-else
- NO_PRERUN_QCOW2=0
-fi
-
-export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
-
if [ "$SETFCAP" != "1" ]; then
export CAPSH_ARG="--drop=cap_setfcap"
fi
@@ -336,98 +295,22 @@ for EXPORT_DIR in ${EXPORT_DIRS}; do
# shellcheck source=/dev/null
source "${EXPORT_DIR}/EXPORT_IMAGE"
EXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename "${EXPORT_DIR}")/rootfs
- if [ "${USE_QCOW2}" = "1" ]; then
- USE_QCOW2=0
- EXPORT_NAME="${IMG_FILENAME}${IMG_SUFFIX}"
- echo "------------------------------------------------------------------------"
- echo "Running export stage for ${EXPORT_NAME}"
- rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.img" || true
- rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" || true
- rm -f "${WORK_DIR}/${EXPORT_NAME}.img" || true
- rm -f "${WORK_DIR}/${EXPORT_NAME}.qcow2" || true
- EXPORT_STAGE=$(basename "${EXPORT_DIR}")
- for s in $STAGE_LIST; do
- TMP_LIST=${TMP_LIST:+$TMP_LIST }$(basename "${s}")
- done
- FIRST_STAGE=${TMP_LIST%% *}
- FIRST_IMAGE="image-${FIRST_STAGE}.qcow2"
-
- pushd "${WORK_DIR}" > /dev/null
- echo "Creating new base "${EXPORT_NAME}.qcow2" from ${FIRST_IMAGE}"
- cp "./${FIRST_IMAGE}" "${EXPORT_NAME}.qcow2"
-
- ARR=($TMP_LIST)
- # rebase stage images to new export base
- for CURR_STAGE in "${ARR[@]}"; do
- if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
- PREV_IMG="${EXPORT_NAME}"
- continue
- fi
- echo "Rebasing image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
- qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
- if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
- break
- fi
- PREV_IMG="image-${CURR_STAGE}"
- done
-
- # commit current export stage into base export image
- echo "Committing image-${EXPORT_STAGE}.qcow2 to ${EXPORT_NAME}.qcow2"
- qemu-img commit -f qcow2 -p -b "${EXPORT_NAME}.qcow2" image-${EXPORT_STAGE}.qcow2
-
- # rebase stage images back to original first stage for easy re-run
- for CURR_STAGE in "${ARR[@]}"; do
- if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
- PREV_IMG="image-${CURR_STAGE}"
- continue
- fi
- echo "Rebasing back image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
- qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
- if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
- break
- fi
- PREV_IMG="image-${CURR_STAGE}"
- done
- popd > /dev/null
-
- mkdir -p "${WORK_DIR}/export-image/rootfs"
- mv "${WORK_DIR}/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/"
- echo "Mounting image ${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2 to rootfs ${WORK_DIR}/export-image/rootfs"
- mount_qimage "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/rootfs"
-
- CLEAN=0
- run_stage
- CLEAN=1
- USE_QCOW2=1
-
- else
- run_stage
- fi
+ run_stage
if [ "${USE_QEMU}" != "1" ]; then
if [ -e "${EXPORT_DIR}/EXPORT_NOOBS" ]; then
# shellcheck source=/dev/null
source "${EXPORT_DIR}/EXPORT_NOOBS"
STAGE_DIR="${BASE_DIR}/export-noobs"
- if [ "${USE_QCOW2}" = "1" ]; then
- USE_QCOW2=0
- run_stage
- USE_QCOW2=1
- else
- run_stage
- fi
+ run_stage
fi
fi
done
-if [ -x postrun.sh ]; then
+if [ -x "${BASE_DIR}/postrun.sh" ]; then
log "Begin postrun.sh"
cd "${BASE_DIR}"
./postrun.sh
log "End postrun.sh"
fi
-if [ "${USE_QCOW2}" = "1" ]; then
- unload_qimage
-fi
-
log "End ${BASE_DIR}"
diff --git a/depends b/depends
index db88171..10fcdd4 100644
--- a/depends
+++ b/depends
@@ -17,7 +17,5 @@ file
git
lsmod:kmod
bc
-qemu-nbd:qemu-utils
-kpartx
gpg
pigz
diff --git a/export-image/04-set-partuuid/00-run.sh b/export-image/04-set-partuuid/00-run.sh
index 2694295..99500f3 100755
--- a/export-image/04-set-partuuid/00-run.sh
+++ b/export-image/04-set-partuuid/00-run.sh
@@ -1,17 +1,13 @@
#!/bin/bash -e
-if [ "${NO_PRERUN_QCOW2}" = "0" ]; then
+IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
- IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
+IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
- IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
+BOOT_PARTUUID="${IMGID}-01"
+ROOT_PARTUUID="${IMGID}-02"
- BOOT_PARTUUID="${IMGID}-01"
- ROOT_PARTUUID="${IMGID}-02"
-
- sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
- sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
-
- sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/firmware/cmdline.txt"
-fi
+sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
+sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
+sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/firmware/cmdline.txt"
diff --git a/export-image/05-finalise/01-run.sh b/export-image/05-finalise/01-run.sh
index 3b56b20..8310e87 100755
--- a/export-image/05-finalise/01-run.sh
+++ b/export-image/05-finalise/01-run.sh
@@ -83,25 +83,18 @@ cp "$ROOTFS_DIR/etc/rpi-issue" "$INFO_FILE"
dpkg -l --root "$ROOTFS_DIR"
} >> "$INFO_FILE"
+ROOT_DEV="$(mount | grep "${ROOTFS_DIR} " | cut -f1 -d' ')"
+
+unmount "${ROOTFS_DIR}"
+zerofree "${ROOT_DEV}"
+
+unmount_image "${IMG_FILE}"
+
mkdir -p "${DEPLOY_DIR}"
rm -f "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.*"
rm -f "${DEPLOY_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
-mv "$INFO_FILE" "$DEPLOY_DIR/"
-
-if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
- ROOT_DEV="$(mount | grep "${ROOTFS_DIR} " | cut -f1 -d' ')"
-
- unmount "${ROOTFS_DIR}"
- zerofree "${ROOT_DEV}"
-
- unmount_image "${IMG_FILE}"
-else
- unload_qimage
- make_bootable_image "${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.qcow2" "$IMG_FILE"
-fi
-
case "${DEPLOY_COMPRESSION}" in
zip)
pushd "${STAGE_WORK_DIR}" > /dev/null
@@ -121,3 +114,5 @@ none | *)
cp "$IMG_FILE" "$DEPLOY_DIR/"
;;
esac
+
+cp "$INFO_FILE" "$DEPLOY_DIR/"
diff --git a/export-image/prerun.sh b/export-image/prerun.sh
index d042c6a..b95fe36 100755
--- a/export-image/prerun.sh
+++ b/export-image/prerun.sh
@@ -1,68 +1,66 @@
#!/bin/bash -e
-if [ "${NO_PRERUN_QCOW2}" = "0" ]; then
- IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
+IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
- unmount_image "${IMG_FILE}"
+unmount_image "${IMG_FILE}"
- rm -f "${IMG_FILE}"
+rm -f "${IMG_FILE}"
- rm -rf "${ROOTFS_DIR}"
- mkdir -p "${ROOTFS_DIR}"
+rm -rf "${ROOTFS_DIR}"
+mkdir -p "${ROOTFS_DIR}"
- BOOT_SIZE="$((512 * 1024 * 1024))"
- ROOT_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot/firmware --block-size=1 | cut -f 1)
+BOOT_SIZE="$((512 * 1024 * 1024))"
+ROOT_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot/firmware --block-size=1 | cut -f 1)
- # All partition sizes and starts will be aligned to this size
- ALIGN="$((4 * 1024 * 1024))"
- # Add this much space to the calculated file size. This allows for
- # some overhead (since actual space usage is usually rounded up to the
- # filesystem block size) and gives some free space on the resulting
- # image.
- ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)"
+# All partition sizes and starts will be aligned to this size
+ALIGN="$((4 * 1024 * 1024))"
+# Add this much space to the calculated file size. This allows for
+# some overhead (since actual space usage is usually rounded up to the
+# filesystem block size) and gives some free space on the resulting
+# image.
+ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)"
- BOOT_PART_START=$((ALIGN))
- BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN))
- ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE))
- ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN))
- IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE))
+BOOT_PART_START=$((ALIGN))
+BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN))
+ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE))
+ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN))
+IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE))
- truncate -s "${IMG_SIZE}" "${IMG_FILE}"
+truncate -s "${IMG_SIZE}" "${IMG_FILE}"
- parted --script "${IMG_FILE}" mklabel msdos
- parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))"
- parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))"
+parted --script "${IMG_FILE}" mklabel msdos
+parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))"
+parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))"
- echo "Creating loop device..."
- cnt=0
- until ensure_next_loopdev && LOOP_DEV="$(losetup --show --find --partscan "$IMG_FILE")"; do
- if [ $cnt -lt 5 ]; then
- cnt=$((cnt + 1))
- echo "Error in losetup. Retrying..."
- sleep 5
- else
- echo "ERROR: losetup failed; exiting"
- exit 1
- fi
- done
-
- ensure_loopdev_partitions "$LOOP_DEV"
- BOOT_DEV="${LOOP_DEV}p1"
- ROOT_DEV="${LOOP_DEV}p2"
-
- ROOT_FEATURES="^huge_file"
- for FEATURE in 64bit; do
- if grep -q "$FEATURE" /etc/mke2fs.conf; then
- ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES"
+echo "Creating loop device..."
+cnt=0
+until ensure_next_loopdev && LOOP_DEV="$(losetup --show --find --partscan "$IMG_FILE")"; do
+ if [ $cnt -lt 5 ]; then
+ cnt=$((cnt + 1))
+ echo "Error in losetup. Retrying..."
+ sleep 5
+ else
+ echo "ERROR: losetup failed; exiting"
+ exit 1
fi
- done
- mkdosfs -n bootfs -F 32 -s 4 -v "$BOOT_DEV" > /dev/null
- mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null
+done
- mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4
- mkdir -p "${ROOTFS_DIR}/boot/firmware"
- mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot/firmware" -t vfat
+ensure_loopdev_partitions "$LOOP_DEV"
+BOOT_DEV="${LOOP_DEV}p1"
+ROOT_DEV="${LOOP_DEV}p2"
- rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot/firmware "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
- rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/firmware/" "${ROOTFS_DIR}/boot/firmware/"
+ROOT_FEATURES="^huge_file"
+for FEATURE in 64bit; do
+if grep -q "$FEATURE" /etc/mke2fs.conf; then
+ ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES"
fi
+done
+mkdosfs -n bootfs -F 32 -s 4 -v "$BOOT_DEV" > /dev/null
+mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null
+
+mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4
+mkdir -p "${ROOTFS_DIR}/boot/firmware"
+mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot/firmware" -t vfat
+
+rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot/firmware "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
+rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/firmware/" "${ROOTFS_DIR}/boot/firmware/"
diff --git a/export-noobs/00-release/00-run.sh b/export-noobs/00-release/00-run.sh
index bfaea9f..513cbfd 100755
--- a/export-noobs/00-release/00-run.sh
+++ b/export-noobs/00-release/00-run.sh
@@ -41,8 +41,4 @@ sed "${NOOBS_DIR}/os.json" -i -e "s|KERNEL|$(cat "${STAGE_WORK_DIR}/kernel_versi
sed "${NOOBS_DIR}/release_notes.txt" -i -e "s|UNRELEASED|${IMG_DATE}|"
-if [ "${USE_QCOW2}" = "1" ]; then
- mv "${NOOBS_DIR}" "${DEPLOY_DIR}/"
-else
- cp -a "${NOOBS_DIR}" "${DEPLOY_DIR}/"
-fi
+cp -a "${NOOBS_DIR}" "${DEPLOY_DIR}/"
diff --git a/export-noobs/prerun.sh b/export-noobs/prerun.sh
index 80cbb8e..8e55c9e 100755
--- a/export-noobs/prerun.sh
+++ b/export-noobs/prerun.sh
@@ -41,8 +41,4 @@ bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs/boot" -cpf -
umount "${STAGE_WORK_DIR}/rootfs/boot"
bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs" --one-file-system -cpf - . | xz -T0 > "${NOOBS_DIR}/root.tar.xz"
-if [ "${USE_QCOW2}" = "1" ]; then
- rm "$ROOTFS_DIR/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service"
-fi
-
unmount_image "${IMG_FILE}"
diff --git a/imagetool.sh b/imagetool.sh
deleted file mode 100755
index 002b50b..0000000
--- a/imagetool.sh
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/bash
-
-if [ "$(id -u)" != "0" ]; then
- echo "Please run as root" 1>&2
- exit 1
-fi
-
-progname=$(basename $0)
-
-function usage()
-{
- cat << HEREDOC
-
-Usage:
- Mount Image : $progname [--mount] [--image-name ] [--mount-point ]
- Umount Image: $progname [--umount] [--mount-point ]
- Cleanup NBD : $progname [--cleanup]
-
- arguments:
- -h, --help show this help message and exit
- -c, --cleanup cleanup orphaned device mappings
- -m, --mount mount image
- -u, --umount umount image
- -i, --image-name path to qcow2 image
- -p, --mount-point mount point for image
-
- This tool will use /dev/nbd1 as default for mounting an image. If you want to use another device, execute like this:
- NBD_DEV=/dev/nbd2 ./$progname --mount --image-name --mount-point
-
-HEREDOC
-}
-
-MOUNT=0
-UMOUNT=0
-IMAGE=""
-MOUNTPOINT=""
-
-nbd_cleanup() {
- DEVS="$(lsblk | grep nbd | grep disk | cut -d" " -f1)"
- if [ ! -z "${DEVS}" ]; then
- for d in $DEVS; do
- if [ ! -z "${d}" ]; then
- QDEV="$(ps xa | grep $d | grep -v grep)"
- if [ -z "${QDEV}" ]; then
- kpartx -d /dev/$d && echo "Unconnected device map removed: /dev/$d"
- fi
- fi
- done
- fi
-}
-
-# As long as there is at least one more argument, keep looping
-while [[ $# -gt 0 ]]; do
- key="$1"
- case "$key" in
- -h|--help)
- usage
- exit
- ;;
- -c|--cleanup)
- nbd_cleanup
- ;;
- -m|--mount)
- MOUNT=1
- ;;
- -u|--umount)
- UMOUNT=1
- ;;
- -i|--image-name)
- shift
- IMAGE="$1"
- ;;
- -p|--mount-point)
- shift
- MOUNTPOINT="$1"
- ;;
- *)
- echo "Unknown option '$key'"
- usage
- exit
- ;;
- esac
- # Shift after checking all the cases to get the next option
- shift
-done
-
-if [ "${MOUNT}" = "1" ] && [ "${UMOUNT}" = "1" ]; then
- usage
- echo "Concurrent mount options not possible."
- exit
-fi
-
-if [ "${MOUNT}" = "1" ] && ([ -z "${IMAGE}" ] || [ -z "${MOUNTPOINT}" ]); then
- usage
- echo "Can not mount image. Image path and/or mount point missing."
- exit
-fi
-
-if [ "${UMOUNT}" = "1" ] && [ -z "${MOUNTPOINT}" ]; then
- usage
- echo "Can not umount. Mount point parameter missing."
- exit
-fi
-
-export NBD_DEV="${NBD_DEV:-/dev/nbd1}"
-export MAP_BOOT_DEV=/dev/mapper/nbd1p1
-export MAP_ROOT_DEV=/dev/mapper/nbd1p2
-source scripts/qcow2_handling
-
-if [ "${MOUNT}" = "1" ]; then
- mount_qimage "${IMAGE}" "${MOUNTPOINT}"
-elif [ "${UMOUNT}" = "1" ]; then
- umount_qimage "${MOUNTPOINT}"
-fi
diff --git a/scripts/qcow2_handling b/scripts/qcow2_handling
deleted file mode 100644
index 66708e7..0000000
--- a/scripts/qcow2_handling
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/bin/bash
-
-# QCOW2 Routines
-
-export CURRENT_IMAGE
-export CURRENT_MOUNTPOINT
-
-export NBD_DEV
-export MAP_BOOT_DEV
-export MAP_ROOT_DEV
-
-# set in build.sh
-# should be fairly enough for the beginning
-# overwrite here by uncommenting following lines
-# BASE_QCOW2_SIZE=12G
-
-# find and initialize free block device nodes
-init_nbd() {
- modprobe nbd max_part=16
- if [ -z "${NBD_DEV}" ]; then
- for x in /sys/class/block/nbd* ; do
- S=`cat $x/size`
- if [ "$S" == "0" ] ; then
- NBD_DEV=/dev/$(basename $x)
- MAP_BOOT_DEV=/dev/mapper/$(basename $x)p1
- MAP_ROOT_DEV=/dev/mapper/$(basename $x)p2
- break
- fi
- done
- fi
-}
-export -f init_nbd
-
-# connect image to block device
-connect_blkdev() {
- init_nbd
- qemu-nbd --discard=unmap -c $NBD_DEV "$1"
- sync
- kpartx -as $NBD_DEV
- sync
- CURRENT_IMAGE="$1"
-}
-export -f connect_blkdev
-
-# disconnect image from block device
-disconnect_blkdev() {
- kpartx -d $NBD_DEV
- qemu-nbd -d $NBD_DEV
- NBD_DEV=
- MAP_BOOT_DEV=
- MAP_ROOT_DEV=
- CURRENT_IMAGE=
-}
-export -f disconnect_blkdev
-
-# mount qcow2 image: mount_image
-mount_qimage() {
- connect_blkdev "$1"
- mount -v -t ext4 $MAP_ROOT_DEV "$2"
- mkdir -p "${ROOTFS_DIR}/boot"
- mount -v -t vfat $MAP_BOOT_DEV "$2/boot"
- CURRENT_MOUNTPOINT="$2"
-}
-export -f mount_qimage
-
-# umount qcow2 image: umount_image
-umount_qimage() {
- sync
- #umount "$1/boot"
- while mount | grep -q "$1"; do
- local LOCS
- LOCS=$(mount | grep "$1" | cut -f 3 -d ' ' | sort -r)
- for loc in $LOCS; do
- echo "$loc"
- while mountpoint -q "$loc" && ! umount "$loc"; do
- sleep 0.1
- done
- done
- done
- CURRENT_MOUNTPOINT=
- disconnect_blkdev
-}
-export -f umount_qimage
-
-# create base image / backing image / mount image
-load_qimage() {
- if [ -z "${CURRENT_MOUNTPOINT}" ]; then
- if [ ! -d "${ROOTFS_DIR}" ]; then
- mkdir -p "${ROOTFS_DIR}";
- fi
-
- if [ "${CLEAN}" = "1" ] && [ -f "${WORK_DIR}/image-${STAGE}.qcow2" ]; then
- rm -f "${WORK_DIR}/image-${STAGE}.qcow2";
- fi
-
- if [ ! -f "${WORK_DIR}/image-${STAGE}.qcow2" ]; then
- pushd ${WORK_DIR} > /dev/null
- init_nbd
- if [ -z "${PREV_STAGE}" ]; then
- echo "Creating base image: image-${STAGE}.qcow2"
- # -o preallocation=falloc
- qemu-img create -f qcow2 image-${STAGE}.qcow2 $BASE_QCOW2_SIZE
- sync
- qemu-nbd --discard=unmap -c $NBD_DEV image-${STAGE}.qcow2
- sync
- sfdisk $NBD_DEV << EOF
-4MiB,250MiB,c,*
-254MiB,,83;
-EOF
- sync
- kpartx -as $NBD_DEV
- mkdosfs -n boot -F 32 -s 4 -v $MAP_BOOT_DEV
- mkfs.ext4 -L rootfs -O "^huge_file,^64bit" $MAP_ROOT_DEV
- sync
- else
- if [ ! -f "${WORK_DIR}/image-${PREV_STAGE}.qcow2" ]; then
- exit 1;
- fi
- echo "Creating backing image: image-${STAGE}.qcow2 <- ${WORK_DIR}/image-${PREV_STAGE}.qcow2"
- qemu-img create -f qcow2 \
- -o backing_file=${WORK_DIR}/image-${PREV_STAGE}.qcow2 \
- ${WORK_DIR}/image-${STAGE}.qcow2
- sync
- qemu-nbd --discard=unmap -c $NBD_DEV image-${STAGE}.qcow2
- sync
- kpartx -as $NBD_DEV
- fi
-
- mount -v -t ext4 $MAP_ROOT_DEV "${ROOTFS_DIR}"
- mkdir -p "${ROOTFS_DIR}/boot"
- mount -v -t vfat $MAP_BOOT_DEV "${ROOTFS_DIR}/boot"
- CURRENT_IMAGE=${WORK_DIR}/image-${STAGE}.qcow2
- CURRENT_MOUNTPOINT=${ROOTFS_DIR}
- popd > /dev/null
- else
- mount_qimage "${WORK_DIR}/image-${STAGE}.qcow2" "${ROOTFS_DIR}"
- fi
- echo "Current image in use: ${CURRENT_IMAGE} (MP: ${CURRENT_MOUNTPOINT})"
- fi
-}
-export -f load_qimage
-
-# umount current image and refresh mount point env var
-unload_qimage() {
- if [ ! -z "${CURRENT_MOUNTPOINT}" ]; then
- fstrim -v "${CURRENT_MOUNTPOINT}" || true
- umount_qimage "${CURRENT_MOUNTPOINT}"
- fi
-}
-export -f unload_qimage
-
-# based on: https://github.com/SirLagz/RaspberryPi-ImgAutoSizer
-# helper function for make_bootable_image, do not call directly
-function resize_qcow2() {
- if [ -z "$CALL_FROM_MBI" ]; then
- echo "resize_qcow2: cannot be called directly, use make_bootable_image instead"
- return 1
- fi
-
- # ROOT_MARGIN=$((800*1024*1024))
- ROOT_MARGIN=$((1*1024*1024))
- PARTED_OUT=`parted -s -m "$NBD_DEV" unit B print`
- PART_NO=`echo "$PARTED_OUT" | grep ext4 | awk -F: ' { print $1 } '`
- PART_START=`echo "$PARTED_OUT" | grep ext4 | awk -F: ' { print substr($2,1,length($2)-1) } '`
-
- e2fsck -y -f $MAP_ROOT_DEV || true
-
- DATA_SIZE=`resize2fs -P $MAP_ROOT_DEV | awk -F': ' ' { print $2 } '`
- BLOCK_SIZE=$(dumpe2fs -h $MAP_ROOT_DEV | grep 'Block size' | awk -F': ' ' { print $2 }')
- BLOCK_SIZE=${BLOCK_SIZE// /}
-
- let DATA_SIZE=$DATA_SIZE+$ROOT_MARGIN/$BLOCK_SIZE
- resize2fs -p $MAP_ROOT_DEV $DATA_SIZE
- sleep 1
-
- let PART_NEW_SIZE=$DATA_SIZE*$BLOCK_SIZE
- let PART_NEW_END=$PART_START+$PART_NEW_SIZE
- ACT1=`parted -s "$NBD_DEV" rm 2`
- ACT2=`parted -s "$NBD_DEV" unit B mkpart primary $PART_START $PART_NEW_END`
- NEW_IMG_SIZE=`parted -s -m "$NBD_DEV" unit B print free | tail -1 | awk -F: ' { print substr($2,1,length($2)-1) } '`
-}
-export -f resize_qcow2
-
-# create raw img from qcow2: make_bootable_image
-function make_bootable_image() {
-
- EXPORT_QCOW2="$1"
- EXPORT_IMAGE="$2"
-
- echo "Connect block device to source qcow2"
- connect_blkdev "${EXPORT_QCOW2}"
-
- echo "Resize fs and partition"
- CALL_FROM_MBI=1
- resize_qcow2
- sync
- CALL_FROM_MBI=
-
- echo "Disconnect block device"
- disconnect_blkdev
-
- if [ -z "$NEW_IMG_SIZE" ]; then
- echo "NEW_IMG_SIZE could not be calculated, cannot process image. Exit."
- exit 1
- fi
-
- echo "Shrinking qcow2 image"
- qemu-img resize --shrink "${EXPORT_QCOW2}" $NEW_IMG_SIZE
- sync
-
- echo "Convert qcow2 to raw image"
- qemu-img convert -f qcow2 -O raw "${EXPORT_QCOW2}" "${EXPORT_IMAGE}"
- sync
-
- echo "Get PARTUUIDs from image"
- IMGID="$(blkid -o value -s PTUUID "${EXPORT_IMAGE}")"
-
- BOOT_PARTUUID="${IMGID}-01"
- echo "Boot: $BOOT_PARTUUID"
- ROOT_PARTUUID="${IMGID}-02"
- echo "Root: $ROOT_PARTUUID"
-
- echo "Mount image"
- MOUNTROOT=${WORK_DIR}/tmpimage
- mkdir -p $MOUNTROOT
-
- MOUNTPT=$MOUNTROOT
- PARTITION=2
- mount "${EXPORT_IMAGE}" "$MOUNTPT" -o loop,offset=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*start=[ ]*//' | sed 's/,.*//'` * 512 ],sizelimit=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*size=[ ]*//' | sed 's/,.*//'` * 512 ] || exit 1
-
- MOUNTPT=$MOUNTROOT/boot
- PARTITION=1
- mount "${EXPORT_IMAGE}" "$MOUNTPT" -o loop,offset=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*start=[ ]*//' | sed 's/,.*//'` * 512 ],sizelimit=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*size=[ ]*//' | sed 's/,.*//'` * 512 ] || exit 1
-
- if [ ! -d "${MOUNTROOT}/root" ]; then
- echo "Image damaged or not mounted. Exit."
- exit 1
- fi
-
- echo "Setup PARTUUIDs"
- if [ ! -z "$BOOT_PARTUUID" ] && [ ! -z "$ROOT_PARTUUID" ]; then
- echo "Set UUIDs to make it bootable"
- sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${MOUNTROOT}/etc/fstab"
- sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${MOUNTROOT}/etc/fstab"
- sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${MOUNTROOT}/boot/cmdline.txt"
- fi
-
- echo "Umount image"
- sync
- umount "${MOUNTROOT}/boot" || exit 1
- umount "${MOUNTROOT}" || exit 1
-
- echo "Remove qcow2 export image"
- rm -f "${EXPORT_QCOW2}"
-}
-export -f make_bootable_image
diff --git a/stage0/prerun.sh b/stage0/prerun.sh
index 0252071..5f0bd2c 100755
--- a/stage0/prerun.sh
+++ b/stage0/prerun.sh
@@ -5,6 +5,6 @@ if [ "$RELEASE" != "bookworm" ]; then
echo " Please check the relevant README.md section."
fi
-if [ ! -d "${ROOTFS_DIR}" ] || [ "${USE_QCOW2}" = "1" ]; then
+if [ ! -d "${ROOTFS_DIR}" ]; then
bootstrap ${RELEASE} "${ROOTFS_DIR}" http://raspbian.raspberrypi.com/raspbian/
fi