~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to libblkid/src/devname.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * devname.c - get a dev by its device inode name
 
3
 *
 
4
 * Copyright (C) Andries Brouwer
 
5
 * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
 
6
 * Copyright (C) 2001 Andreas Dilger
 
7
 *
 
8
 * %Begin-Header%
 
9
 * This file may be redistributed under the terms of the
 
10
 * GNU Lesser General Public License.
 
11
 * %End-Header%
 
12
 */
 
13
 
 
14
#define _GNU_SOURCE 1
 
15
 
 
16
#include <stdio.h>
 
17
#include <string.h>
 
18
#include <limits.h>
 
19
#if HAVE_UNISTD_H
 
20
#include <unistd.h>
 
21
#endif
 
22
#include <stdlib.h>
 
23
#include <ctype.h>
 
24
#include <fcntl.h>
 
25
#if HAVE_SYS_TYPES_H
 
26
#include <sys/types.h>
 
27
#endif
 
28
#include <dirent.h>
 
29
#if HAVE_SYS_STAT_H
 
30
#include <sys/stat.h>
 
31
#endif
 
32
#if HAVE_ERRNO_H
 
33
#include <errno.h>
 
34
#endif
 
35
#include <time.h>
 
36
 
 
37
#include "blkidP.h"
 
38
 
 
39
#include "canonicalize.h"               /* $(top_srcdir)/include */
 
40
#include "pathnames.h"
 
41
#include "sysfs.h"
 
42
#include "at.h"
 
43
 
 
44
/*
 
45
 * Find a dev struct in the cache by device name, if available.
 
46
 *
 
47
 * If there is no entry with the specified device name, and the create
 
48
 * flag is set, then create an empty device entry.
 
49
 */
 
50
blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
 
51
{
 
52
        blkid_dev dev = NULL, tmp;
 
53
        struct list_head *p, *pnext;
 
54
 
 
55
        if (!cache || !devname)
 
56
                return NULL;
 
57
 
 
58
        list_for_each(p, &cache->bic_devs) {
 
59
                tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
 
60
                if (strcmp(tmp->bid_name, devname))
 
61
                        continue;
 
62
 
 
63
                DBG(DEBUG_DEVNAME,
 
64
                    printf("found devname %s in cache\n", tmp->bid_name));
 
65
                dev = tmp;
 
66
                break;
 
67
        }
 
68
 
 
69
        if (!dev && (flags & BLKID_DEV_CREATE)) {
 
70
                if (access(devname, F_OK) < 0)
 
71
                        return NULL;
 
72
                dev = blkid_new_dev();
 
73
                if (!dev)
 
74
                        return NULL;
 
75
                dev->bid_time = INT_MIN;
 
76
                dev->bid_name = blkid_strdup(devname);
 
77
                dev->bid_cache = cache;
 
78
                list_add_tail(&dev->bid_devs, &cache->bic_devs);
 
79
                cache->bic_flags |= BLKID_BIC_FL_CHANGED;
 
80
        }
 
81
 
 
82
        if (flags & BLKID_DEV_VERIFY) {
 
83
                dev = blkid_verify(cache, dev);
 
84
                if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED))
 
85
                        return dev;
 
86
                /*
 
87
                 * If the device is verified, then search the blkid
 
88
                 * cache for any entries that match on the type, uuid,
 
89
                 * and label, and verify them; if a cache entry can
 
90
                 * not be verified, then it's stale and so we remove
 
91
                 * it.
 
92
                 */
 
93
                list_for_each_safe(p, pnext, &cache->bic_devs) {
 
94
                        blkid_dev dev2;
 
95
                        if (!p)
 
96
                                break;
 
97
                        dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
 
98
                        if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
 
99
                                continue;
 
100
                        if (!dev->bid_type || !dev2->bid_type ||
 
101
                            strcmp(dev->bid_type, dev2->bid_type))
 
102
                                continue;
 
103
                        if (dev->bid_label && dev2->bid_label &&
 
104
                            strcmp(dev->bid_label, dev2->bid_label))
 
105
                                continue;
 
106
                        if (dev->bid_uuid && dev2->bid_uuid &&
 
107
                            strcmp(dev->bid_uuid, dev2->bid_uuid))
 
108
                                continue;
 
109
                        if ((dev->bid_label && !dev2->bid_label) ||
 
110
                            (!dev->bid_label && dev2->bid_label) ||
 
111
                            (dev->bid_uuid && !dev2->bid_uuid) ||
 
112
                            (!dev->bid_uuid && dev2->bid_uuid))
 
113
                                continue;
 
114
                        dev2 = blkid_verify(cache, dev2);
 
115
                        if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED))
 
