blob: fef7d533ea3b452fa6dfc092fe863b2d30065a7d
1 | /* |
2 | * volume_id - reads filesystem label and uuid |
3 | * |
4 | * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2.1 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this library; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | //kbuild:lib-$(CONFIG_VOLUMEID) += volume_id.o util.o |
22 | |
23 | #include "volume_id_internal.h" |
24 | |
25 | |
26 | /* Some detection routines do not set label or uuid anyway, |
27 | * so they are disabled. */ |
28 | |
29 | /* Looks for partitions, we don't use it: */ |
30 | #define ENABLE_FEATURE_VOLUMEID_MAC 0 |
31 | /* #define ENABLE_FEATURE_VOLUMEID_MSDOS 0 - NB: this one |
32 | * was not properly added to probe table anyway - ??! */ |
33 | |
34 | /* None of RAIDs have label or uuid, except LinuxRAID: */ |
35 | #define ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID 0 |
36 | #define ENABLE_FEATURE_VOLUMEID_ISWRAID 0 |
37 | #define ENABLE_FEATURE_VOLUMEID_LSIRAID 0 |
38 | #define ENABLE_FEATURE_VOLUMEID_LVM 0 |
39 | #define ENABLE_FEATURE_VOLUMEID_NVIDIARAID 0 |
40 | #define ENABLE_FEATURE_VOLUMEID_PROMISERAID 0 |
41 | #define ENABLE_FEATURE_VOLUMEID_SILICONRAID 0 |
42 | #define ENABLE_FEATURE_VOLUMEID_VIARAID 0 |
43 | |
44 | /* These filesystems also have no label or uuid: */ |
45 | #define ENABLE_FEATURE_VOLUMEID_MINIX 0 |
46 | #define ENABLE_FEATURE_VOLUMEID_HPFS 0 |
47 | #define ENABLE_FEATURE_VOLUMEID_UFS 0 |
48 | |
49 | |
50 | typedef int FAST_FUNC (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size); |
51 | typedef int FAST_FUNC (*probe_fptr)(struct volume_id *id /*, uint64_t off*/); |
52 | |
53 | static const raid_probe_fptr raid1[] = { |
54 | #if ENABLE_FEATURE_VOLUMEID_LINUXRAID |
55 | volume_id_probe_linux_raid, |
56 | #endif |
57 | #if ENABLE_FEATURE_VOLUMEID_ISWRAID |
58 | volume_id_probe_intel_software_raid, |
59 | #endif |
60 | #if ENABLE_FEATURE_VOLUMEID_LSIRAID |
61 | volume_id_probe_lsi_mega_raid, |
62 | #endif |
63 | #if ENABLE_FEATURE_VOLUMEID_VIARAID |
64 | volume_id_probe_via_raid, |
65 | #endif |
66 | #if ENABLE_FEATURE_VOLUMEID_SILICONRAID |
67 | volume_id_probe_silicon_medley_raid, |
68 | #endif |
69 | #if ENABLE_FEATURE_VOLUMEID_NVIDIARAID |
70 | volume_id_probe_nvidia_raid, |
71 | #endif |
72 | #if ENABLE_FEATURE_VOLUMEID_PROMISERAID |
73 | volume_id_probe_promise_fasttrack_raid, |
74 | #endif |
75 | #if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID |
76 | volume_id_probe_highpoint_45x_raid, |
77 | #endif |
78 | }; |
79 | |
80 | static const probe_fptr raid2[] = { |
81 | #if ENABLE_FEATURE_VOLUMEID_LVM |
82 | volume_id_probe_lvm1, |
83 | volume_id_probe_lvm2, |
84 | #endif |
85 | #if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID |
86 | volume_id_probe_highpoint_37x_raid, |
87 | #endif |
88 | #if ENABLE_FEATURE_VOLUMEID_LUKS |
89 | volume_id_probe_luks, |
90 | #endif |
91 | }; |
92 | |
93 | /* signature in the first block, only small buffer needed */ |
94 | static const probe_fptr fs1[] = { |
95 | #if ENABLE_FEATURE_VOLUMEID_FAT |
96 | volume_id_probe_vfat, |
97 | #endif |
98 | #if ENABLE_FEATURE_VOLUMEID_EXFAT |
99 | volume_id_probe_exfat, |
100 | #endif |
101 | #if ENABLE_FEATURE_VOLUMEID_MAC |
102 | volume_id_probe_mac_partition_map, |
103 | #endif |
104 | #if ENABLE_FEATURE_VOLUMEID_SQUASHFS |
105 | volume_id_probe_squashfs, |
106 | #endif |
107 | #if ENABLE_FEATURE_VOLUMEID_XFS |
108 | volume_id_probe_xfs, |
109 | #endif |
110 | #if ENABLE_FEATURE_VOLUMEID_BCACHE |
111 | volume_id_probe_bcache, |
112 | #endif |
113 | }; |
114 | |
115 | /* fill buffer with maximum */ |
116 | static const probe_fptr fs2[] = { |
117 | #if ENABLE_FEATURE_VOLUMEID_LINUXSWAP |
118 | volume_id_probe_linux_swap, |
119 | #endif |
120 | #if ENABLE_FEATURE_VOLUMEID_EXT |
121 | volume_id_probe_ext, |
122 | #endif |
123 | #if ENABLE_FEATURE_VOLUMEID_BTRFS |
124 | volume_id_probe_btrfs, |
125 | #endif |
126 | #if ENABLE_FEATURE_VOLUMEID_REISERFS |
127 | volume_id_probe_reiserfs, |
128 | #endif |
129 | #if ENABLE_FEATURE_VOLUMEID_JFS |
130 | volume_id_probe_jfs, |
131 | #endif |
132 | #if ENABLE_FEATURE_VOLUMEID_UDF |
133 | volume_id_probe_udf, |
134 | #endif |
135 | #if ENABLE_FEATURE_VOLUMEID_ISO9660 |
136 | volume_id_probe_iso9660, |
137 | #endif |
138 | #if ENABLE_FEATURE_VOLUMEID_HFS |
139 | volume_id_probe_hfs_hfsplus, |
140 | #endif |
141 | #if ENABLE_FEATURE_VOLUMEID_UFS |
142 | volume_id_probe_ufs, |
143 | #endif |
144 | #if ENABLE_FEATURE_VOLUMEID_F2FS |
145 | volume_id_probe_f2fs, |
146 | #endif |
147 | #if ENABLE_FEATURE_VOLUMEID_NILFS |
148 | volume_id_probe_nilfs, |
149 | #endif |
150 | #if ENABLE_FEATURE_VOLUMEID_NTFS |
151 | volume_id_probe_ntfs, |
152 | #endif |
153 | #if ENABLE_FEATURE_VOLUMEID_CRAMFS |
154 | volume_id_probe_cramfs, |
155 | #endif |
156 | #if ENABLE_FEATURE_VOLUMEID_ROMFS |
157 | volume_id_probe_romfs, |
158 | #endif |
159 | #if ENABLE_FEATURE_VOLUMEID_HPFS |
160 | volume_id_probe_hpfs, |
161 | #endif |
162 | #if ENABLE_FEATURE_VOLUMEID_SYSV |
163 | volume_id_probe_sysv, |
164 | #endif |
165 | #if ENABLE_FEATURE_VOLUMEID_MINIX |
166 | volume_id_probe_minix, |
167 | #endif |
168 | #if ENABLE_FEATURE_VOLUMEID_OCFS2 |
169 | volume_id_probe_ocfs2, |
170 | #endif |
171 | #if ENABLE_FEATURE_VOLUMEID_UBIFS |
172 | volume_id_probe_ubifs, |
173 | #endif |
174 | }; |
175 | |
176 | int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size) |
177 | { |
178 | unsigned i, arsize; |
179 | |
180 | /* probe for raid first, cause fs probes may be successful on raid members */ |
181 | if (size) { |
182 | arsize=ARRAY_SIZE(raid1); |
183 | for (i = 0; i < arsize; i++) { |
184 | if (raid1[i](id, /*off,*/ size) == 0) |
185 | goto ret; |
186 | if (id->error) |
187 | goto ret; |
188 | } |
189 | } |
190 | |
191 | arsize=ARRAY_SIZE(raid2); |
192 | for (i = 0; i < arsize; i++) { |
193 | if (raid2[i](id /*,off*/) == 0) |
194 | goto ret; |
195 | if (id->error) |
196 | goto ret; |
197 | } |
198 | |
199 | /* signature in the first block, only small buffer needed */ |
200 | arsize=ARRAY_SIZE(fs1); |
201 | for (i = 0; i < arsize; i++) { |
202 | if (fs1[i](id /*,off*/) == 0) |
203 | goto ret; |
204 | if (id->error) |
205 | goto ret; |
206 | } |
207 | |
208 | |
209 | /* fill buffer with maximum */ |
210 | volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); |
211 | |
212 | arsize=ARRAY_SIZE(fs2); |
213 | for (i = 0; i < arsize; i++) { |
214 | if (fs2[i](id /*,off*/) == 0) |
215 | break; |
216 | if (id->error) |
217 | break; |
218 | } |
219 | |
220 | volume_id_free_buffer(id); |
221 | |
222 | ret: |
223 | return (- id->error); /* 0 or -1 */ |
224 | } |
225 | |
226 | /* open volume by device node */ |
227 | struct volume_id* FAST_FUNC volume_id_open_node(int fd) |
228 | { |
229 | struct volume_id *id; |
230 | |
231 | id = xzalloc(sizeof(struct volume_id)); |
232 | id->fd = fd; |
233 | ///* close fd on device close */ |
234 | //id->fd_close = 1; |
235 | return id; |
236 | } |
237 | |
238 | #ifdef UNUSED |
239 | /* open volume by major/minor */ |
240 | struct volume_id* FAST_FUNC volume_id_open_dev_t(dev_t devt) |
241 | { |
242 | struct volume_id *id; |
243 | char *tmp_node[VOLUME_ID_PATH_MAX]; |
244 | |
245 | tmp_node = xasprintf("/dev/.volume_id-%u-%u-%u", |
246 | (unsigned)getpid(), (unsigned)major(devt), (unsigned)minor(devt)); |
247 | |
248 | /* create temporary node to open block device */ |
249 | unlink(tmp_node); |
250 | if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) |
251 | bb_perror_msg_and_die("can't mknod(%s)", tmp_node); |
252 | |
253 | id = volume_id_open_node(tmp_node); |
254 | unlink(tmp_node); |
255 | free(tmp_node); |
256 | return id; |
257 | } |
258 | #endif |
259 | |
260 | void FAST_FUNC free_volume_id(struct volume_id *id) |
261 | { |
262 | if (id == NULL) |
263 | return; |
264 | |
265 | //if (id->fd_close != 0) - always true |
266 | close(id->fd); |
267 | volume_id_free_buffer(id); |
268 | #ifdef UNUSED_PARTITION_CODE |
269 | free(id->partitions); |
270 | #endif |
271 | free(id); |
272 | } |
273 |