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

« back to all changes in this revision

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