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
24
static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev)
31
nvals = blkid_probe_numof_values(pr);
33
for (n = 0; n < nvals; n++) {
34
if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
35
blkid_set_tag(dev, name, data, len);
40
* Verify that the data in dev is consistent with what is on the actual
41
* block device (using the devname field only). Normally this will be
42
* called when finding items in the cache, but for long running processes
43
* is also desirable to revalidate an item before use.
45
* If we are unable to revalidate the data, we return the old data and
46
* do not set the BLKID_BID_FL_VERIFIED flag on it.
48
blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
59
diff = now - dev->bid_time;
61
if (stat(dev->bid_name, &st) < 0) {
63
printf("blkid_verify: error %s (%d) while "
64
"trying to stat %s\n", strerror(errno), errno,
67
if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
68
/* We don't have read permission, just return cache data. */
69
DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
77
if (now >= dev->bid_time &&
78
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
79
(st.st_mtime < dev->bid_time ||
80
(st.st_mtime == dev->bid_time &&
81
st.st_mtim.tv_nsec / 1000 <= dev->bid_utime)) &&
83
st.st_mtime <= dev->bid_time &&
85
(diff < BLKID_PROBE_MIN ||
86
(dev->bid_flags & BLKID_BID_FL_VERIFIED &&
87
diff < BLKID_PROBE_INTERVAL)))
90
#ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
92
printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
93
"time since last check %lu)\n",
94
dev->bid_name, (unsigned long)dev->bid_time,
95
(unsigned long)st.st_mtime, (unsigned long)diff));
98
printf("need to revalidate %s (cache time %lu.%lu, stat time %lu.%lu,\n\t"
99
"time since last check %lu)\n",
101
(unsigned long)dev->bid_time, (unsigned long)dev->bid_utime,
102
(unsigned long)st.st_mtime, (unsigned long)st.st_mtim.tv_nsec / 1000,
103
(unsigned long)diff));
107
cache->probe = blkid_new_probe();
114
fd = open(dev->bid_name, O_RDONLY);
116
DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while "
117
"opening %s\n", strerror(errno), errno,
122
if (blkid_probe_set_device(cache->probe, fd, 0, 0)) {
123
/* failed to read the device */
129
blkid_probe_enable_superblocks(cache->probe, TRUE);
131
blkid_probe_set_superblocks_flags(cache->probe,
132
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
133
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE);
136
* If we already know the type, then try that first.
139
blkid_tag_iterate iter;
140
const char *type, *value;
142
fltr[0] = dev->bid_type;
145
blkid_probe_filter_superblocks_type(cache->probe,
146
BLKID_FLTR_ONLYIN, fltr);
148
if (!blkid_do_probe(cache->probe))
150
blkid_probe_invert_superblocks_filter(cache->probe);
153
* Zap the device filesystem information and try again
156
printf("previous fs type %s not valid, "
157
"trying full probe\n", dev->bid_type));
158
iter = blkid_tag_iterate_begin(dev);
159
while (blkid_tag_next(iter, &type, &value) == 0)
160
blkid_set_tag(dev, type, 0, 0);
161
blkid_tag_iterate_end(iter);
165
* Probe for all types.
167
if (blkid_do_safeprobe(cache->probe)) {
168
/* found nothing or error */
175
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
177
if (!gettimeofday(&tv, NULL)) {
178
dev->bid_time = tv.tv_sec;
179
dev->bid_utime = tv.tv_usec;
182
dev->bid_time = time(0);
184
dev->bid_devno = st.st_rdev;
185
dev->bid_flags |= BLKID_BID_FL_VERIFIED;
186
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
188
blkid_probe_to_tags(cache->probe, dev);
190
DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
191
dev->bid_name, (long long)st.st_rdev, dev->bid_type));
194
blkid_reset_probe(cache->probe);
195
blkid_probe_reset_superblocks_filter(cache->probe);
201
int main(int argc, char **argv)
208
fprintf(stderr, "Usage: %s device\n"
209
"Probe a single device to determine type\n", argv[0]);
212
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
213
fprintf(stderr, "%s: error creating cache (%d)\n",
217
dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
219
printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
222
printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)");
224
printf("LABEL='%s'\n", dev->bid_label);
226
printf("UUID='%s'\n", dev->bid_uuid);