/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

Mac Mount Points

Views:


Depreciated: back in the real world this is a PITA because sometimes it breaks. Sometimes OS X decides to run fsck repeatedly on the disk for no good reason.

fstab just doesn't cut it on OS X 10.5. Neither does mounting all volumes is /Volumes/. Oh and how many partitions can you have and still keep boot camp working??

Why do I even care? Mac's make great desktop computers - nothing comes close as far as I'm concerned - but linux is king of the hill when it comes to servers. The problem here is that developing and testing on a case-insensitive file system can catch you out when you move to a case sensitive one. It's possible to install OS X on a case-sensitive file system but there are plenty of application developers (Adobe) who's software can't take it.

Kieran's solution: Use virtual disk images and the launch daemon to mount them at boot time. The really nice thing about these is that they only fill up as you add files and they give you lots of options for backing up or creating a number of different environments for testing.

This example shows how to create a disk image amount mount it for use with MacPorts.

Create a disk image with hdiutil:

$ hdiutil create -size 20g -type SPARSEBUNDLE -fs HFSX -layout none -uid 0 -gid 0 -volname macports /opt/macports.sparsebundle

Then create a mount point:

$ sudo mkdir /opt/local

Now we need to define a "process" for the Launch Daemon, this will just get loaded at boot time. LaunchD really needs something that is a *daemon*, not just a simple script that dies once it has been executed. Macports contains a small program called daemondo that can act as a wrapper around your scripts. If you want to install macports on a disk image then you must copy daemondo to a location on your root volume. You can extract daemondo from the macports installer package: use the terminal to cd in to the package (or "show package contents" in the Finder) and copy out Archive.pax.gz, you'll find daemondo in the bin directory. Copy it somewhere like /usr/local/bin

Daemondo uses a simple wrapper script to contain start, stop and restart functions. This can be used to run hdiutil to mount and umount the disk image.

/usr/local/bin/local.wrapper:

#!/bin/sh
#based on daemondo wrapper for the mysql5 port

#
# Start
#
Start()
{
        /usr/bin/hdiutil attach /opt/macports.sparsebundle -mountpoint /opt/local -notremovable -owners on
}

#
# Stop
#
Stop()
{
        /usr/bin/hdiutil detach /opt/local
}

#
# Restart
#
Restart()
{
        Stop
        Start
}

#
# Run
#
Run()
{
case $1 in
  start  ) Start   ;;
  stop   ) Stop    ;;
  restart) Restart ;;
  *      ) echo "$0: unknown argument: $1";;
esac
}

#
# Run a phase based on the selector
#
Run $1

Next a daemon for Launch Daemon needs to be defined in a property list. This will trigger daemon do to run the script above.

The file needs to go in /Library/LaunchDaemons (not /System/Library/LaunchDaemons - that's for Apple) and call it something like com.example.localmaount.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>HopefullyExitsLast</key>
        <true/>
        <key>Label</key>
        <string>net.ninjafocus.localmount</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/local/bin/daemondo</string>
                <string>--label=local</string>
                <string>--start-cmd</string>
                <string>/usr/local/bin/local.wrapper</string>
                <string>start</string>
                <string>;</string>
                <string>--stop-cmd</string>
                <string>/usr/local/bin/local.wrapper</string>
                <string>stop</string>
                <string>;</string>
                <string>--restart-cmd</string>
                <string>/usr/local/bin/local.wrapper</string>
                <string>restart</string>
                <string>;</string>
                <string>--pid=none</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

Once you have created the file, you need to get Launch Daemon to read it:

$ sudo launchctl load -w /Library/LaunchDaemons/net.ninjafocus.localmount.plist

The disk will be mounted automatically at boot time and un-mounted automatically at shutdown. You can issue start and stop commands via launchctl at any time.

It's also possible to issue the command to mount the disk manually:

$ sudo hdiutil attach /opt/local.sparsebundle -notremovable -owners on

Likewise for un-mounting:

$ sudo hdiutil detach /Volumes/macports


Contents

hdiutil

type

10.4 can have sparse images where everything is contained in a single file. On 10.5 you can also have a sparse bundle which is a directory structure containing files - each file holds one "band" of data from the disk image.

  • sparse image is specfied as -type SPARSE
  • sparse bundle is specfied as -type SPARSEBUNDLE

layout

When you create a disk image hdiutil will, by default, partion the disk in just the same manner as a real harddisk. You probably don't want to have a partition map and multiple partitions on your disk image. Set the layout options to "none", i.e. hdiutil create -layout none ......

uid and gid

These options set the user and group owner ids for the root of the filesystem, 0 for root is a good choice.

owners

OS X has an interesting approach to external / mobile drives and disk images. Even though the file system supports posix file permission and ACLs, all files on "removable" disks are owned by the user who is viewing them. Behind the scenes OS X is setting the owner on new and changed files to _unknown / 99. (It's like FAT all over again, but they're actually going to a lot of trouble over this!). The solution is simple enough.

Use the "-owners" option, set it to on. i.e. hdiutil attach -owners on /path/to/image

You can also "Get Info" for the partition using the finder, and untick the "Ignore owenership & permission on this dive" option, under "Sharing & Permissions"

notremovable

This flag will prevent the disk image from being un-mounted. You can force umount to take the drive down but that might upset the filesystem. You can use the hdiutil detach command to un-mount a disk image flagged as not removable.

$ hdiutil detatch /path/to/mount/point

Main Menu

Personal tools

Toolbox