VMware Fusion: Shrinking the disk image of an OS X guest vm.

Reducing the size of a guest OS X vm’s vmdk file(s) requires a few steps.  For a Windows OS guest VM, there is a tools utility with a simple GUI.  Unfortunately there is not an equivalent tool for the Mac guest VM (even when vmtools are installed).

This technique was tested and confirmed on OS X 10.7.4 using VMware Fusion 4.1.3  It assumes your guest vm’s disk is not pre-allocated, and the vm does not have any snapshots. The host machine is a MacBook Air 13″ 2012 with the virtual disk images stored on an external drive over USB 3.

Space constraints on the Macbook Air are the primary reason I’m shrinking these disk images.  Saving disk space consumed by backups is the second reason.

1) Prepare the disk image for shrinking by using the guest vm’s Disk Utility.app to “Erase Free Space” (the simple, fast zero’ing will suffice).  For a disk image using 15 to 20GB, this may take five to ten minutes. When complete, shut down the vm and close the VMware Fusion app.

2) Using Finder, confirm the location of your guest vm’s vmdk files.

3) Open Terminal and type /Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -k, followed with a space and the path to your VM’s disk image.  The “\” is necessary to tell Terminal about the space between VMware and Fusion.

* As an alternative to typing the entire command with parameters, you may find it easier to “build” the command in Terminal using these steps:

  • Open Terminal
  • CD to “/Applications/VMware\ Fusion.app/Contents/Library/” (hint: use TAB completion with the CD command)
  • and then type “./vmware-vdiskmanager -k”
  • and then add the path to your virtual disk by locating the file in Finder and dragging it into Terminal. Terminal will then append the file’s path to the command, potentially saving you a lot typing.  This is

If you’ve successfully entered the command, Terminal will display “ Shrink: xx% done.” until the operation is complete (about 10 minutes for a 15GB disk image stored on an external drive).

My results:

  • VM #1 before: 13.5GB zipped to 10.9GB, after: 6.9GB zipped to a 4.9GB archive
  • VM #2 before: 16.7GB zipped to 12GB, after: 11.4GB zipped to a 7.1GB archive
  • Total physical disk savings of ~24GB for two working VMs and zipped archives.

OS X Lion: how to display DNS cache and purge DNS cache

Previously I described using “dscacheutil -cachedump” as a means of flushing your local cache and forcing OS X to query your configured DNS servers.

I’ve since learned the combination of “sudo killall -INFO mDNSResponder” and “sudo killall -HUP mDNSResponder” are a better solution for clearing out the DNS cache on Mac OS X 10.7 Lion.

Since Snow Leopard, Apple has made additional changes to their DNS processes and the previous suggestion no longer works for most OS X Lion users.  Some of us who upgraded over previous installations may still having a working version of this utility; or it may still be present, but do nothing at all.

The mDNSResponder system process handles DNS related task in OS X, and there are two terminal commands which can be useful regarding the status of your DNS cache.

The first command, “sudo killall -INFO mDNSResponder” sends a SIGINFO signal to the process.  This will cause the process to dump a snapshot summary of the internal state to /var/log/system.log.

The second command, “sudo killall -HUP mDNSResponder” sends a SIGHUP signal to the process.  This will cause the process to purge its cache.  Upon successful completion, /var/log/system.log will be sent the message, “PM mDNSResponder: SIGHUP: Purge cache”

The “-INFO” command is quite verbose and provides a way of confirming the contents of your DNS cache before and after the purge.

additional notes:

  • The mDNSResponder first appeared in Mac OS X 10.2 (Jaguar) and has provided features for MultiCast DNS and Bounjour.
  • dns-sd appeared in OS X 10.4 (Tiger) and provides a Library API for applications to interact with the mDNSResponder process.  Some command line options are available, but the command line arguments are still subject to change and should not be relied upon for permanent shell scripts.
  • The command line “scutil –dns” will display your current OS X 10.7 DNS configuration.

Xcode 4.2 – using source code branches and other Xcode shortcuts

command T — to open a new tab in Xcode.  Tabs can be pulled outside the main tab to create a multi-window environment.  These additional windows can then be pulled over to a second monitor.  The Xcode | Settings | Behavior pane can be used to setup window layouts to automatically launch when performing certain activities (like debugging, building, or testing).

Run multiple instances of your project simultaneously:  Xcode 4.2 supports launching multiple instances of an app (or multiple apps).  This helps with testing client-server scenarios and multi-user peer-to-peer apps.  You can mix and match simulator versions and physical device types, or just run multiple instances of the same version.

running Xcode from the command line:
$ /Xcode/usr/bin/clang -c myfile.h
$ /Xcode/usr/bin/clang++ -c another_file.cpp

Source control and multiple branches: From Organizer | Repositiories you can navigate into the Branches folder under a project, and the select the + Add Branch icon to create a new branch (additional options appear in popup dialog boxes).  From within your Xcode Workspace and the Editor, activate the “Show the Version Editor” icon (it’s in the upper right area of the toolbar).  Now you’ll have a navigator bar display at the bottom of each editor pane, and you can use this navigator bar to view items in various branches.

Note: navigating in the Version Editor does not switch your currently actively branch.  Be sure to use the Organizer’s Repository view to switch branches.  When clicking the Version Editor icon, it will initially display the currently active branch and version in the lower navigation bar (in case you need to quickly verify which branch you are working in).