116
                                blkid_free_dev(dev2);
 
117
                }
 
118
        }
 
119
        return dev;
 
120
}
 
121
 
 
122
/* Directories where we will try to search for device names */
 
123
static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL };
 
124
 
 
125
static int is_dm_leaf(const char *devname)
 
126
{
 
127
        struct dirent   *de, *d_de;
 
128
        DIR             *dir, *d_dir;
 
129
        char            path[256];
 
130
        int             ret = 1;
 
131
 
 
132
        if ((dir = opendir("/sys/block")) == NULL)
 
133
                return 0;
 
134
        while ((de = readdir(dir)) != NULL) {
 
135
                if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
 
136
                    !strcmp(de->d_name, devname) ||
 
137
                    strncmp(de->d_name, "dm-", 3) ||
 
138
                    strlen(de->d_name) > sizeof(path)-32)
 
139
                        continue;
 
140
                sprintf(path, "/sys/block/%s/slaves", de->d_name);
 
141
                if ((d_dir = opendir(path)) == NULL)
 
142
                        continue;
 
143
                while ((d_de = readdir(d_dir)) != NULL) {
 
144
                        if (!strcmp(d_de->d_name, devname)) {
 
145
                                ret = 0;
 
146
                                break;
 
147
                        }
 
148
                }
 
149
                closedir(d_dir);
 
150
                if (!ret)
 
151
                        break;
 
152
        }
 
153
        closedir(dir);
 
154
        return ret;
 
155
}
 
156
 
 
157
/*
 
158
 * Probe a single block device to add to the device cache.
 
159
 */
 
160
static void probe_one(blkid_cache cache, const char *ptname,
 
161
                      dev_t devno, int pri, int only_if_new, int removable)
 
162
{
 
163
        blkid_dev dev = NULL;
 
164
        struct list_head *p, *pnext;
 
165
        const char **dir;
 
166
        char *devname = NULL;
 
167
 
 
168
        /* See if we already have this device number in the cache. */
 
169
        list_for_each_safe(p, pnext, &cache->bic_devs) {
 
170
                blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
 
171
                                           bid_devs);
 
172
                if (tmp->bid_devno == devno) {
 
173
                        if (only_if_new && !access(tmp->bid_name, F_OK))
 
174
                                return;
 
175
                        dev = blkid_verify(cache, tmp);
 
176
                        if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
 
177
                                break;
 
178
                        dev = 0;
 
179
                }
 
180
        }
 
181
        if (dev && dev->bid_devno == devno)
 
182
                goto set_pri;
 
183
 
 
184
        /* Try to translate private device-mapper dm-<N> names
 
185
         * to standard /dev/mapper/<name>.
 
186
         */
 
187
        if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
 
188
                devname = canonicalize_dm_name(ptname);
 
189
                if (!devname)
 
190
                        blkid__scan_dir("/dev/mapper", devno, 0, &devname);
 
191
                if (devname)
 
192
                        goto get_dev;
 
193
        }
 
194
 
 
195
        /*
 
196
         * Take a quick look at /dev/ptname for the device number.  We check
 
197
         * all of the likely device directories.  If we don't find it, or if
 
198
         * the stat information doesn't check out, use blkid_devno_to_devname()
 
199
         * to find it via an exhaustive search for the device major/minor.
 
200
         */
 
201
        for (dir = dirlist; *dir; dir++) {
 
202
                struct stat st;
 
203
                char device[256];
 
204
 
 
205
                sprintf(device, "%s/%s", *dir, ptname);
 
206
                if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
 
207
                    dev->bid_devno == devno)
 
208
                        goto set_pri;
 
209
 
 
210
                if (stat(device, &st) == 0 &&
 
211
                    (S_ISBLK(st.st_mode) ||
 
212
                     (S_ISCHR(st.st_mode) && !strncmp(ptname, "ubi", 3))) &&
 
213
                    st.st_rdev == devno) {
 
214
                        devname = blkid_strdup(device);
 
215
                        goto get_dev;
 
216
                }
 
217
        }
 
218
        /* Do a short-cut scan of /dev/mapper first */
 
