Hdiutil fails when executed from detached (daemon) processes.
Hdiutil fails when executed from detached (daemon) processes.
- Subject: Hdiutil fails when executed from detached (daemon) processes.
- From: Kevin Harris <email@hidden>
- Date: Tue, 19 Oct 2004 17:30:21 -0600
First of all, I apologize if I am sending this to the wrong mailing
list. I read through Apple's mailing lists and this seemed like the
closest match. Also, I don't believe that Darwin (without MacOS)
supports hdiutil yet.
I am writing a program which needs to use hdiutil for disk image
manipulation. This will run in the background as a daemon and is not a
gui application, nor is it directly using any of the OSX framework
libraries.
If the process is created and is detached from its parents, any use of
hdiutil will fail after the parent processes exit. This means that if a
user starts (or restarts) the program, it will continue to work only as
long as that user is logged in. When the process is started from its
init script during system startup, it will continue to function
properly. This leads me to believe that the parent processes of the
calling process are examined when using hdiutil.
The error message from hdiutil is as follows:
2004-10-18 15:30:56.722 hdiutil[1691] error: unable to set up framework
server.
A google turned up nothing, as did a search on the Apple developer site
and the "fink" mailing lists.
I have written (and attached) a fairly simple script which can reproduce
this problem. This is just an example and has nowhere near the
functionality of my real project. I have only tested it on MacOS
10.3.x, so I don't know how any other versions would react in the same
situation.
Here's the output I get in my log file:
-------------------------------------------------------------
Waiting for 10 seconds for the parent process to quit.
Ready to try mounting...
Mounting dmg file: /tmp/hdiutil_test.1681.dmg
2004-10-18 15:30:56.722 hdiutil[1691] error: unable to set up framework
server.
hdiutil: mount failed - Device not configured
Failed to mount dmg file.
-------------------------------------------------------------
I am attaching the complete script, and hope that it won't be stripped
from this message.
I don't believe that a required reboot is acceptable for normal
operation, so I would appreciate any suggestions you may have.
Thank you in advance for your help.
-Kevin-
#!/bin/bash
# This script will create a disk image, detach itself from the calling process,
# and attempt to mount the disk image. The purpose of this script is to show
# failures in hdiutil trying to reach the framework server with an error like
# the following:
#
# 2004-10-18 13:59:17.921 hdiutil[1089] error: unable to set up framework server.
#
# This seems to happen any time hdiutil is used, but the parent process tree
# can't trace back to a login. Try this locally. It will work. Run it again
# and log out--it will fail.
#
# The easiest way to test this is remotely through ssh, since it is by far the
# easiset way to quickly log out:
# ssh USER@MACHINE_NAME $PATH_TO/hdiutil_test.sh
set -e
# Specifies if the script completed successfully (1=success).
COMPLETED_SUCCESSFULLY=0
# The amount of time to wait after this script is executed (detached) before
# doing anything. This will give time for the calling process to quit and the
# user to log out.
DELAY_TIME=10
# The path of the device file that the dmg file was mounted under (used to
# unmount it).
DEVICE_PATH=
# The name of the DMG file.
DMG_FILENAME=
# Abort the script, returning an error, and printing anything given as arguments.
abort_script()
{
echo $@
exit 1
}
# Create a 1 megabyte dmg file.
create_dmg()
{
echo "Creating dmg file: $DMG_FILENAME"
if hdiutil create -ov -size 1024k -fs HFS+ -volname "deleteme" ${DMG_FILENAME}; then
return 0
else
return 1
fi
}
# Remove the dmg file.
erase_dmg()
{
echo "Removing dmg file."
rm -f ${DMG_FILENAME}
}
# This function makes sure that the image is unmounted (and only unmounted once) at exit.
unmount_dmg()
{
sync
if [ "x$DEVICE_PATH" != "x" ]; then
echo "Unmounting (detaching) dmg file."
hdiutil detach $DEVICE_PATH
DEVICE_PATH=
fi
if [ $# -ne 1 ]; then
if [ ${COMPLETED_SUCCESSFULLY} -ne 1 ]; then
erase_dmg
echo "An error occurred."
exit 1
fi
fi
}
# Mount the dmg file
mount_dmg()
{
set +e
TEMP_MOUNT_LOG=`mktemp ${DMG_FILENAME}.mount.XXXXXX`
if [ $? -ne 0 ]; then
echo "Failed to create log file. Eeeeeeeeeeeeeeep."
exit 1
fi
echo "Mounting dmg file: $DMG_FILENAME"
hdiutil mount ${DMG_FILENAME} -private >& ${TEMP_MOUNT_LOG}
results=$?
cat ${TEMP_MOUNT_LOG}
if [ $results -eq 0 ]; then
IMAGE_MOUNT_POINT=`grep /dev ${TEMP_MOUNT_LOG} | tail -1 | sed 's|.*\(/Volumes.*$\)|\1|g'`
DEVICE_PATH=`df "${IMAGE_MOUNT_POINT}" | grep "${IMAGE_MOUNT_POINT}" | awk '{ print $1; }'`
trap unmount_dmg EXIT
fi
rm -f ${TEMP_MOUNT_LOG}
set -e
return $results
}
# Detach from the parent process, saving all output in a log file. This will
# re-execute the script, and the result will have no parent process.
detach()
{
LOG_FILE=/tmp/hdiutil_test.$$.log
echo "Detaching... Sending output to $LOG_FILE"
# Close stdin, since the child process won't need to inherit it.
exec 0<&-
# Set a variable to prevent a runaway process.
export ALREADY_DETACHED=1
# Re-execute this script passing in the name of the DMG file that was
# created while the script was still attached.
/bin/bash $0 $DMG_FILENAME >$LOG_FILE 2>&1 &
disown $!
echo "Detached."
}
# The main portion of the script.
main()
{
if [ "x$ALREADY_DETACHED" != "x1" ]; then
# Not detached... Create the disk image file and detach.
DMG_FILENAME=/tmp/hdiutil_test.$$.dmg
create_dmg || abort_script "Failed to create DMG file: $DMG_FILENAME"
detach
else
# We're detached here. Do the real work.
echo "Waiting for $DELAY_TIME seconds for the parent process to quit."
sleep $DELAY_TIME
echo "Ready to try mounting..."
DMG_FILENAME=$1
mount_dmg || abort_script "Failed to mount dmg file."
unmount_dmg NOERROR
erase_dmg
COMPLETED_SUCCESSFULLY=1
echo "Everything appeared to work correctly."
fi
}
main "$@"
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden