skeleton: fix custom skeleton for use with systemd
Hello All!
The current situation with systemd and a custom skeleton is a little bit muddy.
Buildroot does not support a split /usr when systemd is used as the init system. We also have some tricks and tweaks in a few packages to accomodate a merged /usr and play nice with systemd.
However, when a custom skeleton is used, the user may provide a skeleton with a split /usr. In that case, our little tricks and tweaks may no longer be functional.
Since we defined a policy in Buidroot that we use a merged /usr for use with systemd, we must ensure that a custom skeleton is set up for a merged /usr when systemd is used.
The series is pretty trivial, with two initial cleanup patches. The third patch is the core of the change, and actually implements the test that the custom skeleton actually uses a merged /usr when required.
Regards,
Yann E. MORIN.
The following changes since commit 185aa5b0f0a630b14885b78fb0033397ce7eb3a1:
gettext: fix legal info (2015-11-10 11:28:51 +0100)
are available in the git repository at:
git://git.busybox.net/~ymorin/git/buildroot yem/systemd-merged-usr-fix
for you to fetch changes up to d667c39209bc260f60546ee0b9e7f5a661c4b761:
package/skeleton: ensure custom skeleton uses merged /usr if needed (2015-11-10 19:58:42 +0100)
----------------------------------------------------------------
Yann E. MORIN (3):
package/skeleton: qstrip path before using it package/skeleton: don't handle merged /usr for custom skeleton package/skeleton: ensure custom skeleton uses merged /usr if needed
package/skeleton/skeleton.mk | 46 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH 1/3 package/skeleton: qstrip path before using it
--- package/skeleton/skeleton.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
package/skeleton/skeleton.mk +1 -1
@@ -14,7 +14,7 @@ SKELETON_SOURCE = SKELETON_ADD_TOOLCHAIN_DEPENDENCY = NO ifeq ($(BR2_ROOTFS_SKELETON_CUSTOM),y) -SKELETON_PATH = $(BR2_ROOTFS_SKELETON_CUSTOM_PATH) +SKELETON_PATH = $(call qstrip,$(BR2_ROOTFS_SKELETON_CUSTOM_PATH)) else SKELETON_PATH = system/skeleton endif
Signature · 1 line
1.9.1
PATCH 2/3 package/skeleton: don't handle merged /usr for custom skeleton
In reply to Yann E. MORINIn case the user wants to use a custom skeleton, we should not try to handle the symlinks (resp. mkdir) to handle merged (resp. split) /usr.
--- package/skeleton/skeleton.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
package/skeleton/skeleton.mk +4 -2
@@ -15,9 +15,9 @@ SKELETON_ADD_TOOLCHAIN_DEPENDENCY = NO ifeq ($(BR2_ROOTFS_SKELETON_CUSTOM),y) SKELETON_PATH = $(call qstrip,$(BR2_ROOTFS_SKELETON_CUSTOM_PATH)) -else +else # ! custom skeleton + SKELETON_PATH = system/skeleton -endif ifeq ($(BR2_ROOTFS_MERGED_USR),y) define SKELETON_USR_SYMLINKS_OR_DIRS
@@ -33,6 +33,8 @@ define SKELETON_USR_SYMLINKS_OR_DIRS endef endif +endif # ! custom skeleton + define SKELETON_INSTALL_TARGET_CMDS rsync -a --ignore-times $(SYNC_VCS_EXCLUSIONS) \ --chmod=u=rwX,go=rX --exclude .empty --exclude '*~' \
Signature · 1 line
1.9.1
PATCH 3/3 package/skeleton: ensure custom skeleton uses merged /usr if needed
In reply to Yann E. MORINWhen using systemd, the poolicy in Buildroot is to use a merged /usr (see c5bd8af6, "system: add options for /bin /sbin and /lib to be symlinks into /usr" for more info). So, we apply a few tricks in some packages to account for the merged /usr case.
However, when using a custom skeleton, we have no say in how that skeleton is organised, so it may well have a split /usr. In that case, our little tricks might not work as expected.
So, when the user uses a custom skeleton and wants systemd as an init system, we must check that the custom skeleton is setup with a merged /usr.
We do that by checking that each pair of {/lib,/usr/lib} {/bin,/usr/bin} and {/sbin,/usr/sbin} have the same inode numbers, i.e. /lib must have the same inode number as /usr/lib (and so on...). When a pair does not share the same inode number, this is not a merged /usr and we abort.
We implement that check with make constructs, so it is done very early in the build process, and we can abort early if need be.
--- package/skeleton/skeleton.mk | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
package/skeleton/skeleton.mk +38 -0
@@ -14,7 +14,45 @@ SKELETON_SOURCE = SKELETON_ADD_TOOLCHAIN_DEPENDENCY = NO ifeq ($(BR2_ROOTFS_SKELETON_CUSTOM),y) + SKELETON_PATH = $(call qstrip,$(BR2_ROOTFS_SKELETON_CUSTOM_PATH)) + +ifeq ($(BR2_ROOTFS_MERGED_USR),y) + +# Ensure the user has prepared a merged /usr. +# +# Extract the inode numbers for all of those directories. In case any is +# a symlink, we want to get the inode of the pointed-to directory, so we +# append '/.' to be sure we get the target directory. Since the symlinks +# can be anyway (/bin -> /usr/bin or /usr/bin -> /bin), we do that for +# all of them. +# +SKELETON_LIB_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/lib/.) +SKELETON_BIN_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/bin/.) +SKELETON_SBIN_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/sbin/.) +SKELETON_USR_LIB_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/usr/lib/.) +SKELETON_USR_BIN_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/usr/bin/.) +SKELETON_USR_SBIN_INODE = $(shell stat -c '%i' $(SKELETON_PATH)/usr/sbin/.) + +ifneq ($(SKELETON_LIB_INODE),$(SKELETON_USR_LIB_INODE)) +SKELETON_CUSTOM_NOT_MERGED_USR += /lib +endif +ifneq ($(SKELETON_BIN_INODE),$(SKELETON_USR_BIN_INODE)) +SKELETON_CUSTOM_NOT_MERGED_USR += /bin +endif +ifneq ($(SKELETON_SBIN_INODE),$(SKELETON_USR_SBIN_INODE)) +SKELETON_CUSTOM_NOT_MERGED_USR += /sbin +endif + +ifneq ($(SKELETON_CUSTOM_NOT_MERGED_USR),) +$(error Use of systemd as an init system requires a merged /usr. \ + However, the custom skeleton in $(SKELETON_PATH) is not \ + using a merged /usr for the following directories: \ + $(SKELETON_CUSTOM_NOT_MERGED_USR)) +endif + +endif # merged /usr + else # ! custom skeleton SKELETON_PATH = system/skeleton
Signature · 1 line
1.9.1
PATCH 3/3 package/skeleton: ensure custom skeleton uses merged /usr if needed
Quoted 15 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Yann" == Yann E MORIN <[email protected]> writes:
When using systemd, the poolicy in Buildroot is to use a merged /usr (see
c5bd8af6, "system: add options for /bin /sbin and /lib to be symlinks into /usr" for more info). So, we apply a few tricks in some packages to account for the merged /usr case.However, when using a custom skeleton, we have no say in how that skeleton is organised, so it may well have a split /usr. In that case, our little tricks might not work as expected.
So, when the user uses a custom skeleton and wants systemd as an init system, we must check that the custom skeleton is setup with a merged /usr.
Quoted 7 lines
We do that by checking that each pair of {/lib,/usr/lib} {/bin,/usr/bin} and {/sbin,/usr/sbin} have the same inode numbers, i.e. /lib must have the same inode number as
/usr/lib(and so on...). When a pair does not share the same inode number, this is not a merged /usr and we abort.We implement that check with make constructs, so it is done very early in the build process, and we can abort early if need be.
Nice. It doesn't handle cases where absolute symlinks are used (E.G. /bin -> /usr/bin), but I don't see how we can fix that.
Committed series, thanks.
Signature · 1 line
Bye, Peter Korsgaard
PATCH 3/3 package/skeleton: ensure custom skeleton uses merged /usr if needed
Peter, All,
On 2015-11-11 00:22 +0100, Peter Korsgaard spake thusly:
Quoted 20 lines
Quoted 19 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Yann" == Yann E MORIN <[email protected]> writes:
When using systemd, the poolicy in Buildroot is to use a merged /usr (see
c5bd8af6, "system: add options for /bin /sbin and /lib to be symlinks into /usr" for more info). So, we apply a few tricks in some packages to account for the merged /usr case.However, when using a custom skeleton, we have no say in how that skeleton is organised, so it may well have a split /usr. In that case, our little tricks might not work as expected.
So, when the user uses a custom skeleton and wants systemd as an init system, we must check that the custom skeleton is setup with a merged /usr.
We do that by checking that each pair of {/lib,/usr/lib} {/bin,/usr/bin} and {/sbin,/usr/sbin} have the same inode numbers, i.e. /lib must have the same inode number as
/usr/lib(and so on...). When a pair does not share the same inode number, this is not a merged /usr and we abort.
Quoted 5 lines
Quoted 2 lines
We implement that check with make constructs, so it is done very early in the build process, and we can abort early if need be.
Nice. It doesn't handle cases where absolute symlinks are used (E.G. /bin ->
/usr/bin), but I don't see how we can fix that.
In that situation, then target/bin would indeed point to /usr/bin would point to the host's /usr/bin and that would break horribly as soon as a package would try to install something in there.
Well, that is not a change from the previous behaviour. that case was broken (aka unsupported) previously, it is still broken.
Regards,
Yann E. MORIN.
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'