]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
Accept tables from stdin with dmsetup.
[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
d1d9800e 7#include "lib.h"
a381c45a 8#include "metadata.h"
b1713d28 9#include "activate.h"
914c9723 10#include "memlock.h"
78125be9 11#include "display.h"
f7a14956 12#include "fs.h"
41b2fd5f 13#include "lvm-string.h"
413cc918
AK
14#include "pool.h"
15#include "toolcontext.h"
de6c9183 16#include "dev_manager.h"
12137231
JT
17
18#include <limits.h>
5986ec94 19#include <fcntl.h>
914c9723 20#include <unistd.h>
12137231 21
6d52fb46 22#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 23
199e490e
AK
24#ifndef DEVMAPPER_SUPPORT
25void set_activation(int act)
26{
27 if (act)
28 log_error("Compiled without libdevmapper support. "
29 "Can't enable activation.");
30}
31int activation(void)
32{
33 return 0;
34}
35int library_version(char *version, size_t size)
36{
37 return 0;
38}
39int driver_version(char *version, size_t size)
40{
41 return 0;
42}
43int lv_info(const struct logical_volume *lv, struct lvinfo *info)
44{
45 return 0;
46}
47int lv_snapshot_percent(struct logical_volume *lv, float *percent)
48{
49 return 0;
50}
914c9723
AK
51int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
52 uint32_t *event_nr)
10b29b8d
AK
53{
54 return 0;
55}
199e490e
AK
56int lvs_in_vg_activated(struct volume_group *vg)
57{
58 return 0;
59}
60int lvs_in_vg_opened(struct volume_group *vg)
61{
62 return 0;
63}
64int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
65{
66 return 1;
67}
68int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
69{
70 return 1;
71}
72int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
73{
74 return 1;
75}
76int lv_activate(struct cmd_context *cmd, const char *lvid_s)
77{
78 return 1;
79}
914c9723
AK
80void activation_exit(void)
81{
82 return;
83}
199e490e
AK
84
85#else /* DEVMAPPER_SUPPORT */
86
d1d9800e
AK
87static int _activation = 1;
88
8ef2b021 89void set_activation(int act)
d1d9800e 90{
8ef2b021 91 if (act == _activation)
d1d9800e
AK
92 return;
93
8ef2b021 94 _activation = act;
d1d9800e
AK
95 if (_activation)
96 log_verbose("Activation enabled. Device-mapper kernel "
97 "driver will be used.");
98 else
99 log_verbose("Activation disabled. No device-mapper "
100 "interaction will be attempted.");
101}
102
8ef2b021 103int activation(void)
d1d9800e
AK
104{
105 return _activation;
106}
107
fae0c576
AK
108int library_version(char *version, size_t size)
109{
d1d9800e
AK
110 if (!activation())
111 return 0;
112
fae0c576
AK
113 if (!dm_get_library_version(version, size))
114 return 0;
115 return 1;
116}
117
fae0c576
AK
118int driver_version(char *version, size_t size)
119{
120 int r = 0;
121 struct dm_task *dmt;
122
d1d9800e
AK
123 if (!activation())
124 return 0;
125
fae0c576
AK
126 log_very_verbose("Getting driver version");
127 if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
128 stack;
129 return 0;
130 }
131
132 if (!dm_task_run(dmt))
133 log_error("Failed to get driver version");
134
135 if (!dm_task_get_driver_version(dmt, version, size))
136 goto out;
137
138 r = 1;
139
2ed2a724 140 out:
fae0c576
AK
141 dm_task_destroy(dmt);
142
143 return r;
144}
145
de6c9183
JT
146/*
147 * Returns 1 if info structure populated, else 0 on failure.
148 */
199e490e 149int lv_info(const struct logical_volume *lv, struct lvinfo *info)
37ed70b9 150{
de6c9183
JT
151 int r;
152 struct dev_manager *dm;
199e490e 153 struct dm_info dminfo;
4a624ca0 154
d1d9800e
AK
155 if (!activation())
156 return 0;
157
a9953411 158 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
12137231 159 stack;
de6c9183 160 return 0;
12137231 161 }
4a624ca0 162
199e490e 163 if (!(r = dev_manager_info(dm, lv, &dminfo)))
de6c9183 164 stack;
4a624ca0 165
199e490e
AK
166 info->exists = dminfo.exists;
167 info->suspended = dminfo.suspended;
168 info->open_count = dminfo.open_count;
169 info->major = dminfo.major;
170 info->minor = dminfo.minor;
171 info->read_only = dminfo.read_only;
172
de6c9183
JT
173 dev_manager_destroy(dm);
174 return r;
175}
a62ee8ad 176
1951dba9
AL
177/*
178 * Returns 1 if percent set, else 0 on failure.
179 */
c826c0d1 180int lv_snapshot_percent(struct logical_volume *lv, float *percent)
1951dba9
AL
181{
182 int r;
183 struct dev_manager *dm;
184
d1d9800e
AK
185 if (!activation())
186 return 0;
187
a9953411 188 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
1951dba9
AL
189 stack;
190 return 0;
191 }
192
c826c0d1 193 if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
1951dba9 194 stack;
c826c0d1 195
1951dba9
AL
196 dev_manager_destroy(dm);
197
198 return r;
199}
200
10b29b8d
AK
201/* FIXME Merge with snapshot_percent */
202int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
203 uint32_t *event_nr)
204{
205 int r;
206 struct dev_manager *dm;
207
208 if (!activation())
209 return 0;
210
211 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
212 stack;
213 return 0;
214 }
215
216 if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
217 stack;
218
219 dev_manager_destroy(dm);
220
221 return r;
222}
223
41967a02 224static int _lv_active(struct logical_volume *lv)
2ba80b43 225{
199e490e 226 struct lvinfo info;
2ba80b43 227
de6c9183 228 if (!lv_info(lv, &info)) {
2ba80b43 229 stack;
de6c9183 230 return -1;
2ba80b43
JT
231 }
232
de6c9183 233 return info.exists;
2ba80b43
JT
234}
235
41967a02 236static int _lv_open_count(struct logical_volume *lv)
5986ec94 237{
199e490e 238 struct lvinfo info;
5986ec94 239
de6c9183 240 if (!lv_info(lv, &info)) {
5986ec94 241 stack;
de6c9183 242 return -1;
5986ec94
JT
243 }
244
de6c9183 245 return info.open_count;
5986ec94
JT
246}
247
8c013da4 248/* FIXME Need to detect and handle an lv rename */
be326a2f 249static int _lv_activate(struct logical_volume *lv)
b1713d28 250{
6d52fb46 251 int r;
de6c9183 252 struct dev_manager *dm;
b1713d28 253
a9953411 254 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
6d52fb46
JT
255 stack;
256 return 0;
ae2bb665
JT
257 }
258
0fe3a2c5 259 if (!(r = dev_manager_activate(dm, lv)))
6d52fb46 260 stack;
ae2bb665 261
de6c9183 262 dev_manager_destroy(dm);
ae2bb665 263 return r;
b1713d28 264}
a381c45a 265
be326a2f 266static int _lv_deactivate(struct logical_volume *lv)
0a5e4a14 267{
de6c9183
JT
268 int r;
269 struct dev_manager *dm;
37ed70b9 270
a9953411 271 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
6d52fb46
JT
272 stack;
273 return 0;
274 }
37ed70b9 275
de6c9183 276 if (!(r = dev_manager_deactivate(dm, lv)))
37ed70b9 277 stack;
37ed70b9 278
de6c9183
JT
279 dev_manager_destroy(dm);
280 return r;
37ed70b9
JT
281}
282
be326a2f 283static int _lv_suspend(struct logical_volume *lv)
4a624ca0 284{
20c5fcf7
AK
285 int r;
286 struct dev_manager *dm;
c2d72fd4 287
a9953411 288 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
37ed70b9
JT
289 stack;
290 return 0;
291 }
0a5e4a14 292
20c5fcf7 293 if (!(r = dev_manager_suspend(dm, lv)))
37ed70b9 294 stack;
0a5e4a14 295
20c5fcf7
AK
296 dev_manager_destroy(dm);
297 return r;
6d52fb46 298}
4a624ca0 299
8c013da4
AK
300/*
301 * These two functions return the number of LVs in the state,
302 * or -1 on error.
303 */
f047219b
AK
304int lvs_in_vg_activated(struct volume_group *vg)
305{
37ed70b9
JT
306 struct list *lvh;
307 struct logical_volume *lv;
94b8220f 308 int count = 0;
37ed70b9 309
d1d9800e
AK
310 if (!activation())
311 return 0;
312
37ed70b9 313 list_iterate(lvh, &vg->lvs) {
f868d635 314 lv = list_item(lvh, struct lv_list)->lv;
41967a02 315 count += (_lv_active(lv) == 1);
37ed70b9
JT
316 }
317
318 return count;
f047219b 319}
2ba80b43
JT
320
321int lvs_in_vg_opened(struct volume_group *vg)
322{
323 struct list *lvh;
324 struct logical_volume *lv;
94b8220f 325 int count = 0;
2ba80b43 326
d1d9800e
AK
327 if (!activation())
328 return 0;
329
2ba80b43 330 list_iterate(lvh, &vg->lvs) {
f868d635 331 lv = list_item(lvh, struct lv_list)->lv;
41967a02 332 count += (_lv_open_count(lv) == 1);
2ba80b43
JT
333 }
334
335 return count;
336}
413cc918 337
20c5fcf7 338/* These return success if the device is not active */
15c325f0 339int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
413cc918
AK
340{
341 struct logical_volume *lv;
199e490e 342 struct lvinfo info;
413cc918 343
d1d9800e
AK
344 if (!activation())
345 return 1;
346
347 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
348 return 0;
349
20c5fcf7
AK
350 if (test_mode()) {
351 _skip("Suspending '%s'.", lv->name);
711f7fc6 352 return 1;
20c5fcf7
AK
353 }
354
2ed2a724
AK
355 if (!lv_info(lv, &info)) {
356 stack;
357 return 0;
358 }
41967a02 359
914c9723
AK
360 if (!info.exists || info.suspended)
361 return 1;
362
363 memlock_inc();
364 if (!_lv_suspend(lv)) {
365 memlock_dec();
366 fs_unlock();
367 return 0;
368 }
8c013da4 369
413cc918
AK
370 return 1;
371}
372
15c325f0 373int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
413cc918
AK
374{
375 struct logical_volume *lv;
199e490e 376 struct lvinfo info;
413cc918 377
d1d9800e
AK
378 if (!activation())
379 return 1;
380
381 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
382 return 0;
383
20c5fcf7
AK
384 if (test_mode()) {
385 _skip("Resuming '%s'.", lv->name);
711f7fc6 386 return 1;
20c5fcf7
AK
387 }
388
2ed2a724
AK
389 if (!lv_info(lv, &info)) {
390 stack;
391 return 0;
392 }
41967a02 393
914c9723
AK
394 if (!info.exists || !info.suspended)
395 return 1;
396
397 if (!_lv_activate(lv))
398 return 0;
399
400 memlock_dec();
401 fs_unlock();
413cc918
AK
402
403 return 1;
404}
405
be326a2f 406int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
407{
408 struct logical_volume *lv;
199e490e 409 struct lvinfo info;
914c9723 410 int r;
f4cbeaf0 411
d1d9800e
AK
412 if (!activation())
413 return 1;
414
415 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
416 return 0;
417
20c5fcf7
AK
418 if (test_mode()) {
419 _skip("Deactivating '%s'.", lv->name);
711f7fc6 420 return 1;
20c5fcf7
AK
421 }
422
2ed2a724
AK
423 if (!lv_info(lv, &info)) {
424 stack;
425 return 0;
426 }
41967a02 427
914c9723
AK
428 if (!info.exists)
429 return 1;
f4cbeaf0 430
0cf96f33
AK
431 if (info.open_count) {
432 log_error("LV %s/%s in use: not removing", lv->vg->name,
433 lv->name);
434 return 0;
435 }
436
914c9723
AK
437 memlock_inc();
438 r = _lv_deactivate(lv);
439 memlock_dec();
440 fs_unlock();
441
442 return r;
f4cbeaf0
AK
443}
444
be326a2f 445int lv_activate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
446{
447 struct logical_volume *lv;
199e490e 448 struct lvinfo info;
914c9723 449 int r;
f4cbeaf0 450
d1d9800e
AK
451 if (!activation())
452 return 1;
453
454 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
455 return 0;
456
20c5fcf7
AK
457 if (test_mode()) {
458 _skip("Activating '%s'.", lv->name);
711f7fc6 459 return 1;
20c5fcf7
AK
460 }
461
2ed2a724
AK
462 if (!lv_info(lv, &info)) {
463 stack;
464 return 0;
465 }
8c013da4 466
914c9723
AK
467 if (info.exists && !info.suspended)
468 return 1;
f4cbeaf0 469
914c9723
AK
470 memlock_inc();
471 r = _lv_activate(lv);
472 memlock_dec();
473 fs_unlock();
474
475 return r;
f4cbeaf0 476}
199e490e 477
914c9723
AK
478void activation_exit(void)
479{
480 dev_manager_exit();
481}
199e490e 482#endif
This page took 0.087784 seconds and 5 git commands to generate.