Force input_length and output_length to be uint64_t (not size_t).
[dm-merge.git] / README
blobcfcee6a25bd3f779d8cfc5fe91fc0c25d76c6fd6
1 dm-merge
2 --------
4 dm-merge is a simple tool to apply changes recorded in a copy-on-write
5 exception table. It can be effectively used to either "commit" the changes into
6 the source (as made with simple snapshot target) or "rollback" (reverting to a
7 state the snapshot was created; as made with snapshot linked to snapshot-origin
8 target). And while LVM snapshots are simply (maybe not so simply, actually) the
9 latter case, it can revert a logical volume to the exact state it was when the
10 snapshot was taken.
12 dm-merge simply reads an exception table and applies the changes back to the
13 source
15 It can be thought of as a C port of Lars Ellenberg's 'list_exception_chunks'
16 perl script [1]. I liked the idea very much.
20 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 Disclaimer: be warned: the tool was only tested on X86 and X86_64 little endian
23 machines! It is still experimental. Use at _your_ _own_ risk! Before using it,
24 you should understand how device-mapper, LVM and snapshots work.
26 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30 1. Usage
31 --------
33 dm-merge [options] -i <snapshot_device> [ -o <output_device> ]
35 Options:
36 -f              REALLY do it (no dry run)
37 -x              Relaxed mode; allow some things (namely ioctl) to fail
38 -d              Print dd lines as list_exception_chunks.pl would
39 -D              Try to use O_DIRECT
40 -v              Be verbose (more '-v's increase verbosity)
41 -i <file>       Input (snapshot) COW (copy-on-write) filename
42 -o <file>       Output (the device being snapshoted) filename
46 2. Scenarios
47 ------------
49 2.1 Reverting (LVM) snapshot
50 ----------------------------
52 Suppose you have a logical volume ${lv} in a virtual group ${vg} and a snapshot
53 ${sn} of ${lv} made by something like:
55     lvcreate -L ${some_size} -n ${sn} ${vg}/${lv}
57 As long as ${sn} isn't full it will behave like ${lv} at the time the snapshot
58 was taken.
60 Now you make some changes to ${lv} and realize you'd like to revert to the
61 state of ${sn}. This is when dm-merge comes into play.
63 With dm-merge you have basically two options:
65 1) make the changes while ${lv} is "inactive" (recommended)
67 2) keep ${lv} "active" and attempt the changes (for the adventurous)
70 2.1.1 dm-merge and inactive ${lv}
71 ---------------------------------
74 1) Duplicate the tables of ${lv} and snapshot storage:
76     dmsetup ${vg}-${lv}-real | dmsetup create tmp_lv
77     dmsetup ${vg}-${sn}-cow | dmsetup create tmp_cow
79 2) Deactivate the LV (the mappings will disappear, that's why we duplicate the
80 tables):
82     lvchange -a n ${vg}/${lv}
84 3) Flush buffers (better safe than sorry):
86     blockdev --flushbufs /dev/mapper/{tmp_lv,tmp_cow}
88 4) Make sure nothing else touches the data (it should _not_ be mounted!):
90     ...
92 5) First (purely informative; non-destructive) dm-merge run. See if the numbers
93 look reasonable...
95     dm-merge -i /dev/mapper/tmp_cow -o /dev/mapper/tmp_lv -vd
97 6) If everything seems OK, do it:
99     dm-merge -i /dev/mapper/tmp_cow -o /dev/mapper/tmp_lv -f
101 7) Flush buffers (better safe than sorry):
103     blockdev --flushbufs /dev/mapper/{tmp_lv,tmp_cow}
105 8) Now it should be done. You may remove the temporary mapping then:
107     dmsetup remove tmp_lv
108     dmsetup remove tmp_cow
110 9) The original snapshot may not be necessary anymore (it will show the same
111 data as the ${lv} now), so you can remove it:
113     lvremove ${vg}/${sn}
115 10) Activate the LV again:
117     lvchange -a y ${vg}/${lv}
121 2.1.2 dm-merge and active ${lv}
122 -------------------------------
124 1) Make sure nothing else touches the data (it should _not_ be mounted!);
125 perhaps "dmsetup suspend" could help a little...:
127     ...
129 2) Flush buffers (better safe than sorry):
131     blockdev --flushbufs /dev/mapper/${vg}-${sn}* /dev/mapper/${vg}-${lv}*
133 3) First (purely informative; non-destructive) dm-merge run. See if the numbers
134 look reasonable...
136     dm-merge -i /dev/mapper/${vg}-${sn}-cow -o /dev/mapper/${vg}-${lv}-real -vd
138 4) If everything seems OK, do it:
140     dm-merge -i /dev/mapper/${vg}-${sn}-cow -o /dev/mapper/${vg}-${lv}-real -f
142 5) Flush buffers (better safe than sorry):
143     
144     blockdev --flushbufs /dev/mapper/${vg}-${sn}* /dev/mapper/${vg}-${lv}*
146 6) The original snapshot may not be necessary anymore (it will show the same
147 data as the LV now, so you can remove it):
149     lvremove ${vg}/${sn}
153 2.2 Applying a copy-on-write back to the source ("commit")
154 ----------------------------------------------------------
156 With device mapper and the "snapshot" target (dm-snapshot != LVM snapshot [2]),
157 you can simply create a mapping that "redirects" all writes to a different
158 device so the source stays intact. So when not changed, data is read from the
159 source device; when changed, it is read from a special device (exception
160 table).
162 So you have some data mapping ${data}, a COW storage ${cow_s} and a dm-snapshot
163 mapping ${sn} [3] created with something like:
165     echo "0 $(blockdev --getsize /path/to/${data}) snapshot /path/to/${data} /path/to/${cow_s} P 8" | dmsetup create ${sn}
167 Now all writes made to /dev/mapper/${sn} go to /path/to/${cow_s}.
169 Imagine you are testing a program inside ${sn}. After testing you'd like to
170 apply the changes made in ${sn} back into ${data}.
172 Here comes dm-merge.
174 1) Make sure nothing else touches the data (it should _not_ be mounted!) ...
176     ...
178 2) Flush buffers (better safe than sorry):
180     blockdev --flushbufs /path/to/${data} /path/to/${cow_s} /dev/mapper/${sn}
182 3) First (purely informative; non-destructive) dm-merge run. See if the numbers
183 look reasonable...
185     dm-merge -i /path/to/${cow_s} -o /path/to/${data} -vd
187 4) If everything seems OK, do it:
189     dm-merge -i /path/to/${cow_s} -o /path/to/${data} -f
191 5) Flush buffers (better safe than sorry):
193     blockdev --flushbufs /path/to/${data} /path/to/${cow_s} /dev/mapper/${sn}
198 -----
200 [1] http://article.gmane.org/gmane.linux.lvm.general/9899
202 [2] LVM snapshots need "snapshot" and "snapshot-origin" dm targets to
203 accomplish the goal.
205 [3] Neither ${data} nor ${cow_s} has to be a device-mapper device (for the
206 simplest case). But if you want to do some clever tricks (such as table
207 changing so ${sn} takes place of ${data}; as shown at
208 http://linuxgazette.net/114/kapil.html), you'd need them to be.