TweetFollow Us on Twitter

MacEnterprise: Sparseimage Conversion

Volume Number: 26
Issue Number: 04
Column Tag: MacEnterprise

MacEnterprise: Sparseimage Conversion

Scripting the conversion of a Filevault sparseimage to a sparsebundle

By Greg Neagle, MacEnterprise.org

Introduction

Back in 2008, I wrote a series of MacEnterprise columns on managing FileVault in an enterprise environment. We covered preparation steps, including setting up an enterprise-wide FileVault Master Password, using MCX to automate the creation of FileVault-protected home directories for new mobile and local accounts, and how to recover from lost user passwords. In the last of three columns, I discussed how to move a FileVault-protected account and home directory from one machine to another.

These past columns can be found in the MacTech archives:

http://www.mactech.com/articles/mactech/Vol.24/24.07/2407MacEnterprise-FileVaultintheEnterprisePart1/index.html

http://www.mactech.com/articles/mactech/Vol.24/24.09/2409MacEnterprise-FileVaultintheEnterprisePart2/index.html

http://www.mactech.com/articles/mactech/Vol.24/24.10/2410MacEnterprise-MigratingFileVault/index.html

This month, we're going to look at another aspect of managing FileVault-encrypted home directories. The format of such directories in Tiger was an encrypted sparsebundle disk image. In this type of image, the entire contents of the disk image are stored in a single file. If the file became corrupted, the entire disk image could be lost. This is why I recommend that you do not implement FileVault unless you either have a backup strategy or are using portable home directories—where the local home directory is kept in sync with a network copy. But if you are backing up the disk image, any change requires backing up the entire disk image file. Another downside of the sparseimage format is as items are changed in the mounted disk image, the disk image file grows in size, even if you delete items within the image. To shrink the disk image file, on logout users are asked if they want to reclaim unused space. This process can take a long time if a lot of changes have been made since the last recovery operation, as the entire disk image file may need to be rewritten.

To address some of these issues, Apple changed the FileVault disk image format in Leopard. Starting with OS X 10.5, newly created FileVault home directories use the "sparse bundle" format. With this format, instead of storing the disk image contents in a single file, the contents are divided among files inside a directory. Think of the enclosing directory as a physical hard drive, and the files within (called "bands") correspond to sectors on a physical disk. This solves several problems. First, the corruption/failure of a single file within the sparsebundle won't render the entire disk image useless; as with a physical disk, only the data in a specific part of the virtual disk is affected. Backups can be faster since only the changed "band" files need to be backed up, instead of the entire image. Finally, recovering unused space in the image is much, much faster, as the OS can just remove the unused band files.

FileVault migration issues

So a big problem with my technique for migrating FileVault-protected accounts from one machine to another is that if you migrate a FileVault-protected home directory from a Tiger machine to a Leopard (or Snow Leopard) machine, the disk image says in the old sparseimage format. This is not a showstopper, as Leopard and Snow Leopard will still happily use sparseimage FileVault home directories. As we moved users from Tiger to Leopard, we saw this issue, but we thought we'd just go back and manually convert the images to the new format. Apple's recommended technique for the conversion? Turn FileVault off, wait for the image to decrypt, then turn FileVault back on and re-encrypt the image. This can take a long time.

A few years passed, and we have started moving users to Snow Leopard. To our chagrin, we're encountering a not-insignificant number of users that still have sparseimage FileVault homes! We could just take the same approach as before, but I knew that if after two years on Leopard we haven't manually converted most of the sparseimages, we're not going to do it now.

So I decided to script the conversion, with the initial goal of streamlining and standardizing the conversion process, and the eventual goal of automating it entirely. I think I've accomplished the first goal, and I will share my solution with you.

Language choices

If you are going to script a system administration task, the first choice you need to make is what language to use as the scripting language. Normally I am a big fan of Python, but I decided against it this time around. Why? It's really overkill for the simple series of operations needed. I developed the procedures I needed by using the shell, so a simple shell script seemed to fit the bill. It was extremely convenient to test a little bit by just typing stuff into the shell and making sure it worked as expected, then adding that to the shell script. So even if the specific task at hand is not relevant to you, you may learn something about shell scripting by following along.

The script, bit by bit

The script is very linear - there are no functions or subroutines or even any loops! It just starts at the beginning and works its way to the end, bailing at various spots if it runs into an error. This makes it easy to present the script in bite-sized chunks. I'll talk about what each bit does, then move to the next. Here goes!

