]>
Commit | Line | Data |
---|---|---|
ccafadb7 KZ |
1 | |
2 | #include <blkid.h> | |
3 | ||
4 | #ifdef HAVE_LIBUDEV | |
5 | # include <libudev.h> | |
6 | #endif | |
7 | ||
8 | #include "c.h" | |
9 | #include "xalloc.h" | |
10 | #include "mangle.h" | |
11 | ||
12 | #include "lsblk.h" | |
13 | ||
14 | #ifdef HAVE_LIBUDEV | |
15 | static struct udev *udev; | |
16 | #endif | |
17 | ||
18 | void lsblk_device_free_properties(struct lsblk_devprop *p) | |
19 | { | |
20 | if (!p) | |
21 | return; | |
22 | ||
23 | free(p->fstype); | |
24 | free(p->uuid); | |
25 | free(p->ptuuid); | |
26 | free(p->pttype); | |
27 | free(p->label); | |
28 | free(p->parttype); | |
29 | free(p->partuuid); | |
30 | free(p->partlabel); | |
31 | free(p->wwn); | |
32 | free(p->serial); | |
33 | free(p->model); | |
34 | ||
35 | free(p); | |
36 | } | |
37 | ||
38 | #ifndef HAVE_LIBUDEV | |
39 | static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt | |
40 | __attribute__((__unused__))) | |
41 | { | |
42 | return NULL; | |
43 | } | |
44 | #else | |
45 | static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt) | |
46 | { | |
47 | struct udev_device *dev; | |
48 | ||
49 | if (cxt->udev_requested) | |
50 | return cxt->properties; | |
51 | ||
52 | if (lsblk->sysroot) | |
53 | goto done; | |
54 | if (!udev) | |
55 | udev = udev_new(); /* global handler */ | |
56 | if (!udev) | |
57 | goto done; | |
58 | ||
59 | dev = udev_device_new_from_subsystem_sysname(udev, "block", cxt->name); | |
60 | if (dev) { | |
61 | const char *data; | |
62 | struct lsblk_devprop *prop; | |
63 | ||
64 | if (cxt->properties) | |
65 | lsblk_device_free_properties(cxt->properties); | |
66 | prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties)); | |
67 | ||
68 | if ((data = udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))) { | |
69 | prop->label = xstrdup(data); | |
70 | unhexmangle_string(prop->label); | |
71 | } | |
72 | if ((data = udev_device_get_property_value(dev, "ID_FS_UUID_ENC"))) { | |
73 | prop->uuid = xstrdup(data); | |
74 | unhexmangle_string(prop->uuid); | |
75 | } | |
76 | if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_UUID"))) | |
77 | prop->ptuuid = xstrdup(data); | |
78 | if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE"))) | |
79 | prop->pttype = xstrdup(data); | |
80 | if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME"))) { | |
81 | prop->partlabel = xstrdup(data); | |
82 | unhexmangle_string(prop->partlabel); | |
83 | } | |
84 | if ((data = udev_device_get_property_value(dev, "ID_FS_TYPE"))) | |
85 | prop->fstype = xstrdup(data); | |
86 | if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE"))) | |
87 | prop->parttype = xstrdup(data); | |
88 | if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_UUID"))) | |
89 | prop->partuuid = xstrdup(data); | |
90 | if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_FLAGS"))) | |
91 | prop->partflags = xstrdup(data); | |
92 | ||
93 | data = udev_device_get_property_value(dev, "ID_WWN_WITH_EXTENSION"); | |
94 | if (!data) | |
95 | data = udev_device_get_property_value(dev, "ID_WWN"); | |
96 | if (data) | |
97 | prop->wwn = xstrdup(data); | |
98 | ||
99 | if ((data = udev_device_get_property_value(dev, "ID_SERIAL_SHORT"))) | |
100 | prop->serial = xstrdup(data); | |
101 | if ((data = udev_device_get_property_value(dev, "ID_MODEL"))) | |
102 | prop->model = xstrdup(data); | |
103 | ||
104 | udev_device_unref(dev); | |
105 | DBG(DEV, ul_debugobj(cxt, "%s: found udev properties", cxt->name)); | |
106 | } | |
107 | ||
108 | done: | |
109 | cxt->udev_requested = 1; | |
110 | return cxt->properties; | |
111 | } | |
112 | #endif /* HAVE_LIBUDEV */ | |
113 | ||
114 | static struct lsblk_devprop *get_properties_by_blkid(struct blkdev_cxt *cxt) | |
115 | { | |
116 | blkid_probe pr = NULL; | |
117 | ||
118 | if (cxt->blkid_requested) | |
119 | return cxt->properties; | |
120 | ||
121 | if (!cxt->size) | |
122 | goto done; | |
123 | if (getuid() != 0) | |
124 | goto done;; /* no permissions to read from the device */ | |
125 | ||
126 | pr = blkid_new_probe_from_filename(cxt->filename); | |
127 | if (!pr) | |
128 | goto done; | |
129 | ||
130 | blkid_probe_enable_superblocks(pr, 1); | |
131 | blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | | |
132 | BLKID_SUBLKS_UUID | | |
133 | BLKID_SUBLKS_TYPE); | |
134 | blkid_probe_enable_partitions(pr, 1); | |
135 | blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); | |
136 | ||
137 | if (!blkid_do_safeprobe(pr)) { | |
138 | const char *data = NULL; | |
139 | struct lsblk_devprop *prop; | |
140 | ||
141 | if (cxt->properties) | |
142 | lsblk_device_free_properties(cxt->properties); | |
143 | prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties)); | |
144 | ||
145 | if (!blkid_probe_lookup_value(pr, "TYPE", &data, NULL)) | |
146 | prop->fstype = xstrdup(data); | |
147 | if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL)) | |
148 | prop->uuid = xstrdup(data); | |
149 | if (!blkid_probe_lookup_value(pr, "PTUUID", &data, NULL)) | |
150 | prop->ptuuid = xstrdup(data); | |
151 | if (!blkid_probe_lookup_value(pr, "PTTYPE", &data, NULL)) | |
152 | prop->pttype = xstrdup(data); | |
153 | if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL)) | |
154 | prop->label = xstrdup(data); | |
155 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_TYPE", &data, NULL)) | |
156 | prop->parttype = xstrdup(data); | |
157 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_UUID", &data, NULL)) | |
158 | prop->partuuid = xstrdup(data); | |
159 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_NAME", &data, NULL)) | |
160 | prop->partlabel = xstrdup(data); | |
161 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_FLAGS", &data, NULL)) | |
162 | prop->partflags = xstrdup(data); | |
163 | ||
164 | DBG(DEV, ul_debugobj(cxt, "%s: found blkid properties", cxt->name)); | |
165 | } | |
166 | ||
167 | done: | |
168 | blkid_free_probe(pr); | |
169 | ||
170 | cxt->blkid_requested = 1; | |
171 | return cxt->properties; | |
172 | } | |
173 | ||
174 | struct lsblk_devprop *lsblk_device_get_properties(struct blkdev_cxt *cxt) | |
175 | { | |
176 | struct lsblk_devprop *p = get_properties_by_udev(cxt); | |
177 | ||
178 | if (!p) | |
179 | p = get_properties_by_blkid(cxt); | |
180 | return p; | |
181 | } | |
182 | ||
183 | void lsblk_properties_deinit(void) | |
184 | { | |
185 | #ifdef HAVE_LIBUDEV | |
186 | udev_unref(udev); | |
187 | #endif | |
188 | } |