blob: 809884a41b4fbf8a83035a0bee82694f2d635a57 [file] [log] [blame]
Denis Vlasenkode7684a2008-02-18 21:08:49 +00001/*
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#include "volume_id_internal.h"
22
23typedef int (*raid_probe_fptr)(struct volume_id *id, uint64_t off, uint64_t size);
24typedef int (*probe_fptr)(struct volume_id *id, uint64_t off);
25
26static const raid_probe_fptr raid1[] = {
27#if ENABLE_FEATURE_VOLUMEID_LINUXRAID
28 volume_id_probe_linux_raid,
29#endif
30#if ENABLE_FEATURE_VOLUMEID_ISWRAID
31 volume_id_probe_intel_software_raid,
32#endif
33#if ENABLE_FEATURE_VOLUMEID_LSIRAID
34 volume_id_probe_lsi_mega_raid,
35#endif
36#if ENABLE_FEATURE_VOLUMEID_VIARAID
37 volume_id_probe_via_raid,
38#endif
39#if ENABLE_FEATURE_VOLUMEID_SILICONRAID
40 volume_id_probe_silicon_medley_raid,
41#endif
42#if ENABLE_FEATURE_VOLUMEID_NVIDIARAID
43 volume_id_probe_nvidia_raid,
44#endif
45#if ENABLE_FEATURE_VOLUMEID_PROMISERAID
46 volume_id_probe_promise_fasttrack_raid,
47#endif
48#if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID
49 volume_id_probe_highpoint_45x_raid,
50#endif
51};
52
53static const probe_fptr raid2[] = {
54#if ENABLE_FEATURE_VOLUMEID_LVM
55 volume_id_probe_lvm1,
56 volume_id_probe_lvm2,
57#endif
58#if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID
59 volume_id_probe_highpoint_37x_raid,
60#endif
61#if ENABLE_FEATURE_VOLUMEID_LUKS
62 volume_id_probe_luks,
63#endif
64};
65
66/* signature in the first block, only small buffer needed */
67static const probe_fptr fs1[] = {
68#if ENABLE_FEATURE_VOLUMEID_FAT
69 volume_id_probe_vfat,
70#endif
71#if ENABLE_FEATURE_VOLUMEID_MAC
72 volume_id_probe_mac_partition_map,
73#endif
74#if ENABLE_FEATURE_VOLUMEID_XFS
75 volume_id_probe_xfs,
76#endif
77};
78
79/* fill buffer with maximum */
80static const probe_fptr fs2[] = {
81#if ENABLE_FEATURE_VOLUMEID_LINUXSWAP
82 volume_id_probe_linux_swap,
83#endif
84#if ENABLE_FEATURE_VOLUMEID_EXT
85 volume_id_probe_ext,
86#endif
87#if ENABLE_FEATURE_VOLUMEID_REISERFS
88 volume_id_probe_reiserfs,
89#endif
90#if ENABLE_FEATURE_VOLUMEID_JFS
91 volume_id_probe_jfs,
92#endif
93#if ENABLE_FEATURE_VOLUMEID_UDF
94 volume_id_probe_udf,
95#endif
96#if ENABLE_FEATURE_VOLUMEID_ISO9660
97 volume_id_probe_iso9660,
98#endif
99#if ENABLE_FEATURE_VOLUMEID_HFS
100 volume_id_probe_hfs_hfsplus,
101#endif
102#if ENABLE_FEATURE_VOLUMEID_UFS
103 volume_id_probe_ufs,
104#endif
105#if ENABLE_FEATURE_VOLUMEID_NTFS
106 volume_id_probe_ntfs,
107#endif
108#if ENABLE_FEATURE_VOLUMEID_CRAMFS
109 volume_id_probe_cramfs,
110#endif
111#if ENABLE_FEATURE_VOLUMEID_ROMFS
112 volume_id_probe_romfs,
113#endif
114#if ENABLE_FEATURE_VOLUMEID_HPFS
115 volume_id_probe_hpfs,
116#endif
117#if ENABLE_FEATURE_VOLUMEID_SYSV
118 volume_id_probe_sysv,
119#endif
120#if ENABLE_FEATURE_VOLUMEID_MINIX
121 volume_id_probe_minix,
122#endif
123#if ENABLE_FEATURE_VOLUMEID_OCFS2
124 volume_id_probe_ocfs2,
125#endif
126};
127
128int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
129{
130 int i;
131
132 if (id == NULL)
133 return -EINVAL;
134
135 /* probe for raid first, cause fs probes may be successful on raid members */
136 if (size) {
137 for (i = 0; i < ARRAY_SIZE(raid1); i++)
138 if (raid1[i](id, off, size) == 0)
139 goto ret;
140 }
141
142 for (i = 0; i < ARRAY_SIZE(raid2); i++)
143 if (raid2[i](id, off) == 0)
144 goto ret;
145
146 /* signature in the first block, only small buffer needed */
147 for (i = 0; i < ARRAY_SIZE(fs1); i++)
148 if (fs1[i](id, off) == 0)
149 goto ret;
150
151 /* fill buffer with maximum */
152 volume_id_get_buffer(id, 0, SB_BUFFER_SIZE);
153
154 for (i = 0; i < ARRAY_SIZE(fs2); i++)
155 if (fs2[i](id, off) == 0)
156 goto ret;
157 return -1;
158
159 ret:
160 /* If the filestystem in recognized, we free the allocated buffers,
161 otherwise they will stay in place for the possible next probe call */
162 volume_id_free_buffer(id);
163
164 return 0;
165}
166
167/* open volume by device node */
168struct volume_id *volume_id_open_node(const char *path)
169{
170 struct volume_id *id;
171 int fd;
172
173 fd = xopen(path, O_RDONLY);
174 id = xzalloc(sizeof(struct volume_id));
175 id->fd = fd;
176 ///* close fd on device close */
177 //id->fd_close = 1;
178
179 return id;
180}
181
182#ifdef UNUSED
183/* open volume by major/minor */
184struct volume_id *volume_id_open_dev_t(dev_t devt)
185{
186 struct volume_id *id;
187 char *tmp_node[VOLUME_ID_PATH_MAX];
188
189 tmp_node = xasprintf("/dev/.volume_id-%u-%u-%u",
190 (unsigned)getpid(), (unsigned)major(devt), (unsigned)minor(devt));
191
192 /* create temporary node to open block device */
193 unlink(tmp_node);
194 if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0)
195 bb_perror_msg_and_die("cannot mknod(%s)", tmp_node);
196
197 id = volume_id_open_node(tmp_node);
198 unlink(tmp_node);
199 free(tmp_node);
200 return id;
201}
202#endif
203
204void free_volume_id(struct volume_id *id)
205{
206 if (id == NULL)
207 return;
208
209 //if (id->fd_close != 0) - always true
210 close(id->fd);
211 volume_id_free_buffer(id);
212 free(id->partitions);
213 free(id);
214}