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.
14 #include <sys/types.h>
15 #ifdef HAVE_SYS_STAT_H
23 static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev)
30 nvals = blkid_probe_numof_values(pr);
32 for (n = 0; n < nvals; n++) {
33 if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
34 blkid_set_tag(dev, name, data, len);
39 * Verify that the data in dev is consistent with what is on the actual
40 * block device (using the devname field only). Normally this will be
41 * called when finding items in the cache, but for long running processes
42 * is also desirable to revalidate an item before use.
44 * If we are unable to revalidate the data, we return the old data and
45 * do not set the BLKID_BID_FL_VERIFIED flag on it.
47 blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
58 diff = now - dev->bid_time;
60 if (stat(dev->bid_name, &st) < 0) {
62 printf("blkid_verify: error %s (%d) while "
63 "trying to stat %s\n", strerror(errno), errno,
66 if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
67 /* We don't have read permission, just return cache data. */
68 DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
76 if ((now >= dev->bid_time) &&
77 (st.st_mtime <= dev->bid_time) &&
78 ((diff < BLKID_PROBE_MIN) ||
79 (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
80 diff < BLKID_PROBE_INTERVAL)))
84 printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
85 "time since last check %lu)\n",
86 dev->bid_name, (unsigned long)dev->bid_time,
87 (unsigned long)st.st_mtime, (unsigned long)diff));
91 cache->probe = blkid_new_probe();
98 fd = open(dev->bid_name, O_RDONLY);
100 DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while "
101 "opening %s\n", strerror(errno), errno,
106 if (blkid_probe_set_device(cache->probe, fd, 0, 0)) {
107 /* failed to read the device */
113 blkid_probe_set_request(cache->probe,
114 BLKID_PROBREQ_LABEL | BLKID_PROBREQ_UUID |
115 BLKID_PROBREQ_TYPE | BLKID_PROBREQ_SECTYPE);
118 * If we already know the type, then try that first.
121 blkid_tag_iterate iter;
122 const char *type, *value;
124 fltr[0] = dev->bid_type;
127 blkid_probe_filter_types(cache->probe,
128 BLKID_FLTR_ONLYIN, fltr);
130 if (!blkid_do_probe(cache->probe))
132 blkid_probe_invert_filter(cache->probe);
135 * Zap the device filesystem information and try again
138 printf("previous fs type %s not valid, "
139 "trying full probe\n", dev->bid_type));
140 iter = blkid_tag_iterate_begin(dev);
141 while (blkid_tag_next(iter, &type, &value) == 0)
142 blkid_set_tag(dev, type, 0, 0);
143 blkid_tag_iterate_end(iter);
147 * Probe for all types.
149 if (blkid_do_safeprobe(cache->probe)) {
150 /* found nothing or error */
157 dev->bid_devno = st.st_rdev;
158 dev->bid_time = time(0);
159 dev->bid_flags |= BLKID_BID_FL_VERIFIED;
160 cache->bic_flags |= BLKID_BIC_FL_CHANGED;
162 blkid_probe_to_tags(cache->probe, dev);
164 DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
165 dev->bid_name, (long long)st.st_rdev, dev->bid_type));
168 blkid_reset_probe(cache->probe);
169 blkid_probe_reset_filter(cache->probe);
175 int main(int argc, char **argv)
182 fprintf(stderr, "Usage: %s device\n"
183 "Probe a single device to determine type\n", argv[0]);
186 if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
187 fprintf(stderr, "%s: error creating cache (%d)\n",
191 dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
193 printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
196 printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)");
198 printf("LABEL='%s'\n", dev->bid_label);
200 printf("UUID='%s'\n", dev->bid_uuid);