]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
o _read_id function for import.c
[lvm2.git] / lib / activate / activate.c
CommitLineData
b1713d28
JT
1/*
2 * Copyright (C) 2001 Sistina Software (UK) Limited.
3 *
1b9fcf48 4 * This file is released under the LGPL.
b1713d28
JT
5 */
6
a381c45a 7#include "metadata.h"
b1713d28 8#include "activate.h"
78125be9 9#include "display.h"
f047219b 10#include "log.h"
f7a14956 11#include "fs.h"
41b2fd5f 12#include "lvm-string.h"
b1713d28 13
ab269099
JT
14static void _build_lv_name(char *buffer, size_t s, struct logical_volume *lv)
15{
16 snprintf(buffer, s, "%s_%s", lv->vg->name, lv->name);
17}
18
2ba80b43 19static struct dm_task *_setup_task(struct logical_volume *lv, int task)
37ed70b9
JT
20{
21 char name[128];
22 struct dm_task *dmt;
23
24 if (!(dmt = dm_task_create(task))) {
25 stack;
26 return NULL;
27 }
28
29 _build_lv_name(name, sizeof(name), lv);
30 dm_task_set_name(dmt, name);
31
32 return dmt;
33}
34
3080a754 35int lv_info(struct logical_volume *lv, struct dm_info *info)
37ed70b9 36{
ef8a0eae 37 int r = 0;
37ed70b9
JT
38 struct dm_task *dmt;
39
a299e388 40 log_very_verbose("Getting device info for %s", lv->name);
37ed70b9
JT
41 if (!(dmt = _setup_task(lv, DM_DEVICE_INFO))) {
42 stack;
43 return 0;
44 }
45
46 if (!dm_task_run(dmt)) {
2ba80b43 47 stack;
ef8a0eae 48 goto out;
2ba80b43
JT
49 }
50
ef8a0eae
JT
51 if (!dm_task_get_info(dmt, info)) {
52 stack;
53 goto out;
54 }
55 r = 1;
2ba80b43 56
ef8a0eae 57 out:
2ba80b43 58 dm_task_destroy(dmt);
ef8a0eae 59 return r;
2ba80b43
JT
60}
61
94b8220f 62int lv_active(struct logical_volume *lv)
2ba80b43 63{
94b8220f 64 int r = -1;
ef8a0eae 65 struct dm_info info;
2ba80b43 66
3080a754 67 if (!lv_info(lv, &info)) {
37ed70b9 68 stack;
94b8220f 69 return r;
37ed70b9
JT
70 }
71
a299e388 72 log_very_verbose("%s is%s active", lv->name, info.exists ? "":" not");
ef8a0eae 73 return info.exists;
37ed70b9
JT
74}
75
2bc25b54
AK
76int lv_suspended(struct logical_volume *lv)
77{
78 int r = -1;
79 struct dm_info info;
80
81 if (!lv_info(lv, &info)) {
82 stack;
83 return r;
84 }
85
86 log_very_verbose("%s is%s suspended", lv->name,
87 info.suspended ? "":" not");
88 return info.suspended;
89}
90
94b8220f 91int lv_open_count(struct logical_volume *lv)
2ba80b43 92{
94b8220f 93 int r = -1;
ef8a0eae 94 struct dm_info info;
2ba80b43 95
3080a754 96 if (!lv_info(lv, &info)) {
2ba80b43 97 stack;
94b8220f 98 return r;
2ba80b43
JT
99 }
100
a299e388 101 log_very_verbose("%s is open %d time(s)", lv->name, info.open_count);
ef8a0eae 102 return info.open_count;
2ba80b43
JT
103}
104
80f9662b 105/*
0bab6591 106 * Emit a target for a given segment.
80f9662b 107 */
0bab6591 108static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
80f9662b
JT
109{
110 char params[1024];
39497a44 111 uint64_t esize = seg->lv->vg->extent_size;
0bab6591 112 uint32_t s, stripes = seg->stripes;
b546cd6d 113 int w = 0, tw = 0;
6c4ee296
JT
114 const char *no_space =
115 "Insufficient space to write target parameters.";
0bab6591 116
6c4ee296 117 if (stripes > 1) {
41b2fd5f 118 tw = lvm_snprintf(params, sizeof(params), "%u %u ",
6c4ee296
JT
119 stripes, seg->stripe_size);
120
121 if (tw < 0) {
122 log_err(no_space);
123 return 0;
124 }
125
126 w = tw;
127 }
128
b546cd6d 129
6c4ee296 130 for (s = 0; s < stripes; s++, w += tw) {
41b2fd5f 131 tw = lvm_snprintf(params + w, sizeof(params) - w,
0bab6591
JT
132 "%s %" PRIu64 "%s",
133 dev_name(seg->area[s].pv->dev),
134 (seg->area[s].pv->pe_start +
135 (esize * seg->area[s].pe)),
136 s == (stripes - 1) ? "" : " ");
137
138 if (tw < 0) {
6c4ee296 139 log_err(no_space);
0bab6591
JT
140 return 0;
141 }
80f9662b
JT
142 }
143
a299e388
AK
144 log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
145 esize * seg->le, esize * seg->len,
146 stripes == 1 ? "linear" : "striped",
147 params);
148
39497a44 149 if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
0bab6591
JT
150 stripes == 1 ? "linear" : "striped",
151 params)) {
80f9662b
JT
152 stack;
153 return 0;
154 }
155
80f9662b
JT
156 return 1;
157}
158
37ed70b9 159int _load(struct logical_volume *lv, int task)
b1713d28 160{
ae2bb665 161 int r = 0;
ae2bb665 162 struct dm_task *dmt;
0bab6591
JT
163 struct list *segh;
164 struct stripe_segment *seg;
e15559aa 165
a299e388 166 log_very_verbose("Generating devmapper parameters for %s", lv->name);
37ed70b9 167 if (!(dmt = _setup_task(lv, task))) {
ae2bb665
JT
168 stack;
169 return 0;
170 }
b1713d28 171
0bab6591
JT
172 list_iterate(segh, &lv->segments) {
173 seg = list_item(segh, struct stripe_segment);
174 if (!_emit_target(dmt, seg)) {
cf4a4a1f 175 log_error("Unable to activate logical volume '%s'",
80f9662b 176 lv->name);
ae2bb665
JT
177 goto out;
178 }
ae2bb665
JT
179 }
180
2bc25b54
AK
181 if (!(lv->status & LVM_WRITE) && !dm_task_set_ro(dmt))
182 log_error("Failed to set %s read-only during activation.",
183 lv->name);
184
185
f047219b 186 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
187 stack;
188
b546cd6d
AK
189 log_verbose("Logical volume %s%s activated", lv->name,
190 r == 1 ? "" : " not");
3080a754 191
ae2bb665 192 out:
f047219b 193 dm_task_destroy(dmt);
ae2bb665 194 return r;
b1713d28 195}
a381c45a 196
37ed70b9 197/* FIXME: Always display error msg */
37ed70b9 198int lv_activate(struct logical_volume *lv)
0a5e4a14 199{
c2d72fd4
AK
200 if (test_mode())
201 return 0;
202
a299e388 203 log_very_verbose("Activating %s", lv->name);
f7a14956 204 return _load(lv, DM_DEVICE_CREATE) && fs_add_lv(lv);
37ed70b9
JT
205}
206
207int _suspend(struct logical_volume *lv, int sus)
208{
209 int r;
210 struct dm_task *dmt;
211 int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
212
a299e388 213 log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", lv->name);
37ed70b9
JT
214 if (!(dmt = _setup_task(lv, task))) {
215 stack;
216 return 0;
217 }
218
219 if (!(r = dm_task_run(dmt)))
220 log_err("Couldn't %s device '%s'", sus ? "suspend" : "resume",
221 lv->name);
222
223 dm_task_destroy(dmt);
224 return r;
225}
226
227int lv_reactivate(struct logical_volume *lv)
228{
229 int r;
c2d72fd4
AK
230
231 if (test_mode())
232 return 0;
233
2bc25b54 234 if (!lv_suspended(lv) && !_suspend(lv, 1)) {
37ed70b9
JT
235 stack;
236 return 0;
237 }
0a5e4a14 238
37ed70b9 239 r = _load(lv, DM_DEVICE_RELOAD);
ae2bb665 240
37ed70b9
JT
241 if (!_suspend(lv, 0)) {
242 stack;
243 return 0;
244 }
0a5e4a14 245
37ed70b9 246 return r;
0a5e4a14
AK
247}
248
ae2bb665
JT
249int lv_deactivate(struct logical_volume *lv)
250{
f047219b 251 int r;
ab269099
JT
252 struct dm_task *dmt;
253
a299e388 254 log_very_verbose("Deactivating %s", lv->name);
c2d72fd4
AK
255 if (test_mode())
256 return 0;
257
37ed70b9 258 if (!(dmt = _setup_task(lv, DM_DEVICE_REMOVE))) {
ae2bb665
JT
259 stack;
260 return 0;
261 }
262
f047219b 263 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
264 stack;
265
ae2bb665 266 dm_task_destroy(dmt);
f7a14956
JT
267
268 fs_del_lv(lv);
269
ae2bb665
JT
270 return r;
271}
272
37ed70b9
JT
273int activate_lvs_in_vg(struct volume_group *vg)
274{
275 struct list *lvh;
276 struct logical_volume *lv;
94b8220f 277 int count = 0;
37ed70b9
JT
278
279 list_iterate(lvh, &vg->lvs) {
280 lv = &(list_item(lvh, struct lv_list)->lv);
281
94b8220f 282 count += (!lv_active(lv) && lv_activate(lv));
37ed70b9
JT
283 }
284
285 return count;
286}
287
ae2bb665
JT
288int lv_update_write_access(struct logical_volume *lv)
289{
2bc25b54
AK
290 struct dm_info info;
291
292 if (!lv_info(lv, &info)) {
293 stack;
294 return 0;
295 }
296
297 if (!info.exists || info.suspended)
298 /* Noop */
299 return 1;
300
301 return lv_reactivate(lv);
ae2bb665
JT
302}
303
a381c45a
AK
304int deactivate_lvs_in_vg(struct volume_group *vg)
305{
0a5e4a14 306 struct list *lvh;
37ed70b9 307 struct logical_volume *lv;
94b8220f 308 int count = 0;
37ed70b9
JT
309
310 list_iterate(lvh, &vg->lvs) {
311 lv = &(list_item(lvh, struct lv_list)->lv);
0a5e4a14 312
94b8220f 313 count += ((lv_active(lv) == 1) && lv_deactivate(lv));
37ed70b9 314 }
0a5e4a14 315
37ed70b9 316 return count;
a381c45a 317}
f047219b
AK
318
319int lvs_in_vg_activated(struct volume_group *vg)
320{
37ed70b9
JT
321 struct list *lvh;
322 struct logical_volume *lv;
94b8220f 323 int count = 0;
37ed70b9
JT
324
325 list_iterate(lvh, &vg->lvs) {
326 lv = &(list_item(lvh, struct lv_list)->lv);
327
94b8220f 328 count += (lv_active(lv) == 1);
37ed70b9
JT
329 }
330
331 return count;
f047219b 332}
2ba80b43
JT
333
334int lvs_in_vg_opened(struct volume_group *vg)
335{
336 struct list *lvh;
337 struct logical_volume *lv;
94b8220f 338 int count = 0;
2ba80b43
JT
339
340 list_iterate(lvh, &vg->lvs) {
341 lv = &(list_item(lvh, struct lv_list)->lv);
342
94b8220f 343 count += (lv_open_count(lv) == 1);
2ba80b43
JT
344 }
345
346 return count;
347}
This page took 0.068825 seconds and 5 git commands to generate.