]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
Allow syslog facility to be set, or turned off, from the config file.
[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
fae0c576
AK
14int library_version(char *version, size_t size)
15{
16 if (!dm_get_library_version(version, size))
17 return 0;
18 return 1;
19}
20
4a624ca0
AK
21static void _build_lv_name(char *buffer, size_t s, const char *vg_name,
22 const char *lv_name)
ab269099 23{
4a624ca0 24 snprintf(buffer, s, "%s_%s", vg_name, lv_name);
ab269099
JT
25}
26
f2f26349 27static struct dm_task *_setup_task_with_name(struct logical_volume *lv,
4a624ca0 28 const char *lv_name, int task)
37ed70b9
JT
29{
30 char name[128];
31 struct dm_task *dmt;
32
33 if (!(dmt = dm_task_create(task))) {
34 stack;
35 return NULL;
36 }
37
4a624ca0 38 _build_lv_name(name, sizeof(name), lv->vg->name, lv_name);
37ed70b9
JT
39 dm_task_set_name(dmt, name);
40
41 return dmt;
42}
43
4a624ca0
AK
44static struct dm_task *_setup_task(struct logical_volume *lv, int task)
45{
46 return _setup_task_with_name(lv, lv->name, task);
47}
48
fae0c576
AK
49int driver_version(char *version, size_t size)
50{
51 int r = 0;
52 struct dm_task *dmt;
53
54 log_very_verbose("Getting driver version");
55 if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
56 stack;
57 return 0;
58 }
59
60 if (!dm_task_run(dmt))
61 log_error("Failed to get driver version");
62
63 if (!dm_task_get_driver_version(dmt, version, size))
64 goto out;
65
66 r = 1;
67
68 out:
69 dm_task_destroy(dmt);
70
71 return r;
72}
73
3080a754 74int lv_info(struct logical_volume *lv, struct dm_info *info)
37ed70b9 75{
ef8a0eae 76 int r = 0;
37ed70b9
JT
77 struct dm_task *dmt;
78
a299e388 79 log_very_verbose("Getting device info for %s", lv->name);
37ed70b9
JT
80 if (!(dmt = _setup_task(lv, DM_DEVICE_INFO))) {
81 stack;
82 return 0;
83 }
84
85 if (!dm_task_run(dmt)) {
2ba80b43 86 stack;
ef8a0eae 87 goto out;
2ba80b43
JT
88 }
89
ef8a0eae
JT
90 if (!dm_task_get_info(dmt, info)) {
91 stack;
92 goto out;
93 }
94 r = 1;
2ba80b43 95
ef8a0eae 96 out:
2ba80b43 97 dm_task_destroy(dmt);
ef8a0eae 98 return r;
2ba80b43
JT
99}
100
4a624ca0
AK
101int lv_rename(const char *old_name, struct logical_volume *lv)
102{
103 int r = 0;
104 char new_name[128];
105 struct dm_task *dmt;
106
107 if (test_mode())
108 return 0;
109
110 if (!(dmt = _setup_task_with_name(lv, old_name, DM_DEVICE_RENAME))) {
111 stack;
112 return 0;
113 }
114
115 _build_lv_name(new_name, sizeof(new_name), lv->vg->name, lv->name);
116
117 if (!dm_task_set_newname(dmt, new_name)) {
118 stack;
119 r = 0;
120 goto end;
121 }
122
123 if (!dm_task_run(dmt)) {
124 stack;
125 r = 0;
126 goto end;
127 }
128
129 fs_rename_lv(old_name, lv);
130
131 end:
132 dm_task_destroy(dmt);
4a624ca0
AK
133 return r;
134}
135
94b8220f 136int lv_active(struct logical_volume *lv)
2ba80b43 137{
94b8220f 138 int r = -1;
ef8a0eae 139 struct dm_info info;
2ba80b43 140
3080a754 141 if (!lv_info(lv, &info)) {
37ed70b9 142 stack;
94b8220f 143 return r;
37ed70b9
JT
144 }
145
a299e388 146 log_very_verbose("%s is%s active", lv->name, info.exists ? "":" not");
ef8a0eae 147 return info.exists;
37ed70b9
JT
148}
149
2bc25b54
AK
150int lv_suspended(struct logical_volume *lv)
151{
152 int r = -1;
153 struct dm_info info;
154
155 if (!lv_info(lv, &info)) {
156 stack;
157 return r;
158 }
159
f2f26349 160 log_very_verbose("%s is%s suspended", lv->name,
2bc25b54
AK
161 info.suspended ? "":" not");
162 return info.suspended;
163}
164
94b8220f 165int lv_open_count(struct logical_volume *lv)
2ba80b43 166{
94b8220f 167 int r = -1;
ef8a0eae 168 struct dm_info info;
2ba80b43 169
3080a754 170 if (!lv_info(lv, &info)) {
2ba80b43 171 stack;
94b8220f 172 return r;
2ba80b43
JT
173 }
174
a299e388 175 log_very_verbose("%s is open %d time(s)", lv->name, info.open_count);
ef8a0eae 176 return info.open_count;
2ba80b43
JT
177}
178
80f9662b 179/*
0bab6591 180 * Emit a target for a given segment.
80f9662b 181 */
0bab6591 182static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
80f9662b
JT
183{
184 char params[1024];
39497a44 185 uint64_t esize = seg->lv->vg->extent_size;
0bab6591 186 uint32_t s, stripes = seg->stripes;
b546cd6d 187 int w = 0, tw = 0;
6c4ee296
JT
188 const char *no_space =
189 "Insufficient space to write target parameters.";
0bab6591 190
6c4ee296 191 if (stripes > 1) {
41b2fd5f 192 tw = lvm_snprintf(params, sizeof(params), "%u %u ",
6c4ee296
JT
193 stripes, seg->stripe_size);
194
195 if (tw < 0) {
196 log_err(no_space);
197 return 0;
198 }
199
200 w = tw;
201 }
202
f2f26349 203
6c4ee296 204 for (s = 0; s < stripes; s++, w += tw) {
4a624ca0
AK
205/******
206 log_debug("stripes: %d", stripes);
207 log_debug("dev_name(seg->area[s].pv->dev): %s",
208 dev_name(seg->area[s].pv->dev));
209 log_debug("esize: %" PRIu64, esize);
210 log_debug("seg->area[s].pe: %" PRIu64, seg->area[s].pe);
211 log_debug("seg->area[s].pv->pe_start: %" PRIu64,
212 seg->area[s].pv->pe_start);
213*******/
214
41b2fd5f 215 tw = lvm_snprintf(params + w, sizeof(params) - w,
0bab6591
JT
216 "%s %" PRIu64 "%s",
217 dev_name(seg->area[s].pv->dev),
218 (seg->area[s].pv->pe_start +
219 (esize * seg->area[s].pe)),
220 s == (stripes - 1) ? "" : " ");
221
222 if (tw < 0) {
6c4ee296 223 log_err(no_space);
0bab6591
JT
224 return 0;
225 }
80f9662b
JT
226 }
227
a299e388
AK
228 log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
229 esize * seg->le, esize * seg->len,
230 stripes == 1 ? "linear" : "striped",
231 params);
232
39497a44 233 if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
0bab6591
JT
234 stripes == 1 ? "linear" : "striped",
235 params)) {
80f9662b
JT
236 stack;
237 return 0;
238 }
239
80f9662b
JT
240 return 1;
241}
242
37ed70b9 243int _load(struct logical_volume *lv, int task)
b1713d28 244{
ae2bb665 245 int r = 0;
ae2bb665 246 struct dm_task *dmt;
0bab6591
JT
247 struct list *segh;
248 struct stripe_segment *seg;
e15559aa 249
a299e388 250 log_very_verbose("Generating devmapper parameters for %s", lv->name);
37ed70b9 251 if (!(dmt = _setup_task(lv, task))) {
ae2bb665
JT
252 stack;
253 return 0;
254 }
b1713d28 255
0bab6591
JT
256 list_iterate(segh, &lv->segments) {
257 seg = list_item(segh, struct stripe_segment);
258 if (!_emit_target(dmt, seg)) {
cf4a4a1f 259 log_error("Unable to activate logical volume '%s'",
80f9662b 260 lv->name);
ae2bb665
JT
261 goto out;
262 }
ae2bb665
JT
263 }
264
2bc25b54
AK
265 if (!(lv->status & LVM_WRITE) && !dm_task_set_ro(dmt))
266 log_error("Failed to set %s read-only during activation.",
267 lv->name);
268
269
f047219b 270 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
271 stack;
272
b546cd6d
AK
273 log_verbose("Logical volume %s%s activated", lv->name,
274 r == 1 ? "" : " not");
3080a754 275
ae2bb665 276 out:
f047219b 277 dm_task_destroy(dmt);
ae2bb665 278 return r;
b1713d28 279}
a381c45a 280
37ed70b9 281/* FIXME: Always display error msg */
37ed70b9 282int lv_activate(struct logical_volume *lv)
0a5e4a14 283{
c2d72fd4
AK
284 if (test_mode())
285 return 0;
286
a299e388 287 log_very_verbose("Activating %s", lv->name);
f7a14956 288 return _load(lv, DM_DEVICE_CREATE) && fs_add_lv(lv);
37ed70b9
JT
289}
290
291int _suspend(struct logical_volume *lv, int sus)
292{
293 int r;
294 struct dm_task *dmt;
295 int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
296
a299e388 297 log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", lv->name);
37ed70b9
JT
298 if (!(dmt = _setup_task(lv, task))) {
299 stack;
300 return 0;
301 }
302
303 if (!(r = dm_task_run(dmt)))
304 log_err("Couldn't %s device '%s'", sus ? "suspend" : "resume",
305 lv->name);
306
307 dm_task_destroy(dmt);
308 return r;
309}
310
4a624ca0
AK
311int lv_suspend(struct logical_volume *lv)
312{
313 return _suspend(lv, 1);
314}
315
37ed70b9
JT
316int lv_reactivate(struct logical_volume *lv)
317{
318 int r;
c2d72fd4
AK
319
320 if (test_mode())
321 return 0;
322
2bc25b54 323 if (!lv_suspended(lv) && !_suspend(lv, 1)) {
37ed70b9
JT
324 stack;
325 return 0;
326 }
0a5e4a14 327
37ed70b9 328 r = _load(lv, DM_DEVICE_RELOAD);
ae2bb665 329
37ed70b9
JT
330 if (!_suspend(lv, 0)) {
331 stack;
332 return 0;
333 }
0a5e4a14 334
37ed70b9 335 return r;
0a5e4a14
AK
336}
337
4a624ca0 338
ae2bb665
JT
339int lv_deactivate(struct logical_volume *lv)
340{
f047219b 341 int r;
ab269099
JT
342 struct dm_task *dmt;
343
a299e388 344 log_very_verbose("Deactivating %s", lv->name);
c2d72fd4
AK
345 if (test_mode())
346 return 0;
347
37ed70b9 348 if (!(dmt = _setup_task(lv, DM_DEVICE_REMOVE))) {
ae2bb665
JT
349 stack;
350 return 0;
351 }
352
f047219b 353 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
354 stack;
355
ae2bb665 356 dm_task_destroy(dmt);
f7a14956
JT
357
358 fs_del_lv(lv);
359
ae2bb665
JT
360 return r;
361}
362
37ed70b9
JT
363int activate_lvs_in_vg(struct volume_group *vg)
364{
365 struct list *lvh;
366 struct logical_volume *lv;
94b8220f 367 int count = 0;
37ed70b9
JT
368
369 list_iterate(lvh, &vg->lvs) {
370 lv = &(list_item(lvh, struct lv_list)->lv);
371
94b8220f 372 count += (!lv_active(lv) && lv_activate(lv));
37ed70b9
JT
373 }
374
375 return count;
376}
377
ae2bb665
JT
378int lv_update_write_access(struct logical_volume *lv)
379{
2bc25b54
AK
380 struct dm_info info;
381
382 if (!lv_info(lv, &info)) {
383 stack;
384 return 0;
385 }
386
387 if (!info.exists || info.suspended)
388 /* Noop */
389 return 1;
390
391 return lv_reactivate(lv);
ae2bb665
JT
392}
393
a381c45a
AK
394int deactivate_lvs_in_vg(struct volume_group *vg)
395{
0a5e4a14 396 struct list *lvh;
37ed70b9 397 struct logical_volume *lv;
94b8220f 398 int count = 0;
37ed70b9
JT
399
400 list_iterate(lvh, &vg->lvs) {
401 lv = &(list_item(lvh, struct lv_list)->lv);
0a5e4a14 402
94b8220f 403 count += ((lv_active(lv) == 1) && lv_deactivate(lv));
37ed70b9 404 }
0a5e4a14 405
37ed70b9 406 return count;
a381c45a 407}
f047219b
AK
408
409int lvs_in_vg_activated(struct volume_group *vg)
410{
37ed70b9
JT
411 struct list *lvh;
412 struct logical_volume *lv;
94b8220f 413 int count = 0;
37ed70b9
JT
414
415 list_iterate(lvh, &vg->lvs) {
416 lv = &(list_item(lvh, struct lv_list)->lv);
417
94b8220f 418 count += (lv_active(lv) == 1);
37ed70b9
JT
419 }
420
421 return count;
f047219b 422}
2ba80b43
JT
423
424int lvs_in_vg_opened(struct volume_group *vg)
425{
426 struct list *lvh;
427 struct logical_volume *lv;
94b8220f 428 int count = 0;
2ba80b43
JT
429
430 list_iterate(lvh, &vg->lvs) {
431 lv = &(list_item(lvh, struct lv_list)->lv);
432
94b8220f 433 count += (lv_open_count(lv) == 1);
2ba80b43
JT
434 }
435
436 return count;
437}
This page took 0.079581 seconds and 5 git commands to generate.