219
        if (!devname)
 
220
                blkid__scan_dir("/dev/mapper", devno, 0, &devname);
 
221
        if (!devname) {
 
222
                devname = blkid_devno_to_devname(devno);
 
223
                if (!devname)
 
224
                        return;
 
225
        }
 
226
 
 
227
get_dev:
 
228
        dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
 
229
        free(devname);
 
230
 
 
231
set_pri:
 
232
        if (dev) {
 
233
                if (pri)
 
234
                        dev->bid_pri = pri;
 
235
                else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) {
 
236
                        dev->bid_pri = BLKID_PRI_DM;
 
237
                        if (is_dm_leaf(ptname))
 
238
                                dev->bid_pri += 5;
 
239
                } else if (!strncmp(ptname, "md", 2))
 
240
                        dev->bid_pri = BLKID_PRI_MD;
 
241
                if (removable)
 
242
                        dev->bid_flags |= BLKID_BID_FL_REMOVABLE;
 
243
        }
 
244
        return;
 
245
}
 
246
 
 
247
#define PROC_PARTITIONS "/proc/partitions"
 
248
#define VG_DIR          "/proc/lvm/VGs"
 
249
 
 
250
/*
 
251
 * This function initializes the UUID cache with devices from the LVM
 
252
 * proc hierarchy.  We currently depend on the names of the LVM
 
253
 * hierarchy giving us the device structure in /dev.  (XXX is this a
 
254
 * safe thing to do?)
 
255
 */
 
256
#ifdef VG_DIR
 
257
static dev_t lvm_get_devno(const char *lvm_device)
 
258
{
 
259
        FILE *lvf;
 
260
        char buf[1024];
 
261
        int ma, mi;
 
262
        dev_t ret = 0;
 
263
 
 
264
        DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
 
265
        if ((lvf = fopen(lvm_device, "r")) == NULL) {
 
266
                DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
 
267
                                          strerror(errno)));
 
268
                return 0;
 
269
        }
 
270
 
 
271
        while (fgets(buf, sizeof(buf), lvf)) {
 
272
                if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
 
273
                        ret = makedev(ma, mi);
 
274
                        break;
 
275
                }
 
276
        }
 
277
        fclose(lvf);
 
278
 
 
279
        return ret;
 
280
}
 
281
 
 
282
static void lvm_probe_all(blkid_cache cache, int only_if_new)
 
283
{
 
284
        DIR             *vg_list;
 
285
        struct dirent   *vg_iter;
 
286
        int             vg_len = strlen(VG_DIR);
 
287
        dev_t           dev;
 
288
 
 
289
        if ((vg_list = opendir(VG_DIR)) == NULL)
 
290
                return;
 
291
 
 
292
        DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
 
293
 
 
294
        while ((vg_iter = readdir(vg_list)) != NULL) {
 
295
                DIR             *lv_list;
 
296
                char            *vdirname;
 
297
                char            *vg_name;
 
298
                struct dirent   *lv_iter;
 
299
 
 
300
                vg_name = vg_iter->d_name;
 
301
                if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
 
302
                        continue;
 
303
                vdirname = malloc(vg_len + strlen(vg_name) + 8);
 
304
                if (!vdirname)
 
305
                        goto exit;
 
306
                sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
 
307
 
 
308
                lv_list = opendir(vdirname);
 
309
                free(vdirname);
 
310
                if (lv_list == NULL)
 
311
                        continue;
 
312
 
 
313
                while ((lv_iter = readdir(lv_list)) != NULL) {
 
314
                        char            *lv_name, *lvm_device;
 
315
 
 
316
                        lv_name = lv_iter->d_name;
 
317
                        if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
 
318
                                continue;
 
319
 
 
320
                        lvm_device = malloc(vg_len + strlen(vg_name) +
 
321
                                            strlen(lv_name) + 8);
 
322
                        if (!lvm_device) {
 
323
                                closedir(lv_list);
 
324
                                goto exit;
 
325
                        }
 
326
                        sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
 
327
                                lv_name);
 
328
                        dev = lvm_get_devno(lvm_device);
 
329
                        sprintf(lvm_device, "%s/%s", vg_name, lv_name);
 
330
                        DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
 
331
                                                  lvm_device,
 
332
                                                  (unsigned int) dev));
 
333
                        probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
 
334
                                  only_if_new, 0);
 
335
                        free(lvm_device);
 
