git: 1cf8528fec85 - stable/14 - freebsd-update: handle directories changing to files

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Sun, 07 Jan 2024 01:27:31 UTC
The branch stable/14 has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=1cf8528fec85a965baa5df2d8852166437af88a6

commit 1cf8528fec85a965baa5df2d8852166437af88a6
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-09-12 02:59:30 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2024-01-07 01:27:17 +0000

    freebsd-update: handle directories changing to files
    
    Further to f6d37c9ca13f ("freebsd-update: handle file -> directory on
    upgrade"), handle the reverse case of a directory changing to a file.
    We may not encounter this case on upgradess (before freebsd-update is
    retired) but it is needed to support rollback.
    
    PR:             273950
    Reviewed by:    dim
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D41945
    
    (cherry picked from commit c0f52443166ae7ecd512ab0350469d9c3648788c)
---
 usr.sbin/freebsd-update/freebsd-update.sh | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index f5289e1cd9fc..7408ef1c6721 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -2899,6 +2899,15 @@ backup_kernel () {
 	set +f
 }
 
+# Check for and remove an existing directory that conflicts with the file or
+# symlink that we are going to install.
+dir_conflict () {
+	if [ -d "$1" ]; then
+		echo "Removing conflicting directory $1"
+		rm -rf -- "$1"
+	fi
+}
+
 # Install new files
 install_from_index () {
 	# First pass: Do everything apart from setting file flags.  We
@@ -2919,6 +2928,7 @@ install_from_index () {
 			    -m ${PERM} ${BASEDIR}/${FPATH}
 			;;
 		f)
+			dir_conflict "${BASEDIR}/${FPATH}"
 			if [ -z "${LINK}" ]; then
 				# Create a file, without setting flags.
 				gunzip < files/${HASH}.gz > ${HASH}
@@ -2931,6 +2941,7 @@ install_from_index () {
 			fi
 			;;
 		L)
+			dir_conflict "${BASEDIR}/${FPATH}"
 			# Create a symlink
 			ln -sfh ${HASH} ${BASEDIR}/${FPATH}
 			;;
@@ -2967,10 +2978,14 @@ install_delete () {
 			rmdir ${BASEDIR}/${FPATH}
 			;;
 		f)
-			rm ${BASEDIR}/${FPATH}
+			if [ -f "${BASEDIR}/${FPATH}" ]; then
+				rm "${BASEDIR}/${FPATH}"
+			fi
 			;;
 		L)
-			rm ${BASEDIR}/${FPATH}
+			if [ -L "${BASEDIR}/${FPATH}" ]; then
+				rm "${BASEDIR}/${FPATH}"
+			fi
 			;;
 		esac
 	done < killfiles