OS Hacking and more.

7.20.2008

ZFS Volume Copy and OS imaging reborn


dd has been around since the dawn of time, using its sheer muscle to move entire filesystems from disk to disk without defect. If you want to make sure nothing changes when imaging and cloning an OS, you turn to dd. Problem with dd is that is too comprehensive, it copies a the content of a disk block by block, ignorant to the actual files contained in those blocks. dding to a disk or partition also means that disk is entirely erased, and the new blocks are locked in place. If you're dding a disk image, the filesystem on the receiving disk becomes locked to the image's original size...dd is just too crude sometimes...

Enter ZFS

ZFS is abstracted away from the physical disk blocks, dealing instead in files and directories. Further, ZFS deals in dynamically-sized volumes instead of partitions; each is literally a collection of files that is highly portable yet cloneable.
Interestingly enough, there is no built-in function to copy an entire ZFS volume from one pool to another, as one would do when preparing many disks with a particular OS-application setup...but all the pieces are there to produce one, so why not?
ZFS currently supports the creation and copying of snapshots, which on their own contain now files, but can be used as precursors to a cloned filesystem. What we will do is create a snapshot of the zfs volume in question, send it from that pool to the target pool, restore it as a filesystem and ensure that all the files are migrated as a part of that process.

let zfpool be the source zfs pool with the volume zvol to be copied.
let rpool be the target pool where a new zfs volume will be created in the image of zvol.

First, let's snapshot zfpool/zvol, this will save its current state without saving files.


$ zfs snapshot zfpool/zvol@20080720



Next, we need to move that snapshot from zfpool to rpool...


$ zfs send zfpool/zvol > /tmp/temp.snapshot && zfs receive rpool < /tmp/temp/snapshot



Now if we zfs list, we'll see that there is a snapshot in both zfpool and rpool...this is quite good...and then you see the new, populated volume there as well...
And we're done...we've cloned zvol and moved it to another disk/set of disks!
So, imagine if we have an Opensolaris install on a volume like zvol, it's now been imaged to another disk...ready to use!

One thing, this works pretty well with clones of volumes, but cloning the root of a pool(zfpool alone) is not as clear cut, and i do not suggest it for exactly that reason...I'm not sure if it works.
These steps are summarized below.
note that there are segments in comments that can be used instead of the prompts for target and source, for complete automation of this task.


Script:


#!/bin/bash
sudo zpool list

#prespecify snapshot
#SNAPSHOT = zfpool/zvol@20080714
#TARGET = rpool
#---

echo "Enter snapshot name: "
read SNAPSHOT
echo "Enter FS/pool"
read POOL
echo "Enter volume"
read LOCATION
echo "Enter target pool/volume"
read TARGET
if ["$LOCATION" = ""]
then
FROMSNAPSHOT="$POOL@$SNAPSHOT"
else
FROMSNAPSHOT="$POOL/$LOCATION@$SNAPSHOT"
fi
#auto generate a new snapshot
sudo zfs snapshot $FROMSNAPSHOT
if ["$LOCATION" = ""]
then
TOSNAPSHOT="$TARGET@$SNAPSHOT"
else
TOSNAPSHOT="$TARGET/$LOCATION@$SNAPSHOT"
fi
sudo zfs send $SNAPSHOT > /tmp/temp.snapshot && zfs receive $TOSNAPSHOT < /tmp/temp.snapshot

2 comments:

Stripes said...

Why do you write a file in /tmp and then reread it as opposed to using a pipe?

mc said...

@Stripes:

If you're using spinning media, doing all your reads to dump the file to /tmp (in memory), then all your writes to write the file to disk at once will be faster than thrashing the disk to read/write simultaneously if using a pipe