336
                }
 
337
                closedir(lv_list);
 
338
        }
 
339
exit:
 
340
        closedir(vg_list);
 
341
}
 
342
#endif
 
343
 
 
344
#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
 
345
 
 
346
static int
 
347
evms_probe_all(blkid_cache cache, int only_if_new)
 
348
{
 
349
        char line[100];
 
350
        int ma, mi, sz, num = 0;
 
351
        FILE *procpt;
 
352
        char device[110];
 
353
 
 
354
        procpt = fopen(PROC_EVMS_VOLUMES, "r");
 
355
        if (!procpt)
 
356
                return 0;
 
357
        while (fgets(line, sizeof(line), procpt)) {
 
358
                if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
 
359
                            &ma, &mi, &sz, device) != 4)
 
360
                        continue;
 
361
 
 
362
                DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
 
363
                                          device, ma, mi));
 
364
 
 
365
                probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
 
366
                          only_if_new, 0);
 
367
                num++;
 
368
        }
 
369
        fclose(procpt);
 
370
        return num;
 
371
}
 
372
 
 
373
static void
 
374
ubi_probe_all(blkid_cache cache, int only_if_new)
 
375
{
 
376
        const char **dirname;
 
377
 
 
378
        for (dirname = dirlist; *dirname; dirname++) {
 
379
                DBG(DEBUG_DEVNAME, printf("probing UBI volumes under %s\n",
 
380
                                          *dirname));
 
381
 
 
382
                DIR             *dir;
 
383
                struct dirent   *iter;
 
384
 
 
385
                dir = opendir(*dirname);
 
386
                if (dir == NULL)
 
387
                        continue ;
 
388
 
 
389
                while ((iter = readdir(dir)) != NULL) {
 
390
                        char            *name;
 
391
                        struct stat     st;
 
392
                        dev_t           dev;
 
393
 
 
394
                        name = iter->d_name;
 
395
#ifdef _DIRENT_HAVE_D_TYPE
 
396
                        if (iter->d_type != DT_UNKNOWN &&
 
397
                            iter->d_type != DT_CHR && iter->d_type != DT_LNK)
 
398
                                continue;
 
399
#endif
 
400
                        if (!strcmp(name, ".") || !strcmp(name, "..") ||
 
401
                            !strstr(name, "ubi"))
 
402
                                continue;
 
403
                        if (!strcmp(name, "ubi_ctrl"))
 
404
                                continue;
 
405
                        if (fstat_at(dirfd(dir), *dirname, name, &st, 0))
 
406
                                continue;
 
407
 
 
408
                        dev = st.st_rdev;
 
409
 
 
410
                        if (!S_ISCHR(st.st_mode) || !minor(dev))
 
411
                                continue;
 
412
                        DBG(DEBUG_DEVNAME, printf("UBI vol %s/%s: devno 0x%04X\n",
 
413
                                  *dirname, name, (int) dev));
 
414
                        probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new, 0);
 
415
                }
 
416
                closedir(dir);
 
417
        }
 
418
}
 
419
 
 
420
/*
 
421
 * Read the device data for all available block devices in the system.
 
422
 */
 
423
static int probe_all(blkid_cache cache, int only_if_new)
 
