2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
15 #include <sys/types.h>
16 #ifdef HAVE_SYS_STAT_H
26 static void blkid_probe_to_tags(blkid_probe pr
, blkid_dev dev
)
33 nvals
= blkid_probe_numof_values(pr
);
35 for (n
= 0; n
< nvals
; n
++) {
36 if (blkid_probe_get_value(pr
, n
, &name
, &data
, &len
) != 0)
38 if (strncmp(name
, "PART_ENTRY_", 11) == 0) {
39 if (strcmp(name
, "PART_ENTRY_UUID") == 0)
40 blkid_set_tag(dev
, "PARTUUID", data
, len
);
41 else if (strcmp(name
, "PART_ENTRY_NAME") == 0)
42 blkid_set_tag(dev
, "PARTLABEL", data
, len
);
44 } else if (!strstr(name
, "_ID")) {
45 /* superblock UUID, LABEL, ...
46 * but not {SYSTEM,APPLICATION,..._ID} */
47 blkid_set_tag(dev
, name
, data
, len
);
53 * Verify that the data in dev is consistent with what is on the actual
54 * block device (using the devname field only). Normally this will be
55 * called when finding items in the cache, but for long running processes
56 * is also desirable to revalidate an item before use.
58 * If we are unable to revalidate the data, we return the old data and
59 * do not set the BLKID_BID_FL_VERIFIED flag on it.
61 blkid_dev
blkid_verify(blkid_cache cache
, blkid_dev dev
)
63 blkid_tag_iterate iter
;
64 const char *type
, *value
;
73 diff
= (uintmax_t)now
- dev
->bid_time
;
75 if (stat(dev
->bid_name
, &st
) < 0) {
76 DBG(PROBE
, ul_debug("blkid_verify: error %s (%d) while "
77 "trying to stat %s", strerror(errno
), errno
,
80 if ((errno
== EPERM
) || (errno
== EACCES
) || (errno
== ENOENT
)) {
81 /* We don't have read permission, just return cache data. */
82 DBG(PROBE
, ul_debug("returning unverified data for %s",
90 if (now
>= dev
->bid_time
&&
91 #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
92 (st
.st_mtime
< dev
->bid_time
||
93 (st
.st_mtime
== dev
->bid_time
&&
94 st
.st_mtim
.tv_nsec
/ 1000 <= dev
->bid_utime
)) &&
96 st
.st_mtime
<= dev
->bid_time
&&
98 diff
>= 0 && diff
< BLKID_PROBE_MIN
) {
99 dev
->bid_flags
|= BLKID_BID_FL_VERIFIED
;
103 #ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
104 DBG(PROBE
, ul_debug("need to revalidate %s (cache time %lld, stat time %lld,\t"
105 "time since last check %lld)",
106 dev
->bid_name
, (long long)dev
->bid_time
,
107 (long long)st
.st_mtime
, (long long)diff
));
109 DBG(PROBE
, ul_debug("need to revalidate %s (cache time %lld.%lld, stat time %lld.%lld,\t"
110 "time since last check %lld)",
112 (long long)dev
->bid_time
, (long long)dev
->bid_utime
,
113 (long long)st
.st_mtime
, (long long)st
.st_mtim
.tv_nsec
/ 1000,
117 if (sysfs_devno_is_dm_private(st
.st_rdev
, NULL
)) {
122 cache
->probe
= blkid_new_probe();
129 fd
= open(dev
->bid_name
, O_RDONLY
|O_CLOEXEC
|O_NONBLOCK
);
131 DBG(PROBE
, ul_debug("blkid_verify: error %s (%d) while "
132 "opening %s", strerror(errno
), errno
,
137 if (blkid_probe_set_device(cache
->probe
, fd
, 0, 0)) {
138 /* failed to read the device */
144 /* remove old cache info */
145 iter
= blkid_tag_iterate_begin(dev
);
146 while (blkid_tag_next(iter
, &type
, &value
) == 0)
147 blkid_set_tag(dev
, type
, NULL
, 0);
148 blkid_tag_iterate_end(iter
);
150 /* enable superblocks probing */
151 blkid_probe_enable_superblocks(cache
->probe
, TRUE
);
152 blkid_probe_set_superblocks_flags(cache
->probe
,
153 BLKID_SUBLKS_LABEL
| BLKID_SUBLKS_UUID
|
154 BLKID_SUBLKS_TYPE
| BLKID_SUBLKS_SECTYPE
);
156 /* enable partitions probing */
157 blkid_probe_enable_partitions(cache
->probe
, TRUE
);
158 blkid_probe_set_partitions_flags(cache
->probe
, BLKID_PARTS_ENTRY_DETAILS
);
161 if (blkid_do_safeprobe(cache
->probe
)) {
162 /* found nothing or error */
168 #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
170 if (!gettimeofday(&tv
, NULL
)) {
171 dev
->bid_time
= tv
.tv_sec
;
172 dev
->bid_utime
= tv
.tv_usec
;
175 dev
->bid_time
= time(NULL
);
177 dev
->bid_devno
= st
.st_rdev
;
178 dev
->bid_flags
|= BLKID_BID_FL_VERIFIED
;
179 cache
->bic_flags
|= BLKID_BIC_FL_CHANGED
;
181 blkid_probe_to_tags(cache
->probe
, dev
);
183 DBG(PROBE
, ul_debug("%s: devno 0x%04llx, type %s",
184 dev
->bid_name
, (long long)st
.st_rdev
, dev
->bid_type
));
188 blkid_probe_reset_superblocks_filter(cache
->probe
);
189 blkid_probe_set_device(cache
->probe
, -1, 0, 0);
196 int main(int argc
, char **argv
)
203 fprintf(stderr
, "Usage: %s device\n"
204 "Probe a single device to determine type\n", argv
[0]);
207 if ((ret
= blkid_get_cache(&cache
, "/dev/null")) != 0) {
208 fprintf(stderr
, "%s: error creating cache (%d)\n",
212 dev
= blkid_get_dev(cache
, argv
[1], BLKID_DEV_NORMAL
);
214 printf("%s: %s has an unsupported type\n", argv
[0], argv
[1]);
217 printf("TYPE='%s'\n", dev
->bid_type
? dev
->bid_type
: "(null)");
219 printf("LABEL='%s'\n", dev
->bid_label
);
221 printf("UUID='%s'\n", dev
->bid_uuid
);