#!/bin/bash
# convertsparseimage
#
# Copyright 2010 by Greg Neagle
# converts FileVault sparseimages to sparsebundles
# free to use, but no suitability for any purpose implied.
# use at your own risk! data loss is a possibility.
WHOAMI=`/usr/bin/id -u`
if [ "$WHOAMI" -ne 0 ]; then
    echo "You must run this as root!"
    exit -1
fi

We start with the familiar "she-bang" line: #!/bin/bash. This tells the OS to use the bash interpreter for this script. Then follow a few comments absolving me of any responsibility if this script causes you or your users to lose data. I don't think it will, but it never hurts to be careful. Test this script carefully before using it on actual user data!

First we check to make sure the effective user ID is that of the root user. In order to convert a user's data we need to run with root privileges. Running this script with 'sudo' is fine. If the current user doesn't have root privileges, we print an error and exit with an error code.

USER=$1
if [ "$USER" == "" ]; then
    echo "Need to specify a user to convert:"
    echo "$0 shortusername"
    exit -1
fi

When we run this script, we need to pass the short name of a user to convert, like so:

/path/to/convertsparseimage gneagle

The username is made available to the script in the $1 variable, and we copy it to a new variable named "$USER". If $USER is empty, we print an error and exit with an error code.

USERLOGGEDIN=`/usr/bin/who | 
              /usr/bin/grep console | 
              /usr/bin/grep $USER`
if [ "$USERLOGGEDIN" != "" ]; then
    echo "$USER is currently logged in!"
    exit -1
fi

Next, we check to see if the user we want to convert is logged in via to GUI. This is done by piping the output of /usr/bin/who to /usr/bin/grep, which will output only lines containing "console", then piping these lines to grep again, this time looking only for lines with our user's name. If $USER is logged in via the console, $USERLOGGEDIN will have something in it; otherwise it will be empty. If it's not empty, we print an error message and exit with an error code.

Note that this simple code could return a false positive. If the user you are looking for has a shortname of "sjohn" and "sjohnson" is logged in, grep will return a match. You can do more sophisticated matches with grep to avoid this issue.

SPARSEIMAGE="/Users/$USER/$USER.sparseimage"
if [ ! -e "$SPARSEIMAGE" ]; then
    echo "Sparseimage $SPARSEIMAGE does not exist!"
    exit -1
fi

Now we check to make sure there actually is a sparseimage to convert. Again, this code is a little simplistic, because the user's home directory and sparseimage name do not technically have to match the user shortname. In 99% or more of cases, though, they do, so this code will work. If you have users with home directories in places other than "/Users" or with alternate names, you'll have to get more clever; perhaps by reading the output of

 `dscl . read /Users/$USER HomeDirectory`.
SPARSEBUNDLE="/Users/$USER/$USER.sparsebundle"
if [ -e "$SPARSEBUNDLE" ]; then
    echo "Sparsebundle $SPARSEBUNDLE already exists!"
    exit -1
fi

This time we check to make sure a sparsebundle doesn't exist. We probably don't want to write over an existing sparsebundle in the user's home directory path.

# get the size of the sparseimage in megabytes
IMAGESIZE=`/usr/bin/du -m "$SPARSEIMAGE" |
           /usr/bin/cut -f1`
# add some breathing room; 100 MB
SPACENEEDED=$((IMAGESIZE+100))
# get the free space on the disk in megabytes
DISKSPACE=`/bin/df -m / | /usr/bin/awk 'NR>1 { print $4 }'`
if [ $DISKSPACE -lt $SPACENEEDED ]; then
    echo "Not enough free space on disk:" 
    echo "$DISKSPACE MB available; want $SPACENEEDED MB."
    exit -1
fi
echo "Need $SPACENEEDED MB to convert; found $DISKSPACE MB"

For our next subtask, we figure out the size of the sparseimage in megabytes and add another 100MB to guess at how much space we'll need to do the conversion. We then figure out the amount of free space on the startup disk, also in megabytes. If the free space on the disk is less than the space we need to convert the image, we print an error message and exit with an error code.

This bit makes use of the du (disk usage) and df (disk freespace) commands. To parse the output of these commands, we use cut and awk. awk is somewhat arcane - in fact, it is another language all to itself, but very useful when it comes to parsing text output from another shell command.

echo "Unlocking FileVaultMaster keychain..."
FVMASTER="/Library/Keychains/FileVaultMaster.keychain"
# /usr/bin/security will prompt the for the password
/usr/bin/security unlock-keychain "$FVMASTER"
if [ $? -ne 0 ]; then
    echo "Error unlocking FileVaultMaster keychain"
    exit -2
