1 # Copyright (C) 2011 Red Hat, Inc. All rights reserved.
2 # This file is part of LVM2.
4 # This copyrighted material is made available to anyone wishing to use,
5 # modify, copy, or redistribute it subject to the terms and conditions
6 # of the GNU Lesser General Public License v.2.1.
8 # You should have received a copy of the GNU Lesser General Public License
9 # along with this program; if not, write to the Free Software Foundation,
10 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
13 # Jonathan Brassow <jbrassow@redhat.com>
15 # Copy this file to ~/.gdbinit or <working_dir>/.gdbinit
18 printf "Loading commands:\n"
19 printf " - dm_list_size <list ptr>\n"
20 printf " - pv_dev_name <PV ptr>\n"
21 printf " - first_seg <LV ptr>\n"
22 printf " - lv_status <LV ptr>\n"
23 printf " - lv_status_r <LV ptr>\n"
24 printf " - lv_is_mirrored <LV ptr>\n"
25 printf " - seg_item <seg ptr> <index>\n"
26 printf " - seg_status <seg ptr>\n"
27 printf " - segs_using_this_lv <seg ptr>\n"
28 printf " - seg_pvs <list ptr>\n"
30 printf "Use 'help <command>' for more info\n"
32 printf "Popular breakpoints:\n"
33 printf "break _alloc_image_components\n"
34 printf "run --repair --use-policies vg/lv\n"
37 set follow-fork-mode child
40 # foo : function named 'foo' available to user
41 # __foo : an internal function
43 # External functions should have a corresponding 'document'
44 # section. Internal functions should have leading comments
49 set $_DLS_list_head = (struct dm_list *)$arg0
50 set $_DLS_list = $_DLS_list_head->n
53 while (($_DLS_list != $_DLS_list_head) && ($_DLS_size < 100))
54 set $_DLS_list = $_DLS_list->n
58 printf "%d list items\n", $_DLS_size
62 Returns the number of elements in the dm_list
64 Usage: dm_list_size <list ptr>
68 set $_PDN_pv = (struct physical_volume *)$arg0
69 set $_PDN_dev = $_PDN_pv->dev
70 set $_PDN_strl = (struct str_list *)$_PDN_dev->aliases.n
72 printf "%s\n", $_PDN_strl->str
76 Print the name of the PV for the given PV pointer
78 Usage: pv_dev_name <PV ptr>
82 set $_SP_list_head = (struct dm_list *)$arg0
83 set $_SP_list = $_SP_list_head->n
85 while (($_SP_list != $_SP_list_head) && ($_SP_size < 100))
86 set $_SP_spv = (struct seg_pvs *)$_SP_list
88 printf "* Can't print PV list\n"
90 set $_SP_list = $_SP_list->n
93 printf "%d list items\n", $_SP_size
97 Print the elements of a seg_pvs list
99 Usage: seg_pvs <list ptr>
103 # __first_seg <return> <LV>
106 set $_FS_lv = (struct logical_volume *)$arg1
108 if ($_FS_lv->segments.n != &$_FS_lv->segments)
109 set $arg0 = (struct lv_segment *)$_FS_lv->segments.n
115 set $_lv=(struct logical_volume *)$arg0
117 __first_seg $_seg $_lv
122 printf "No segments (list empty)\n"
127 Returns the pointer to the first segment of an LV
129 Usage: first_seg <LV ptr>
131 WARNING: If the list pointer in 'struct lv_segment' moves,
132 this function will be wrong.
136 # __seg_type <return> <seg> <index>
139 set $_ST_seg = (struct lv_segment *)$arg1
140 set $_ST_index= $arg2
141 set $_ST_area = $_ST_seg->areas[$_ST_index]
142 set $_ST_type = $_ST_area.type
144 set $arg0 = $_ST_type
148 # __seg_item <return> <seg> <index>
151 set $_SI_seg = (struct lv_segment *)$arg1
152 set $_SI_index= $arg2
154 if ($_SI_index < $_SI_seg->area_count)
155 set $_SI_area = $_SI_seg->areas[$_SI_index]
156 set $_SI_type = $_SI_area.type
158 if ($_SI_type == AREA_PV)
159 set $arg0 = $_SI_area.u.pv.pvseg->pv
161 if ($_SI_type == AREA_LV)
162 set $arg0 = $_SI_area.u.lv.lv
169 # __seg_metaitem <return> <seg> <index>
170 define __seg_metaitem
172 set $_SMI_seg = (struct lv_segment *)$arg1
173 set $_SMI_index= $arg2
175 if (($_SMI_index < $_SMI_seg->area_count) && $_SMI_seg->meta_areas)
176 set $_SMI_area = $_SMI_seg->meta_areas[$_SMI_index]
177 set $_SMI_type = $_SMI_area.type
179 if ($_SMI_type == AREA_PV)
180 set $arg0 = $_SMI_area.u.pv.pvseg->pv
182 if ($_SMI_type == AREA_LV)
183 set $arg0 = $_SMI_area.u.lv.lv
192 __seg_item $_item $arg0 $arg1
196 printf "AREA_UNASSIGNED or invalid\n"
203 __seg_metaitem $_metaitem $arg0 $arg1
207 printf "AREA_UNASSIGNED or invalid\n"
212 Returns the pointer to the LV or PV for the indexed area of a segment
214 Usage: seg_item <struct lv_segment *> <index>
216 Example - Getting to the sub-lv of a mirror:
221 $2 = (struct lv_segment *) 0x7128b8
224 $3 = (struct logical_volume *) 0x712688
227 $4 = 0x712770 "lv_mimage_0"
231 set $_s_status = $arg0->status
233 # Constants defined in metadata-exported.h
235 # if ($_s_status & RAID)
236 if ($_s_status & 0x0000000100000000LU)
237 set $_s_status = $_s_status & ~0x0000000100000000LU
240 # if ($_s_status & RAID_META)
241 if ($_s_status & 0x0000000200000000LU)
242 set $_s_status = $_s_status & ~0x0000000200000000LU
245 # if ($_s_status & RAID_IMAGE)
246 if ($_s_status & 0x0000000400000000LU)
247 set $_s_status = $_s_status & ~0x0000000400000000LU
250 # if ($_s_status & MIRRORED)
251 if ($_s_status & 0x00008000U)
252 set $_s_status = $_s_status & ~0x00008000U
255 # if ($_s_status & MIRROR_LOG)
256 if ($_s_status & 0x00020000U)
257 set $_s_status = $_s_status & ~0x00020000U
260 # if ($_s_status & MIRROR_IMAGE)
261 if ($_s_status & 0x00040000U)
262 set $_s_status = $_s_status & ~0x00040000U
263 printf " MIRROR_IMAGE"
265 # if ($_s_status & VISIBLE_LV)
266 if ($_s_status & 0x00000040U)
268 set $_s_status = $_s_status & ~0x00000040U
270 printf " *HIDDEN_LV*"
272 # if ($_s_status & FIXED_MINOR)
273 if ($_s_status & 0x00000080U)
274 set $_s_status = $_s_status & ~0x00000080U
275 printf " FIXED_MINOR"
277 # if ($_s_status & LVM_READ)
278 if ($_s_status & 0x00000100U)
279 set $_s_status = $_s_status & ~0x00000100U
282 # if ($_s_status & LVM_WRITE)
283 if ($_s_status & 0x00000200U)
284 set $_s_status = $_s_status & ~0x00000200U
287 # if ($_s_status & SNAPSHOT)
288 if ($_s_status & 0x00001000U)
289 set $_s_status = $_s_status & ~0x00001000U
292 # if ($_s_status & PVMOVE)
293 if ($_s_status & 0x00002000U)
294 set $_s_status = $_s_status & ~0x00002000U
297 # if ($_s_status & LOCKED)
298 if ($_s_status & 0x00004000U)
299 set $_s_status = $_s_status & ~0x00004000U
302 # if ($_s_status & LV_NOTSYNCED)
303 if ($_s_status & 0x00080000U)
304 set $_s_status = $_s_status & ~0x00080000U
305 printf " LV_NOTSYNCED"
307 # if ($_s_status & CONVERTING)
308 if ($_s_status & 0x00400000U)
309 set $_s_status = $_s_status & ~0x00400000U
312 # if ($_s_status & LV_REBUILD)
313 if ($_s_status & 0x100000U)
314 set $_s_status = $_s_status & ~0x100000U
317 # if ($_s_status & PARTIAL_LV)
318 if ($_s_status & 0x1000000U)
319 set $_s_status = $_s_status & ~0x1000000U
322 # if ($_s_status & MERGING)
323 if ($_s_status & 0x10000000U)
324 set $_s_status = $_s_status & ~0x10000000U
327 # if ($_s_status & LV_WRITEMOSTLY)
328 if ($_s_status & 0x10000000000U)
329 set $_s_status = $_s_status & ~0x10000000000U
330 printf " LV_WRITEMOSTLY"
334 printf " 0x%x", $_s_status
339 # __print_indent <num indents> [No marks]
340 define __print_indent
341 set $_PI_indent = $arg0
342 set $_PI_lead_mark = 0
345 if ($_PI_indent == 1)
357 set $_PI_lead_mark = 1
364 # Use __lv because we don't want to overwrite higher functions
365 set $__lv = (struct logical_volume *)$arg0
370 printf "%s->status:", $__lv->name
376 Display the flags that are set on an LV.
378 Usage: lv_status <LV ptr>
382 set $_seg=(struct lv_segment *)$arg0
385 __print_indent $arg1 1
387 printf "[ (%s) seg->status:", $_seg->lv->name
393 Display the flags that are set on an lv_segment.
395 Usage: seg_status <(struct lv_segment *)>
399 # get_only_segment_using_this_lv <return> <LV>
400 define __get_only_segment_using_this_lv
402 set $_lv=(struct logical_volume *)$arg1
403 set $_seg_list_head = &$_lv->segs_using_this_lv
404 set $_s = $_lv->segs_using_this_lv.n
407 while (($_s != $_seg_list_head) && ($_i < 100))
408 set $_seg_list = (struct seg_list *)$_s
409 set $_seg = (struct lv_segment *)$_seg_list->seg
416 printf "More than %s using %s\n", ($_i > 99) ? "100 segments" : "one segment", $_lv->name
423 define segs_using_this_lv
424 set $_lv=(struct logical_volume *)$arg0
425 set $_seg_list_head = &$_lv->segs_using_this_lv
426 set $_s = $_lv->segs_using_this_lv.n
429 if ($_s != $_seg_list_head)
430 printf "Segments using %s\n", $_lv->name
432 printf "No segments using %s\n", $_lv->name
434 while ($_s != $_seg_list_head)
435 set $_seg_list = (struct seg_list *)$_s
436 set $_seg = (struct lv_segment *)$_seg_list->seg
437 printf " %d) seg: %p", $_i, $_seg
438 if ($_seg->lv < 0x200)
439 printf " [BAD LV POINTER FROM THIS SEG]\n"
441 printf " [seg found in %s]\n", $_seg->lv->name
448 document segs_using_this_lv
449 Display the segments (and their associated LV) using an LV
451 Usage: segs_using_this_lv <LV ptr>
454 (gdb) lv_is_mirrored lv
455 lv is mirrored ('core' log)
457 (gdb) segs_using_this_lv lv
461 $1 = (struct lv_segment *) 0x92d360
464 $2 = (struct logical_volume *) 0x928f58
466 (gdb) segs_using_this_lv $2
467 Segments using lv_mimage_0
468 0) seg: 0x92d360 [seg found in lv]
472 # __next_area_index <return> <seg> <seg_item>
473 define __next_area_index
475 set $_seg = (struct lv_segment *)$arg1
479 __seg_item $_item $_seg $_i
480 while ($_item && ($_item != $arg2))
482 __seg_item $_item $_seg $_i
485 # $_i points to current, now get next (if there)
487 __seg_item $_item $_seg $_i
496 # Descend tree, printing LV and seg status as we go. This
497 # performs a depth first approach (but can't come up)
501 # __lv_status_r <sub_lv> <seg using sub_lv>
502 # Try continuing decent of tree by first shifting to the
503 # next 'area' in the seg ($arg1). If no more areas, then
504 # try going to the next segment.
507 set $_lv=(struct logical_volume *)$arg0
508 set $_seg_list_head = &$_lv->segments
509 set $_s = $_lv->segments.n
513 lv_status $_lv $indent
515 set $_seg = (struct lv_segment *)$arg1
517 __next_area_index $_area_index $_seg $arg0
519 # Don't fuck this up. We need the next two lines here.
520 set $_lv=(struct logical_volume *)$_seg->lv
521 set $_seg_list_head = &$_lv->segments
522 set $_s = (struct dm_list *)$_seg
529 if ($_s == $_seg_list_head)
531 __print_indent $indent 1
532 printf "[ No segments for %s ]\n", $_lv->name
534 __get_only_segment_using_this_lv $_seg $_lv
536 if ($_seg && $indent)
538 __lv_status_r $_lv $_seg
541 set $_seg = (struct lv_segment *)$_s
545 seg_status $_seg $indent
547 __seg_type $_type $_seg $_area_index
548 if ($_type == AREA_LV)
551 __seg_metaitem $_lv $_seg $_area_index
553 set $rindent = $indent
555 set $rarea_index = $_area_index
560 set $indent = $rindent
562 set $_area_index = $rarea_index
566 __seg_item $_lv $_seg $_area_index
573 __first_seg $_log_seg $_seg->log_lv
574 lv_status $_seg->log_lv $indent
575 seg_status $_log_seg $indent
579 __get_only_segment_using_this_lv $_seg $_lv
582 __lv_status_r $_lv $_seg
594 Display the status flags of an LV and its sub_lvs.
596 Usage: lv_status_r <LV ptr>
598 This function is useful for checking that all the LVs that
599 compose a logical volume have the correct flags set (and also
600 their associated lv_segments)
603 define lv_is_mirrored
604 set $_lv=(struct logical_volume *)$arg0
605 set $_fs=(struct lv_segment *)$_lv->segments.n
606 set $_log_lv=(struct logical_volume *)$_fs->log_lv
608 # if ($_lv->status & MIRRORED)
609 if ($_lv->status & 0x00008000U)
610 printf "%s is mirrored (", $_lv->name
612 if ($_log_lv->status & 0x00008000U)
613 printf "'mirrored' log)\n"
615 printf "'disk' log)\n"
618 printf "'core' log)\n"
621 printf "%s is not mirrored\n", $_lv->name
625 document lv_is_mirrored
626 Report whether the given LV is mirrored (and its log type).
628 Usage: lv_is_mirrored <LV ptr>