Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Sep 2012 15:55:13 -0500
From:      Bryan Drewery <bdrewery@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        bapt@FreeBSD.org, portmgr@FreeBSD.org
Subject:   ports/171672: [bsd.port.mk / bsd.pkgng.mk][exp-run] Make 'do-package' atomic while creating the pkg file
Message-ID:  <201209152055.q8FKtIWA018650@freefall.freebsd.org>
Resent-Message-ID: <201209152100.q8FL0N07033691@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         171672
>Category:       ports
>Synopsis:       [bsd.port.mk / bsd.pkgng.mk][exp-run] Make 'do-package' atomic while creating the pkg file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 15 21:00:23 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Bryan Drewery
>Release:        FreeBSD 8.3-RELEASE i386
>Organization:
>Environment:

	
>Description:
	I found while developing poudriere (for package building), that if you hit CTRL C at the right moment (while a large port is in the 'package' phase), the package repository is left with a bad package that is only partially full.
	This can also occur under more automatic means during package creation such as running out of memory, system panics, NFS mount disappearing, etc.
>How-To-Repeat:
	## Test 1
	# make -C /usr/ports/lang/ruby18 package
	## Hit ctrl+c during the package phase, observe that a bad package is created.

	## Test 2
	# make -C /usr/ports/lang/ruby18 repackage
	## A valid package now exists
	# make -C /usr/ports/lang/ruby18 repackage
	## Hit ctrl+c during the 2nd repackage phase, observe that a partial (bad) package overwrites the existing package.
>Fix:

	Patch fixes 'do-package' for both pkgng and pkg_install to use a tempfile, and then anatomically move that file to the real location once completed. A trap is used to ensure that no tmp file is leftover. The same tmpfile pattern is used from the 'make config' handling.

	Patch is mirrored at http://people.freebsd.org/~bdrewery/patch-bpm-atomic-do-package.txt

--- patch-bpm-atomic-do-package.txt begins here ---
diff --git bsd.pkgng.mk bsd.pkgng.mk
index 924df65..18fbad1 100644
--- bsd.pkgng.mk
+++ bsd.pkgng.mk
@@ -230,11 +230,16 @@ do-package: ${TMPPLIST}
 			fi; \
 		fi; \
 	fi;
-	@if ${PKG_CREATE} -o ${PKGREPOSITORY} ${PKGNAME}; then \
+	@TMPPKGREPOSITORY=$$(mktemp -dt pkg); \
+	trap "${RM} -rf $${TMPPKGREPOSITORY}; exit 1" 1 2 3 5 10 13 15; \
+	if ${PKG_CREATE} -o $${TMPPKGREPOSITORY} ${PKGNAME}; then \
+		${MV} -f $${TMPPKGREPOSITORY}/${PKGNAME}${PKG_SUFX} ${PKGREPOSITORY}; \
+		${RM} -rf $${TMPPKGREPOSITORY}; \
 		if [ -d ${PACKAGES} ]; then \
 			cd ${.CURDIR} && eval ${MAKE} package-links; \
 		fi; \
 	else \
+		${RM} -rf $${TMPPKGREPOSITORY}; \
 		cd ${.CURDIR} && eval ${MAKE} delete-package; \
 		exit 1; \
 	fi
diff --git bsd.port.mk bsd.port.mk
index 09e800f..f41773a 100644
--- bsd.port.mk
+++ bsd.port.mk
@@ -3911,11 +3911,15 @@ do-package: ${TMPPLIST}
 			fi; \
 		fi; \
 	fi
-	@if ${PKG_CMD} -b ${PKGNAME} ${PKGFILE}; then \
+	@TMPPKGFILE=$$(mktemp -t pkg); \
+	trap "${RM} -f $${TMPPKGFILE} $${TMPPKGFILE}${PKG_SUFX}; exit 1" 1 2 3 5 10 13 15; \
+	if ${PKG_CMD} -b ${PKGNAME} $${TMPPKGFILE}; then \
+		${MV} -f $${TMPPKGFILE}${PKG_SUFX} ${PKGFILE}; \
 		if [ -d ${PACKAGES} ]; then \
 			cd ${.CURDIR} && eval ${MAKE} package-links; \
 		fi; \
 	else \
+		${RM} -f $${TMPPKGFILE}; \
 		cd ${.CURDIR} && eval ${MAKE} delete-package; \
 		exit 1; \
 	fi
--- patch-bpm-atomic-do-package.txt ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209152055.q8FKtIWA018650>