bmigrate - migrate a live block device to a new location Copyright (c) 1999, Malcolm Beattie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. bmigrate is a set of programs which make use of the CONFIG_REQUEST_LOG option available in (the reqlog patch to) the Linux kernel in order to migrate the contents of a live in-use block device to a new location. This can be used to help migrate a large filesystem or database to a new system with only a few seconds unavailability time as the service is switched over. SUMMARY bmigrate is made up of three main programs: breqd, bmigrate and breceive. breqd runs as a daemon and reads a configuration file /etc/breqd.conf to determine which block devices it should monitor and where it should keep their "dirty bitmaps" up to date. It constantly monitors the request log device which the (patched) kernel notifies whenever any sector on any block device is written to. When a sector/block is written, breqd sets the corresponding bit of its configured bitmap file (a 1MB bitmap will handle an 8GB block device using 1KB blocks). bmigrate is the command which initiates the migration of data from a live in-use block to a new location. It sweeps through the bitmap for that device (whose newly dirtied blocks are constantly being kept track of in the bitmap file) and for all dirty blocks, it zeroes their dirty bits, reads the corresponding real data blocks from the device and writes them to stdout along with their sector numbers and sizes. bmigrate makes continuous sweeps of the bitmap (pausing for a configurable time such as 5 seconds whenever the bitmap goes from non-clean to all-clean). breceive reads from stdin the (sector, size, data) information generated by bmigrate and seeks and writes the new blocks to the file/device passed as its first command line argument. EXAMPLE An example usage of bmigrate is the pipeline: bmigrate -f /dev/sdb1 | ssh newhost breceive /dev/sdb1 (with breqd running as a daemon in the background). The "-f" option starts by setting all bits in the bitmap file for /dev/sdb1 to 1 so that all data blocks are migrated. After the first sweep through the bitmap file, the only data blocks not cloned on newhost's /dev/sdb1 are those which were modified while bmigrate was running through that sweep (remember, /dev/sdb1 is assumed to be a live, in-use block device). When the activity on sdb1 is low and bmigrate is only migrating a small number of blocks per sweep, the user of the block device can be shut down briefly (i.e. the filesystem unmounted or the database using that device quiesced). With no further activity on the device, bmigrate's next full sweep takes the dirty block count down to zero and, at that point, the sdb1 device on newhost is an exact copy of the original system's device and you can bring up the filesystem/database/whatever on newhost. INSTALLATION bmigrate depends on the CONFIG_REQUEST_LOG feature being enabled in the Linux kernel. This feature is currently available as a patch against the 2.2.12 kernel (and the patch itself depends on a further patch: the bufflink device patch). You can get these from ftp://ftp.ox.ac.uk/pub/linux/reqlog-0.3.tar.gz ftp://ftp.ox.ac.uk/pub/linux/bufflink-0.3.tar.gz The bmigrate suite programs aren't complicated and shouldn't prove difficult to compile/build: you don't need any special libraries or such like. Just type make and you should end up with executables breqd, bmigrate and breceive. (There's also the utility bfill but you can ignore that). Copy the resulting executables into a directory such as /usr/sbin (or /usr/local/sbin or wherever you like really). Copy the sample configuration file breqd.conf.sample as /etc/breqd.conf and follow the comments included in that file to configure what devices you want breqd to monitor and where you want to put the resulting bitmap files (putting a bitmap file for a device on a filesystem which lives on that same device is not recommended). Now, you just need to make sure that breqd is running before you start a "bmigrate -f". If you want to do an incremental migration, see below. That's it. You can use the output of bmigrate either as input to breceive to clone the data onto a new device (via rsh, ssh or whatever method you like) or write it to tape or disk or a file elsewhere for use as a backup (i.e. to be later fed to breceive). INCREMENTAL MIGRATION It is possible (although possibly not often practical) to use "bmigrate -f" to generate a full block device "dump" snapshot (either to another disk by using breceive or even just dumping the block data output of bmigrate to tape) and then generate an incremental dump on top of that. *Provided* that (1) breqd is always set running *before* the block device is activated (i.e. before its filesystem is mounted if the block device hosts a filesystem); and (2) breqd is never killed until the block device is inactive (e.g. unmounted); and (3) breqd never detects an overflow condition on /dev/reqlog (meaning that it has failed to keep up with all the notifications from the kernel) then using bmigrate without the -f option will write out only the blocks dirtied since the last time a full "bmigrate -f" was taken. In that case, you can use the full snapshot and the small (one hopes) incremental snapshot to reconstruct the entire device at two different times. This may not be practical, but the feature arises quite simply from the design of bmigrate and, who knows, it may turn out to be useful. Malcolm Beattie mbeattie@sable.ox.ac.uk 1 November 1999