Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 : : * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
4 : : *
5 : : * This file is part of LVM2.
6 : : *
7 : : * This copyrighted material is made available to anyone wishing to use,
8 : : * modify, copy, or redistribute it subject to the terms and conditions
9 : : * of the GNU Lesser General Public License v.2.1.
10 : : *
11 : : * You should have received a copy of the GNU Lesser General Public License
12 : : * along with this program; if not, write to the Free Software Foundation,
13 : : * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 : : */
15 : :
16 : : #include "lib.h"
17 : : #include "metadata.h"
18 : : #include "activate.h"
19 : : #include "memlock.h"
20 : : #include "display.h"
21 : : #include "fs.h"
22 : : #include "lvm-exec.h"
23 : : #include "lvm-file.h"
24 : : #include "lvm-string.h"
25 : : #include "toolcontext.h"
26 : : #include "dev_manager.h"
27 : : #include "str_list.h"
28 : : #include "config.h"
29 : : #include "filter.h"
30 : : #include "segtype.h"
31 : :
32 : : #include <limits.h>
33 : : #include <fcntl.h>
34 : : #include <unistd.h>
35 : :
36 : : #define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
37 : :
38 : 0 : int lvm1_present(struct cmd_context *cmd)
39 : : {
40 : : char path[PATH_MAX];
41 : :
42 [ # # ]: 0 : if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
43 : : < 0) {
44 : 0 : log_error("LVM1 proc global snprintf failed");
45 : 0 : return 0;
46 : : }
47 : :
48 [ # # ]: 0 : if (path_exists(path))
49 : 0 : return 1;
50 : : else
51 : 0 : return 0;
52 : : }
53 : :
54 : 0 : int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
55 : : struct dm_list *modules)
56 : : {
57 : : unsigned int s;
58 : : struct lv_segment *seg2, *snap_seg;
59 : : struct dm_list *snh;
60 : :
61 [ # # # # ]: 0 : if (seg->segtype->ops->modules_needed &&
62 : 0 : !seg->segtype->ops->modules_needed(mem, seg, modules)) {
63 : 0 : log_error("module string allocation failed");
64 : 0 : return 0;
65 : : }
66 : :
67 [ # # ]: 0 : if (lv_is_origin(seg->lv))
68 [ # # ]: 0 : dm_list_iterate(snh, &seg->lv->snapshot_segs)
69 [ # # ]: 0 : if (!list_lv_modules(mem,
70 : 0 : dm_list_struct_base(snh,
71 : : struct lv_segment,
72 : : origin_list)->cow,
73 : : modules))
74 : 0 : return_0;
75 : :
76 [ # # ]: 0 : if (lv_is_cow(seg->lv)) {
77 : 0 : snap_seg = find_cow(seg->lv);
78 [ # # # # ]: 0 : if (snap_seg->segtype->ops->modules_needed &&
79 : 0 : !snap_seg->segtype->ops->modules_needed(mem, snap_seg,
80 : : modules)) {
81 : 0 : log_error("snap_seg module string allocation failed");
82 : 0 : return 0;
83 : : }
84 : : }
85 : :
86 [ # # ]: 0 : for (s = 0; s < seg->area_count; s++) {
87 [ # # ]: 0 : switch (seg_type(seg, s)) {
88 : : case AREA_LV:
89 : 0 : seg2 = find_seg_by_le(seg_lv(seg, s), seg_le(seg, s));
90 [ # # # # ]: 0 : if (seg2 && !list_segment_modules(mem, seg2, modules))
91 : 0 : return_0;
92 : : break;
93 : : case AREA_PV:
94 : : case AREA_UNASSIGNED:
95 : : ;
96 : : }
97 : : }
98 : :
99 : 0 : return 1;
100 : : }
101 : :
102 : 0 : int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
103 : : struct dm_list *modules)
104 : : {
105 : : struct lv_segment *seg;
106 : :
107 [ # # ]: 0 : dm_list_iterate_items(seg, &lv->segments)
108 [ # # ]: 0 : if (!list_segment_modules(mem, seg, modules))
109 : 0 : return_0;
110 : :
111 : 0 : return 1;
112 : : }
113 : :
114 : : #ifndef DEVMAPPER_SUPPORT
115 : : void set_activation(int act)
116 : : {
117 : : static int warned = 0;
118 : :
119 : : if (warned || !act)
120 : : return;
121 : :
122 : : log_error("Compiled without libdevmapper support. "
123 : : "Can't enable activation.");
124 : :
125 : : warned = 1;
126 : : }
127 : : int activation(void)
128 : : {
129 : : return 0;
130 : : }
131 : : int library_version(char *version, size_t size)
132 : : {
133 : : return 0;
134 : : }
135 : : int driver_version(char *version, size_t size)
136 : : {
137 : : return 0;
138 : : }
139 : : int target_version(const char *target_name, uint32_t *maj,
140 : : uint32_t *min, uint32_t *patchlevel)
141 : : {
142 : : return 0;
143 : : }
144 : : int target_present(struct cmd_context *cmd, const char *target_name,
145 : : int use_modprobe)
146 : : {
147 : : return 0;
148 : : }
149 : : int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
150 : : int with_open_count, int with_read_ahead)
151 : : {
152 : : return 0;
153 : : }
154 : : int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
155 : : struct lvinfo *info, int with_open_count, int with_read_ahead)
156 : : {
157 : : return 0;
158 : : }
159 : : int lv_snapshot_percent(const struct logical_volume *lv, float *percent,
160 : : percent_range_t *percent_range)
161 : : {
162 : : return 0;
163 : : }
164 : : int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
165 : : int wait, float *percent, percent_range_t *percent_range,
166 : : uint32_t *event_nr)
167 : : {
168 : : return 0;
169 : : }
170 : : int lvs_in_vg_activated(struct volume_group *vg)
171 : : {
172 : : return 0;
173 : : }
174 : : int lvs_in_vg_opened(struct volume_group *vg)
175 : : {
176 : : return 0;
177 : : }
178 : : int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
179 : : {
180 : : return 1;
181 : : }
182 : : int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
183 : : {
184 : : return 1;
185 : : }
186 : : int lv_resume(struct cmd_context *cmd, const char *lvid_s)
187 : : {
188 : : return 1;
189 : : }
190 : : int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
191 : : {
192 : : return 1;
193 : : }
194 : : int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
195 : : {
196 : : return 1;
197 : : }
198 : : int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
199 : : int *activate_lv)
200 : : {
201 : : return 1;
202 : : }
203 : : int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
204 : : {
205 : : return 1;
206 : : }
207 : : int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
208 : : {
209 : : return 1;
210 : : }
211 : :
212 : : int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
213 : : {
214 : : return 1;
215 : : }
216 : :
217 : : int pv_uses_vg(struct physical_volume *pv,
218 : : struct volume_group *vg)
219 : : {
220 : : return 0;
221 : : }
222 : :
223 : : void activation_release(void)
224 : : {
225 : : return;
226 : : }
227 : :
228 : : void activation_exit(void)
229 : : {
230 : : return;
231 : : }
232 : :
233 : : #else /* DEVMAPPER_SUPPORT */
234 : :
235 : : static int _activation = 1;
236 : :
237 : 5 : void set_activation(int act)
238 : : {
239 [ + - ]: 5 : if (act == _activation)
240 : 5 : return;
241 : :
242 : 0 : _activation = act;
243 [ # # ]: 0 : if (_activation)
244 : 0 : log_verbose("Activation enabled. Device-mapper kernel "
245 : : "driver will be used.");
246 : : else
247 : 5 : log_warn("WARNING: Activation disabled. No device-mapper "
248 : : "interaction will be attempted.");
249 : : }
250 : :
251 : 0 : int activation(void)
252 : : {
253 : 0 : return _activation;
254 : : }
255 : :
256 : 0 : static int _passes_activation_filter(struct cmd_context *cmd,
257 : : struct logical_volume *lv)
258 : : {
259 : : const struct config_node *cn;
260 : : struct config_value *cv;
261 : : char *str;
262 : : char path[PATH_MAX];
263 : :
264 [ # # ]: 0 : if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
265 : : /* If no host tags defined, activate */
266 [ # # ]: 0 : if (dm_list_empty(&cmd->tags))
267 : 0 : return 1;
268 : :
269 : : /* If any host tag matches any LV or VG tag, activate */
270 [ # # # # ]: 0 : if (str_list_match_list(&cmd->tags, &lv->tags) ||
271 : 0 : str_list_match_list(&cmd->tags, &lv->vg->tags))
272 : 0 : return 1;
273 : :
274 : : /* Don't activate */
275 : 0 : return 0;
276 : : }
277 : :
278 [ # # ]: 0 : for (cv = cn->v; cv; cv = cv->next) {
279 [ # # ]: 0 : if (cv->type != CFG_STRING) {
280 : 0 : log_error("Ignoring invalid string in config file "
281 : : "activation/volume_list");
282 : 0 : continue;
283 : : }
284 : 0 : str = cv->v.str;
285 [ # # ]: 0 : if (!*str) {
286 : 0 : log_error("Ignoring empty string in config file "
287 : : "activation/volume_list");
288 : 0 : continue;
289 : : }
290 : :
291 : : /* Tag? */
292 [ # # ]: 0 : if (*str == '@') {
293 : 0 : str++;
294 [ # # ]: 0 : if (!*str) {
295 : 0 : log_error("Ignoring empty tag in config file "
296 : : "activation/volume_list");
297 : 0 : continue;
298 : : }
299 : : /* If any host tag matches any LV or VG tag, activate */
300 [ # # ]: 0 : if (!strcmp(str, "*")) {
301 [ # # # # ]: 0 : if (str_list_match_list(&cmd->tags, &lv->tags)
302 : 0 : || str_list_match_list(&cmd->tags,
303 : 0 : &lv->vg->tags))
304 : 0 : return 1;
305 : : else
306 : 0 : continue;
307 : : }
308 : : /* If supplied tag matches LV or VG tag, activate */
309 [ # # # # ]: 0 : if (str_list_match_item(&lv->tags, str) ||
310 : 0 : str_list_match_item(&lv->vg->tags, str))
311 : 0 : return 1;
312 : : else
313 : 0 : continue;
314 : : }
315 [ # # ]: 0 : if (!strchr(str, '/')) {
316 : : /* vgname supplied */
317 [ # # ]: 0 : if (!strcmp(str, lv->vg->name))
318 : 0 : return 1;
319 : : else
320 : 0 : continue;
321 : : }
322 : : /* vgname/lvname */
323 [ # # ]: 0 : if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
324 : : lv->name) < 0) {
325 : 0 : log_error("dm_snprintf error from %s/%s", lv->vg->name,
326 : : lv->name);
327 : 0 : continue;
328 : : }
329 [ # # ]: 0 : if (!strcmp(path, str))
330 : 0 : return 1;
331 : : }
332 : :
333 : 0 : return 0;
334 : : }
335 : :
336 : 0 : int library_version(char *version, size_t size)
337 : : {
338 [ # # ]: 0 : if (!activation())
339 : 0 : return 0;
340 : :
341 : 0 : return dm_get_library_version(version, size);
342 : : }
343 : :
344 : 0 : int driver_version(char *version, size_t size)
345 : : {
346 [ # # ]: 0 : if (!activation())
347 : 0 : return 0;
348 : :
349 : 0 : log_very_verbose("Getting driver version");
350 : :
351 : 0 : return dm_driver_version(version, size);
352 : : }
353 : :
354 : 0 : int target_version(const char *target_name, uint32_t *maj,
355 : : uint32_t *min, uint32_t *patchlevel)
356 : : {
357 : 0 : int r = 0;
358 : : struct dm_task *dmt;
359 : : struct dm_versions *target, *last_target;
360 : :
361 : 0 : log_very_verbose("Getting target version for %s", target_name);
362 [ # # ]: 0 : if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
363 : 0 : return_0;
364 : :
365 [ # # ]: 0 : if (!dm_task_run(dmt)) {
366 : 0 : log_debug("Failed to get %s target version", target_name);
367 : : /* Assume this was because LIST_VERSIONS isn't supported */
368 : 0 : return 1;
369 : : }
370 : :
371 : 0 : target = dm_task_get_versions(dmt);
372 : :
373 : : do {
374 : 0 : last_target = target;
375 : :
376 [ # # ]: 0 : if (!strcmp(target_name, target->name)) {
377 : 0 : r = 1;
378 : 0 : *maj = target->version[0];
379 : 0 : *min = target->version[1];
380 : 0 : *patchlevel = target->version[2];
381 : 0 : goto out;
382 : : }
383 : :
384 : 0 : target = (void *) target + target->next;
385 [ # # ]: 0 : } while (last_target != target);
386 : :
387 : : out:
388 : 0 : dm_task_destroy(dmt);
389 : :
390 : 0 : return r;
391 : : }
392 : :
393 : 0 : int module_present(struct cmd_context *cmd, const char *target_name)
394 : : {
395 : 0 : int ret = 0;
396 : : #ifdef MODPROBE_CMD
397 : : char module[128];
398 : : const char *argv[3];
399 : :
400 [ # # ]: 0 : if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
401 : 0 : log_error("module_present module name too long: %s",
402 : : target_name);
403 : 0 : return 0;
404 : : }
405 : :
406 : 0 : argv[0] = MODPROBE_CMD;
407 : 0 : argv[1] = module;
408 : 0 : argv[2] = NULL;
409 : :
410 : 0 : ret = exec_cmd(cmd, argv);
411 : : #endif
412 : 0 : return ret;
413 : : }
414 : :
415 : 0 : int target_present(struct cmd_context *cmd, const char *target_name,
416 : : int use_modprobe)
417 : : {
418 : : uint32_t maj, min, patchlevel;
419 : :
420 [ # # ]: 0 : if (!activation())
421 : 0 : return 0;
422 : :
423 : : #ifdef MODPROBE_CMD
424 [ # # ]: 0 : if (use_modprobe) {
425 [ # # ]: 0 : if (target_version(target_name, &maj, &min, &patchlevel))
426 : 0 : return 1;
427 : :
428 [ # # ]: 0 : if (!module_present(cmd, target_name))
429 : 0 : return_0;
430 : : }
431 : : #endif
432 : :
433 : 0 : return target_version(target_name, &maj, &min, &patchlevel);
434 : : }
435 : :
436 : : /*
437 : : * Returns 1 if info structure populated, else 0 on failure.
438 : : */
439 : 0 : int lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
440 : : struct lvinfo *info, int with_open_count, int with_read_ahead)
441 : : {
442 : : struct dm_info dminfo;
443 : :
444 [ # # ]: 0 : if (!activation())
445 : 0 : return 0;
446 : :
447 [ # # ]: 0 : if (!dev_manager_info(lv->vg->cmd->mem, lv, with_open_count,
448 : : with_read_ahead, &dminfo, &info->read_ahead))
449 : 0 : return_0;
450 : :
451 : 0 : info->exists = dminfo.exists;
452 : 0 : info->suspended = dminfo.suspended;
453 : 0 : info->open_count = dminfo.open_count;
454 : 0 : info->major = dminfo.major;
455 : 0 : info->minor = dminfo.minor;
456 : 0 : info->read_only = dminfo.read_only;
457 : 0 : info->live_table = dminfo.live_table;
458 : 0 : info->inactive_table = dminfo.inactive_table;
459 : :
460 : 0 : return 1;
461 : : }
462 : :
463 : 0 : int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
464 : : struct lvinfo *info, int with_open_count, int with_read_ahead)
465 : : {
466 : : int r;
467 : : struct logical_volume *lv;
468 : :
469 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
470 : 0 : return 0;
471 : :
472 : 0 : r = lv_info(cmd, lv, info, with_open_count, with_read_ahead);
473 : 0 : vg_release(lv->vg);
474 : :
475 : 0 : return r;
476 : : }
477 : :
478 : : /*
479 : : * Returns 1 if percent set, else 0 on failure.
480 : : */
481 : 0 : int lv_snapshot_percent(const struct logical_volume *lv, float *percent,
482 : : percent_range_t *percent_range)
483 : : {
484 : : int r;
485 : : struct dev_manager *dm;
486 : :
487 [ # # ]: 0 : if (!activation())
488 : 0 : return 0;
489 : :
490 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
491 : 0 : return_0;
492 : :
493 [ # # ]: 0 : if (!(r = dev_manager_snapshot_percent(dm, lv, percent, percent_range)))
494 : 0 : stack;
495 : :
496 : 0 : dev_manager_destroy(dm);
497 : :
498 : 0 : return r;
499 : : }
500 : :
501 : : /* FIXME Merge with snapshot_percent */
502 : 0 : int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
503 : : int wait, float *percent, percent_range_t *percent_range,
504 : : uint32_t *event_nr)
505 : : {
506 : : int r;
507 : : struct dev_manager *dm;
508 : : struct lvinfo info;
509 : :
510 : : /* If mirrored LV is temporarily shrinked to 1 area (= linear),
511 : : * it should be considered in-sync. */
512 [ # # ][ # # ]: 0 : if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
513 : 0 : *percent = 100.0;
514 : 0 : return 1;
515 : : }
516 : :
517 [ # # ]: 0 : if (!activation())
518 : 0 : return 0;
519 : :
520 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 0, 0))
521 : 0 : return_0;
522 : :
523 [ # # ]: 0 : if (!info.exists)
524 : 0 : return 0;
525 : :
526 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
527 : 0 : return_0;
528 : :
529 [ # # ]: 0 : if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent,
530 : : percent_range, event_nr)))
531 : 0 : stack;
532 : :
533 : 0 : dev_manager_destroy(dm);
534 : :
535 : 0 : return r;
536 : : }
537 : :
538 : 0 : static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv)
539 : : {
540 : : struct lvinfo info;
541 : :
542 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 0, 0)) {
543 : 0 : stack;
544 : 0 : return -1;
545 : : }
546 : :
547 : 0 : return info.exists;
548 : : }
549 : :
550 : 0 : static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
551 : : {
552 : : struct lvinfo info;
553 : :
554 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 1, 0)) {
555 : 0 : stack;
556 : 0 : return -1;
557 : : }
558 : :
559 : 0 : return info.open_count;
560 : : }
561 : :
562 : 0 : static int _lv_activate_lv(struct logical_volume *lv)
563 : : {
564 : : int r;
565 : : struct dev_manager *dm;
566 : :
567 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
568 : 0 : return_0;
569 : :
570 [ # # ]: 0 : if (!(r = dev_manager_activate(dm, lv)))
571 : 0 : stack;
572 : :
573 : 0 : dev_manager_destroy(dm);
574 : 0 : return r;
575 : : }
576 : :
577 : 0 : static int _lv_preload(struct logical_volume *lv, int *flush_required)
578 : : {
579 : : int r;
580 : : struct dev_manager *dm;
581 : :
582 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
583 : 0 : return_0;
584 : :
585 [ # # ]: 0 : if (!(r = dev_manager_preload(dm, lv, flush_required)))
586 : 0 : stack;
587 : :
588 : 0 : dev_manager_destroy(dm);
589 : 0 : return r;
590 : : }
591 : :
592 : 0 : static int _lv_deactivate(struct logical_volume *lv)
593 : : {
594 : : int r;
595 : : struct dev_manager *dm;
596 : :
597 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
598 : 0 : return_0;
599 : :
600 [ # # ]: 0 : if (!(r = dev_manager_deactivate(dm, lv)))
601 : 0 : stack;
602 : :
603 : 0 : dev_manager_destroy(dm);
604 : 0 : return r;
605 : : }
606 : :
607 : 0 : static int _lv_suspend_lv(struct logical_volume *lv, int lockfs, int flush_required)
608 : : {
609 : : int r;
610 : : struct dev_manager *dm;
611 : :
612 [ # # ]: 0 : if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
613 : 0 : return_0;
614 : :
615 [ # # ]: 0 : if (!(r = dev_manager_suspend(dm, lv, lockfs, flush_required)))
616 : 0 : stack;
617 : :
618 : 0 : dev_manager_destroy(dm);
619 : 0 : return r;
620 : : }
621 : :
622 : : /*
623 : : * These two functions return the number of visible LVs in the state,
624 : : * or -1 on error.
625 : : */
626 : 0 : int lvs_in_vg_activated(struct volume_group *vg)
627 : : {
628 : : struct lv_list *lvl;
629 : 0 : int count = 0;
630 : :
631 [ # # ]: 0 : if (!activation())
632 : 0 : return 0;
633 : :
634 [ # # ]: 0 : dm_list_iterate_items(lvl, &vg->lvs) {
635 [ # # ]: 0 : if (lv_is_visible(lvl->lv))
636 : 0 : count += (_lv_active(vg->cmd, lvl->lv) == 1);
637 : : }
638 : :
639 : 0 : return count;
640 : : }
641 : :
642 : 0 : int lvs_in_vg_opened(const struct volume_group *vg)
643 : : {
644 : : const struct lv_list *lvl;
645 : 0 : int count = 0;
646 : :
647 [ # # ]: 0 : if (!activation())
648 : 0 : return 0;
649 : :
650 [ # # ]: 0 : dm_list_iterate_items(lvl, &vg->lvs) {
651 [ # # ]: 0 : if (lv_is_visible(lvl->lv))
652 : 0 : count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
653 : : }
654 : :
655 : 0 : return count;
656 : : }
657 : :
658 : : /*
659 : : * Determine whether an LV is active locally or in a cluster.
660 : : * Assumes vg lock held.
661 : : * Returns:
662 : : * 0 - not active locally or on any node in cluster
663 : : * 1 - active either locally or some node in the cluster
664 : : */
665 : 0 : int lv_is_active(struct logical_volume *lv)
666 : : {
667 : : int ret;
668 : :
669 [ # # ]: 0 : if (_lv_active(lv->vg->cmd, lv))
670 : 0 : return 1;
671 : :
672 [ # # ]: 0 : if (!vg_is_clustered(lv->vg))
673 : 0 : return 0;
674 : :
675 [ # # ]: 0 : if ((ret = remote_lock_held(lv->lvid.s)) >= 0)
676 : 0 : return ret;
677 : :
678 : : /*
679 : : * Old compatibility code if locking doesn't support lock query
680 : : * FIXME: check status to not deactivate already activate device
681 : : */
682 [ # # ][ # # ]: 0 : if (activate_lv_excl(lv->vg->cmd, lv)) {
[ # # ]
683 [ # # ][ # # ]: 0 : if (!deactivate_lv(lv->vg->cmd, lv))
[ # # ]
684 : 0 : stack;
685 : 0 : return 0;
686 : : }
687 : :
688 : : /*
689 : : * Exclusive local activation failed so assume it is active elsewhere.
690 : : */
691 : 0 : return 1;
692 : : }
693 : :
694 : : /*
695 : : * Returns 0 if an attempt to (un)monitor the device failed.
696 : : * Returns 1 otherwise.
697 : : */
698 : 0 : int monitor_dev_for_events(struct cmd_context *cmd,
699 : : struct logical_volume *lv, int monitor)
700 : : {
701 : : #ifdef DMEVENTD
702 : : int i, pending = 0, monitored;
703 : : int r = 1;
704 : : struct dm_list *tmp, *snh, *snht;
705 : : struct lv_segment *seg;
706 : : struct lv_segment *log_seg;
707 : : int (*monitor_fn) (struct lv_segment *s, int e);
708 : : uint32_t s;
709 : :
710 : : /* skip dmeventd code altogether */
711 : : if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
712 : : return 1;
713 : :
714 : : /*
715 : : * Nothing to do if dmeventd configured not to be used.
716 : : */
717 : : if (monitor && !dmeventd_monitor_mode())
718 : : return 1;
719 : :
720 : : /*
721 : : * In case of a snapshot device, we monitor lv->snapshot->lv,
722 : : * not the actual LV itself.
723 : : */
724 : : if (lv_is_cow(lv) && !lv_is_merging_cow(lv))
725 : : return monitor_dev_for_events(cmd, lv->snapshot->lv, monitor);
726 : :
727 : : /*
728 : : * In case this LV is a snapshot origin, we instead monitor
729 : : * each of its respective snapshots (the origin itself does
730 : : * not need to be monitored).
731 : : *
732 : : * TODO: This may change when snapshots of mirrors are allowed.
733 : : */
734 : : if (lv_is_origin(lv)) {
735 : : dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
736 : : if (!monitor_dev_for_events(cmd, dm_list_struct_base(snh,
737 : : struct lv_segment, origin_list)->cow, monitor))
738 : : r = 0;
739 : : return r;
740 : : }
741 : :
742 : : /*
743 : : * If the volume is mirrored and its log is also mirrored, monitor
744 : : * the log volume as well.
745 : : */
746 : : if ((seg = first_seg(lv)) != NULL && seg->log_lv != NULL &&
747 : : (log_seg = first_seg(seg->log_lv)) != NULL &&
748 : : seg_is_mirrored(log_seg))
749 : : if (!monitor_dev_for_events(cmd, seg->log_lv, monitor))
750 : : r = 0;
751 : :
752 : : dm_list_iterate(tmp, &lv->segments) {
753 : : seg = dm_list_item(tmp, struct lv_segment);
754 : :
755 : : /* Recurse for AREA_LV */
756 : : for (s = 0; s < seg->area_count; s++) {
757 : : if (seg_type(seg, s) != AREA_LV)
758 : : continue;
759 : : if (!monitor_dev_for_events(cmd, seg_lv(seg, s),
760 : : monitor)) {
761 : : log_error("Failed to %smonitor %s",
762 : : monitor ? "" : "un",
763 : : seg_lv(seg, s)->name);
764 : : r = 0;
765 : : }
766 : : }
767 : :
768 : : if (!seg_monitored(seg) || (seg->status & PVMOVE))
769 : : continue;
770 : :
771 : : monitor_fn = NULL;
772 : :
773 : : /* Check monitoring status */
774 : : if (seg->segtype->ops->target_monitored)
775 : : monitored = seg->segtype->ops->target_monitored(seg, &pending);
776 : : else
777 : : continue; /* segtype doesn't support registration */
778 : :
779 : : /*
780 : : * FIXME: We should really try again if pending
781 : : */
782 : : monitored = (pending) ? 0 : monitored;
783 : :
784 : : if (monitor) {
785 : : if (monitored)
786 : : log_verbose("%s/%s already monitored.", lv->vg->name, lv->name);
787 : : else if (seg->segtype->ops->target_monitor_events)
788 : : monitor_fn = seg->segtype->ops->target_monitor_events;
789 : : } else {
790 : : if (!monitored)
791 : : log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name);
792 : : else if (seg->segtype->ops->target_unmonitor_events)
793 : : monitor_fn = seg->segtype->ops->target_unmonitor_events;
794 : : }
795 : :
796 : : /* Do [un]monitor */
797 : : if (!monitor_fn)
798 : : continue;
799 : :
800 : : log_verbose("%sonitoring %s/%s", monitor ? "M" : "Not m", lv->vg->name, lv->name);
801 : :
802 : : /* FIXME specify events */
803 : : if (!monitor_fn(seg, 0)) {
804 : : log_error("%s/%s: %s segment monitoring function failed.",
805 : : lv->vg->name, lv->name, seg->segtype->name);
806 : : return 0;
807 : : }
808 : :
809 : : /* Check [un]monitor results */
810 : : /* Try a couple times if pending, but not forever... */
811 : : for (i = 0; i < 10; i++) {
812 : : pending = 0;
813 : : monitored = seg->segtype->ops->target_monitored(seg, &pending);
814 : : if (pending ||
815 : : (!monitored && monitor) ||
816 : : (monitored && !monitor))
817 : : log_very_verbose("%s/%s %smonitoring still pending: waiting...",
818 : : lv->vg->name, lv->name, monitor ? "" : "un");
819 : : else
820 : : break;
821 : : sleep(1);
822 : : }
823 : :
824 : : r = (monitored && monitor) || (!monitored && !monitor);
825 : : }
826 : :
827 : : return r;
828 : : #else
829 : 0 : return 1;
830 : : #endif
831 : : }
832 : :
833 : 0 : static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
834 : : int error_if_not_suspended)
835 : : {
836 : 0 : struct logical_volume *lv = NULL, *lv_pre = NULL;
837 : : struct lvinfo info;
838 : 0 : int r = 0, lockfs = 0, flush_required = 0;
839 : :
840 [ # # ]: 0 : if (!activation())
841 : 0 : return 1;
842 : :
843 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
844 : 0 : goto_out;
845 : :
846 : : /* Use precommitted metadata if present */
847 [ # # ]: 0 : if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
848 : 0 : goto_out;
849 : :
850 [ # # ]: 0 : if (test_mode()) {
851 : 0 : _skip("Suspending '%s'.", lv->name);
852 : 0 : r = 1;
853 : 0 : goto out;
854 : : }
855 : :
856 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 0, 0))
857 : 0 : goto_out;
858 : :
859 [ # # ][ # # ]: 0 : if (!info.exists || info.suspended) {
860 [ # # ]: 0 : if (!error_if_not_suspended) {
861 : 0 : r = 1;
862 [ # # ]: 0 : if (info.suspended)
863 : 0 : memlock_inc(cmd);
864 : : }
865 : 0 : goto out;
866 : : }
867 : :
868 [ # # ]: 0 : if (!lv_read_replicator_vgs(lv))
869 : 0 : goto_out;
870 : :
871 : 0 : lv_calculate_readahead(lv, NULL);
872 : :
873 : : /* If VG was precommitted, preload devices for the LV */
874 [ # # ]: 0 : if ((lv_pre->vg->status & PRECOMMITTED)) {
875 [ # # ]: 0 : if (!_lv_preload(lv_pre, &flush_required)) {
876 : : /* FIXME Revert preloading */
877 : 0 : goto_out;
878 : : }
879 : : }
880 : :
881 [ # # ]: 0 : if (!monitor_dev_for_events(cmd, lv, 0))
882 : : /* FIXME Consider aborting here */
883 : 0 : stack;
884 : :
885 : 0 : memlock_inc(cmd);
886 : :
887 [ # # # # ]: 0 : if (lv_is_origin(lv_pre) || lv_is_cow(lv_pre))
888 : 0 : lockfs = 1;
889 : :
890 [ # # ]: 0 : if (!_lv_suspend_lv(lv, lockfs, flush_required)) {
891 : 0 : memlock_dec(cmd);
892 : 0 : fs_unlock();
893 : 0 : goto out;
894 : : }
895 : :
896 : 0 : r = 1;
897 : : out:
898 [ # # ]: 0 : if (lv_pre)
899 : 0 : vg_release(lv_pre->vg);
900 [ # # ]: 0 : if (lv) {
901 : 0 : lv_release_replicator_vgs(lv);
902 : 0 : vg_release(lv->vg);
903 : : }
904 : 0 : return r;
905 : : }
906 : :
907 : : /* Returns success if the device is not active */
908 : 0 : int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
909 : : {
910 : 0 : return _lv_suspend(cmd, lvid_s, 0);
911 : : }
912 : :
913 : 0 : int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
914 : : {
915 : 0 : return _lv_suspend(cmd, lvid_s, 1);
916 : : }
917 : :
918 : 0 : static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
919 : : int error_if_not_active)
920 : : {
921 : : struct logical_volume *lv;
922 : : struct lvinfo info;
923 : 0 : int r = 0;
924 : :
925 [ # # ]: 0 : if (!activation())
926 : 0 : return 1;
927 : :
928 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
929 : 0 : goto_out;
930 : :
931 [ # # ]: 0 : if (test_mode()) {
932 : 0 : _skip("Resuming '%s'.", lv->name);
933 : 0 : r = 1;
934 : 0 : goto out;
935 : : }
936 : :
937 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 0, 0))
938 : 0 : goto_out;
939 : :
940 [ # # ][ # # ]: 0 : if (!info.exists || !info.suspended) {
941 : 0 : r = error_if_not_active ? 0 : 1;
942 : 0 : goto_out;
943 : : }
944 : :
945 [ # # ]: 0 : if (!_lv_activate_lv(lv))
946 : 0 : goto_out;
947 : :
948 : 0 : memlock_dec(cmd);
949 : 0 : fs_unlock();
950 : :
951 [ # # ]: 0 : if (!monitor_dev_for_events(cmd, lv, 1))
952 : 0 : stack;
953 : :
954 : 0 : r = 1;
955 : : out:
956 [ # # ]: 0 : if (lv)
957 : 0 : vg_release(lv->vg);
958 : :
959 : 0 : return r;
960 : : }
961 : :
962 : : /* Returns success if the device is not active */
963 : 0 : int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
964 : : {
965 : 0 : return _lv_resume(cmd, lvid_s, 0);
966 : : }
967 : :
968 : 0 : int lv_resume(struct cmd_context *cmd, const char *lvid_s)
969 : : {
970 : 0 : return _lv_resume(cmd, lvid_s, 1);
971 : : }
972 : :
973 : 0 : static int _lv_has_open_snapshots(struct logical_volume *lv)
974 : : {
975 : : struct lv_segment *snap_seg;
976 : : struct lvinfo info;
977 : 0 : int r = 0;
978 : :
979 [ # # ]: 0 : dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list) {
980 [ # # ]: 0 : if (!lv_info(lv->vg->cmd, snap_seg->cow, &info, 1, 0)) {
981 : 0 : r = 1;
982 : 0 : continue;
983 : : }
984 : :
985 [ # # ][ # # ]: 0 : if (info.exists && info.open_count) {
986 : 0 : log_error("LV %s/%s has open snapshot %s: "
987 : : "not deactivating", lv->vg->name, lv->name,
988 : : snap_seg->cow->name);
989 : 0 : r = 1;
990 : : }
991 : : }
992 : :
993 : 0 : return r;
994 : : }
995 : :
996 : 0 : int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
997 : : {
998 : : struct logical_volume *lv;
999 : : struct lvinfo info;
1000 : 0 : int r = 0;
1001 : :
1002 [ # # ]: 0 : if (!activation())
1003 : 0 : return 1;
1004 : :
1005 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
1006 : 0 : goto out;
1007 : :
1008 [ # # ]: 0 : if (test_mode()) {
1009 : 0 : _skip("Deactivating '%s'.", lv->name);
1010 : 0 : r = 1;
1011 : 0 : goto out;
1012 : : }
1013 : :
1014 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 1, 0))
1015 : 0 : goto_out;
1016 : :
1017 [ # # ]: 0 : if (!info.exists) {
1018 : 0 : r = 1;
1019 : 0 : goto out;
1020 : : }
1021 : :
1022 [ # # ]: 0 : if (lv_is_visible(lv)) {
1023 [ # # ]: 0 : if (info.open_count) {
1024 : 0 : log_error("LV %s/%s in use: not deactivating",
1025 : : lv->vg->name, lv->name);
1026 : 0 : goto out;
1027 : : }
1028 [ # # ][ # # ]: 0 : if (lv_is_origin(lv) && _lv_has_open_snapshots(lv))
1029 : 0 : goto_out;
1030 : : }
1031 : :
1032 [ # # ]: 0 : if (!lv_read_replicator_vgs(lv))
1033 : 0 : goto_out;
1034 : :
1035 : 0 : lv_calculate_readahead(lv, NULL);
1036 : :
1037 [ # # ]: 0 : if (!monitor_dev_for_events(cmd, lv, 0))
1038 : 0 : stack;
1039 : :
1040 : 0 : memlock_inc(cmd);
1041 : 0 : r = _lv_deactivate(lv);
1042 : 0 : memlock_dec(cmd);
1043 : 0 : fs_unlock();
1044 : :
1045 [ # # # # ]: 0 : if (!lv_info(cmd, lv, &info, 1, 0) || info.exists)
1046 : 0 : r = 0;
1047 : : out:
1048 [ # # ]: 0 : if (lv) {
1049 : 0 : lv_release_replicator_vgs(lv);
1050 : 0 : vg_release(lv->vg);
1051 : : }
1052 : :
1053 : 0 : return r;
1054 : : }
1055 : :
1056 : : /* Test if LV passes filter */
1057 : 0 : int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
1058 : : int *activate_lv)
1059 : : {
1060 : : struct logical_volume *lv;
1061 : 0 : int r = 0;
1062 : :
1063 [ # # ]: 0 : if (!activation()) {
1064 : 0 : *activate_lv = 1;
1065 : 0 : return 1;
1066 : : }
1067 : :
1068 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
1069 : 0 : goto out;
1070 : :
1071 [ # # ]: 0 : if (!_passes_activation_filter(cmd, lv)) {
1072 : 0 : log_verbose("Not activating %s/%s due to config file settings",
1073 : : lv->vg->name, lv->name);
1074 : 0 : *activate_lv = 0;
1075 : : } else
1076 : 0 : *activate_lv = 1;
1077 : 0 : r = 1;
1078 : : out:
1079 [ # # ]: 0 : if (lv)
1080 : 0 : vg_release(lv->vg);
1081 : :
1082 : 0 : return r;
1083 : : }
1084 : :
1085 : 0 : static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
1086 : : int exclusive, int filter)
1087 : : {
1088 : : struct logical_volume *lv;
1089 : : struct lvinfo info;
1090 : 0 : int r = 0;
1091 : :
1092 [ # # ]: 0 : if (!activation())
1093 : 0 : return 1;
1094 : :
1095 [ # # ]: 0 : if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
1096 : 0 : goto out;
1097 : :
1098 [ # # ][ # # ]: 0 : if (filter && !_passes_activation_filter(cmd, lv)) {
1099 : 0 : log_verbose("Not activating %s/%s due to config file settings",
1100 : : lv->vg->name, lv->name);
1101 : 0 : goto out;
1102 : : }
1103 : :
1104 [ # # ][ # # ]: 0 : if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
1105 : 0 : log_error("Refusing activation of partial LV %s. Use --partial to override.",
1106 : : lv->name);
1107 : 0 : goto_out;
1108 : : }
1109 : :
1110 [ # # ]: 0 : if (lv_has_unknown_segments(lv)) {
1111 : 0 : log_error("Refusing activation of LV %s containing "
1112 : : "an unrecognised segment.", lv->name);
1113 : 0 : goto_out;
1114 : : }
1115 : :
1116 [ # # ]: 0 : if (test_mode()) {
1117 : 0 : _skip("Activating '%s'.", lv->name);
1118 : 0 : r = 1;
1119 : 0 : goto out;
1120 : : }
1121 : :
1122 [ # # ]: 0 : if (!lv_info(cmd, lv, &info, 0, 0))
1123 : 0 : goto_out;
1124 : :
1125 [ # # ][ # # ]: 0 : if (info.exists && !info.suspended && info.live_table) {
[ # # ]
1126 : 0 : r = 1;
1127 : 0 : goto out;
1128 : : }
1129 : :
1130 [ # # ]: 0 : if (!lv_read_replicator_vgs(lv))
1131 : 0 : goto_out;
1132 : :
1133 : 0 : lv_calculate_readahead(lv, NULL);
1134 : :
1135 [ # # ]: 0 : if (exclusive)
1136 : 0 : lv->status |= ACTIVATE_EXCL;
1137 : :
1138 : 0 : memlock_inc(cmd);
1139 [ # # ]: 0 : if (!(r = _lv_activate_lv(lv)))
1140 : 0 : stack;
1141 : 0 : memlock_dec(cmd);
1142 : 0 : fs_unlock();
1143 : :
1144 [ # # # # ]: 0 : if (r && !monitor_dev_for_events(cmd, lv, 1))
1145 : 0 : stack;
1146 : :
1147 : : out:
1148 [ # # ]: 0 : if (lv) {
1149 : 0 : lv_release_replicator_vgs(lv);
1150 : 0 : vg_release(lv->vg);
1151 : : }
1152 : :
1153 : 0 : return r;
1154 : : }
1155 : :
1156 : : /* Activate LV */
1157 : 0 : int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
1158 : : {
1159 [ # # ]: 0 : if (!_lv_activate(cmd, lvid_s, exclusive, 0))
1160 : 0 : return_0;
1161 : :
1162 : 0 : return 1;
1163 : : }
1164 : :
1165 : : /* Activate LV only if it passes filter */
1166 : 0 : int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
1167 : : {
1168 [ # # ]: 0 : if (!_lv_activate(cmd, lvid_s, exclusive, 1))
1169 : 0 : return_0;
1170 : :
1171 : 0 : return 1;
1172 : : }
1173 : :
1174 : 0 : int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
1175 : : {
1176 : 0 : int r = 1;
1177 : :
1178 [ # # ]: 0 : if (!lv) {
1179 : 0 : r = dm_mknodes(NULL);
1180 : 0 : fs_unlock();
1181 : 0 : return r;
1182 : : }
1183 : :
1184 [ # # ]: 0 : if (!activation())
1185 : 0 : return 1;
1186 : :
1187 : 0 : r = dev_manager_mknodes(lv);
1188 : :
1189 : 0 : fs_unlock();
1190 : :
1191 : 0 : return r;
1192 : : }
1193 : :
1194 : : /*
1195 : : * Does PV use VG somewhere in its construction?
1196 : : * Returns 1 on failure.
1197 : : */
1198 : 0 : int pv_uses_vg(struct physical_volume *pv,
1199 : : struct volume_group *vg)
1200 : : {
1201 [ # # ]: 0 : if (!activation())
1202 : 0 : return 0;
1203 : :
1204 [ # # ]: 0 : if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
1205 : 0 : return 0;
1206 : :
1207 : 0 : return dev_manager_device_uses_vg(pv->dev, vg);
1208 : : }
1209 : :
1210 : 2 : void activation_release(void)
1211 : : {
1212 : 2 : dev_manager_release();
1213 : 2 : }
1214 : :
1215 : 1 : void activation_exit(void)
1216 : : {
1217 : 1 : dev_manager_exit();
1218 : 1 : }
1219 : : #endif
|