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