fi

All the preliminary checks are done. We can finally start with the actual task. Since this script is eventually destined for automation, we can't count on having the user's password. Fortunately, we've created all our FileVault-protected home directories along with a FileVault Master Password, and so we can use the FileVaultMaster keychain to decrypt the sparseimage. (If, in the name of security, you've moved (or removed!) the FileVaultMater keychain, you'll need to modify the script to use the new location or retrieve the keychain from wherever you've stashed it. If you aren't using a FileVault Master password, then this script would have to be modified to require and use the user's login password.

We're using the security command to unlock the FileVaultMaster keychain. It will prompt for a password for this keychain. That's a pretty significant barrier to completely automating this process. The security command does take a -p parameter, which allows you to pass the keychain password, but including the password in a script like this immediately compromises the security of all the FileVault-protected accounts in your organization, so I do not recommend it. For now, we're just going to have to type in the password.

echo "Mounting sparseimage $SPARSEIMAGE..."
/usr/bin/hdiutil attach "$SPARSEIMAGE" -recover "$FVMASTER" -nobrowse -mountpoint /tmp/fvimage
if [ $? -ne 0 ]; then
    echo "Error mounting FileVault-protected sparseimage"
    exit -3
fi

(In the above code block, the /usr/bin/hdiutil line should all be one single line through "/tmp/fvimage")

Now we use the FileVaultMaster keychain to mount the encrypted disk image even though we don't have the user's password. We also specify the -nobrowse option so it does not appear in the Finder (which would be bad if another user was logged in). We also specify a custom mountpoint in /tmp, so the volume is not accessible via the normal /Volumes mountpoints. Both of these options improve security somewhat. If we get an error while trying to mount the image, we exit with an error.

echo "Creating encrypted sparsebundle with contents from"
echo "sparseimage..."
PASSWORD="LetMeIn!\\0000"
echo -e "$PASSWORD" | /usr/bin/hdiutil create -srcfolder /tmp/fvimage -format UDSB -o "$SPARSEBUNDLE" -volname $USER -encryption -stdinpass -certificate /Library/Keychains/FileVaultMaster.cer
if [ $? -ne 0 ]; then
    echo "Error creating sparsebundle"
    rm -r $SPARSEBUNDLE
    echo "Unmounting sparseimage"
    /usr/bin/hdiutil eject /tmp/fvimage
    exit -4
fi

(In the above code block, the section starting with 'echo -e "$PASSWORD" ' and ending with '/Library/Keychains/FileVaultMaster.cer ' is all one long line.)

The actual image conversion happens here at long last. Since we don't have the user's password, we have to create this sparsebundle with a default password, which we'll need to provide to the user to use on the first login. Change this password as you wish, but leave the "\\0000" at the end - this is a null-character, which is needed by hdiutil at the end of a password passed in via STDIN.

Let's tear apart the rather complicated line with hdiutil:

echo -e "$PASSWORD" | 

- send the password via STDIN to hdiutil

/usr/bin/hdiutil create -srcfolder /tmp/fvimage 

- create a new disk image from the contents of the folder /tmp/fvimage, which is where we've mounted the sparseimage.

-format UDSB 

- the new disk image should be formatted as a sparsebundle.

-o "$SPARSEBUNDLE" 

- write the new disk image to the path described by $SPARSEBUNDLE, which we've previously set to "/Users/$USER/$USER.sparesbundle".

-volname $USER 

- make sure the volume has the same name as the user

-encryption 

- use the standard encryption

-stdinpass 

- read the password from STDIN.

-certificate /Library/Keychains/FileVaultMaster.cer

- use the certificate given as the alternate unlock key. This allows us to decrypt an image with the FileVaultMaster keychain.

hdiutil create may take a while to do its job. The larger the original sparseimage, the longer creating the sparsebundle will take. It does print some progress info as it works. If an error is encountered, we delete the sparesbundle, eject the sparseimage, and exit with an error message.

echo "Unmounting sparseimage $SPARSEIMAGE"

/usr/bin/hdiutil eject /tmp/fvimage
echo "Moving $SPARSEIMAGE to /Users/Shared/..."
/bin/mv "$SPARSEIMAGE" "/Users/Shared/$USER.sparseimage"
echo "Updating DirectoryService HomeDirectory to point to" 
echo "new sparsebundle"
/usr/bin/dscl . -create /Users/$USER HomeDirectory "<home_dir><url>file://localhost$SPARSEBUNDLE</url></home_dir>"