To switch your active editing to a different branch, navigate back to the Organizer | Repositories and select the blue folder under your project repository (left side of screen).  From here, the lower area of the Repository view will display icons to Pull, Commit, or Switch Brach.  The upper right hand portion of the Repository view will display “Current Branch: yourBranchNameHere“.  If you switch branches while a workspace has that project open, the workspace window will refresh and load the selected branch’s files into the navigator.

Reconciling code from multiple branches:  When using the Version Editor, the navigation bar in the lower area of screen “appears” to allow you to look at two branches simultaneously.  At least for me (and my installation of Xcode 4.2.1), that doesn’t actually work.  The version editor is limited to viewing within the currently active branch.   Instead, when you need to compare across branches (or are ready to merge), it seems necessary use the Xcode | File | Source Control | Merge menu option.  This will launch you into a another popup window version of the version editor; however, it will only show the most recent version in each branch (the other version navigation features are disabled in the Merge view).

I’ll update these notes if I find a better way to compare versions across multiple branches or if this is updated/fixed in a subsequent release of Xcode.

OS X: display hostname on login screen

I frequently copy multiple virtual instances of OS X under VMware Fusion for testing beta applications, database server configs, and other dev/test work requirements.  As a result, I’ve found this little setting to be handy when dealing with a small fleet of OS X instances.

OSX -> show hostinfo at login screen

sudo defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName

OS X — using X Windows with a Linux/Unix host

X Windows to a linux/unix host:

Fedora:  running SSHD with port 22 open.
* launch MAC OSX “xterm.app”
* ssh -Y -X username@

run some apps… examples:
[usern@hostne ~]# system-config-firewall   (start app in window)
[usern@hostn ~]# X                                        (msg “server is already active…”)
[usern@hostn ~]# startkde                            (launchstarfdfdfdfdfdfdf KDE desktop)

If problems, then: check the user’s $HOME/ .Xauthority file
** it might be necessary to RM the file and then TOUCH a new file.

Run multiple instances of Firefox

do shell script "/Applications/Firefox.app/Contents/MacOS/firefox-bin -P TargetProfileName TargetURL > /dev/null 2>&1 &"
Substitue your required values for TargetProfilename and TargetURL as needed.
Multiple instances of this command can entered into an AppleScript and saved for resuse as needed.  The above command creates “windowless” processes.  I like to have a small browser window appear for each session launched by the script, so I use the syntax:
 do shell script "/Applications/Firefox.app/Contents/MacOS/firefox-bin -P TargetProfilename TargetURL &> /dev/null &"

I’ve found it helps to separate each command with a “delay 1” command in the script.  You may want to experiment with this depending upon your machine’s capabilities and the complexity of the TartgetURL you’re launching in each instance of the browser.

By incorporating browser plugins such as Greasemonkey, YSlow, and Firebug you can automate a wide range of web site testing scenarios.  This technique is also handy for scripting the automatic and schedule retrieval of data from web servers.  A couple associates use this for retrieving application server logs and the daily market data for their personal stock portfolio.

For Windows users, this shell script will accomplish similar results on WinXP:

save the following script as a Windows XP batch file.

This script includes a menu to choose between launching all configured profiles, a single profile/tab, the profile manager, or just exiting without doing anything.

@echo off

set UserChoiceIs=

echo  Would you like to launch all available Mozilla Firefox profiles and tabs?.
echo      Select A, to launch all profiles and tabs.
echo      Select S, to launch a single profile with only 1 tab.
echo      select P, to launch the Mozilla Firefox profile manager.
echo      Select E, to exit (launch nothing).

set /p UserChoiceIs={a,s,p,e}
IF NOT "%UserChoiceIS%"=='' SET UserChoiceIs=%UserChoiceIs:~0,1%
IF /I "%UserChoiceIs%"=="a" GOTO ALLPROFILES
IF /I "%UserChoiceIs%"=="s" GOTO SINGLETAB
IF /I "%UserChoiceIs%"=="e" GOTO ENDGOODBYE

REM echo you've selected to launch all profiles/tabs.
REM pause
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -p 1stTargetProfile -no-remote
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -p 2ndTargetProfile -no-remote
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -p 3rdTargetProfile -no-remote

REM echo you've selected to launch a single profile/tab.
REM pause
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -p 1stTargetProfile -no-remote "about:robots"

REM echo you've select to launch the Mozilla Firefox profile manager.
REM pause
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" -p

REM echo you've selected to exit
REM pause

REM echo Goodbye.
REM pause

network testing: using IPFW to add latency or limit bandwidth

If you need to test an iOS app’s network performance, this technique helps make the simulator perform a little more like it is out on a real mobile network.  This is also helpful testing / simulating any other scenario that may involve slow WAN links, dial up connections, Satellite links, etc.

ipfw to add latency or limit bandwidth:

as root, run:

ipfw add pipe 1 ip from any to any out
ipfw add pipe 2 ip from any to any in
ipfw pipe 1 config delay 150 bw 50kbit/s
ipfw pipe 2 config delay 150 bw 200kbit/s

to reset:

ipfw flush

OS X — DVDs to ISO where source format is “ISO UDF”

DVDs to ISO where source format is “ISO UDF”
df  –> shows current disks & volumes
sudo umount /dev/disk2  (normally the CD/DVD drive)
dd if=/dev/disk2 of=”filename-to-output”.iso

OS X — LiveCD ISO to a bootable USB stick

LiveCD ISO to a bootable USB stick:

$ mount   *\\ to see current drives
$ diskutil umountDisk /dev/diskN
$ sudo dd if=/path/to/downloaded.iso of=/dev/diskN bs=1m
$ diskutil eject /dev/diskN