summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2015-05-13 22:52:51 +0000
committerXin LI <delphij@FreeBSD.org>2015-05-13 22:52:51 +0000
commitb6595c901e915b667554d39721a6709e727ddcdb (patch)
tree6af8a6e76330ac4a47b13eaa3e822253e7ed4caa
parentee715bcbe9d3dc78a9c2f9fde2c367db75599b00 (diff)
downloadsrc-test2-b6595c901e915b667554d39721a6709e727ddcdb.tar.gz
src-test2-b6595c901e915b667554d39721a6709e727ddcdb.zip
Notes
-rw-r--r--UPDATING5
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.845
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.sh149
4 files changed, 146 insertions, 55 deletions
diff --git a/UPDATING b/UPDATING
index 9f9b030e4e60..f6dd8887d9e6 100644
--- a/UPDATING
+++ b/UPDATING
@@ -15,6 +15,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
debugging tools present in HEAD were left in place because
sun4v support still needs work to become production ready.
+20150513: p28 FreeBSD-EN-15:04.freebsd-update
+
+ Fix bug with freebsd-update(8) that does not ensure the previous
+ upgrade was completed. [EN-15:04]
+
20150407: p27 FreeBSD-SA-15:04.igmp [revised]
FreeBSD-SA-15:07.ntp
FreeBSD-SA-15:09.ipv6
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 42587eb6e61b..1b166a94f65c 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="8.4"
-BRANCH="RELEASE-p27"
+BRANCH="RELEASE-p28"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/usr.sbin/freebsd-update/freebsd-update.8 b/usr.sbin/freebsd-update/freebsd-update.8
index ccae36f1dbf1..dcba710166b2 100644
--- a/usr.sbin/freebsd-update/freebsd-update.8
+++ b/usr.sbin/freebsd-update/freebsd-update.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 14, 2010
+.Dd March 2, 2015
.Dt FREEBSD-UPDATE 8
.Os FreeBSD
.Sh NAME
@@ -36,10 +36,12 @@
.Op Fl b Ar basedir
.Op Fl d Ar workdir
.Op Fl f Ar conffile
+.Op Fl F
.Op Fl k Ar KEY
.Op Fl r Ar newrelease
.Op Fl s Ar server
.Op Fl t Ar address
+.Op Fl -not-running-from-cron
.Cm command ...
.Sh DESCRIPTION
The
@@ -49,21 +51,21 @@ updates to the FreeBSD base system.
Note that updates are only available if they are being built for the
FreeBSD release and architecture being used; in particular, the
.Fx
-Security Team only builds updates for releases shipped in binary form
+Security Team only builds updates for releases shipped in binary form
by the
.Fx
Release Engineering Team, e.g.,
.Fx
-7.3-RELEASE and
+9.3-RELEASE and
.Fx
-8.0, but not
+10.1-RELEASE, but not
.Fx
-6.3-STABLE or
+9.3-STABLE or
.Fx
-9.0-CURRENT.
+11-CURRENT.
.Sh OPTIONS
The following options are supported:
-.Bl -tag -width "-f conffile"
+.Bl -tag -width "-r newrelease"
.It Fl b Ar basedir
Operate on a system mounted at
.Ar basedir .
@@ -81,6 +83,10 @@ Read configuration options from
.Ar conffile .
(default:
.Pa /etc/freebsd-update.conf )
+.It Fl F
+Force
+.Nm Cm fetch
+to proceed where it normally would not, such as an unfinished upgrade
.It Fl k Ar KEY
Trust an RSA key with SHA256 of
.Ar KEY .
@@ -98,13 +104,21 @@ Mail output of
command, if any, to
.Ar address .
(default: root, or as given in the configuration file.)
+.It Fl -not-running-from-cron
+Force
+.Nm Cm fetch
+to proceed when there is no controlling tty.
+This is for use by automated scripts and orchestration tools.
+Please do not run
+.Nm Cm fetch
+from crontab or similar using this flag, see:
+.Nm Cm cron
.El
.Sh COMMANDS
The
.Cm command
can be any one of the following:
-.Pp
-.Bl -tag -width "-f conffile"
+.Bl -tag -width "rollback"
.It Cm fetch
Based on the currently installed world and the configuration
options set, fetch all available binary updates.
@@ -128,6 +142,11 @@ Fetch files necessary for upgrading to a new release.
Before using this command, make sure that you read the
announcement and release notes for the new release in
case there are any special steps needed for upgrading.
+Note that this command may require up to 500 MB of space in
+.Ar workdir
+depending on which components of the
+.Fx
+base system are installed.
.It Cm install
Install the most recently fetched updates or upgrade.
.It Cm rollback
@@ -149,7 +168,7 @@ other than 3AM, to avoid overly imposing an uneven load
on the server(s) hosting the updates.
.It
In spite of its name,
-.Cm
+.Nm
IDS should not be relied upon as an "Intrusion Detection
System", since if the system has been tampered with
it cannot be trusted to operate correctly.
@@ -158,11 +177,11 @@ purposes, make sure you boot from a secure disk (e.g., a CD).
.El
.Sh FILES
.Bl -tag -width "/etc/freebsd-update.conf"
-.It /etc/freebsd-update.conf
+.It Pa /etc/freebsd-update.conf
Default location of the
.Nm
configuration file.
-.It /var/db/freebsd-update/
+.It Pa /var/db/freebsd-update/
Default location where
.Nm
stores temporary files and downloaded updates.
@@ -170,4 +189,4 @@ stores temporary files and downloaded updates.
.Sh SEE ALSO
.Xr freebsd-update.conf 5
.Sh AUTHORS
-.An Colin Percival Aq cperciva@FreeBSD.org
+.An Colin Percival Aq Mt cperciva@FreeBSD.org
diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index 23f2c109ee23..fda1d9049db2 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -43,12 +43,15 @@ Options:
(default: /var/db/freebsd-update/)
-f conffile -- Read configuration options from conffile
(default: /etc/freebsd-update.conf)
+ -F -- Force a fetch operation to proceed
-k KEY -- Trust an RSA key with SHA256 hash of KEY
-r release -- Target for upgrade (e.g., 6.2-RELEASE)
-s server -- Server from which to fetch updates
(default: update.FreeBSD.org)
-t address -- Mail output of cron command, if any, to address
(default: root)
+ --not-running-from-cron
+ -- Run without a tty, for use by automated tools
Commands:
fetch -- Fetch updates from server
cron -- Sleep rand(3600) seconds, fetch updates, and send an
@@ -284,6 +287,9 @@ config_TargetRelease () {
else
return 1
fi
+ if echo ${TARGETRELEASE} | grep -qE '^[0-9.]+$'; then
+ TARGETRELEASE="${TARGETRELEASE}-RELEASE"
+ fi
}
# Define what happens to output of utilities
@@ -396,6 +402,12 @@ init_params () {
# No commands specified yet
COMMANDS=""
+
+ # Force fetch to proceed
+ FORCEFETCH=0
+
+ # Run without a TTY
+ NOTTYOK=0
}
# Parse the command line
@@ -408,6 +420,12 @@ parse_cmdline () {
if [ ! -z "${CONFFILE}" ]; then usage; fi
shift; CONFFILE="$1"
;;
+ -F)
+ FORCEFETCH=1
+ ;;
+ --not-running-from-cron)
+ NOTTYOK=1
+ ;;
# Configuration file equivalents
-b)
@@ -569,7 +587,7 @@ fetch_setup_verboselevel () {
# running *-p[0-9]+, strip off the last part; if the
# user is running -SECURITY, call it -RELEASE. Chdir
# into the working directory.
-fetch_check_params () {
+fetchupgrade_check_params () {
export HTTP_USER_AGENT="freebsd-update (${COMMAND}, `uname -r`)"
_SERVERNAME_z=\
@@ -577,6 +595,7 @@ fetch_check_params () {
_KEYPRINT_z="Key must be given via -k option or configuration file."
_KEYPRINT_bad="Invalid key fingerprint: "
_WORKDIR_bad="Directory does not exist or is not writable: "
+ _WORKDIR_bad2="Directory is not on a persistent filesystem: "
if [ -z "${SERVERNAME}" ]; then
echo -n "`basename $0`: "
@@ -600,6 +619,13 @@ fetch_check_params () {
echo ${WORKDIR}
exit 1
fi
+ case `df -T ${WORKDIR}` in */dev/md[0-9]* | *tmpfs*)
+ echo -n "`basename $0`: "
+ echo -n "${_WORKDIR_bad2}"
+ echo ${WORKDIR}
+ exit 1
+ ;;
+ esac
chmod 700 ${WORKDIR}
cd ${WORKDIR} || exit 1
@@ -652,9 +678,29 @@ fetch_check_params () {
BDHASH=`echo ${BASEDIR} | sha256 -q`
}
+# Perform sanity checks etc. before fetching updates.
+fetch_check_params () {
+ fetchupgrade_check_params
+
+ if ! [ -z "${TARGETRELEASE}" ]; then
+ echo -n "`basename $0`: "
+ echo -n "-r option is meaningless with 'fetch' command. "
+ echo "(Did you mean 'upgrade' instead?)"
+ exit 1
+ fi
+
+ # Check that we have updates ready to install
+ if [ -f ${BDHASH}-install/kerneldone -a $FORCEFETCH -eq 0 ]; then
+ echo "You have a partially completed upgrade pending"
+ echo "Run '$0 install' first."
+ echo "Run '$0 fetch -F' to proceed anyway."
+ exit 1
+ fi
+}
+
# Perform sanity checks etc. before fetching upgrades.
upgrade_check_params () {
- fetch_check_params
+ fetchupgrade_check_params
# Unless set otherwise, we're upgrading to the same kernel config.
NKERNCONF=${KERNCONF}
@@ -1185,7 +1231,7 @@ fetch_metadata_sanity () {
# Some aliases to save space later: ${P} is a character which can
# appear in a path; ${M} is the four numeric metadata fields; and
# ${H} is a sha256 hash.
- P="[-+./:=%@_[~[:alnum:]]"
+ P="[-+./:=,%@_[~[:alnum:]]"
M="[0-9]+\|[0-9]+\|[0-9]+\|[0-9]+"
H="[0-9a-f]{64}"
@@ -1456,7 +1502,7 @@ fetch_inspect_system () {
sort -k 3,3 -t '|' > $2.tmp
rm filelist
- # Check if an error occured during system inspection
+ # Check if an error occurred during system inspection
if [ -f .err ]; then
return 1
fi
@@ -2240,6 +2286,19 @@ upgrade_oldall_to_oldnew () {
mv $2 $3
}
+# Helper for upgrade_merge: Return zero true iff the two files differ only
+# in the contents of their RCS tags.
+samef () {
+ X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}`
+ Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}`
+
+ if [ $X = $Y ]; then
+ return 0;
+ else
+ return 1;
+ fi
+}
+
# From the list of "old" files in $1, merge changes in $2 with those in $3,
# and update $3 to reflect the hashes of merged files.
upgrade_merge () {
@@ -2323,6 +2382,14 @@ upgrade_merge () {
# Ask the user to handle any files which didn't merge.
while read F; do
+ # If the installed file differs from the version in
+ # the old release only due to RCS tag expansion
+ # then just use the version in the new release.
+ if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then
+ cp merge/${RELNUM}/${F} merge/new/${F}
+ continue
+ fi
+
cat <<-EOF
The following file could not be merged automatically: ${F}
@@ -2337,9 +2404,18 @@ manually...
# Ask the user to confirm that he likes how the result
# of merging files.
while read F; do
- # Skip files which haven't changed.
- if [ -f merge/new/${F} ] &&
- cmp -s merge/old/${F} merge/new/${F}; then
+ # Skip files which haven't changed except possibly
+ # in their RCS tags.
+ if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] &&
+ samef merge/old/${F} merge/new/${F}; then
+ continue
+ fi
+
+ # Skip files where the installed file differs from
+ # the old file only due to RCS tags.
+ if [ -f merge/old/${F} ] &&
+ [ -f merge/${OLDRELNUM}/${F} ] &&
+ samef merge/old/${F} merge/${OLDRELNUM}/${F}; then
continue
fi
@@ -2526,6 +2602,10 @@ upgrade_run () {
# Leave a note behind to tell the "install" command that the kernel
# needs to be installed before the world.
touch ${BDHASH}-install/kernelfirst
+
+ # Remind the user that they need to run "freebsd-update install"
+ # to install the downloaded bits, in case they didn't RTFM.
+ echo "To install the downloaded upgrades, run \"$0 install\"."
}
# Make sure that all the file hashes mentioned in $@ have corresponding
@@ -2577,14 +2657,14 @@ backup_kernel_finddir () {
while true ; do
# Pathname does not exist, so it is OK use that name
# for backup directory.
- if [ ! -e $BACKUPKERNELDIR ]; then
+ if [ ! -e $BASEDIR/$BACKUPKERNELDIR ]; then
return 0
fi
# If directory do exist, we only use if it has our
# marker file.
- if [ -d $BACKUPKERNELDIR -a \
- -e $BACKUPKERNELDIR/.freebsd-update ]; then
+ if [ -d $BASEDIR/$BACKUPKERNELDIR -a \
+ -e $BASEDIR/$BACKUPKERNELDIR/.freebsd-update ]; then
return 0
fi
@@ -2592,7 +2672,7 @@ backup_kernel_finddir () {
# the end and try again.
CNT=$((CNT + 1))
if [ $CNT -gt 9 ]; then
- echo "Could not find valid backup dir ($BACKUPKERNELDIR)"
+ echo "Could not find valid backup dir ($BASEDIR/$BACKUPKERNELDIR)"
exit 1
fi
BACKUPKERNELDIR="`echo $BACKUPKERNELDIR | sed -Ee 's/[0-9]\$//'`"
@@ -2619,17 +2699,17 @@ backup_kernel () {
# Remove old kernel backup files. If $BACKUPKERNELDIR was
# "not ours", backup_kernel_finddir would have exited, so
# deleting the directory content is as safe as we can make it.
- if [ -d $BACKUPKERNELDIR ]; then
- rm -fr $BACKUPKERNELDIR
+ if [ -d $BASEDIR/$BACKUPKERNELDIR ]; then
+ rm -fr $BASEDIR/$BACKUPKERNELDIR
fi
# Create directories for backup.
- mkdir -p $BACKUPKERNELDIR
- mtree -cdn -p "${KERNELDIR}" | \
- mtree -Ue -p "${BACKUPKERNELDIR}" > /dev/null
+ mkdir -p $BASEDIR/$BACKUPKERNELDIR
+ mtree -cdn -p "${BASEDIR}/${KERNELDIR}" | \
+ mtree -Ue -p "${BASEDIR}/${BACKUPKERNELDIR}" > /dev/null
# Mark the directory as having been created by freebsd-update.
- touch $BACKUPKERNELDIR/.freebsd-update
+ touch $BASEDIR/$BACKUPKERNELDIR/.freebsd-update
if [ $? -ne 0 ]; then
echo "Could not create kernel backup directory"
exit 1
@@ -2647,8 +2727,8 @@ backup_kernel () {
fi
# Backup all the kernel files using hardlinks.
- (cd $KERNELDIR && find . -type f $FINDFILTER -exec \
- cp -pl '{}' ${BACKUPKERNELDIR}/'{}' \;)
+ (cd ${BASEDIR}/${KERNELDIR} && find . -type f $FINDFILTER -exec \
+ cp -pl '{}' ${BASEDIR}/${BACKUPKERNELDIR}/'{}' \;)
# Re-enable patchname expansion.
set +f
@@ -2746,7 +2826,7 @@ install_files () {
# Update linker.hints if necessary
if [ -s INDEX-OLD -o -s INDEX-NEW ]; then
- kldxref -R /boot/ 2>/dev/null
+ kldxref -R ${BASEDIR}/boot/ 2>/dev/null
fi
# We've finished updating the kernel.
@@ -2797,14 +2877,14 @@ Kernel updates have been installed. Please reboot and run
install_delete INDEX-OLD INDEX-NEW || return 1
# Rebuild /etc/spwd.db and /etc/pwd.db if necessary.
- if [ /etc/master.passwd -nt /etc/spwd.db ] ||
- [ /etc/master.passwd -nt /etc/pwd.db ]; then
- pwd_mkdb /etc/master.passwd
+ if [ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/spwd.db ] ||
+ [ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/pwd.db ]; then
+ pwd_mkdb -d ${BASEDIR}/etc ${BASEDIR}/etc/master.passwd
fi
# Rebuild /etc/login.conf.db if necessary.
- if [ /etc/login.conf -nt /etc/login.conf.db ]; then
- cap_mkdb /etc/login.conf
+ if [ ${BASEDIR}/etc/login.conf -nt ${BASEDIR}/etc/login.conf.db ]; then
+ cap_mkdb ${BASEDIR}/etc/login.conf
fi
# We've finished installing the world and deleting old files
@@ -3011,21 +3091,8 @@ IDS_compare () {
mv INDEX-NOTMATCHING.tmp INDEX-NOTMATCHING
# Go through the lines and print warnings.
- while read LINE; do
- FPATH=`echo "${LINE}" | cut -f 1 -d '|'`
- TYPE=`echo "${LINE}" | cut -f 2 -d '|'`
- OWNER=`echo "${LINE}" | cut -f 3 -d '|'`
- GROUP=`echo "${LINE}" | cut -f 4 -d '|'`
- PERM=`echo "${LINE}" | cut -f 5 -d '|'`
- HASH=`echo "${LINE}" | cut -f 6 -d '|'`
- LINK=`echo "${LINE}" | cut -f 7 -d '|'`
- P_TYPE=`echo "${LINE}" | cut -f 8 -d '|'`
- P_OWNER=`echo "${LINE}" | cut -f 9 -d '|'`
- P_GROUP=`echo "${LINE}" | cut -f 10 -d '|'`
- P_PERM=`echo "${LINE}" | cut -f 11 -d '|'`
- P_HASH=`echo "${LINE}" | cut -f 12 -d '|'`
- P_LINK=`echo "${LINE}" | cut -f 13 -d '|'`
-
+ local IFS='|'
+ while read FPATH TYPE OWNER GROUP PERM HASH LINK P_TYPE P_OWNER P_GROUP P_PERM P_HASH P_LINK; do
# Warn about different object types.
if ! [ "${TYPE}" = "${P_TYPE}" ]; then
echo -n "${FPATH} is a "
@@ -3153,7 +3220,7 @@ get_params () {
# Fetch command. Make sure that we're being called
# interactively, then run fetch_check_params and fetch_run
cmd_fetch () {
- if [ ! -t 0 ]; then
+ if [ ! -t 0 -a $NOTTYOK -eq 0 ]; then
echo -n "`basename $0` fetch should not "
echo "be run non-interactively."
echo "Run `basename $0` cron instead."