Finally, some cleanup and housekeeping: We eject the sparseimage and move it to /Users/Shared for safekeeping—I'm still not confident enough to delete it outright. After a day or so, assuming the converted sparsebundle works as expected, you could then go back and delete the old sparseimage.

Lastly, we update the HomeDirectory attribute in the local directory service to point to the sparsebundle instead of the old sparseimage. Note that the section starting with "/usr/bin/dscl" and ending with "</home_dir>" should all be a single line. This of course assumes the account information is local, but for mobile account or local users, the account info will be in the local directory service.

Now what?

So you've implemented and tested this script on some test accounts and you want to try it on a user's data. It's important to remember that the new sparsebundle does not have the user's login password, since we don't have that password anywhere in the script. Instead, we've created the disk image with a generic password that we'll provide to the user.

The first time the user tries to login after the conversion, they will see a dialog like the one in Figure 1.


Figure 1 - FileVault password warning

What is happening here is that the user has successfully authenticated against the directory service, but the current password isn't working to unlock the encrypted disk image. Since this is typically caused by network users changing their password, Mac OS X helpfully suggests that the user try their previous password to unlock the FileVault image.

In this case, you don't want the user to try their previous password. Instead, you want them to use the generic password that was used to encrypt the sparsebundle during the conversion. Once they provide that password, the sparsebundle will be unlocked and its password updated to the current user password.

Conclusion

In this month's MacEnterprise column, we stepped through a BASH script that converts FileVault sparseimages into FileVault sparsebundles for better performance and compatibility with Leopard and Snow Leopard. If you haven't done much shell scripting, I hope the examples in this script inspire you to learn more. Good luck!


Greg Neagle is a member of the steering committee of the Mac OS X Enterprise Project (macenterprise.org) and is a senior systems engineer at a large animation studio. Greg has been working with the Mac since 1984, and with OS X since its release. He can be reached at gregneagle@mac.com.

 
AAPL
$98.15
Apple Inc.
-0.23
MSFT
$43.58
Microsoft Corpora
-0.31
GOOG
$587.42
Google Inc.
+1.81

MacTech Search:
Community Search:

Software Updates via MacUpdate

Knock 1.1.7 - Unlock your Mac by knockin...
Knock is a faster, safer way to sign in. You keep your iPhone with you all the time. Now you can use it as a password. You never have to open the app -- just knock on your phone twice, even when it's... Read more
Mellel 3.3.6 - Powerful word processor w...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
LibreOffice 4.3.0.4 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Freeway Pro 7.0 - Drag-and-drop Web desi...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With it's user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more
Drive Genius 3.2.4 - Powerful system uti...
Drive Genius is an OS X utility designed to provide unsurpassed storage management. Featuring an easy-to-use interface, Drive Genius is packed with powerful tools such as a drive optimizer, a... Read more
Vitamin-R 2.15 - Personal productivity t...
Vitamin-R creates the optimal conditions for your brain to work at its best by structuring your work into short bursts of distraction-free, highly focused activity alternating with opportunities for... Read more
Toast Titanium 12.0 - The ultimate media...
Toast Titanium goes way beyond the very basic burning in the Mac OS and iLife software, and sets the standard for burning CDs, DVDs, and now Blu-ray discs on the Mac. Create superior sounding audio... Read more
OS X Yosemite Wallpaper 1.0 - Desktop im...
OS X Yosemite Wallpaper is the gorgeous new background image for Apple's upcoming OS X 10.10 Yosemite. This wallpaper is available for all screen resolutions with a source file that measures 5,418... Read more
Acorn 4.4 - Bitmap image editor. (Demo)
Acorn is a new image editor built with one goal in mind - simplicity. Fast, easy, and fluid, Acorn provides the options you'll need without any overhead. Acorn feels right, and won't drain your bank... Read more
Bartender 1.2.20 - Organize your menu ba...
Bartender lets you organize your menu bar apps. Features: Lets you tidy your menu bar apps how you want. See your menu bar apps when you want. Hide the apps you need to run, but do not need to... Read more

Latest Forum Discussions

See All

