diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc
index 622325aabb..c0b63ad2c0 100644
--- a/meta/recipes-core/busybox/busybox.inc
+++ b/meta/recipes-core/busybox/busybox.inc
@@ -387,95 +387,95 @@ python do_package:prepend () {
         set_alternative_vars("${sysconfdir}/busybox.links.suid", "${base_bindir}/busybox.suid")
 }
 
-# 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.
-# The update-alternatives.bbclass' postinst script runs firstly before other
-# postinst, but this part of code needs run firstly, so add this funtion.
-python populate_packages_updatealternatives:append() {
-    postinst = """
-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 ${base_bindir}/busybox.nosuid; then
-        rm -f ${base_bindir}/busybox.nosuid
-    fi
-    for suffix in "" ".nosuid" ".suid"; do
-        if test -e ${sysconfdir}/busybox.links$suffix; then
-            while read link; do
-                if test ! -e "$link"; then
-                    # 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 "${base_bindir}/busybox$suffix" $link
-                fi
-            done < ${sysconfdir}/busybox.links$suffix
-        fi
-    done
-fi
-if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links*; then
-    grep -q "^${base_bindir}/bash$" $D${sysconfdir}/shells || echo ${base_bindir}/bash >> $D${sysconfdir}/shells
-fi
-
-"""
-    d.prependVar('pkg_postinst:%s' % pkg, postinst)
-}
-
-pkg_postinst:${PN}:prepend () {
-        # Need path to saved utils, but they may have be removed on upgrade of busybox
-        # Only use shell to get paths. Also capture if busybox was saved.
-        BUSYBOX=""
-        if [ "x$D" = "x" ] ; then 
+pkg_postinst:${PN}:append () {
+        if [ "x$D" = "x" ] ; then
+           # Older versions may have added a temporary directory and an alternative
+           # to sh in a prerm step.  Remove these if they are present.
            for busybox_rmdir in /tmp/busyboxrm-*; do
                if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then
-                  export PATH=$busybox_rmdir:$PATH
                   if [ -e $busybox_rmdir/busybox* ] ; then
                     BUSYBOX="$busybox_rmdir/busybox*"
+                    update-alternatives --remove sh $BUSYBOX
+                    rm -f $BUSYBOX
                   fi
                fi
            done
-        fi
-}
 
-pkg_postinst:${PN}:append () {
-        # If busybox exists in the remove directory it is because it was the only shell left.
-        if [ "x$D" = "x" ] ; then
-           if [ "x$BUSYBOX" != "x" ] ; then
-              update-alternatives --remove sh $BUSYBOX
-              rm -f $BUSYBOX
-           fi
+           # Remove the temporary alternatives
+           for busybox_preinstdir in /tmp/busyboxpreinst-*; do
+               if [ "$busybox_preinstdir" != '/tmp/busyboxpreinst-*' ] ; then
+                  BUSYBOX_PREINST_DIR="$busybox_preinstdir"
+                  BUSYBOX="$BUSYBOX_PREINST_DIR/busybox"
+                  if [ -e $BUSYBOX ] ; then
+                      for suffix in "" ".nosuid" ".suid"; do
+                          if [ -e $BUSYBOX_PREINST_DIR/busybox.links$suffix ] ; then
+                              while read link; do
+                                  update-alternatives --remove $($BUSYBOX basename $link) $BUSYBOX
+                              done < $BUSYBOX_PREINST_DIR/busybox.links$suffix
+                          fi
+                      done
+                  fi
+                  rm -rf $BUSYBOX_PREINST_DIR
+               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
-	# for syslog, httpd and/or udhcpd will fail if there is no other package providing sh
-	tmpdir=`mktemp -d /tmp/busyboxrm-XXXXXX`
-	ln -s ${base_bindir}/busybox $tmpdir/[
-	ln -s ${base_bindir}/busybox $tmpdir/test
-	ln -s ${base_bindir}/busybox $tmpdir/head
-	ln -s ${base_bindir}/busybox $tmpdir/sh
-	ln -s ${base_bindir}/busybox $tmpdir/basename
-	ln -s ${base_bindir}/busybox $tmpdir/echo
-	ln -s ${base_bindir}/busybox $tmpdir/mv
-	ln -s ${base_bindir}/busybox $tmpdir/ln
-	ln -s ${base_bindir}/busybox $tmpdir/dirname
-	ln -s ${base_bindir}/busybox $tmpdir/rm
-	ln -s ${base_bindir}/busybox $tmpdir/sed
-	ln -s ${base_bindir}/busybox $tmpdir/sort
-	ln -s ${base_bindir}/busybox $tmpdir/grep
-	ln -s ${base_bindir}/busybox $tmpdir/tail
-	export PATH=$PATH:$tmpdir
-
-        # If busybox is the shell, we need to save it since its the lowest priority shell
-        # Register saved bitbake as the lowest priority shell possible as back up.
-        if [ -n "$(readlink -f /bin/sh | grep busybox)" ] ; then
-           BUSYBOX=$(readlink -f /bin/sh)
-           cp $BUSYBOX $tmpdir/$(basename $BUSYBOX)
-           update-alternatives --install /bin/sh sh $tmpdir/$(basename $BUSYBOX) 1 
+pkg_preinst:${PN} () {
+
+        # Create a temporary copy the busybox binary and the links files.  Then,
+        # install an alternative link for all the links.  Other packages use these
+        # commands during their upgrade process.  This ensures the links are available
+        # to all the other packages.  We do this in the preinst step because it is
+        # the first step guaranteed to be used from the new package.  The prerm is
+        # used from the old package.  Placing this here ensures it runs on upgrade even
+        # on older systems.
+
+        if [ "x$D" = "x" ] ; then
+           # Create a temporary directory for the busybox binary and the link lists
+           BUSYBOX=${base_bindir}/busybox
+           BUSYBOX_TMP_DIR=`$BUSYBOX mktemp -d /tmp/busyboxpreinst-XXXXXX`
+           BUSYBOX_TMP_LOC="$BUSYBOX_TMP_DIR/busybox"
+           $BUSYBOX cp $BUSYBOX $BUSYBOX_TMP_LOC
+
+           # Commands needed by update-alternatives may not exist anymore.  Set softlinks
+           # for these commands so update-alternatives will function.
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/[
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/test
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/head
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/sh
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/basename
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/echo
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/mv
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/ln
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/dirname
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/rm
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/sed
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/sort
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/grep
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/tail
+           $BUSYBOX ln -s $BUSYBOX_TMP_LOC $BUSYBOX_TMP_DIR/cp
+
+           # Export the path to the temporary directory so update-alternatives can find the
+           # new links
+           OLD_PATH=$PATH
+           export PATH=$PATH:$BUSYBOX_TMP_DIR
+
+           # Go through all the links and install an alternative that points to the temporary
+           # busybox binary.
+           for suffix in "" ".nosuid" ".suid"; do
+               if [ -e ${sysconfdir}/busybox.links$suffix ] ; then
+                   cp ${sysconfdir}/busybox.links$suffix $BUSYBOX_TMP_DIR
+                   while read link; do
+                       # Old packages may have installed an alternative to sh at priority 1.
+                       # Install these at priority 2 to avoid conflict.
+                       update-alternatives --install $link $(basename $link) $BUSYBOX_TMP_LOC 2
+                   done < $BUSYBOX_TMP_DIR/busybox.links$suffix
+               fi
+           done
+
+           # Reset PATH to its previous value
+           PATH=$OLD_PATH
         fi
 }
 
