This is the third part of my supposedly short GEOM GATE tutorial. In this part I would like to show how to use ggatel and what do I want to do as a brand new GEOM GATE module.
Here's a list of tutorial parts:
- First part - Describes what GEOM and GEOM GATE are
- Second part - Describes some more on how GEOM and GEOM GATE work, discusses sector sizes and dissects ggatel.
- Third part - Shows how to use ggatel, describes the idea behind the new module which will be written in the tutorial
Using ggatel is extremely simple. The basic sequence of the operations is to create a new file which will be used as a disk drive, attach the file as a device, work on the new device and then destroy the device when it's not needed.
Creating a file which will be used as a virtual disk
The usual way of creating files is with dd. The only important thing here is that the file size must be a multiple of the desired sector size. In this example, we will create a 10 GiB file, and since it's a large power of two, we can later use any number of valid sector sizes.
dd if=/dev/zero of=vd bs=1M count=10240
Note that the file name is "vd".
Attaching the file as a ggatel device
The ggatel executable is used for all operations, including attaching the file as a drive. In this case, we will use a sector size of 4 KiB:
ggatel create -s 4096 vd
If everything goes ok, the ggatel utility will display a line containing the name of the newly created device, e.g. "ggate0". You can verify this by e.g. using the "diskinfo" utility:
# diskinfo -v /dev/ggate0
4096 # sectorsize
10737418240 # mediasize in bytes (10.0G)
262144 # mediasize in sectors
0 # stripesize
0 # stripeoffset
Note the sector size and the media size.
Using the device
The new device (e.g. /dev/ggate0) can now be used as any other storage device, e.g. with newfs and mount:
newfs -U /dev/ggate0
mount /dev/ggate0 /mnt
All of these operations should complete without error.
Destroying the device
The same utility can be used to destroy the ggate device when it's no longer used (e.g. no longer mounted):
ggatel destroy -u 0
There it is - the basics of using ggatel. There are also the "list" command which lists the created devices and the "rescue" command which attempts to reopen the file, but they are not used that often.
The idea for the new ggate module
As an example which also has the potential of being useful, I will create a ggate device which implements "growable" virtual drives. In other words, this will be a device backed by a file which will grow as the used space on the virtual drive grows.
This is basically similar to what VMDK and VHD formats used in virtualization do, but I don't want to reverse engineer them just for this tutorial - and if there are some easy-to-use libraries which already do that, they should be easy to integrate into the ggate module later.
To keep things simple, I'll use a simple DBM-like database for the backing file, in which keys will be the sector offsets and values the sector contents. Since GEOM enforces sector granularity, we know that all IO will be sector-aligned and we can easily split large IO requests into multiple sectors / records to write to the database.
I could use the FreeBSD's built-in DB1.85 database, but it's simply too old, without any real support for crash recovery. I've looked around and Kyoto Cabinet seems like a good alternative, supporting everything (and more) a simple system like this needs.
The starting point for the new module
I'm calling the new module "ggvd", from "GEOM GATE virtual drive", and I've started the project by copying and adapting the ggatel sources. I've created a BitBucket repository for the new project and tagged the starting point which doesn't yet contain any module-specific code.