Question

[macOS Mojave 10.14.6]

I've recently discovered r/w disk images and the particularly fascinating sparse bundle.

As I understand it, an image (the .dmg or .sparsebundle itself) is "attached" and "detached" much the same as an external drive, for example, would be "plugged in" or "unplugged." The volumes contained in either case would then be "mounted" and "unmounted." But here's the problem:

caffeinatedbits ~$ hdiutil create -size 1g -layout GPTSPUD -fs APFS -volname temp -type SPARSEBUNDLE -nospotlight -encryption AES-256 temp.sparsebundle
Enter a new password to secure "temp.sparsebundle": 
Re-enter new password: 
created: /Users/caffeinatedbits/temp.sparsebundle
caffeinatedbits ~$ 
caffeinatedbits ~$ hdiutil attach temp.sparsebundle -mountroot .
Enter password to access "temp.sparsebundle": 
/dev/disk8              GUID_partition_scheme           
/dev/disk8s1            Apple_APFS                      
/dev/disk9              EF57347C-0000-11AA-AA11-0030654 
/dev/disk9s1            41504653-0000-11AA-AA11-0030654 /Users/caffeinatedbits/temp

I noted here that attaching the image apparently auto-mounts the volume. Cool.

I figure maybe it would do the same in reverse, but when attempting to detach the image, it only ejects the volume:

caffeinatedbits ~$ hdiutil detach temp
"disk9" ejected.
caffeinatedbits ~$ diskutil list | grep disk8
/dev/disk8 (disk image):
   0:      GUID_partition_scheme                        +1.1 GB     disk8
   1:                 Apple_APFS Container disk9         1.1 GB     disk8s1
                                 Physical Store disk8s1

The image itself (/dev/disk8) remains attached and must be detached separate from the volume itself (previously /dev/disk9s1).

At this point, I began to wonder if it's safe to rsync/backup the image since it's still attached? Or could that cause corruption? So I wanted to figure out how to completely detach the image...

caffeinatedbits ~$ hdiutil detach disk8
"disk8" ejected.

Then I wondered if I could've just done that in the first place. As it turns out, I can...

caffeinatedbits ~$ hdiutil attach temp.sparsebundle -mountroot .
Enter password to access "temp.sparsebundle": 
/dev/disk8              GUID_partition_scheme           
/dev/disk8s1            Apple_APFS                      
/dev/disk9              EF57347C-0000-11AA-AA11-0030654 
/dev/disk9s1            41504653-0000-11AA-AA11-0030654 /Users/caffeinatedbits/temp
caffeinatedbits ~$ hdiutil detach disk8
"disk8" ejected.

But then I wondered whether damage could be caused to the volume since it wasn't first unmounted. Should I unmount the volume first, or does detaching the image (disk8) do that automatically?

caffeinatedbits ~$ hdiutil attach temp.sparsebundle -mountroot .
Enter password to access "temp.sparsebundle": 
/dev/disk8              GUID_partition_scheme           
/dev/disk8s1            Apple_APFS                      
/dev/disk9              EF57347C-0000-11AA-AA11-0030654 
/dev/disk9s1            41504653-0000-11AA-AA11-0030654 /Users/caffeinatedbits/temp
caffeinatedbits ~$ umount disk9s1
caffeinatedbits ~$ hdiutil detach disk8
"disk8" ejected.

Anyone know why calling hdiutil detach <mountpoint> doesn't detach the image? I figure it's because only the volume (disk9s1) is mounted to that mountpoint and it just stops there.

Once detached, I'm using rsync -ai --inplace image.sparsebundle -e ssh u@x.x.x.x::share/ to backup the image to my NAS. As I understand it, it's a very bad idea to do this while the volume is still mounted, but what about the image itself remaining attached? Does it matter?

What is the proper way to do this to ensure I don't corrupt my images?

Update @Gordon Davisson

