Mac OS X Server v10.4.11: Software Update Server stops providing updates to clients
Symptoms
Certain update packages (including Security Update 2009-002) may not appear as expected in, or download from, Software Update Server running on Mac OS X Server v10.4.11. Clients accessing Software Update Server may not be able to view or install updates.
The affected packages may appear in Server Admin with a generic name (generally a series of numbers), or the list may appear blank.
Products Affected
Mac OS X Server 10.4
Resolution
There are two different workarounds to address this issue. The first changes client-side configuration, while the second changes server-side configuration. Only one of the two workarounds should be used.
Workaround 1: Reconfigure Mac OS X Clients
Mac OS X clients that do not have their settings managed by Mac OS X Server (MCX) can be configured to use Apple's public Software Update Server for updates. To make this change, enter the following command in Terminal:
sudo defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL
For workstations with managed settings (MCX) for Software Update preferences, the administrator can disable the Software Update managed preferences so the workstations will use Apple's public Software Update service. Administrators can also use the second workaround on any Mac OS X Server 10.4.11 system that provides Software Update services for the local network.
Workaround 2: Install a script on Mac OS X Server v10.4.11
With this workaround, a script will run and install a launchd item (named swu-update) that will automatically detect and modify updates which are downloaded in an unexpected format. It will also update any existing packages that are in an unexpected format. It is not necessary to run the script more than once. The script must be run on each Mac OS X v10.4.11 Server running the Software Update service in your organization. The script will automatically run whenever the Software Update service downloads new updates from Apple and modify the new updates if necessary.
- Using these guidelines, create a new file on your desktop named swu-modify.sh and copy and paste the script below into TextEdit. The script is all the text between ---START SCRIPT--- and ---END SCRIPT--- .
- Save as a plain text file named "swu_modify.sh".
- Once saved, open Terminal and navigate to the folder where the script was saved.
- Execute the following Terminal command:
sudo bash swu_modify.sh
Note: Depending on the number of downloads present, the load on the server, and the available system resources, the initial run of the script may take more than 15 minutes to complete and should not be abnormally ended. The messages from launchd are completely normal in this event as you are waiting for a file to get created. When completed, you should see entries similar to the following in the system.log file on the server:
Jun 22 16:17:46 saffron swu-update: job 26384 loaded
Jun 22 16:17:58 saffron swu-update: job execution started
Jun 22 16:17:58 saffron swu-update: finding distribution files
Jun 22 16:18:43 saffron swu-update: found 237 files to modify
Jun 22 16:18:43 saffron swu-update: software update service paused.
Jun 22 16:18:43 saffron swu-update: modifying distribution files
Jun 22 16:20:29 saffron swu-update: modified 237 distribution files
Jun 22 16:20:29 saffron swu-update: regenerating update list
Jun 22 16:22:16 saffron swu-update: unpausing software update service.
Jun 22 16:23:05 saffron swu-update: software update service is RUNNING
Jun 22 16:24:55 saffron launchd: com.apple.applecareengineering.tigerswupdate: open("/etc/swupd/.sync_done", O_EVTONLY): No such file or directory
Jun 22 16:24:55 saffron launchd: launchd.c:810:9: kevent_mod(j->vnodes[i], EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE|NOTE_EXTEND|NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_ATTRIB|NOTE_LINK, 0, &j->kqjob_callback) != -1
Jun 22 16:24:24 saffron launchd: launchd.c:757:9: kevent_mod(j->vnodes[i], EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1
Note: If the script is interrupted before completion, it will not run again unless you run the script with the "-unlock" parameter. To unlock the script, execute the following Terminal command:
sudo /usr/local/bin/swu-update-finished -unlock
---START SCRIPT---
#!/usr/bin/env bash ---END SCRIPT---
# swu-update-finished
# Copyright 2009 Apple, Inc. All rights reserved.
function writelaunchditem() {
/bin/cat - > /Library/LaunchDaemons/com.apple.applecareengineering.tigerswupdate.plist << 'END_OF_LAUNCHD_ITEM'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.applecareengineering.tigerswupdate</string>
<key>Program</key>
<string>/usr/local/bin/swu-update-finished</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/swu-update-finished</string>
</array>
<key>RunAtLoad</key>
<false/>
<key>StandardErrorPath</key>
<string>/private/var/log/swu-update.log</string>
<key>StandardOutPath</key>
<string>/private/var/log/swu-update.log</string>
<key>WatchPaths</key>
<array>
<string>/etc/swupd/.sync_done</string>
<string>/etc/swupd/.sync_in_progress</string>
</array>
</dict>
</plist>
END_OF_LAUNCHD_ITEM
}
function writedistfiles() {
/bin/cat - > /tmp/swu-unzip-distfiles << 'END_OF_DISTFILES'
#!/usr/bin/env bash
# swu-unzip-distfiles
# Copyright 2009 Apple, Inc. All rights reserved.
DISTFILE="$1"
/usr/bin/file "$DISTFILE" | grep gzip 2>&1 >> /dev/null
COMPRESSED=$?
if [ $COMPRESSED -eq 0 ]; then
/bin/mv "$DISTFILE" "$DISTFILE.gz"
/usr/bin/gzip -dc "$DISTFILE.gz" > "$DISTFILE"
/bin/rm -f "$DISTFILE.gz"
echo "$DISTFILE was decompressed"
fi
END_OF_DISTFILES
}
function runfirst() {
if [ ! -f /tmp/swu-unzip-distfiles ]; then
/usr/bin/touch /tmp/swu-unzip-distfiles
/bin/chmod 0700 /tmp/swu-unzip-distfiles
writedistfiles
/bin/chmod 0500 /tmp/swu-unzip-distfiles
fi
if [ ! -f /usr/local/bin/swu-update-finished ]; then
if [ ! -d /usr/local/bin ]; then
mkdir -m 0775 -p /usr/local/bin
fi
/bin/cp "$0" /usr/local/bin/swu-update-finished
/bin/chmod 0550 /usr/local/bin/swu-update-finished
fi
if [ ! -f /Library/LaunchDaemons/com.apple.applecareengineering.tigerswupdate.plist ]; then
/usr/bin/touch /Library/LaunchDaemons/com.apple.applecareengineering.tigerswupdate.plist
/bin/chmod 644 /Library/LaunchDaemons/com.apple.applecareengineering.tigerswupdate.plist
writelaunchditem
/bin/launchctl load /Library/LaunchDaemons/com.apple.applecareengineering.tigerswupdate.plist
fi
}
function logmsg() { /usr/bin/logger -t swu-update "$*"; }
function lockme() { echo "LOCK_PID=$*" > /private/tmp/.swu-update-locked; }
function unlock() { /bin/rm -f /private/tmp/.swu-update-locked; }
function verifylock() {
unset LOCK_PID
if [ -f /private/tmp/.swu-update-locked ]; then
source /private/tmp/.swu-update-locked
if [ $LOCK_PID -eq $1 ]; then
return 1
else
return 0
fi
fi
return 0
}
SWUPD_LOCK="/private/tmp/.swu-update-locked"
SWUPD_BASE="/private/etc/swupd/"
SWUPD_SYNC_PROG=".sync_in_progress"
SWUPD_SYNC_DONE=".sync_done"
SWUPD_PID=$$
if [ "$1" == "-unlock" ]; then
unlock
exit 0
fi
logmsg "job $SWUPD_PID loaded"
#sleep for launchd
/bin/sleep 12
_sw_vers=`/usr/bin/sw_vers -productVersion`
if [ "$_sw_vers" != "10.4.11" ]; then
logmsg "You must be at 10.4.11 to use $0"
fi
if [ "$USER" != "root" -a $UID -ne 0 ]; then
logmsg "not run as root. Exiting."
exit 0
fi
runfirst
if [ -e "$SWUPD_LOCK" ]; then
logmsg "lock file already exists, exiting."
logmsg "you may need to run $0 -unlock."
exit 0
fi
lockme $SWUPD_PID
verifylock $SWUPD_PID
_verify=$?
if [ $_verify -eq 0 ]; then
logmsg "we do not own the lock file, exiting."
exit 0
fi
unset _verify
logmsg "job execution started"
if [ $PPID -ne 1 ]
then
echo "Use the Console to review the system.log for status messages."
fi
while [ -f "$SWUPD_BASE$SWUPD_SYNC_PROG" ]
do
sleep 15 #seconds
done
logmsg "finding distribution files"
COMPDIST_COUNT=`(/usr/bin/find /usr/share/swupd/html -name \*.dist -exec file {} \;) | /usr/bin/grep gzip | /usr/bin/wc -l | sed -e 's/ //g'`
if [ $COMPDIST_COUNT -eq 0 ]; then
logmsg "no files to change, exiting."
unlock
exit 0
fi
logmsg "found $COMPDIST_COUNT files to modify"
/usr/sbin/swupdctl stop
/usr/bin/killall swupd_syncd
logmsg "software update service paused."
logmsg "modifying distribution files"
DECOMP_COUNT=`(/usr/bin/find /usr/share/swupd/html -name \*.dist -exec /tmp/swu-unzip-distfiles {} \;) | wc -l`
logmsg "changed $DECOMP_COUNT distribution files"
logmsg "regenerating update list"
/usr/bin/find /usr/share/swupd/html -exec /usr/bin/touch {} \;
/bin/sleep 15
/usr/sbin/swupd_syncd -gen
/bin/sleep 15
/usr/sbin/swupd_syncd -check
logmsg "unpausing software update service."
/usr/sbin/swupdctl start
STATUS=`/usr/sbin/serveradmin status swupdate | /usr/bin/awk '{print $3}' | /usr/bin/sed -e s/\"//g `
logmsg "software update service is $STATUS"
/bin/sleep 300 #sleep 5 minutes before unlocking
unlock
This document will be updated as more information becomes available.