Patchwork [1/1] busybox: fix the on-target upgrade problem

login
register
mail settings
Submitter Qi.Chen@windriver.com
Date July 3, 2013, 4:48 a.m.
Message ID <61d58e6bfc00142957a77a3a1747c9848710917a.1372826827.git.Qi.Chen@windriver.com>
Download mbox | patch
Permalink /patch/52861/
State Accepted
Commit cb534214286cb59f1ac377b6f1643c923c1289b1
Headers show

Comments

Qi.Chen@windriver.com - July 3, 2013, 4:48 a.m.
From: Chen Qi <Qi.Chen@windriver.com>

We now can have a 'one-binary' version of busybox, or 'two-binary'
version of busybox, controlled by the 'BUSYBOX_SPLIT_SUID' variable.
This makes on-target upgrade a problem, as we have to support the
following four upgrading paths.

For convenience, in the following context, A is used to denote a
'two-binary' version of busybox while B is used to denote a 'one-binary'
version of busybox.

A --(upgrade)--> B
B --(upgrade)--> A
A --(upgrade)--> A
B --(upgrade)--> B

This patch makes effort to support the above four situations.

[YOCTO #4802]

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
 meta/recipes-core/busybox/busybox.inc |   48 +++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
Martin Jansa - July 6, 2013, 10:27 a.m.
On Wed, Jul 03, 2013 at 12:48:12PM +0800, Qi.Chen@windriver.com wrote:
> From: Chen Qi <Qi.Chen@windriver.com>
> 
> We now can have a 'one-binary' version of busybox, or 'two-binary'
> version of busybox, controlled by the 'BUSYBOX_SPLIT_SUID' variable.
> This makes on-target upgrade a problem, as we have to support the
> following four upgrading paths.
> 
> For convenience, in the following context, A is used to denote a
> 'two-binary' version of busybox while B is used to denote a 'one-binary'
> version of busybox.
> 
> A --(upgrade)--> B
> B --(upgrade)--> A
> A --(upgrade)--> A
> B --(upgrade)--> B
> 
> This patch makes effort to support the above four situations.

Thanks for looking into it (it's more complicated then I've first
expected) and it looks like there is more issues probably caused
by applet path moved in latest busybox upgrade (but ip looks weird) :/

update-alternatives: Error: cannot register alternative addgroup to
/usr/sbin/addgroup since it is already registered to /bin/addgroup
update-alternatives: Error: cannot register alternative adduser to
/usr/sbin/adduser since it is already registered to /bin/adduser

update-alternatives: Error: cannot register alternative delgroup to
/usr/sbin/delgroup since it is already registered to /bin/delgroup
update-alternatives: Error: cannot register alternative deluser to
/usr/sbin/deluser since it is already registered to /bin/deluser

update-alternatives: Error: cannot register alternative ip to /sbin/ip
since it is already registered to /bin/ip

SHR root@gjama ~ $ cat /var/lib/opkg/alternatives/ip
/bin/ip
busybox 50
/bin/busybox 50
/bin/busybox.nosuid 50
SHR root@gjama ~ $ cat /var/lib/opkg/alternatives/adduser
/bin/adduser
/bin/busybox.nosuid 50
SHR root@gjama ~ $ cat /var/lib/opkg/alternatives/addgroup
/bin/addgroup
/bin/busybox.nosuid 50
SHR root@gjama ~ $ cat /var/lib/opkg/alternatives/delgroup
/bin/delgroup
/bin/busybox.nosuid 50
SHR root@gjama ~ $ cat /var/lib/opkg/alternatives/deluser
/bin/deluser
/bin/busybox.nosuid 50

> [YOCTO #4802]
> 
> Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
> ---
>  meta/recipes-core/busybox/busybox.inc |   48 +++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc
> index 8567d64..acd2bfb 100644
> --- a/meta/recipes-core/busybox/busybox.inc
> +++ b/meta/recipes-core/busybox/busybox.inc
> @@ -190,6 +190,10 @@ do_install () {
>  			install -m 0644 ${S}/busybox.links.suid ${D}${sysconfdir}
>  			install -m 0644 ${S}/busybox.links.nosuid ${D}${sysconfdir}
>  			ln -sf busybox.nosuid ${D}${base_bindir}/sh
> +			# Keep a default busybox for people who want to invoke busybox directly.
> +			# This is also useful for the on device upgrade. Because we want
> +			# to use the busybox command in postinst.
> +			ln -sf busybox.nosuid ${D}${base_bindir}/busybox
>  		else
>  			if grep -q "CONFIG_FEATURE_SUID=y" ${B}/.config; then
>  				install -m 4755 ${B}/busybox ${D}${base_bindir}
> @@ -198,6 +202,12 @@ do_install () {
>  			fi
>  			install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
>  			ln -sf busybox ${D}${base_bindir}/sh
> +			# We make this symlink here to eliminate the error when upgrading together
> +			# with busybox-syslog. Without this symlink, the opkg may think of the
> +			# busybox.nosuid as obsolete and remove it, resulting in dead links like
> +			# /bin/sed -> /bin/busybox.nosuid. This will make upgrading busybox-syslog fail.
> +			# This symlink will be safely deleted in postinst, thus no negative effect.
> +			ln -sf busybox ${D}${base_bindir}/busybox.nosuid
>  		fi
>  	else
>  		install -d ${D}${base_bindir} ${D}${base_sbindir}
> @@ -306,6 +316,44 @@ python do_package_prepend () {
>          set_alternative_vars("/etc/busybox.links.suid", "/bin/busybox.suid")
>  }
>  
> +pkg_postinst_${PN} () {
> +	# This part of code is dedicated to the on target upgrade problem.
> +	# It's known that if we don't make appropriate symlinks before update-alternatives calls,
> +	# there will be errors indicating missing commands such as 'sed'.
> +	# These symlinks will later be updated by update-alternatives calls.
> +	test -n 2 > /dev/null || alias test='busybox test'
> +	if test "x$D" = "x"; then
> +		# Remove busybox.nosuid if it's a symlink, because this situation indicates
> +		# that we're installing or upgrading to a one-binary busybox.
> +		if test -h /bin/busybox.nosuid; then
> +			rm -f /bin/busybox.nosuid
> +		fi
> +		for suffix in "" ".nosuid" ".suid"; do
> +			if test -e /etc/busybox.links$suffix; then
> +				while read link; do
> +					if test ! -e "$link"; then
> +						case "$link" in
> +							/*/*/*)
> +								to="../../bin/busybox$suffix"
> +								;;
> +							/bin/*)
> +								to="busybox$suffix"
> +								;;
> +							/*/*)
> +								to="../bin/busybox$suffix"
> +								;;
> +						esac
> +						# we can use busybox here because even if we are using splitted busybox
> +						# we've made a symlink from /bin/busybox to /bin/busybox.nosuid.
> +						busybox rm -f $link
> +						busybox ln -s $to $link
> +					fi
> +				done < /etc/busybox.links$suffix
> +			fi
> +		done
> +	fi
> +}
> +
>  pkg_prerm_${PN} () {
>  	# This is so you can make busybox commit suicide - removing busybox with no other packages
>  	# providing its files, this will make update-alternatives work, but the update-rc.d part
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core

Patch

diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc
index 8567d64..acd2bfb 100644
--- a/meta/recipes-core/busybox/busybox.inc
+++ b/meta/recipes-core/busybox/busybox.inc
@@ -190,6 +190,10 @@  do_install () {
 			install -m 0644 ${S}/busybox.links.suid ${D}${sysconfdir}
 			install -m 0644 ${S}/busybox.links.nosuid ${D}${sysconfdir}
 			ln -sf busybox.nosuid ${D}${base_bindir}/sh
+			# Keep a default busybox for people who want to invoke busybox directly.
+			# This is also useful for the on device upgrade. Because we want
+			# to use the busybox command in postinst.
+			ln -sf busybox.nosuid ${D}${base_bindir}/busybox
 		else
 			if grep -q "CONFIG_FEATURE_SUID=y" ${B}/.config; then
 				install -m 4755 ${B}/busybox ${D}${base_bindir}
@@ -198,6 +202,12 @@  do_install () {
 			fi
 			install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
 			ln -sf busybox ${D}${base_bindir}/sh
+			# We make this symlink here to eliminate the error when upgrading together
+			# with busybox-syslog. Without this symlink, the opkg may think of the
+			# busybox.nosuid as obsolete and remove it, resulting in dead links like
+			# /bin/sed -> /bin/busybox.nosuid. This will make upgrading busybox-syslog fail.
+			# This symlink will be safely deleted in postinst, thus no negative effect.
+			ln -sf busybox ${D}${base_bindir}/busybox.nosuid
 		fi
 	else
 		install -d ${D}${base_bindir} ${D}${base_sbindir}
@@ -306,6 +316,44 @@  python do_package_prepend () {
         set_alternative_vars("/etc/busybox.links.suid", "/bin/busybox.suid")
 }
 
+pkg_postinst_${PN} () {
+	# This part of code is dedicated to the on target upgrade problem.
+	# It's known that if we don't make appropriate symlinks before update-alternatives calls,
+	# there will be errors indicating missing commands such as 'sed'.
+	# These symlinks will later be updated by update-alternatives calls.
+	test -n 2 > /dev/null || alias test='busybox test'
+	if test "x$D" = "x"; then
+		# Remove busybox.nosuid if it's a symlink, because this situation indicates
+		# that we're installing or upgrading to a one-binary busybox.
+		if test -h /bin/busybox.nosuid; then
+			rm -f /bin/busybox.nosuid
+		fi
+		for suffix in "" ".nosuid" ".suid"; do
+			if test -e /etc/busybox.links$suffix; then
+				while read link; do
+					if test ! -e "$link"; then
+						case "$link" in
+							/*/*/*)
+								to="../../bin/busybox$suffix"
+								;;
+							/bin/*)
+								to="busybox$suffix"
+								;;
+							/*/*)
+								to="../bin/busybox$suffix"
+								;;
+						esac
+						# we can use busybox here because even if we are using splitted busybox
+						# we've made a symlink from /bin/busybox to /bin/busybox.nosuid.
+						busybox rm -f $link
+						busybox ln -s $to $link
+					fi
+				done < /etc/busybox.links$suffix
+			fi
+		done
+	fi
+}
+
 pkg_prerm_${PN} () {
 	# This is so you can make busybox commit suicide - removing busybox with no other packages
 	# providing its files, this will make update-alternatives work, but the update-rc.d part