caffeinatedbits ~$ hdiutil attach temp.sparsebundle -mountroot .
Enter password to access "temp.sparsebundle": 
/dev/disk8              GUID_partition_scheme           
/dev/disk8s1            Apple_APFS                      
/dev/disk9              EF57347C-0000-11AA-AA11-0030654 
/dev/disk9s1            41504653-0000-11AA-AA11-0030654 /Users/caffeinatedbits/temp
caffeinatedbits ~$ cd temp
caffeinatedbits temp$ hdiutil detach disk8
hdiutil: couln't unmount "disk8" - Resource busy
caffeinatedbits temp$ cd ..
caffeinatedbits ~$ hdiutil detach disk8
"disk8" ejected.

Based on your comment, I guess this shows that the volume is unmounted by detaching the parent image?

Was it helpful?

Solution

The man page for hdiutil(1) states

 detach dev_name [-force]
            detach a disk image and terminate any associated process.  dev_name is a partial /dev node path (e.g. "disk1").  As of Mac OS X 10.4, dev_name can also be a mount-
            point.  If Disk Arbitration is running, detach will use it to unmount any filesystems and detach the image.  If not, detach will attempt to unmount any filesystems
            and detach the image directly (using the `eject' ioctl).  If Disk Arbitration is not running, it may be necessary to unmount the filesystems with umount(8) before
            detaching the image.  eject is a synonym for detach.  In common operation, detach is very similar to diskutil(8)'s eject.

So the recommended way to detach would be to simply pass the mountpoint. I’ve tested this on Catalina and it works for me. Here is the transcript:

1. Creating the image and reviewing the automounted volume

% cd ~/Desktop 

% hdiutil create -size 1m -layout GPTSPUD -fs APFS -volname temp -type SPARSEBUNDLE -nospotlight -encryption AES-256 temp.sparsebundle
Enter a new password to secure "temp.sparsebundle": 
Re-enter new password: 
created: /Users/pion/Desktop/temp.sparsebundle

% mount
[...]
/dev/disk5s1 on /Volumes/temp (apfs, local, nodev, nosuid, journaled, noowners, mounted by pion)

% diskutil list
[...]
/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.0 MB     disk4
   1:                 Apple_APFS Container disk5         1.0 MB     disk4s1
/dev/disk5 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +1.0 MB     disk5
                                 Physical Store disk4s1
   1:                APFS Volume temp                    41.0 KB    disk5s1

2. Unmounting the automounted volume

% hdiutil detach /Volumes/temp 
"disk4" ejected.

% mount
[...]

% diskutil list               
[...]

3. Mounting onto Desktop mountroot

% hdiutil attach -mountroot . temp.sparsebundle
Enter password to access "temp.sparsebundle": 
/dev/disk4              GUID_partition_scheme           
/dev/disk4s1            Apple_APFS                      
/dev/disk5              EF57347C-0000-11AA-AA11-0030654 
/dev/disk5s1            41504653-0000-11AA-AA11-0030654 /Users/pion/Desktop/temp

% mount
[...]
/dev/disk5s1 on /Users/pion/Desktop/temp (apfs, local, nodev, nosuid, journaled, noowners, mounted by pion)

% diskutil list
[...]
/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.0 MB     disk4
   1:                 Apple_APFS Container disk5         1.0 MB     disk4s1

/dev/disk5 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +1.0 MB     disk5
                                 Physical Store disk4s1
   1:                APFS Volume temp                    24.6 KB    disk5s1

4. Unmounting from Desktop mountroot

% hdiutil detach temp
"disk4" ejected.

% mount
[...]

% diskutil list
[...]

Incidentally, if you were curious why you get both a disk8 and disk9 instead of just disk8, it's because you're using APFS. disk8 is the new disk you've just created (as a disk image) and mounted. disk8s1 is its first (and only) partition, formatted as APFS. The way that APFS works is by creating its own container that covers an entire partition and then mounts it as a separate virtual disk (disk9) which can then have its own virtual partition (disk9s1).

Licensed under: CC-BY-SA with attribution
Not affiliated with apple.stackexchange
scroll top