424
{
 
425
        FILE *proc;
 
426
        char line[1024];
 
427
        char ptname0[128], ptname1[128], *ptname = 0;
 
428
        char *ptnames[2];
 
429
        dev_t devs[2];
 
430
        int ma, mi;
 
431
        unsigned long long sz;
 
432
        int lens[2] = { 0, 0 };
 
433
        int which = 0, last = 0;
 
434
        struct list_head *p, *pnext;
 
435
 
 
436
        ptnames[0] = ptname0;
 
437
        ptnames[1] = ptname1;
 
438
 
 
439
        if (!cache)
 
440
                return -BLKID_ERR_PARAM;
 
441
 
 
442
        if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
 
443
            time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
 
444
                return 0;
 
445
 
 
446
        blkid_read_cache(cache);
 
447
        evms_probe_all(cache, only_if_new);
 
448
#ifdef VG_DIR
 
449
        lvm_probe_all(cache, only_if_new);
 
450
#endif
 
451
        ubi_probe_all(cache, only_if_new);
 
452
 
 
453
        proc = fopen(PROC_PARTITIONS, "r");
 
454
        if (!proc)
 
455
                return -BLKID_ERR_PROC;
 
456
 
 
457
        while (fgets(line, sizeof(line), proc)) {
 
458
                last = which;
 
459
                which ^= 1;
 
460
                ptname = ptnames[which];
 
461
 
 
462
                if (sscanf(line, " %d %d %llu %128[^\n ]",
 
463
                           &ma, &mi, &sz, ptname) != 4)
 
464
                        continue;
 
465
                devs[which] = makedev(ma, mi);
 
466
 
 
467
                DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
 
468
 
 
469
                /* Skip whole disk devs unless they have no partitions.
 
470
                 * If base name of device has changed, also
 
471
                 * check previous dev to see if it didn't have a partn.
 
472
                 * heuristic: partition name ends in a digit, & partition
 
473
                 * names contain whole device name as substring.
 
474
                 *
 
475
                 * Skip extended partitions.
 
476
                 * heuristic: size is 1
 
477
                 *
 
478
                 * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
 
479
                 */
 
480
 
 
481
                lens[which] = strlen(ptname);
 
482
 
 
483
                /* ends in a digit, clearly a partition, so check */
 
484
                if (isdigit(ptname[lens[which] - 1])) {
 
485
                        DBG(DEBUG_DEVNAME,
 
486
                            printf("partition dev %s, devno 0x%04X\n",
 
487
                                   ptname, (unsigned int) devs[which]));
 
488
 
 
489
                        if (sz > 1)
 
490
                                probe_one(cache, ptname, devs[which], 0,
 
491
                                          only_if_new, 0);
 
492
                        lens[which] = 0;        /* mark as checked */
 
493
                }
 
494
 
 
495
                /*
 
496
                 * If last was a whole disk and we just found a partition
 
497
                 * on it, remove the whole-disk dev from the cache if
 
498
                 * it exists.
 
499
                 */
 
500
                if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
 
501
                        list_for_each_safe(p, pnext, &cache->bic_devs) {
 
502
                                blkid_dev tmp;
 
503
 
 
504
                                /* find blkid dev for the whole-disk devno */
 
505
                                tmp = list_entry(p, struct blkid_struct_dev,
 
506
                                                 bid_devs);
 
507
                                if (tmp->bid_devno == devs[last]) {
 
508
                                        DBG(DEBUG_DEVNAME,
 
509
                                                printf("freeing %s\n",
 
510
                                                       tmp->bid_name));
 
511
                                        blkid_free_dev(tmp);
 
512
                                        cache->bic_flags |= BLKID_BIC_FL_CHANGED;
 
513
                                        break;
 
514
                                }
 
515
                        }
 
516
                        lens[last] = 0;
 
517
                }
 
518
                /*
 
519
                 * If last was not checked because it looked like a whole-disk
 
520
                 * dev, and the device's base name has changed,
 
521
                 * check last as well.
 
522
                 */
 
523
                if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
 
524
                        DBG(DEBUG_DEVNAME,
 
525
                            printf("whole dev %s, devno 0x%04X\n",
 
526
                                   ptnames[last], (unsigned int) devs[last]));
 
527
                        probe_one(cache, ptnames[last], devs[last], 0,
 
528
                                  only_if_new, 0);
 
529
                        lens[last] = 0;
 
530
                }
 
531
        }
 
532
 
 
533
        /* Handle the last device if it wasn't partitioned */
 
534
        if (lens[which])
 
535
                probe_one(cache, ptname, devs[which], 0, only_if_new, 0);
 
536
 
 
537
        fclose(proc);
 
538
        blkid_flush_cache(cache);
 
539
        return 0;
 
540
}
 
541
 
 
542
/* Don't use it by default -- it's pretty slow (because cdroms, floppy, ...)
 
543
 */
 
544
static int probe_all_removable(blkid_cache cache)
 