Empire Manager (Games)
Empire Manager 1.0 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: Become ruler of an empire. Manage your economy, develop technology, hire an army and conquer the world in this addictive turn-... | Read more »
Empire Manager HD (Games)
Empire Manager HD 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: Become ruler of an empire. Manage your economy, develop technology, hire an army and conquer the world in this addictive... | Read more »
Star Admiral Review
Star Admiral Review By Rob Thomas on July 30th, 2014 Our Rating: :: ADMIRABLE ADMIRALSUniversal App - Designed for iPhone and iPad While this new digital CCG may feel a bit familiar, Star Admiral offers a sci-fi twist and galaxy’s... | Read more »
Zap! Pow! Become a Badass Wizard in Phan...
Zap! Pow! | Read more »
Urban Trial Freestyle Review
Urban Trial Freestyle Review By Blake Grundman on July 30th, 2014 Our Rating: :: RIDIN' DIRTYUniversal App - Designed for iPhone and iPad A rough ride that has trouble keeping its wheels on the track.   | Read more »
Take Note! Noteshelf Has Recieved a Big...
Take Note! Noteshelf Has Recieved a Big Update. Posted by Jessica Fisher on July 30th, 2014 [ permalink ] iPad Only App - Designed for the iPad | Read more »
Cubama Review
Cubama Review By Nadia Oxford on July 30th, 2014 Our Rating: :: TETRIIIIIS IIIIIN SPAAAAACE!Universal App - Designed for iPhone and iPad With its addictive challenge and interesting premise, Cubama is frantic screen-tapping fun.   | Read more »
Become a Guardians of Galactic Peace Wit...
Become a Guardians of Galactic Peace With the New Spacefaring Sim, Kairobotica. Posted by Jessica Fisher on July 30th, 2014 [ permalink ] | Read more »
Soul Guardians: Age of Midgard Review
Soul Guardians: Age of Midgard Review By George Fagundes on July 30th, 2014 Our Rating: :: SO MUCH GRIND IT CRUNCHESUniversal App - Designed for iPhone and iPad Swords and trading cards are fun, right? So is Soul Guardians: Age of... | Read more »
NFL Fantasy Football App Redesigned Ahea...
NFL Fantasy Football App Redesigned Ahead of Upcoming 2014 Season Posted by Ellis Spice on July 30th, 2014 [ permalink ] | Read more »

Price Scanner via MacPrices.net

More iPad Upgrade Musings – The ‘Book Mystiqu...
Much discussed recently, what with Apple reporting iPad sales shrinkage over two consecutive quarters, is that it had apparently been widely assumed that tablet users would follow a two-year hardware... Read more
13-inch 2.5GHz MacBook Pro on sale for $999,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $999.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $100 off MSRP. Price is... Read more
Save up to $300 on an iMac with Apple refurbi...
The Apple Store has Apple Certified Refurbished iMacs available for up to $300 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. These are the best prices on... Read more
WaterField Unveils 15″ Outback Solo & 13″...
Hard on the heels of Apple’s refreshed MacBook Pro Retina laptops announcement, WaterField Designs has unveiled a 15-inch version of the waxed-canvas and leather Outback Solo and a 13-inch version of... Read more
New Roxio Toast 12 Delivers Digital Media Pow...
Roxio Toast 12 is a hub for sharing digital media to virtually any platform or device. has introduced two new additions to its Roxio Toast product family – Roxio Toast 12 Titanium and Roxio Toast 12... Read more
The lowest prices on leftover Retina MacBook...
Best Buy has dropped prices on leftover 13″ and 15″ Retina MacBook Pros by up to $300 off original MSRP on their online store for a limited time. Choose free local store pickup (if available) or free... Read more
Apple Updates MacBook Pro with Retina Display...
Apple today updated its MacBook Pro with Retina display with faster processors and double the amount of memory in both entry-level configurations. MacBook Pro with Retina display features a Retina... Read more
Up to $250 price drop on leftover 15-inch Mac...
B&H Photo has dropped prices on 2013 15″ Retina MacBook Pros by as much as $250 off original MSRP. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.3GHz Retina MacBook Pro: $2349... Read more
Updated MacBook Pro Price Trackers
We’ve updated our MacBook Pro Price Trackers with the latest information on prices, bundles, and availability on the new 2014 models from Apple’s authorized internet/catalog resellers as well as... Read more
Apple updates MacBook Pros with slightly fast...
Apple updated 13″ and 15″ Retina MacBook Pros today with slightly faster Haswell processors. 13″ models now ship with 8GB of RAM standard, while 15″ MacBook Pros ship with 16GB across the board. Most... Read more

Jobs Board

Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Sr. Product Leader, *Apple* Store Apps - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.