409d4c3fe9
Since 118534fe54
(fs: use a common tarball as base for the other
filesystems), the filesystem creation is split in two steps, using an
intermediate tarball to carry the generic, common finalisations to the
per-filesystem finalisation and image creation.
However, this intermediate tarball causes an issue with capabilities:
they are entirely missing in the generated filesystems.
Capabilities are stored in the extended attribute security.capability,
which tar by default will not store/restore, unless explicitly told to,
e.g. with --xattrs-include='*', which we don't pass.
Now, passing this option when creating and extracting the intermediate
tarball, both done under fakeroot, will cause fakeroot to report an
invalid filetype for files with capabilities. mksquashfs would report
such unknown files as a warning, while mkfs.ext2 would fail (with a
similar error message), e.g.:
File [...]/usr/sbin/getcap has unrecognised filetype 0, ignoring
This is due to a poor interaction between tar and fakeroot; running as
root the exact same commands we run under fakeroot, works as expected.
Unfortunately, short of fixing fakeroot (which would first require
understanding the problem in there), we don't have much options.
The intermediate tarball was made to avoid redoing the same actions over
and over again for each filesystem to build. However, most of the time,
only one or two such filesystems would be enabled [0], and those actions
are usually pretty lightweight. So, using an intermediate tarball does
not provide a big optimisation.
The main reason to introduce the intermediate tarball, however, is that
it allows to postpone per-filesystem finalisations to be applied only
for the corresponding filesystem, not for all of them.
So, we get rid of the intermediate tarball, and simply move all of the
code to run under fakeroot to the per-filesystem fakeroot script.
Instead of extracting the intermediate tarball, we just rsync the
original target/ directory, and apply the filesystem finalisations on
that copy. The only thing still done in the rootfs-common step is to
generate the intermediate files (users file, devices file) that are used
in the fakeroot script.
Fixes: https://bugs.busybox.net/show_bug.cgi?id=11216
Note: an alternate solution would have been to keep the intermediate
tarball to keep most of the common finalisations, and move only the
permissions to each filesystem, but that was getting a bit more complex
and changed the ordering of permissions and post-fakeroot scripts. Once
we bite the bullet of having some common finalisation done in each
filesystem, it's easier to just move all of them.
[0] Most probsably, users would enable the real filesystem to put on
their device, plus the 'tar' filesystem, to be able to easily inspect
the content on their development machine.
Reported-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Ricardo Martincoski <ricardo.martincoski@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle <arnout@mind.be>
Cc: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
166 lines
5.8 KiB
Makefile
166 lines
5.8 KiB
Makefile
#
|
|
# Macro that builds the needed Makefile target to create a root
|
|
# filesystem image.
|
|
#
|
|
# The following variable must be defined before calling this macro
|
|
#
|
|
# ROOTFS_$(FSTYPE)_CMD, the command that generates the root
|
|
# filesystem image. A single command is allowed. The filename of the
|
|
# filesystem image that it must generate is $$@.
|
|
#
|
|
# The following variables can optionaly be defined
|
|
#
|
|
# ROOTFS_$(FSTYPE)_DEPENDENCIES, the list of dependencies needed to
|
|
# build the root filesystem (usually host tools)
|
|
#
|
|
# ROOTFS_$(FSTYPE)_PRE_GEN_HOOKS, a list of hooks to call before
|
|
# generating the filesystem image
|
|
#
|
|
# ROOTFS_$(FSTYPE)_POST_GEN_HOOKS, a list of hooks to call after
|
|
# generating the filesystem image
|
|
#
|
|
# In terms of configuration option, this macro assumes that the
|
|
# BR2_TARGET_ROOTFS_$(FSTYPE) config option allows to enable/disable
|
|
# the generation of a filesystem image of a particular type. If
|
|
# the configuration options BR2_TARGET_ROOTFS_$(FSTYPE)_GZIP,
|
|
# BR2_TARGET_ROOTFS_$(FSTYPE)_BZIP2 or
|
|
# BR2_TARGET_ROOTFS_$(FSTYPE)_LZMA exist and are enabled, then the
|
|
# macro will automatically generate a compressed filesystem image.
|
|
|
|
FS_DIR = $(BUILD_DIR)/buildroot-fs
|
|
FULL_DEVICE_TABLE = $(FS_DIR)/device_table.txt
|
|
ROOTFS_DEVICE_TABLES = $(call qstrip,$(BR2_ROOTFS_DEVICE_TABLE) \
|
|
$(BR2_ROOTFS_STATIC_DEVICE_TABLE))
|
|
USERS_TABLE = $(FS_DIR)/users_table.txt
|
|
ROOTFS_USERS_TABLES = $(call qstrip,$(BR2_ROOTFS_USERS_TABLES))
|
|
|
|
ifeq ($(BR2_REPRODUCIBLE),y)
|
|
define ROOTFS_REPRODUCIBLE
|
|
find $(TARGET_DIR) -print0 | xargs -0 -r touch -hd @$(SOURCE_DATE_EPOCH)
|
|
endef
|
|
endif
|
|
|
|
ROOTFS_COMMON_DEPENDENCIES = \
|
|
host-fakeroot host-makedevs \
|
|
$(BR2_TAR_HOST_DEPENDENCY) \
|
|
$(if $(PACKAGES_USERS)$(ROOTFS_USERS_TABLES),host-mkpasswd)
|
|
|
|
.PHONY: rootfs-common
|
|
rootfs-common: $(ROOTFS_COMMON_DEPENDENCIES) target-finalize
|
|
@$(call MESSAGE,"Generating root filesystems common tables")
|
|
rm -rf $(FS_DIR)
|
|
mkdir -p $(FS_DIR)
|
|
|
|
$(call PRINTF,$(PACKAGES_USERS)) >> $(USERS_TABLE)
|
|
ifneq ($(ROOTFS_USERS_TABLES),)
|
|
cat $(ROOTFS_USERS_TABLES) >> $(USERS_TABLE)
|
|
endif
|
|
ifneq ($(ROOTFS_DEVICE_TABLES),)
|
|
cat $(ROOTFS_DEVICE_TABLES) > $(FULL_DEVICE_TABLE)
|
|
ifeq ($(BR2_ROOTFS_DEVICE_CREATION_STATIC),y)
|
|
$(call PRINTF,$(PACKAGES_DEVICES_TABLE)) >> $(FULL_DEVICE_TABLE)
|
|
endif
|
|
endif
|
|
$(call PRINTF,$(PACKAGES_PERMISSIONS_TABLE)) >> $(FULL_DEVICE_TABLE)
|
|
|
|
rootfs-common-show-depends:
|
|
@echo $(ROOTFS_COMMON_DEPENDENCIES)
|
|
|
|
# Since this function will be called from within an $(eval ...)
|
|
# all variable references except the arguments must be $$-quoted.
|
|
define inner-rootfs
|
|
|
|
ROOTFS_$(2)_DIR = $$(FS_DIR)/$(1)
|
|
ROOTFS_$(2)_TARGET_DIR = $$(ROOTFS_$(2)_DIR)/target
|
|
|
|
ROOTFS_$(2)_DEPENDENCIES += rootfs-common
|
|
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_GZIP),y)
|
|
ROOTFS_$(2)_COMPRESS_EXT = .gz
|
|
ROOTFS_$(2)_COMPRESS_CMD = gzip -9 -c
|
|
endif
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_BZIP2),y)
|
|
ROOTFS_$(2)_COMPRESS_EXT = .bz2
|
|
ROOTFS_$(2)_COMPRESS_CMD = bzip2 -9 -c
|
|
endif
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_LZMA),y)
|
|
ROOTFS_$(2)_DEPENDENCIES += host-lzma
|
|
ROOTFS_$(2)_COMPRESS_EXT = .lzma
|
|
ROOTFS_$(2)_COMPRESS_CMD = $$(LZMA) -9 -c
|
|
endif
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_LZ4),y)
|
|
ROOTFS_$(2)_DEPENDENCIES += host-lz4
|
|
ROOTFS_$(2)_COMPRESS_EXT = .lz4
|
|
ROOTFS_$(2)_COMPRESS_CMD = lz4 -l -9 -c
|
|
endif
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_LZO),y)
|
|
ROOTFS_$(2)_DEPENDENCIES += host-lzop
|
|
ROOTFS_$(2)_COMPRESS_EXT = .lzo
|
|
ROOTFS_$(2)_COMPRESS_CMD = $$(LZOP) -9 -c
|
|
endif
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)_XZ),y)
|
|
ROOTFS_$(2)_DEPENDENCIES += host-xz
|
|
ROOTFS_$(2)_COMPRESS_EXT = .xz
|
|
ROOTFS_$(2)_COMPRESS_CMD = xz -9 -C crc32 -c
|
|
endif
|
|
|
|
$$(BINARIES_DIR)/rootfs.$(1): ROOTFS=$(2)
|
|
$$(BINARIES_DIR)/rootfs.$(1): FAKEROOT_SCRIPT=$$(ROOTFS_$(2)_DIR)/fakeroot
|
|
$$(BINARIES_DIR)/rootfs.$(1): $$(ROOTFS_$(2)_DEPENDENCIES)
|
|
@$$(call MESSAGE,"Generating root filesystem image rootfs.$(1)")
|
|
rm -rf $$(ROOTFS_$(2)_DIR)
|
|
mkdir -p $$(ROOTFS_$(2)_DIR)
|
|
rsync -auH \
|
|
--exclude=/$$(notdir $$(TARGET_DIR_WARNING_FILE)) \
|
|
$$(BASE_TARGET_DIR)/ \
|
|
$$(TARGET_DIR)
|
|
|
|
echo '#!/bin/sh' > $$(FAKEROOT_SCRIPT)
|
|
echo "set -e" >> $$(FAKEROOT_SCRIPT)
|
|
|
|
echo "chown -h -R 0:0 $$(TARGET_DIR)" >> $$(FAKEROOT_SCRIPT)
|
|
PATH=$$(BR_PATH) $$(TOPDIR)/support/scripts/mkusers $$(USERS_TABLE) $$(TARGET_DIR) >> $$(FAKEROOT_SCRIPT)
|
|
echo "$$(HOST_DIR)/bin/makedevs -d $$(FULL_DEVICE_TABLE) $$(TARGET_DIR)" >> $$(FAKEROOT_SCRIPT)
|
|
$$(foreach s,$$(call qstrip,$$(BR2_ROOTFS_POST_FAKEROOT_SCRIPT)),\
|
|
echo "echo '$$(TERM_BOLD)>>> Executing fakeroot script $$(s)$$(TERM_RESET)'" >> $$(FAKEROOT_SCRIPT); \
|
|
echo $$(EXTRA_ENV) $$(s) $$(TARGET_DIR) $$(BR2_ROOTFS_POST_SCRIPT_ARGS) >> $$(FAKEROOT_SCRIPT)$$(sep))
|
|
$$(foreach hook,$$(ROOTFS_PRE_CMD_HOOKS),\
|
|
$$(call PRINTF,$$($$(hook))) >> $$(FAKEROOT_SCRIPT)$$(sep))
|
|
|
|
$$(foreach hook,$$(ROOTFS_$(2)_PRE_GEN_HOOKS),\
|
|
$$(call PRINTF,$$($$(hook))) >> $$(FAKEROOT_SCRIPT)$$(sep))
|
|
$$(call PRINTF,$$(ROOTFS_REPRODUCIBLE)) >> $$(FAKEROOT_SCRIPT)
|
|
$$(call PRINTF,$$(ROOTFS_$(2)_CMD)) >> $$(FAKEROOT_SCRIPT)
|
|
chmod a+x $$(FAKEROOT_SCRIPT)
|
|
PATH=$$(BR_PATH) $$(HOST_DIR)/bin/fakeroot -- $$(FAKEROOT_SCRIPT)
|
|
$(Q)rm -rf $$(TARGET_DIR)
|
|
ifneq ($$(ROOTFS_$(2)_COMPRESS_CMD),)
|
|
PATH=$$(BR_PATH) $$(ROOTFS_$(2)_COMPRESS_CMD) $$@ > $$@$$(ROOTFS_$(2)_COMPRESS_EXT)
|
|
endif
|
|
$$(foreach hook,$$(ROOTFS_$(2)_POST_GEN_HOOKS),$$(call $$(hook))$$(sep))
|
|
|
|
rootfs-$(1)-show-depends:
|
|
@echo $$(ROOTFS_$(2)_DEPENDENCIES)
|
|
|
|
rootfs-$(1): $$(BINARIES_DIR)/rootfs.$(1)
|
|
|
|
.PHONY: rootfs-$(1) rootfs-$(1)-show-depends
|
|
|
|
ifeq ($$(BR2_TARGET_ROOTFS_$(2)),y)
|
|
TARGETS_ROOTFS += rootfs-$(1)
|
|
PACKAGES += $$(filter-out rootfs-%,$$(ROOTFS_$(2)_DEPENDENCIES))
|
|
endif
|
|
|
|
# Check for legacy POST_TARGETS rules
|
|
ifneq ($$(ROOTFS_$(2)_POST_TARGETS),)
|
|
$$(error Filesystem $(1) uses post-target rules, which are no longer supported.\
|
|
Update $(1) to use post-gen hooks instead)
|
|
endif
|
|
|
|
endef
|
|
|
|
# $(pkgname) also works well to return the filesystem name
|
|
rootfs = $(call inner-rootfs,$(pkgname),$(call UPPERCASE,$(pkgname)))
|
|
|
|
include $(sort $(wildcard fs/*/*.mk))
|