]>
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 | |
fed34a1e | 39 | static struct lsblk_devprop *get_properties_by_udev(struct lsblk_device *dev |
ccafadb7 KZ |
40 | __attribute__((__unused__))) |
41 | { | |
42 | return NULL; | |
43 | } | |
44 | #else | |
fed34a1e | 45 | static struct lsblk_devprop *get_properties_by_udev(struct lsblk_device *ld) |
ccafadb7 KZ |
46 | { |
47 | struct udev_device *dev; | |
48 | ||
fed34a1e KZ |
49 | if (ld->udev_requested) |
50 | return ld->properties; | |
ccafadb7 KZ |
51 | |
52 | if (lsblk->sysroot) | |
53 | goto done; | |
54 | if (!udev) | |
55 | udev = udev_new(); /* global handler */ | |
56 | if (!udev) | |
57 | goto done; | |
58 | ||
fed34a1e | 59 | dev = udev_device_new_from_subsystem_sysname(udev, "block", ld->name); |
ccafadb7 KZ |
60 | if (dev) { |
61 | const char *data; | |
62 | struct lsblk_devprop *prop; | |
63 | ||
fed34a1e KZ |
64 | if (ld->properties) |
65 | lsblk_device_free_properties(ld->properties); | |
66 | prop = ld->properties = xcalloc(1, sizeof(*ld->properties)); | |
ccafadb7 KZ |
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 | ||
c2f6513c SW |
99 | data = udev_device_get_property_value(dev, "ID_SCSI_SERIAL"); |
100 | if(!data) | |
101 | data = udev_device_get_property_value(dev, "ID_SERIAL_SHORT"); | |
102 | if (data) | |
ccafadb7 | 103 | prop->serial = xstrdup(data); |
c2f6513c | 104 | |
ccafadb7 KZ |
105 | if ((data = udev_device_get_property_value(dev, "ID_MODEL"))) |
106 | prop->model = xstrdup(data); | |
107 | ||
108 | udev_device_unref(dev); | |
fed34a1e | 109 | DBG(DEV, ul_debugobj(ld, "%s: found udev properties", ld->name)); |
ccafadb7 KZ |
110 | } |
111 | ||
112 | done: | |
fed34a1e KZ |
113 | ld->udev_requested = 1; |
114 | return ld->properties; | |
ccafadb7 KZ |
115 | } |
116 | #endif /* HAVE_LIBUDEV */ | |
117 | ||
fed34a1e | 118 | static struct lsblk_devprop *get_properties_by_blkid(struct lsblk_device *dev) |
ccafadb7 KZ |
119 | { |
120 | blkid_probe pr = NULL; | |
121 | ||
fed34a1e KZ |
122 | if (dev->blkid_requested) |
123 | return dev->properties; | |
ccafadb7 | 124 | |
fed34a1e | 125 | if (!dev->size) |
ccafadb7 KZ |
126 | goto done; |
127 | if (getuid() != 0) | |
128 | goto done;; /* no permissions to read from the device */ | |
129 | ||
fed34a1e | 130 | pr = blkid_new_probe_from_filename(dev->filename); |
ccafadb7 KZ |
131 | if (!pr) |
132 | goto done; | |
133 | ||
134 | blkid_probe_enable_superblocks(pr, 1); | |
135 | blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | | |
136 | BLKID_SUBLKS_UUID | | |
137 | BLKID_SUBLKS_TYPE); | |
138 | blkid_probe_enable_partitions(pr, 1); | |
139 | blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); | |
140 | ||
141 | if (!blkid_do_safeprobe(pr)) { | |
142 | const char *data = NULL; | |
143 | struct lsblk_devprop *prop; | |
144 | ||
fed34a1e KZ |
145 | if (dev->properties) |
146 | lsblk_device_free_properties(dev->properties); | |
147 | prop = dev->properties = xcalloc(1, sizeof(*dev->properties)); | |
ccafadb7 KZ |
148 | |
149 | if (!blkid_probe_lookup_value(pr, "TYPE", &data, NULL)) | |
150 | prop->fstype = xstrdup(data); | |
151 | if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL)) | |
152 | prop->uuid = xstrdup(data); | |
153 | if (!blkid_probe_lookup_value(pr, "PTUUID", &data, NULL)) | |
154 | prop->ptuuid = xstrdup(data); | |
155 | if (!blkid_probe_lookup_value(pr, "PTTYPE", &data, NULL)) | |
156 | prop->pttype = xstrdup(data); | |
157 | if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL)) | |
158 | prop->label = xstrdup(data); | |
159 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_TYPE", &data, NULL)) | |
160 | prop->parttype = xstrdup(data); | |
161 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_UUID", &data, NULL)) | |
162 | prop->partuuid = xstrdup(data); | |
163 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_NAME", &data, NULL)) | |
164 | prop->partlabel = xstrdup(data); | |
165 | if (!blkid_probe_lookup_value(pr, "PART_ENTRY_FLAGS", &data, NULL)) | |
166 | prop->partflags = xstrdup(data); | |
167 | ||
fed34a1e | 168 | DBG(DEV, ul_debugobj(dev, "%s: found blkid properties", dev->name)); |
ccafadb7 KZ |
169 | } |
170 | ||
171 | done: | |
172 | blkid_free_probe(pr); | |
173 | ||
fed34a1e KZ |
174 | dev->blkid_requested = 1; |
175 | return dev->properties; | |
ccafadb7 KZ |
176 | } |
177 | ||
fed34a1e | 178 | struct lsblk_devprop *lsblk_device_get_properties(struct lsblk_device *dev) |
ccafadb7 | 179 | { |
fed34a1e | 180 | struct lsblk_devprop *p = get_properties_by_udev(dev); |
ccafadb7 KZ |
181 | |
182 | if (!p) | |
fed34a1e | 183 | p = get_properties_by_blkid(dev); |
ccafadb7 KZ |
184 | return p; |
185 | } | |
186 | ||
187 | void lsblk_properties_deinit(void) | |
188 | { | |
189 | #ifdef HAVE_LIBUDEV | |
190 | udev_unref(udev); | |
191 | #endif | |
192 | } |