dm_target_snapshot.c revision 1.1.2.6 1 /* $NetBSD: dm_target_snapshot.c,v 1.1.2.6 2008/08/20 00:45:47 haad Exp $ */
2
3 /*
4 * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * 1. Suspend my_data to temporarily stop any I/O while the snapshot is being
34 * activated.
35 * dmsetup suspend my_data
36 *
37 * 2. Create the snapshot-origin device with no table.
38 * dmsetup create my_data_org
39 *
40 * 3. Read the table from my_data and load it into my_data_org.
41 * dmsetup table my_data | dmsetup load my_data_org
42 *
43 * 4. Resume this new table.
44 * dmsetup resume my_data_org
45 *
46 * 5. Create the snapshot device with no table.
47 * dmsetup create my_data_snap
48 *
49 * 6. Load the table into my_data_snap. This uses /dev/hdd1 as the COW device and
50 * uses a 32kB chunk-size.
51 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot \
52 * /dev/mapper/my_data_org /dev/hdd1 p 64" | dmsetup load my_data_snap
53 *
54 * 7. Reload my_data as a snapshot-origin device that points to my_data_org.
55 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot-origin \
56 * /dev/mapper/my_data_org" | dmsetup load my_data
57 *
58 * 8. Resume the snapshot and origin devices.
59 * dmsetup resume my_data_snap
60 * dmsetup resume my_data
61 */
62
63 /*
64 * This file implements initial version of device-mapper snapshot target.
65 */
66 #include <sys/types.h>
67 #include <sys/param.h>
68
69 #include <sys/buf.h>
70 #include <sys/errno.h>
71 #include <sys/ioctl.h>
72 #include <sys/ioccom.h>
73 #include <sys/kmem.h>
74 #include <sys/types.h>
75 #include <sys/param.h>
76 #include <sys/queue.h>
77
78 #include "dm.h"
79
80 /*
81 * Init function called from dm_table_load_ioctl.
82 * argv: /dev/mapper/my_data_org /dev/mapper/cow_dev p 64
83 * snapshot_origin device, cow device, persistent flag, chunk size
84 */
85 int
86 dm_target_snapshot_init(struct dm_dev *dmv, void **target_config, char *params)
87 {
88 struct target_snapshot_config *tsc;
89
90 char **ap, *argv[5];
91
92 /*
93 * Parse a string, containing tokens delimited by white space,
94 * into an argument vector
95 */
96 for (ap = argv; ap < &argv[4] &&
97 (*ap = strsep(¶ms, " \t")) != NULL;) {
98 if (**ap != '\0')
99 ap++;
100 }
101
102 printf("Snapshot target init function called!!\n");
103 printf("Snapshotted device: %s, cow device %s, persistent flag: %s,"
104 "chunk size: %s\n", argv[0], argv[1], argv[2], argv[3]);
105
106 if ((tsc = kmem_alloc(sizeof(struct target_snapshot_config), KM_NOSLEEP))
107 == NULL)
108 return 1;
109
110 tsc->persistent_dev = 0;
111
112 tsc->chunk_size = atoi(argv[3]);
113
114 if (strcmp(argv[2], "p") == 0)
115 tsc->persistent_dev = 1;
116
117 *target_config = tsc;
118
119
120 dmv->dev_type = DM_SNAPSHOT_DEV;
121
122 return 0;
123 }
124
125 /*
126 * Status routine is called to get params string, which is target
127 * specific. When dm_table_status_ioctl is called with flag
128 * DM_STATUS_TABLE_FLAG I have to sent params string back.
129 */
130 char *
131 dm_target_snapshot_status(void *target_config)
132 {
133 struct target_snapshot_config *tlc;
134
135 tlc = target_config;
136
137 printf("Snapshot target status function called\n");
138
139 return 0;
140 }
141
142 /* Strategy routine called from dm_strategy. */
143 int
144 dm_target_snapshot_strategy(struct dm_table_entry *table_en, struct buf *bp)
145 {
146
147 printf("Snapshot target read function called!!\n");
148
149 bp->b_error = EIO;
150 bp->b_resid = 0;
151
152 biodone(bp);
153
154 return 0;
155 }
156
157 /* Doesn't do anything here. */
158 int
159 dm_target_snapshot_destroy(struct dm_table_entry *table_en)
160 {
161 table_en->target_config = NULL;
162
163 return 0;
164 }
165
166 /* Unsupported for this target. */
167 int
168 dm_target_snapshot_upcall(struct dm_table_entry *table_en, struct buf *bp)
169 {
170 return 0;
171 }
172 /*
173 * dm target snapshot origin routines.
174 *
175 * Keep for compatibility with linux lvm2tools. They use two targets
176 * to implement snapshots. Snapshot target will implement exception
177 * store and snapshot origin will implement device which calls every
178 * snapshot device when write is done on master device.
179 */
180
181 /* Init function called from dm_table_load_ioctl. */
182 int
183 dm_target_snapshot_orig_init(struct dm_dev *dmv, void **target_config, char *argv)
184 {
185
186 printf("Snapshot_Orig target init function called!!\n");
187
188 *target_config = NULL;
189
190
191 dmv->dev_type = DM_SNAPSHOT_ORIG_DEV;
192
193 return 0;
194 }
195
196 /*
197 * Status routine is called to get params string, which is target
198 * specific. When dm_table_status_ioctl is called with flag
199 * DM_STATUS_TABLE_FLAG I have to sent params string back.
200 */
201 char *
202 dm_target_snapshot_orig_status(void *target_config)
203 {
204 struct target_snapshot_orig_config *tlc;
205
206 tlc = target_config;
207
208 printf("Snapshot_Orig target status function called\n");
209
210 return 0;
211 }
212
213 /* Strategy routine called from dm_strategy. */
214 int
215 dm_target_snapshot_orig_strategy(struct dm_table_entry *table_en, struct buf *bp)
216 {
217
218 printf("Snapshot_Orig target read function called!!\n");
219
220 bp->b_error = EIO;
221 bp->b_resid = 0;
222
223 biodone(bp);
224
225 return 0;
226 }
227
228 /* Doesn't do anything here. */
229 int
230 dm_target_snapshot_orig_destroy(struct dm_table_entry *table_en)
231 {
232 table_en->target_config = NULL;
233
234 return 0;
235 }
236
237 /* Unsupported for this target. */
238 int
239 dm_target_snapshot_orig_upcall(struct dm_table_entry *table_en, struct buf *bp)
240 {
241 return 0;
242 }
243