]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved. | |
3 | * Written by Milan Broz <mbroz@redhat.com> | |
4 | * Karel Zak <kzak@redhat.com> | |
5 | */ | |
6 | #ifndef UTIL_LINUX_LSBLK_H | |
7 | #define UTIL_LINUX_LSBLK_H | |
8 | ||
9 | #include <stdint.h> | |
10 | #include <inttypes.h> | |
11 | #include <sys/stat.h> | |
12 | #include <sys/statvfs.h> | |
13 | ||
14 | #include <libsmartcols.h> | |
15 | ||
16 | #include "c.h" | |
17 | #include "list.h" | |
18 | #include "debug.h" | |
19 | ||
20 | #define LSBLK_DEBUG_INIT (1 << 1) | |
21 | #define LSBLK_DEBUG_FILTER (1 << 2) | |
22 | #define LSBLK_DEBUG_DEV (1 << 3) | |
23 | #define LSBLK_DEBUG_TREE (1 << 4) | |
24 | #define LSBLK_DEBUG_DEP (1 << 5) | |
25 | #define LSBLK_DEBUG_ALL 0xFFFF | |
26 | ||
27 | UL_DEBUG_DECLARE_MASK(lsblk); | |
28 | #define DBG(m, x) __UL_DBG(lsblk, LSBLK_DEBUG_, m, x) | |
29 | #define ON_DBG(m, x) __UL_DBG_CALL(lsblk, LSBLK_DEBUG_, m, x) | |
30 | ||
31 | #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(lsblk) | |
32 | #include "debugobj.h" | |
33 | ||
34 | struct lsblk { | |
35 | struct libscols_table *table; /* output table */ | |
36 | ||
37 | struct libscols_column *sort_col;/* sort output by this column */ | |
38 | ||
39 | int sort_id; /* id of the sort column */ | |
40 | int tree_id; /* od of column used for tree */ | |
41 | ||
42 | int dedup_id; | |
43 | ||
44 | const char *sysroot; | |
45 | int flags; /* LSBLK_* */ | |
46 | ||
47 | unsigned int all_devices:1; /* print all devices, including empty */ | |
48 | unsigned int bytes:1; /* print SIZE in bytes */ | |
49 | unsigned int inverse:1; /* print inverse dependencies */ | |
50 | unsigned int merge:1; /* merge sub-trees */ | |
51 | unsigned int nodeps:1; /* don't print slaves/holders */ | |
52 | unsigned int scsi:1; /* print only device with HCTL (SCSI) */ | |
53 | unsigned int paths:1; /* print devnames with "/dev" prefix */ | |
54 | unsigned int sort_hidden:1; /* sort column not between output columns */ | |
55 | unsigned int dedup_hidden :1; /* deduplication column not between output columns */ | |
56 | unsigned int force_tree_order:1;/* sort lines by parent->tree relation */ | |
57 | }; | |
58 | ||
59 | extern struct lsblk *lsblk; /* global handler */ | |
60 | ||
61 | struct lsblk_devprop { | |
62 | char *fstype; /* detected fs, NULL or "?" if cannot detect */ | |
63 | char *uuid; /* filesystem UUID (or stack uuid) */ | |
64 | char *ptuuid; /* partition table UUID */ | |
65 | char *pttype; /* partition table type */ | |
66 | char *label; /* filesystem label */ | |
67 | char *parttype; /* partition type UUID */ | |
68 | char *partuuid; /* partition UUID */ | |
69 | char *partlabel; /* partition label */ | |
70 | char *partflags; /* partition flags */ | |
71 | char *wwn; /* storage WWN */ | |
72 | char *serial; /* disk serial number */ | |
73 | char *model; /* disk model */ | |
74 | }; | |
75 | ||
76 | /* Device dependence | |
77 | * | |
78 | * Note that the same device may be slave/holder for more another devices. It | |
79 | * means we need to allocate list member rather than use @child directly. | |
80 | */ | |
81 | struct lsblk_devdep { | |
82 | struct list_head ls_childs; /* item in parent->childs */ | |
83 | struct list_head ls_parents; /* item in child->parents */ | |
84 | ||
85 | struct lsblk_device *child; | |
86 | struct lsblk_device *parent; | |
87 | }; | |
88 | ||
89 | struct lsblk_device { | |
90 | int refcount; | |
91 | ||
92 | struct list_head childs; /* list with lsblk_devdep */ | |
93 | struct list_head parents; | |
94 | struct list_head ls_roots; /* item in devtree->roots list */ | |
95 | struct list_head ls_devices; /* item in devtree->devices list */ | |
96 | ||
97 | struct lsblk_device *wholedisk; /* for partitions */ | |
98 | ||
99 | struct libscols_line *scols_line; | |
100 | ||
101 | struct lsblk_devprop *properties; | |
102 | struct stat st; | |
103 | ||
104 | char *name; /* kernel name in /sys/block */ | |
105 | char *dm_name; /* DM name (dm/block) */ | |
106 | ||
107 | char *filename; /* path to device node */ | |
108 | char *dedupkey; /* de-duplication key */ | |
109 | ||
110 | struct path_cxt *sysfs; | |
111 | ||
112 | char *mountpoint; /* device mountpoint */ | |
113 | struct statvfs fsstat; /* statvfs() result */ | |
114 | ||
115 | int npartitions; /* # of partitions this device has */ | |
116 | int nholders; /* # of devices mapped directly to this device | |
117 | * /sys/block/.../holders */ | |
118 | int nslaves; /* # of devices this device maps to */ | |
119 | int maj, min; /* devno */ | |
120 | ||
121 | uint64_t discard_granularity; /* sunknown:-1, yes:1, not:0 */ | |
122 | ||
123 | uint64_t size; /* device size */ | |
124 | int removable; /* unknown:-1, yes:1, not:0 */ | |
125 | ||
126 | unsigned int is_mounted : 1, | |
127 | is_swap : 1, | |
128 | is_printed : 1, | |
129 | udev_requested : 1, | |
130 | blkid_requested : 1; | |
131 | }; | |
132 | ||
133 | #define device_is_partition(_x) ((_x)->wholedisk != NULL) | |
134 | ||
135 | /* | |
136 | * Note that lsblk tree uses bottom devices (devices without slaves) as root | |
137 | * of the tree, and partitions are interpreted as a dependence too; it means: | |
138 | * sda -> sda1 -> md0 | |
139 | * | |
140 | * The flag 'is_inverted' turns the tree over (root is device without holders): | |
141 | * md0 -> sda1 -> sda | |
142 | */ | |
143 | struct lsblk_devtree { | |
144 | int refcount; | |
145 | ||
146 | struct list_head roots; /* tree root devices */ | |
147 | struct list_head devices; /* all devices */ | |
148 | ||
149 | unsigned int is_inverse : 1; /* inverse tree */ | |
150 | }; | |
151 | ||
152 | ||
153 | /* | |
154 | * Generic iterator | |
155 | */ | |
156 | struct lsblk_iter { | |
157 | struct list_head *p; /* current position */ | |
158 | struct list_head *head; /* start position */ | |
159 | int direction; /* LSBLK_ITER_{FOR,BACK}WARD */ | |
160 | }; | |
161 | ||
162 | #define LSBLK_ITER_FORWARD 0 | |
163 | #define LSBLK_ITER_BACKWARD 1 | |
164 | ||
165 | #define IS_ITER_FORWARD(_i) ((_i)->direction == LSBLK_ITER_FORWARD) | |
166 | #define IS_ITER_BACKWARD(_i) ((_i)->direction == LSBLK_ITER_BACKWARD) | |
167 | ||
168 | #define LSBLK_ITER_INIT(itr, list) \ | |
169 | do { \ | |
170 | (itr)->p = IS_ITER_FORWARD(itr) ? \ | |
171 | (list)->next : (list)->prev; \ | |
172 | (itr)->head = (list); \ | |
173 | } while(0) | |
174 | ||
175 | #define LSBLK_ITER_ITERATE(itr, res, restype, member) \ | |
176 | do { \ | |
177 | res = list_entry((itr)->p, restype, member); \ | |
178 | (itr)->p = IS_ITER_FORWARD(itr) ? \ | |
179 | (itr)->p->next : (itr)->p->prev; \ | |
180 | } while(0) | |
181 | ||
182 | ||
183 | /* lsblk-mnt.c */ | |
184 | extern void lsblk_mnt_init(void); | |
185 | extern void lsblk_mnt_deinit(void); | |
186 | ||
187 | extern char *lsblk_device_get_mountpoint(struct lsblk_device *dev); | |
188 | ||
189 | /* lsblk-properties.c */ | |
190 | extern void lsblk_device_free_properties(struct lsblk_devprop *p); | |
191 | extern struct lsblk_devprop *lsblk_device_get_properties(struct lsblk_device *dev); | |
192 | extern void lsblk_properties_deinit(void); | |
193 | ||
194 | /* lsblk-devtree.c */ | |
195 | void lsblk_reset_iter(struct lsblk_iter *itr, int direction); | |
196 | struct lsblk_device *lsblk_new_device(void); | |
197 | void lsblk_ref_device(struct lsblk_device *dev); | |
198 | void lsblk_unref_device(struct lsblk_device *dev); | |
199 | int lsblk_device_new_dependence(struct lsblk_device *parent, struct lsblk_device *child); | |
200 | int lsblk_device_has_child(struct lsblk_device *dev, struct lsblk_device *child); | |
201 | int lsblk_device_next_child(struct lsblk_device *dev, | |
202 | struct lsblk_iter *itr, | |
203 | struct lsblk_device **child); | |
204 | ||
205 | int lsblk_device_is_last_parent(struct lsblk_device *dev, struct lsblk_device *parent); | |
206 | int lsblk_device_next_parent( | |
207 | struct lsblk_device *dev, | |
208 | struct lsblk_iter *itr, | |
209 | struct lsblk_device **parent); | |
210 | ||
211 | struct lsblk_devtree *lsblk_new_devtree(void); | |
212 | void lsblk_ref_devtree(struct lsblk_devtree *tr); | |
213 | void lsblk_unref_devtree(struct lsblk_devtree *tr); | |
214 | int lsblk_devtree_add_root(struct lsblk_devtree *tr, struct lsblk_device *dev); | |
215 | int lsblk_devtree_next_root(struct lsblk_devtree *tr, | |
216 | struct lsblk_iter *itr, | |
217 | struct lsblk_device **dev); | |
218 | int lsblk_devtree_add_device(struct lsblk_devtree *tr, struct lsblk_device *dev); | |
219 | int lsblk_devtree_next_device(struct lsblk_devtree *tr, | |
220 | struct lsblk_iter *itr, | |
221 | struct lsblk_device **dev); | |
222 | int lsblk_devtree_has_device(struct lsblk_devtree *tr, struct lsblk_device *dev); | |
223 | struct lsblk_device *lsblk_devtree_get_device(struct lsblk_devtree *tr, const char *name); | |
224 | int lsblk_devtree_remove_device(struct lsblk_devtree *tr, struct lsblk_device *dev); | |
225 | int lsblk_devtree_deduplicate_devices(struct lsblk_devtree *tr); | |
226 | ||
227 | #endif /* UTIL_LINUX_LSBLK_H */ |