545
{
 
546
        DIR *dir;
 
547
        struct dirent *d;
 
548
 
 
549
        if (!cache)
 
550
                return -BLKID_ERR_PARAM;
 
551
 
 
552
        dir = opendir(_PATH_SYS_BLOCK);
 
553
        if (!dir)
 
554
                return -BLKID_ERR_PROC;
 
555
 
 
556
        while((d = readdir(dir))) {
 
557
                struct sysfs_cxt sysfs;
 
558
                int removable = 0;
 
559
                dev_t devno;
 
560
 
 
561
#ifdef _DIRENT_HAVE_D_TYPE
 
562
                if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK)
 
563
                        continue;
 
564
#endif
 
565
                if (d->d_name[0] == '.' &&
 
566
                    ((d->d_name[1] == 0) ||
 
567
                     ((d->d_name[1] == '.') && (d->d_name[2] == 0))))
 
568
                        continue;
 
569
 
 
570
                devno = sysfs_devname_to_devno(d->d_name, NULL);
 
571
                if (!devno)
 
572
                        continue;
 
573
 
 
574
                if (sysfs_init(&sysfs, devno, NULL) == 0) {
 
575
                        sysfs_read_int(&sysfs, "removable", &removable);
 
576
                        sysfs_deinit(&sysfs);
 
577
                }
 
578
 
 
579
                if (removable)
 
580
                        probe_one(cache, d->d_name, devno, 0, 0, 1);
 
581
        }
 
582
 
 
583
        closedir(dir);
 
584
        return 0;
 
585
}
 
586
 
 
587
 
 
588
/**
 
589
 * blkid_probe_all:
 
590
 * @cache: cache handler
 
591
 *
 
592
 * Probes all block devices.
 
593
 *
 
594
 * Returns: 0 on success, or number less than zero in case of error.
 
595
 */
 
596
int blkid_probe_all(blkid_cache cache)
 
597
{
 
598
        int ret;
 
599
 
 
600
        DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
 
601
        ret = probe_all(cache, 0);
 
602
        cache->bic_time = time(0);
 
603
        cache->bic_flags |= BLKID_BIC_FL_PROBED;
 
604
        DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
 
605
        return ret;
 
606
}
 
607
 
 
608
/**
 
609
 * blkid_probe_all_new:
 
610
 * @cache: cache handler
 
611
 *
 
612
 * Probes all new block devices.
 
613
 *
 
614
 * Returns: 0 on success, or number less than zero in case of error.
 
615
 */
 
616
int blkid_probe_all_new(blkid_cache cache)
 
617
{
 
618
        int ret;
 
619
 
 
620
        DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
 
621
        ret = probe_all(cache, 1);
 
622
        DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
 
623
        return ret;
 
624
}
 
625
 
 
626
/**
 
627
 * blkid_probe_all_removable:
 
628
 * @cache: cache handler
 
629
 *
 
630
 * The libblkid probing is based on devices from /proc/partitions by default.
 
631
 * This file usually does not contain removable devices (e.g. CDROMs) and this kind
 
632
 * of devices are invisible for libblkid.
 
633
 *
 
634
 * This function adds removable block devices to @cache (probing is based on
 
635
 * information from the /sys directory). Don't forget that removable devices
 
636
 * (floppies, CDROMs, ...) could be pretty slow. It's very bad idea to call
 
637
 * this function by default.
 
638
 *
 
639
 * Note that devices which were detected by this function won't be written to
 
640
 * blkid.tab cache file.
 
641
 *
 
642
 * Returns: 0 on success, or number less than zero in case of error.
 
643
 */
 
644
int blkid_probe_all_removable(blkid_cache cache)
 
645
{
 
646
        int ret;
 
647
 
 
648
        DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_removable()\n"));
 
649
        ret = probe_all_removable(cache);
 
650
        DBG(DEBUG_PROBE, printf("End blkid_probe_all_removable()\n"));
 
651
        return ret;
 
652
}
 
653
 
 
654
#ifdef TEST_PROGRAM
 
655
int main(int argc, char **argv)
 
656
{
 
657
        blkid_cache cache = NULL;
 
658
        int ret;
 
659
 
 
660
        blkid_init_debug(DEBUG_ALL);
 
661
        if (argc != 1) {
 
662
                fprintf(stderr, "Usage: %s\n"
 
663
                        "Probe all devices and exit\n", argv[0]);
 
664
                exit(1);
 
665
        }
 
666
        if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
 
667
                fprintf(stderr, "%s: error creating cache (%d)\n",
 
668
                        argv[0], ret);
 
669
                exit(1);
 
670
        }
 
671
        if (blkid_probe_all(cache) < 0)
 
672
                printf("%s: error probing devices\n", argv[0]);
 
673
 
 
674
        if (blkid_probe_all_removable(cache) < 0)
 
675
                printf("%s: error probing removable devices\n", argv[0]);
 
676
 
 
677
        blkid_put_cache(cache);
 
678
        return (0);
 
679
}
 
680
#endif