4 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
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.
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
20 #include "dev_manager.h"
21 #include "lvm-string.h"
26 #include "toolcontext.h"
35 #define MAX_TARGET_PARAMSIZE 50000
36 #define UUID_PREFIX "LVM-"
50 struct cmd_context
*cmd
;
53 uint32_t pvmove_mirror_count
;
60 struct logical_volume
*lv
;
64 static char *_build_dlid(struct dm_pool
*mem
, const char *lvid
, const char *layer
)
72 len
= sizeof(UUID_PREFIX
) + sizeof(union lvid
) + strlen(layer
);
74 if (!(dlid
= dm_pool_alloc(mem
, len
))) {
75 log_error("_build_dlid: pool allocation failed for %" PRIsize_t
76 " %s %s.", len
, lvid
, layer
);
80 sprintf(dlid
, UUID_PREFIX
"%s%s%s", lvid
, (*layer
) ? "-" : "", layer
);
85 char *build_dlid(struct dev_manager
*dm
, const char *lvid
, const char *layer
)
87 return _build_dlid(dm
->mem
, lvid
, layer
);
90 static int _read_only_lv(struct logical_volume
*lv
)
92 return (!(lv
->vg
->status
& LVM_WRITE
) || !(lv
->status
& LVM_WRITE
));
96 * Low level device-layer operations.
98 static struct dm_task
*_setup_task(const char *name
, const char *uuid
,
99 uint32_t *event_nr
, int task
,
100 uint32_t major
, uint32_t minor
)
104 if (!(dmt
= dm_task_create(task
)))
108 dm_task_set_name(dmt
, name
);
111 dm_task_set_uuid(dmt
, uuid
);
114 dm_task_set_event_nr(dmt
, *event_nr
);
117 dm_task_set_major_minor(dmt
, major
, minor
, 1);
122 static int _info_run(const char *name
, const char *dlid
, struct dm_info
*info
,
123 uint32_t *read_ahead
, int mknodes
, int with_open_count
,
124 int with_read_ahead
, uint32_t major
, uint32_t minor
)
130 dmtask
= mknodes
? DM_DEVICE_MKNODES
: DM_DEVICE_INFO
;
132 if (!(dmt
= _setup_task(name
, dlid
, 0, dmtask
, major
, minor
)))
135 if (!with_open_count
)
136 if (!dm_task_no_open_count(dmt
))
137 log_error("Failed to disable open_count");
139 if (!dm_task_run(dmt
))
142 if (!dm_task_get_info(dmt
, info
))
145 if (with_read_ahead
&& info
->exists
) {
146 if (!dm_task_get_read_ahead(dmt
, read_ahead
))
148 } else if (read_ahead
)
149 *read_ahead
= DM_READ_AHEAD_NONE
;
154 dm_task_destroy(dmt
);
158 int device_is_usable(dev_t dev
)
163 uint64_t start
, length
;
164 char *target_type
= NULL
;
169 if (!(dmt
= dm_task_create(DM_DEVICE_STATUS
))) {
170 log_error("Failed to allocate dm_task struct to check dev status");
174 if (!dm_task_set_major_minor(dmt
, MAJOR(dev
), MINOR(dev
), 1))
177 if (!dm_task_run(dmt
)) {
178 log_error("Failed to get state of mapped device");
182 if (!dm_task_get_info(dmt
, &info
))
185 if (!info
.exists
|| info
.suspended
)
188 name
= dm_task_get_name(dmt
);
190 /* FIXME Also check for mirror block_on_error and mpath no paths */
191 /* For now, we exclude all mirrors */
194 next
= dm_get_next_target(dmt
, next
, &start
, &length
,
195 &target_type
, ¶ms
);
196 /* Skip if target type doesn't match */
197 if (target_type
&& !strcmp(target_type
, "mirror"))
201 /* FIXME Also check dependencies? */
206 dm_task_destroy(dmt
);
210 static int _info(const char *name
, const char *dlid
, int mknodes
,
211 int with_open_count
, int with_read_ahead
,
212 struct dm_info
*info
, uint32_t *read_ahead
)
214 if (!mknodes
&& dlid
&& *dlid
) {
215 if (_info_run(NULL
, dlid
, info
, read_ahead
, 0, with_open_count
,
216 with_read_ahead
, 0, 0) &&
219 else if (_info_run(NULL
, dlid
+ sizeof(UUID_PREFIX
) - 1, info
,
220 read_ahead
, 0, with_open_count
,
221 with_read_ahead
, 0, 0) &&
227 return _info_run(name
, NULL
, info
, read_ahead
, mknodes
,
228 with_open_count
, with_read_ahead
, 0, 0);
233 static int _info_by_dev(uint32_t major
, uint32_t minor
, struct dm_info
*info
)
235 return _info_run(NULL
, NULL
, info
, NULL
, 0, 0, 0, major
, minor
);
238 int dev_manager_info(struct dm_pool
*mem
, const char *name
,
239 const struct logical_volume
*lv
, int with_mknodes
,
240 int with_open_count
, int with_read_ahead
,
241 struct dm_info
*info
, uint32_t *read_ahead
)
245 if (!(dlid
= _build_dlid(mem
, lv
->lvid
.s
, NULL
))) {
246 log_error("dlid build failed for %s", lv
->name
);
250 return _info(name
, dlid
, with_mknodes
, with_open_count
, with_read_ahead
,
254 /* FIXME Interface must cope with multiple targets */
255 static int _status_run(const char *name
, const char *uuid
,
256 unsigned long long *s
, unsigned long long *l
,
257 char **t
, uint32_t t_size
, char **p
, uint32_t p_size
)
263 uint64_t start
, length
;
267 if (!(dmt
= _setup_task(name
, uuid
, 0, DM_DEVICE_STATUS
, 0, 0)))
270 if (!dm_task_no_open_count(dmt
))
271 log_error("Failed to disable open_count");
273 if (!dm_task_run(dmt
))
276 if (!dm_task_get_info(dmt
, &info
) || !info
.exists
)
280 next
= dm_get_next_target(dmt
, next
, &start
, &length
,
285 /* Make sure things are null terminated */
286 strncpy(*t
, type
, t_size
);
287 (*t
)[t_size
- 1] = '\0';
288 strncpy(*p
, params
, p_size
);
289 (*p
)[p_size
- 1] = '\0';
292 /* FIXME Cope with multiple targets! */
299 dm_task_destroy(dmt
);
303 static int _status(const char *name
, const char *uuid
,
304 unsigned long long *start
, unsigned long long *length
,
305 char **type
, uint32_t type_size
, char **params
,
306 uint32_t param_size
) __attribute__ ((unused
));
308 static int _status(const char *name
, const char *uuid
,
309 unsigned long long *start
, unsigned long long *length
,
310 char **type
, uint32_t type_size
, char **params
,
314 if (_status_run(NULL
, uuid
, start
, length
, type
,
315 type_size
, params
, param_size
) &&
318 else if (_status_run(NULL
, uuid
+ sizeof(UUID_PREFIX
) - 1, start
,
319 length
, type
, type_size
, params
,
325 if (name
&& _status_run(name
, NULL
, start
, length
, type
, type_size
,
332 static percent_range_t
_combine_percent_ranges(percent_range_t a
,
335 if (a
== PERCENT_INVALID
|| b
== PERCENT_INVALID
)
336 return PERCENT_INVALID
;
338 if (a
== PERCENT_100
&& b
== PERCENT_100
)
341 if (a
== PERCENT_0
&& b
== PERCENT_0
)
344 return PERCENT_0_TO_100
;
347 static int _percent_run(struct dev_manager
*dm
, const char *name
,
349 const char *target_type
, int wait
,
350 struct logical_volume
*lv
, float *percent
,
351 percent_range_t
*overall_percent_range
,
358 uint64_t start
, length
;
361 struct dm_list
*segh
= &lv
->segments
;
362 struct lv_segment
*seg
= NULL
;
363 struct segment_type
*segtype
;
364 percent_range_t percent_range
= 0, combined_percent_range
= 0;
367 uint64_t total_numerator
= 0, total_denominator
= 0;
370 *overall_percent_range
= PERCENT_INVALID
;
372 if (!(dmt
= _setup_task(name
, dlid
, event_nr
,
373 wait
? DM_DEVICE_WAITEVENT
: DM_DEVICE_STATUS
, 0, 0)))
376 if (!dm_task_no_open_count(dmt
))
377 log_error("Failed to disable open_count");
379 if (!dm_task_run(dmt
))
382 if (!dm_task_get_info(dmt
, &info
) || !info
.exists
)
386 *event_nr
= info
.event_nr
;
389 next
= dm_get_next_target(dmt
, next
, &start
, &length
, &type
,
392 if (!(segh
= dm_list_next(&lv
->segments
, segh
))) {
393 log_error("Number of segments in active LV %s "
394 "does not match metadata", lv
->name
);
397 seg
= dm_list_item(segh
, struct lv_segment
);
400 if (!type
|| !params
|| strcmp(type
, target_type
))
403 if (!(segtype
= get_segtype_from_string(dm
->cmd
, type
)))
406 if (segtype
->ops
->target_percent
&&
407 !segtype
->ops
->target_percent(&dm
->target_state
,
408 &percent_range
, dm
->mem
,
409 dm
->cmd
, seg
, params
,
415 combined_percent_range
= percent_range
;
418 combined_percent_range
=
419 _combine_percent_ranges(combined_percent_range
,
423 if (lv
&& (segh
= dm_list_next(&lv
->segments
, segh
))) {
424 log_error("Number of segments in active LV %s does not "
425 "match metadata", lv
->name
);
429 if (total_denominator
) {
430 *percent
= (float) total_numerator
*100 / total_denominator
;
431 *overall_percent_range
= combined_percent_range
;
435 *overall_percent_range
= PERCENT_100
;
437 *overall_percent_range
= combined_percent_range
;
440 log_debug("LV percent: %f", *percent
);
444 dm_task_destroy(dmt
);
448 static int _percent(struct dev_manager
*dm
, const char *name
, const char *dlid
,
449 const char *target_type
, int wait
,
450 struct logical_volume
*lv
, float *percent
,
451 percent_range_t
*overall_percent_range
, uint32_t *event_nr
)
454 if (_percent_run(dm
, NULL
, dlid
, target_type
, wait
, lv
, percent
,
455 overall_percent_range
, event_nr
))
457 else if (_percent_run(dm
, NULL
, dlid
+ sizeof(UUID_PREFIX
) - 1,
458 target_type
, wait
, lv
, percent
,
459 overall_percent_range
, event_nr
))
463 if (name
&& _percent_run(dm
, name
, NULL
, target_type
, wait
, lv
, percent
,
464 overall_percent_range
, event_nr
))
471 * dev_manager implementation.
473 struct dev_manager
*dev_manager_create(struct cmd_context
*cmd
,
477 struct dev_manager
*dm
;
479 if (!(mem
= dm_pool_create("dev_manager", 16 * 1024)))
482 if (!(dm
= dm_pool_zalloc(mem
, sizeof(*dm
))))
488 if (!(dm
->vg_name
= dm_pool_strdup(dm
->mem
, vg_name
)))
491 dm
->target_state
= NULL
;
493 dm_udev_set_sync_support(cmd
->current_settings
.udev_sync
);
498 dm_pool_destroy(mem
);
502 void dev_manager_destroy(struct dev_manager
*dm
)
504 dm_pool_destroy(dm
->mem
);
507 void dev_manager_release(void)
512 void dev_manager_exit(void)
517 int dev_manager_snapshot_percent(struct dev_manager
*dm
,
518 const struct logical_volume
*lv
,
519 float *percent
, percent_range_t
*percent_range
)
525 * Build a name for the top layer.
527 if (!(name
= build_dm_name(dm
->mem
, lv
->vg
->name
, lv
->name
, NULL
)))
530 if (!(dlid
= build_dlid(dm
, lv
->lvid
.s
, NULL
)))
534 * Try and get some info on this device.
536 log_debug("Getting device status percentage for %s", name
);
537 if (!(_percent(dm
, name
, dlid
, "snapshot", 0, NULL
, percent
,
538 percent_range
, NULL
)))
541 /* FIXME dm_pool_free ? */
543 /* If the snapshot isn't available, percent will be -1 */
547 /* FIXME Merge with snapshot_percent, auto-detecting target type */
548 /* FIXME Cope with more than one target */
549 int dev_manager_mirror_percent(struct dev_manager
*dm
,
550 struct logical_volume
*lv
, int wait
,
551 float *percent
, percent_range_t
*percent_range
,
556 const char *suffix
= (lv_is_origin(lv
)) ? "real" : NULL
;
559 * Build a name for the top layer.
561 if (!(name
= build_dm_name(dm
->mem
, lv
->vg
->name
, lv
->name
, suffix
)))
564 /* FIXME dm_pool_free ? */
566 if (!(dlid
= build_dlid(dm
, lv
->lvid
.s
, suffix
))) {
567 log_error("dlid build failed for %s", lv
->name
);
571 log_debug("Getting device mirror status percentage for %s", name
);
572 if (!(_percent(dm
, name
, dlid
, "mirror", wait
, lv
, percent
,
573 percent_range
, event_nr
)))
580 log_very_verbose("%s %s", sus
? "Suspending" : "Resuming", name
);
582 log_verbose("Loading %s", dl
->name
);
583 log_very_verbose("Activating %s read-only", dl
->name
);
584 log_very_verbose("Activated %s %s %03u:%03u", dl
->name
,
585 dl
->dlid
, dl
->info
.major
, dl
->info
.minor
);
587 if (_get_flag(dl
, VISIBLE
))
588 log_verbose("Removing %s", dl
->name
);
590 log_very_verbose("Removing %s", dl
->name
);
592 log_debug("Adding target: %" PRIu64
" %" PRIu64
" %s %s",
593 extent_size
* seg
->le
, extent_size
* seg
->len
, target
, params
);
595 log_debug("Adding target: 0 %" PRIu64
" snapshot-origin %s",
596 dl
->lv
->size
, params
);
597 log_debug("Adding target: 0 %" PRIu64
" snapshot %s", size
, params
);
598 log_debug("Getting device info for %s", dl
->name
);
601 if ((suffix
= strrchr(dl
->dlid
+ sizeof(UUID_PREFIX
) - 1, '-')))
603 new_name
= build_dm_name(dm
->mem
, dm
->vg_name
, dl
->lv
->name
,
606 static int _belong_to_vg(const char *vgname
, const char *name
)
608 const char *v
= vgname
, *n
= name
;
611 if ((*v
!= *n
) || (*v
== '-' && *(++n
) != '-'))
616 if (*n
== '-' && *(n
+ 1) != '-')
622 if (!(snap_seg
= find_cow(lv
)))
625 old_origin
= snap_seg
->origin
;
627 /* Was this the last active snapshot with this origin? */
628 dm_list_iterate_items(lvl
, active_head
) {
630 if ((snap_seg
= find_cow(active
)) &&
631 snap_seg
->origin
== old_origin
) {
638 /*************************/
639 /* NEW CODE STARTS HERE */
640 /*************************/
642 int dev_manager_lv_mknodes(const struct logical_volume
*lv
)
646 if (!(name
= build_dm_name(lv
->vg
->cmd
->mem
, lv
->vg
->name
,
650 return fs_add_lv(lv
, name
);
653 int dev_manager_lv_rmnodes(const struct logical_volume
*lv
)
655 return fs_del_lv(lv
);
658 static int _add_dev_to_dtree(struct dev_manager
*dm
, struct dm_tree
*dtree
,
659 struct logical_volume
*lv
, const char *layer
)
662 struct dm_info info
, info2
;
664 if (!(name
= build_dm_name(dm
->mem
, lv
->vg
->name
, lv
->name
, layer
)))
667 if (!(dlid
= build_dlid(dm
, lv
->lvid
.s
, layer
)))
670 log_debug("Getting device info for %s [%s]", name
, dlid
);
671 if (!_info(name
, dlid
, 0, 1, 0, &info
, NULL
)) {
672 log_error("Failed to get info for %s [%s].", name
, dlid
);
677 * For top level volumes verify that existing device match
678 * requested major/minor and that major/minor pair is available for use
680 if (!layer
&& lv
->major
!= -1 && lv
->minor
!= -1) {
682 * FIXME compare info.major with lv->major if multiple major support
684 if (info
.exists
&& (info
.minor
!= lv
->minor
)) {
685 log_error("Volume %s (%" PRIu32
":%" PRIu32
")"
686 " differs from already active device "
687 "(%" PRIu32
":%" PRIu32
")",
688 lv
->name
, lv
->major
, lv
->minor
, info
.major
, info
.minor
);
691 if (!info
.exists
&& _info_by_dev(lv
->major
, lv
->minor
, &info2
) &&
693 log_error("The requested major:minor pair "
694 "(%" PRIu32
":%" PRIu32
") is already used",
695 lv
->major
, lv
->minor
);
700 if (info
.exists
&& !dm_tree_add_dev(dtree
, info
.major
, info
.minor
)) {
701 log_error("Failed to add device (%" PRIu32
":%" PRIu32
") to dtree",
702 info
.major
, info
.minor
);
710 * Add LV and any known dependencies
712 static int _add_lv_to_dtree(struct dev_manager
*dm
, struct dm_tree
*dtree
, struct logical_volume
*lv
)
714 if (!_add_dev_to_dtree(dm
, dtree
, lv
, NULL
))
717 /* FIXME Can we avoid doing this every time? */
718 if (!_add_dev_to_dtree(dm
, dtree
, lv
, "real"))
721 if (!_add_dev_to_dtree(dm
, dtree
, lv
, "cow"))
724 if (!_add_dev_to_dtree(dm
, dtree
, lv
, "_mlog"))
730 static struct dm_tree
*_create_partial_dtree(struct dev_manager
*dm
, struct logical_volume
*lv
)
732 struct dm_tree
*dtree
;
733 struct dm_list
*snh
, *snht
;
734 struct lv_segment
*seg
;
737 if (!(dtree
= dm_tree_create())) {
738 log_error("Partial dtree creation failed for %s.", lv
->name
);
742 if (!_add_lv_to_dtree(dm
, dtree
, lv
))
745 /* Add any snapshots of this LV */
746 dm_list_iterate_safe(snh
, snht
, &lv
->snapshot_segs
)
747 if (!_add_lv_to_dtree(dm
, dtree
, dm_list_struct_base(snh
, struct lv_segment
, origin_list
)->cow
))
750 /* Add any LVs used by segments in this LV */
751 dm_list_iterate_items(seg
, &lv
->segments
)
752 for (s
= 0; s
< seg
->area_count
; s
++)
753 if (seg_type(seg
, s
) == AREA_LV
&& seg_lv(seg
, s
)) {
754 if (!_add_lv_to_dtree(dm
, dtree
, seg_lv(seg
, s
)))
765 static char *_add_error_device(struct dev_manager
*dm
, struct dm_tree
*dtree
,
766 struct lv_segment
*seg
, int s
)
770 struct dm_tree_node
*node
;
771 struct lv_segment
*seg_i
;
772 int segno
= -1, i
= 0;;
773 uint64_t size
= seg
->len
* seg
->lv
->vg
->extent_size
;
775 dm_list_iterate_items(seg_i
, &seg
->lv
->segments
) {
782 log_error("_add_error_device called with bad segment");
786 sprintf(errid
, "missing_%d_%d", segno
, s
);
788 if (!(id
= build_dlid(dm
, seg
->lv
->lvid
.s
, errid
)))
791 if (!(name
= build_dm_name(dm
->mem
, seg
->lv
->vg
->name
,
792 seg
->lv
->name
, errid
)))
794 if (!(node
= dm_tree_add_new_dev(dtree
, name
, id
, 0, 0, 0, 0, 0)))
796 if (!dm_tree_node_add_error_target(node
, size
))
802 static int _add_error_area(struct dev_manager
*dm
, struct dm_tree_node
*node
,
803 struct lv_segment
*seg
, int s
)
806 uint64_t extent_size
= seg
->lv
->vg
->extent_size
;
808 if (!strcmp(dm
->cmd
->stripe_filler
, "error")) {
810 * FIXME, the tree pointer is first field of dm_tree_node, but
811 * we don't have the struct definition available.
813 struct dm_tree
**tree
= (struct dm_tree
**) node
;
814 dlid
= _add_error_device(dm
, *tree
, seg
, s
);
817 dm_tree_node_add_target_area(node
, NULL
, dlid
,
818 extent_size
* seg_le(seg
, s
));
820 dm_tree_node_add_target_area(node
,
821 dm
->cmd
->stripe_filler
,
827 int add_areas_line(struct dev_manager
*dm
, struct lv_segment
*seg
,
828 struct dm_tree_node
*node
, uint32_t start_area
,
831 uint64_t extent_size
= seg
->lv
->vg
->extent_size
;
835 for (s
= start_area
; s
< areas
; s
++) {
836 if ((seg_type(seg
, s
) == AREA_PV
&&
837 (!seg_pvseg(seg
, s
) ||
839 !seg_dev(seg
, s
))) ||
840 (seg_type(seg
, s
) == AREA_LV
&& !seg_lv(seg
, s
))) {
841 if (!_add_error_area(dm
, node
, seg
, s
))
843 } else if (seg_type(seg
, s
) == AREA_PV
)
844 dm_tree_node_add_target_area(node
,
845 dev_name(seg_dev(seg
, s
)),
847 (seg_pv(seg
, s
)->pe_start
+
848 (extent_size
* seg_pe(seg
, s
))));
849 else if (seg_type(seg
, s
) == AREA_LV
) {
850 if (!(dlid
= build_dlid(dm
,
851 seg_lv(seg
, s
)->lvid
.s
,
854 dm_tree_node_add_target_area(node
, NULL
, dlid
,
855 extent_size
* seg_le(seg
, s
));
857 log_error("Internal error: Unassigned area found in LV %s.",
866 static int _add_origin_target_to_dtree(struct dev_manager
*dm
,
867 struct dm_tree_node
*dnode
,
868 struct logical_volume
*lv
)
870 const char *real_dlid
;
872 if (!(real_dlid
= build_dlid(dm
, lv
->lvid
.s
, "real")))
875 if (!dm_tree_node_add_snapshot_origin_target(dnode
, lv
->size
, real_dlid
))
881 static int _add_snapshot_target_to_dtree(struct dev_manager
*dm
,
882 struct dm_tree_node
*dnode
,
883 struct logical_volume
*lv
)
885 const char *origin_dlid
;
886 const char *cow_dlid
;
887 struct lv_segment
*snap_seg
;
890 if (!(snap_seg
= find_cow(lv
))) {
891 log_error("Couldn't find snapshot for '%s'.", lv
->name
);
895 if (!(origin_dlid
= build_dlid(dm
, snap_seg
->origin
->lvid
.s
, "real")))
898 if (!(cow_dlid
= build_dlid(dm
, snap_seg
->cow
->lvid
.s
, "cow")))
901 size
= (uint64_t) snap_seg
->len
* snap_seg
->origin
->vg
->extent_size
;
903 if (!dm_tree_node_add_snapshot_target(dnode
, size
, origin_dlid
, cow_dlid
, 1, snap_seg
->chunk_size
))
909 static int _add_target_to_dtree(struct dev_manager
*dm
,
910 struct dm_tree_node
*dnode
,
911 struct lv_segment
*seg
)
913 uint64_t extent_size
= seg
->lv
->vg
->extent_size
;
915 if (!seg
->segtype
->ops
->add_target_line
) {
916 log_error("_emit_target: Internal error: Can't handle "
917 "segment type %s", seg
->segtype
->name
);
921 return seg
->segtype
->ops
->add_target_line(dm
, dm
->mem
, dm
->cmd
,
922 &dm
->target_state
, seg
,
924 extent_size
* seg
->len
,
925 &dm
-> pvmove_mirror_count
);
928 static int _add_new_lv_to_dtree(struct dev_manager
*dm
, struct dm_tree
*dtree
,
929 struct logical_volume
*lv
, const char *layer
);
931 static int _add_segment_to_dtree(struct dev_manager
*dm
,
932 struct dm_tree
*dtree
,
933 struct dm_tree_node
*dnode
,
934 struct lv_segment
*seg
,
939 struct lv_segment
*seg_present
;
941 /* Ensure required device-mapper targets are loaded */
942 seg_present
= find_cow(seg
->lv
) ? : seg
;
944 log_debug("Checking kernel supports %s segment type for %s%s%s",
945 seg_present
->segtype
->name
, seg
->lv
->name
,
946 layer
? "-" : "", layer
? : "");
948 if (seg_present
->segtype
->ops
->target_present
&&
949 !seg_present
->segtype
->ops
->target_present(seg_present
->lv
->vg
->cmd
,
950 seg_present
, NULL
)) {
951 log_error("Can't expand LV %s: %s target support missing "
952 "from kernel?", seg
->lv
->name
, seg_present
->segtype
->name
);
958 !_add_new_lv_to_dtree(dm
, dtree
, seg
->log_lv
, NULL
))
961 /* If this is a snapshot origin, add real LV */
962 if (lv_is_origin(seg
->lv
) && !layer
) {
963 if (vg_is_clustered(seg
->lv
->vg
)) {
964 log_error("Clustered snapshots are not yet supported");
967 if (!_add_new_lv_to_dtree(dm
, dtree
, seg
->lv
, "real"))
969 } else if (lv_is_cow(seg
->lv
) && !layer
) {
970 if (!_add_new_lv_to_dtree(dm
, dtree
, seg
->lv
, "cow"))
973 /* Add any LVs used by this segment */
974 for (s
= 0; s
< seg
->area_count
; s
++)
975 if ((seg_type(seg
, s
) == AREA_LV
) &&
976 (!_add_new_lv_to_dtree(dm
, dtree
, seg_lv(seg
, s
), NULL
)))
980 /* Now we've added its dependencies, we can add the target itself */
981 if (lv_is_origin(seg
->lv
) && !layer
) {
982 if (!_add_origin_target_to_dtree(dm
, dnode
, seg
->lv
))
984 } else if (lv_is_cow(seg
->lv
) && !layer
) {
985 if (!_add_snapshot_target_to_dtree(dm
, dnode
, seg
->lv
))
987 } else if (!_add_target_to_dtree(dm
, dnode
, seg
))
990 if (lv_is_origin(seg
->lv
) && !layer
)
991 /* Add any snapshots of this LV */
992 dm_list_iterate(snh
, &seg
->lv
->snapshot_segs
)
993 if (!_add_new_lv_to_dtree(dm
, dtree
, dm_list_struct_base(snh
, struct lv_segment
, origin_list
)->cow
, NULL
))
999 static int _add_new_lv_to_dtree(struct dev_manager
*dm
, struct dm_tree
*dtree
,
1000 struct logical_volume
*lv
, const char *layer
)
1002 struct lv_segment
*seg
;
1003 struct lv_layer
*lvlayer
;
1004 struct dm_tree_node
*dnode
;
1006 uint32_t max_stripe_size
= UINT32_C(0);
1007 uint32_t read_ahead
= lv
->read_ahead
;
1008 uint32_t read_ahead_flags
= UINT32_C(0);
1009 uint16_t udev_flags
= 0;
1011 if (!(name
= build_dm_name(dm
->mem
, lv
->vg
->name
, lv
->name
, layer
)))
1014 if (!(dlid
= build_dlid(dm
, lv
->lvid
.s
, layer
)))
1017 /* We've already processed this node if it already has a context ptr */
1018 if ((dnode
= dm_tree_find_node_by_uuid(dtree
, dlid
)) &&
1019 dm_tree_node_get_context(dnode
))
1022 if (!(lvlayer
= dm_pool_alloc(dm
->mem
, sizeof(*lvlayer
)))) {
1023 log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv
->name
, layer
);
1029 if (layer
|| !lv_is_visible(lv
))
1030 udev_flags
|= DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG
|
1031 DM_UDEV_DISABLE_DISK_RULES_FLAG
|
1032 DM_UDEV_DISABLE_OTHER_RULES_FLAG
;
1035 udev_flags
|= DM_UDEV_LOW_PRIORITY_FLAG
;
1039 * If we're working with precommitted metadata, clear any
1040 * existing inactive table left behind.
1041 * Major/minor settings only apply to the visible layer.
1043 if (!(dnode
= dm_tree_add_new_dev_with_udev_flags(dtree
, name
, dlid
,
1044 layer
? UINT32_C(0) : (uint32_t) lv
->major
,
1045 layer
? UINT32_C(0) : (uint32_t) lv
->minor
,
1047 (lv
->vg
->status
& PRECOMMITTED
) ? 1 : 0,
1052 /* Store existing name so we can do rename later */
1053 lvlayer
->old_name
= dm_tree_node_get_name(dnode
);
1056 dm
->pvmove_mirror_count
= 0u;
1057 dm_list_iterate_items(seg
, &lv
->segments
) {
1058 if (!_add_segment_to_dtree(dm
, dtree
, dnode
, seg
, layer
))
1060 /* These aren't real segments in the LVM2 metadata */
1061 if (lv_is_origin(lv
) && !layer
)
1063 if (lv_is_cow(lv
) && !layer
)
1065 if (max_stripe_size
< seg
->stripe_size
* seg
->area_count
)
1066 max_stripe_size
= seg
->stripe_size
* seg
->area_count
;
1069 if (read_ahead
== DM_READ_AHEAD_AUTO
) {
1070 /* we need RA at least twice a whole stripe - see the comment in md/raid0.c */
1071 read_ahead
= max_stripe_size
* 2;
1073 lv_calculate_readahead(lv
, &read_ahead
);
1074 read_ahead_flags
= DM_READ_AHEAD_MINIMUM_FLAG
;
1077 dm_tree_node_set_read_ahead(dnode
, read_ahead
, read_ahead_flags
);
1082 /* FIXME: symlinks should be created/destroyed at the same time
1083 * as the kernel devices but we can't do that from within libdevmapper
1084 * at present so we must walk the tree twice instead. */
1087 * Create LV symlinks for children of supplied root node.
1089 static int _create_lv_symlinks(struct dev_manager
*dm
, struct dm_tree_node
*root
)
1091 void *handle
= NULL
;
1092 struct dm_tree_node
*child
;
1093 struct lv_layer
*lvlayer
;
1094 char *old_vgname
, *old_lvname
, *old_layer
;
1095 char *new_vgname
, *new_lvname
, *new_layer
;
1099 while ((child
= dm_tree_next_child(&handle
, root
, 0))) {
1100 if (!(lvlayer
= (struct lv_layer
*) dm_tree_node_get_context(child
)))
1104 name
= dm_tree_node_get_name(child
);
1106 if (name
&& lvlayer
->old_name
&& *lvlayer
->old_name
&& strcmp(name
, lvlayer
->old_name
)) {
1107 if (!dm_split_lvm_name(dm
->mem
, lvlayer
->old_name
, &old_vgname
, &old_lvname
, &old_layer
)) {
1108 log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer
->old_name
);
1111 if (!dm_split_lvm_name(dm
->mem
, name
, &new_vgname
, &new_lvname
, &new_layer
)) {
1112 log_error("_create_lv_symlinks: Couldn't split up new device name %s", name
);
1115 if (!fs_rename_lv(lvlayer
->lv
, name
, old_vgname
, old_lvname
))
1119 if (lv_is_visible(lvlayer
->lv
)) {
1120 if (!dev_manager_lv_mknodes(lvlayer
->lv
))
1124 if (!dev_manager_lv_rmnodes(lvlayer
->lv
))
1132 * Remove LV symlinks for children of supplied root node.
1134 static int _remove_lv_symlinks(struct dev_manager
*dm
, struct dm_tree_node
*root
)
1136 void *handle
= NULL
;
1137 struct dm_tree_node
*child
;
1138 char *vgname
, *lvname
, *layer
;
1141 while ((child
= dm_tree_next_child(&handle
, root
, 0))) {
1142 if (!dm_split_lvm_name(dm
->mem
, dm_tree_node_get_name(child
), &vgname
, &lvname
, &layer
)) {
1150 /* only top level layer has symlinks */
1154 fs_del_lv_byname(dm
->cmd
->dev_dir
, vgname
, lvname
);
1160 static int _clean_tree(struct dev_manager
*dm
, struct dm_tree_node
*root
)
1162 void *handle
= NULL
;
1163 struct dm_tree_node
*child
;
1164 char *vgname
, *lvname
, *layer
;
1165 const char *name
, *uuid
;
1168 while ((child
= dm_tree_next_child(&handle
, root
, 0))) {
1169 if (!(name
= dm_tree_node_get_name(child
)))
1172 if (!(uuid
= dm_tree_node_get_uuid(child
)))
1175 if (!dm_split_lvm_name(dm
->mem
, name
, &vgname
, &lvname
, &layer
)) {
1176 log_error("_clean_tree: Couldn't split up device name %s.", name
);
1180 /* Not meant to be top level? */
1184 dm_tree_set_cookie(root
, 0);
1185 r
= dm_tree_deactivate_children(root
, uuid
, strlen(uuid
));
1186 if (!dm_udev_wait(dm_tree_get_cookie(root
)))
1196 static int _tree_action(struct dev_manager
*dm
, struct logical_volume
*lv
, action_t action
)
1198 struct dm_tree
*dtree
;
1199 struct dm_tree_node
*root
;
1203 if (!(dtree
= _create_partial_dtree(dm
, lv
)))
1206 if (!(root
= dm_tree_find_node(dtree
, 0, 0))) {
1207 log_error("Lost dependency tree root node");
1211 if (!(dlid
= build_dlid(dm
, lv
->lvid
.s
, NULL
)))
1214 /* Only process nodes with uuid of "LVM-" plus VG id. */
1217 /* Deactivate any unused non-toplevel nodes */
1218 if (!_clean_tree(dm
, root
))
1222 /* Deactivate LV and all devices it references that nothing else has open. */
1223 dm_tree_set_cookie(root
, 0);
1224 r
= dm_tree_deactivate_children(root
, dlid
, ID_LEN
+ sizeof(UUID_PREFIX
) - 1);
1225 if (!dm_udev_wait(dm_tree_get_cookie(root
)))
1229 if (!_remove_lv_symlinks(dm
, root
))
1230 log_error("Failed to remove all device symlinks associated with %s.", lv
->name
);
1233 dm_tree_skip_lockfs(root
);
1234 if (!dm
->flush_required
&& (lv
->status
& MIRRORED
) && !(lv
->status
& PVMOVE
))
1235 dm_tree_use_no_flush_suspend(root
);
1236 case SUSPEND_WITH_LOCKFS
:
1237 if (!dm_tree_suspend_children(root
, dlid
, ID_LEN
+ sizeof(UUID_PREFIX
) - 1))
1242 /* Add all required new devices to tree */
1243 if (!_add_new_lv_to_dtree(dm
, dtree
, lv
, NULL
))
1246 /* Preload any devices required before any suspensions */
1247 dm_tree_set_cookie(root
, 0);
1248 r
= dm_tree_preload_children(root
, dlid
, ID_LEN
+ sizeof(UUID_PREFIX
) - 1);
1249 if (!dm_udev_wait(dm_tree_get_cookie(root
)))
1254 if (dm_tree_node_size_changed(root
))
1255 dm
->flush_required
= 1;
1257 if (action
== ACTIVATE
) {
1258 dm_tree_set_cookie(root
, 0);
1259 r
= dm_tree_activate_children(root
, dlid
, ID_LEN
+ sizeof(UUID_PREFIX
) - 1);
1260 if (!dm_udev_wait(dm_tree_get_cookie(root
)))
1264 if (!_create_lv_symlinks(dm
, root
)) {
1265 log_error("Failed to create symlinks for %s.", lv
->name
);
1272 log_error("_tree_action: Action %u not supported.", action
);
1279 dm_tree_free(dtree
);
1284 int dev_manager_activate(struct dev_manager
*dm
, struct logical_volume
*lv
)
1286 if (!_tree_action(dm
, lv
, ACTIVATE
))
1289 return _tree_action(dm
, lv
, CLEAN
);
1292 int dev_manager_preload(struct dev_manager
*dm
, struct logical_volume
*lv
,
1293 int *flush_required
)
1295 /* FIXME Update the pvmove implementation! */
1296 if ((lv
->status
& PVMOVE
) || (lv
->status
& LOCKED
))
1299 if (!_tree_action(dm
, lv
, PRELOAD
))
1302 *flush_required
= dm
->flush_required
;
1307 int dev_manager_deactivate(struct dev_manager
*dm
, struct logical_volume
*lv
)
1311 r
= _tree_action(dm
, lv
, DEACTIVATE
);
1318 int dev_manager_suspend(struct dev_manager
*dm
, struct logical_volume
*lv
,
1319 int lockfs
, int flush_required
)
1321 dm
->flush_required
= flush_required
;
1323 return _tree_action(dm
, lv
, lockfs
? SUSPEND_WITH_LOCKFS
: SUSPEND
);
1327 * Does device use VG somewhere in its construction?
1328 * Returns 1 if uncertain.
1330 int dev_manager_device_uses_vg(struct device
*dev
,
1331 struct volume_group
*vg
)
1333 struct dm_tree
*dtree
;
1334 struct dm_tree_node
*root
;
1335 char dlid
[sizeof(UUID_PREFIX
) + sizeof(struct id
) - 1] __attribute((aligned(8)));
1338 if (!(dtree
= dm_tree_create())) {
1339 log_error("partial dtree creation failed");
1343 if (!dm_tree_add_dev(dtree
, (uint32_t) MAJOR(dev
->dev
), (uint32_t) MINOR(dev
->dev
))) {
1344 log_error("Failed to add device %s (%" PRIu32
":%" PRIu32
") to dtree",
1345 dev_name(dev
), (uint32_t) MAJOR(dev
->dev
), (uint32_t) MINOR(dev
->dev
));
1349 memcpy(dlid
, UUID_PREFIX
, sizeof(UUID_PREFIX
) - 1);
1350 memcpy(dlid
+ sizeof(UUID_PREFIX
) - 1, &vg
->id
.uuid
[0], sizeof(vg
->id
));
1352 if (!(root
= dm_tree_find_node(dtree
, 0, 0))) {
1353 log_error("Lost dependency tree root node");
1357 if (dm_tree_children_use_uuid(root
, dlid
, sizeof(UUID_PREFIX
) + sizeof(vg
->id
) - 1))
1363 dm_tree_free(dtree
);