2
* Low-level libblkid probing API
4
* Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
6
* This file may be redistributed under the terms of the
7
* GNU Lesser General Public License.
12
* @title: Low-level probing
13
* @short_description: low-level prober initialization
15
* The low-level probing routines always and directly read information from
16
* the selected (see blkid_probe_set_device()) device.
18
* The probing routines are grouped together into separate chains. Currently,
19
* the library provides superblocks, partitions and topology chains.
21
* The probing routines is possible to filter (enable/disable) by type (e.g.
22
* fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID).
23
* These filters are per-chain. Note that always when you touch the chain
24
* filter the current probing position is reseted and probing starts from
25
* scratch. It means that the chain filter should not be modified during
26
* probing, for example in loop where you call blkid_do_probe().
28
* For more details see the chain specific documentation.
30
* The low-level API provides two ways how access to probing results.
32
* 1. The NAME=value (tag) interface. This interface is older and returns all data
33
* as strings. This interface is generic for all chains.
35
* 2. The binary interfaces. These interfaces return data in the native formats.
36
* The interface is always specific to the probing chain.
38
* Note that the previous probing result (binary or NAME=value) is always
39
* zeroized when a chain probing function is called. For example
43
* blkid_probe_enable_partitions(pr, TRUE);
44
* blkid_probe_enable_superblocks(pr, FALSE);
46
* blkid_do_safeprobe(pr);
50
* overwrites the previous probing result for the partitions chain, the superblocks
51
* result is not modified.
55
* SECTION: lowprobe-tags
56
* @title: Low-level tags
57
* @short_description: generic NAME=value interface.
59
* The probing routines inside the chain are mutually exclusive by default --
60
* only few probing routines are marked as "tolerant". The "tolerant" probing
61
* routines are used for filesystem which can share the same device with any
62
* other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag.
64
* The SUPERBLOCKS chain is enabled by default. The all others chains is
65
* necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific
68
* The blkid_do_probe() function returns a result from only one probing
69
* routine, and the next call from the next probing routine. It means you need
70
* to call the function in loop, for example:
74
* while((blkid_do_probe(pr) == 0)
79
* The blkid_do_safeprobe() is the same as blkid_do_probe(), but returns only
80
* first probing result for every enabled chain. This function checks for
81
* ambivalent results (e.g. more "intolerant" filesystems superblocks on the
84
* The probing result is set of NAME=value pairs (the NAME is always unique).
93
#include <sys/types.h>
94
#ifdef HAVE_LINUX_CDROM_H
95
#include <linux/cdrom.h>
97
#ifdef HAVE_SYS_STAT_H
103
#include <inttypes.h>
114
extern const struct blkid_chaindrv superblocks_drv;
115
extern const struct blkid_chaindrv topology_drv;
116
extern const struct blkid_chaindrv partitions_drv;
119
* All supported chains
121
static const struct blkid_chaindrv *chains_drvs[] = {
122
[BLKID_CHAIN_SUBLKS] = &superblocks_drv,
123
[BLKID_CHAIN_TOPLGY] = &topology_drv,
124
[BLKID_CHAIN_PARTS] = &partitions_drv
127
static void blkid_probe_reset_vals(blkid_probe pr);
128
static void blkid_probe_reset_buffer(blkid_probe pr);
133
* Returns: a pointer to the newly allocated probe struct.
135
blkid_probe blkid_new_probe(void)
141
pr = calloc(1, sizeof(struct blkid_struct_probe));
145
DBG(DEBUG_LOWPROBE, printf("allocate a new probe %p\n", pr));
147
/* initialize chains */
148
for (i = 0; i < BLKID_NCHAINS; i++) {
149
pr->chains[i].driver = chains_drvs[i];
150
pr->chains[i].flags = chains_drvs[i]->dflt_flags;
151
pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
153
INIT_LIST_HEAD(&pr->buffers);
158
* Clone @parent, the new clone shares all, but except:
161
* - bufferes if another device (or offset) is set to the prober
163
blkid_probe blkid_clone_probe(blkid_probe parent)
170
DBG(DEBUG_LOWPROBE, printf("allocate a probe clone\n"));
172
pr = blkid_new_probe();
177
pr->off = parent->off;
178
pr->size = parent->size;
179
pr->devno = parent->devno;
180
pr->disk_devno = parent->disk_devno;
181
pr->blkssz = parent->blkssz;
182
pr->flags = parent->flags;
191
* blkid_new_probe_from_filename:
192
* @filename: device or regular file
194
* This function is same as call open(filename), blkid_new_probe() and
195
* blkid_probe_set_device(pr, fd, 0, 0).
197
* The @filename is closed by blkid_free_probe() or by the
198
* blkid_probe_set_device() call.
200
* Returns: a pointer to the newly allocated probe struct or NULL in case of
203
blkid_probe blkid_new_probe_from_filename(const char *filename)
206
blkid_probe pr = NULL;
211
fd = open(filename, O_RDONLY);
215
pr = blkid_new_probe();
219
if (blkid_probe_set_device(pr, fd, 0, 0))
222
pr->flags |= BLKID_FL_PRIVATE_FD;
227
blkid_free_probe(pr);
235
* Deallocates the probe struct, buffers and all allocated
236
* data that are associated with this probing control struct.
238
void blkid_free_probe(blkid_probe pr)
245
for (i = 0; i < BLKID_NCHAINS; i++) {
246
struct blkid_chain *ch = &pr->chains[i];
248
if (ch->driver->free_data)
249
ch->driver->free_data(pr, ch->data);
253
if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
255
blkid_probe_reset_buffer(pr);
256
blkid_free_probe(pr->disk_probe);
258
DBG(DEBUG_LOWPROBE, printf("free probe %p\n", pr));
264
* Removes chain values from probing result.
266
void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn)
268
int nvals = pr->nvals;
271
for (x = 0, i = 0; i < pr->nvals; i++) {
272
struct blkid_prval *v = &pr->vals[i];
274
if (v->chain != chn && x == i) {
278
if (v->chain == chn) {
282
memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval));
287
static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
294
* Copies chain values from probing result to @vals, the max size of @vals is
295
* @nvals and returns real number of values.
297
int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn,
298
struct blkid_prval *vals, int nvals)
302
for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) {
303
struct blkid_prval *v = &pr->vals[i];
307
memcpy(&vals[x++], v, sizeof(struct blkid_prval));
313
* Appends values from @vals to the probing result
315
void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals)
319
while (i < nvals && pr->nvals < BLKID_NVALS) {
320
memcpy(&pr->vals[pr->nvals++], &vals[i++],
321
sizeof(struct blkid_prval));
325
static void blkid_probe_reset_vals(blkid_probe pr)
327
memset(pr->vals, 0, sizeof(pr->vals));
331
struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
333
return pr->cur_chain;
336
void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
338
int rc, org_prob_flags;
339
struct blkid_chain *org_chn;
344
/* save the current setting -- the binary API has to be completely
345
* independent on the current probing status
347
org_chn = pr->cur_chain;
348
org_prob_flags = pr->prob_flags;
353
blkid_probe_chain_reset_position(chn);
355
rc = chn->driver->probe(pr, chn);
358
blkid_probe_chain_reset_position(chn);
360
/* restore the original setting
362
pr->cur_chain = org_chn;
363
pr->prob_flags = org_prob_flags;
369
printf("returning %s binary data\n", chn->driver->name));
378
* Zeroize probing results and resets the current probing (this has impact to
379
* blkid_do_probe() only). This function does not touch probing filters and
380
* keeps assigned device.
382
void blkid_reset_probe(blkid_probe pr)
389
blkid_probe_reset_vals(pr);
391
pr->cur_chain = NULL;
393
for (i = 0; i < BLKID_NCHAINS; i++)
394
blkid_probe_chain_reset_position(&pr->chains[i]);
398
static int blkid_probe_dump_filter(blkid_probe pr, int chain)
400
struct blkid_chain *chn;
403
if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
406
chn = &pr->chains[chain];
411
for (i = 0; i < chn->driver->nidinfos; i++) {
412
const struct blkid_idinfo *id = chn->driver->idinfos[i];
414
DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n",
417
blkid_bmp_get_item(chn->fltr, i)
418
? "disabled" : "enabled <--"));
425
* Returns properly initialized chain filter
427
unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
429
struct blkid_chain *chn;
431
if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
434
chn = &pr->chains[chain];
436
/* always when you touch the chain filter all indexes are reseted and
437
* probing starts from scratch
439
blkid_probe_chain_reset_position(chn);
440
pr->cur_chain = NULL;
442
if (!chn->driver->has_fltr || (!chn->fltr && !create))
446
chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
448
memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));
450
/* blkid_probe_dump_filter(pr, chain); */
455
* Generic private functions for filter setting
457
int __blkid_probe_invert_filter(blkid_probe pr, int chain)
460
struct blkid_chain *chn;
462
chn = &pr->chains[chain];
464
if (!chn->driver->has_fltr || !chn->fltr)
467
for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
468
chn->fltr[i] = ~chn->fltr[i];
470
DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n"));
471
/* blkid_probe_dump_filter(pr, chain); */
475
int __blkid_probe_reset_filter(blkid_probe pr, int chain)
477
return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
480
int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
483
struct blkid_chain *chn;
486
fltr = blkid_probe_get_filter(pr, chain, TRUE);
490
chn = &pr->chains[chain];
492
for (i = 0; i < chn->driver->nidinfos; i++) {
494
const struct blkid_idinfo *id = chn->driver->idinfos[i];
497
for (n = names; *n; n++) {
498
if (!strcmp(id->name, *n)) {
503
if (flag & BLKID_FLTR_ONLYIN) {
505
blkid_bmp_set_item(fltr, i);
506
} else if (flag & BLKID_FLTR_NOTIN) {
508
blkid_bmp_set_item(fltr, i);
513
printf("%s: a new probing type-filter initialized\n",
515
/* blkid_probe_dump_filter(pr, chain); */
519
unsigned char *blkid_probe_get_buffer(blkid_probe pr,
520
blkid_loff_t off, blkid_loff_t len)
523
struct blkid_bufinfo *bf = NULL;
529
pr->parent->devno == pr->devno &&
530
pr->parent->off <= pr->off &&
531
pr->parent->off + pr->parent->size >= pr->off + pr->size) {
533
* This is a cloned prober and points to the same area as
534
* parent. Let's use parent's buffers.
536
* Note that pr->off (and pr->parent->off) is always from the
537
* beginig of the device.
539
return blkid_probe_get_buffer(pr->parent,
540
pr->off + off - pr->parent->off, len);
543
list_for_each(p, &pr->buffers) {
544
struct blkid_bufinfo *x =
545
list_entry(p, struct blkid_bufinfo, bufs);
547
if (x->off <= off && off + len <= x->off + x->len) {
549
printf("\treuse buffer: off=%jd len=%jd pr=%p\n",
550
x->off, x->len, pr));
558
if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0)
561
/* allocate info and space for data by why call */
562
bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
566
bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
569
INIT_LIST_HEAD(&bf->bufs);
572
printf("\tbuffer read: off=%jd len=%jd pr=%p\n",
575
ret = read(pr->fd, bf->data, len);
576
if (ret != (ssize_t) len) {
580
list_add_tail(&bf->bufs, &pr->buffers);
583
return off ? bf->data + (off - bf->off) : bf->data;
587
static void blkid_probe_reset_buffer(blkid_probe pr)
589
uint64_t read_ct = 0, len_ct = 0;
591
if (!pr || list_empty(&pr->buffers))
594
DBG(DEBUG_LOWPROBE, printf("reseting probing buffers pr=%p\n", pr));
596
while (!list_empty(&pr->buffers)) {
597
struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
598
struct blkid_bufinfo, bufs);
606
printf("buffers summary: %"PRIu64" bytes "
607
"by %"PRIu64" read() call(s)\n",
610
INIT_LIST_HEAD(&pr->buffers);
614
* Small devices need a special care.
616
int blkid_probe_is_tiny(blkid_probe pr)
618
return pr && (pr->flags & BLKID_FL_TINY_DEV);
622
* CDROMs may fail when probed for RAID (last sector problem)
624
int blkid_probe_is_cdrom(blkid_probe pr)
626
return pr && (pr->flags & BLKID_FL_CDROM_DEV);
630
* blkid_probe_set_device:
632
* @fd: device file descriptor
633
* @off: begin of probing area
634
* @size: size of probing area (zero means whole device/file)
636
* Assigns the device to probe control struct, resets internal buffers and
637
* resets the current probing.
639
* Returns: -1 in case of failure, or 0 on success.
641
int blkid_probe_set_device(blkid_probe pr, int fd,
642
blkid_loff_t off, blkid_loff_t size)
649
blkid_reset_probe(pr);
650
blkid_probe_reset_buffer(pr);
652
if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
655
pr->flags &= ~BLKID_FL_PRIVATE_FD;
656
pr->flags &= ~BLKID_FL_TINY_DEV;
657
pr->flags &= ~BLKID_FL_CDROM_DEV;
668
pr->wipe_chain = NULL;
670
#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
671
/* Disable read-ahead */
672
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
677
if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode))
680
pr->mode = sb.st_mode;
681
if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
682
pr->devno = sb.st_rdev;
687
if (S_ISBLK(sb.st_mode)) {
688
if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) {
689
DBG(DEBUG_LOWPROBE, printf(
690
"failed to get device size\n"));
693
} else if (S_ISCHR(sb.st_mode))
694
pr->size = 1; /* UBI devices are char... */
695
else if (S_ISREG(sb.st_mode))
696
pr->size = sb.st_size; /* regular file */
698
if (pr->off > pr->size)
701
/* The probing area cannot be larger than whole device, pr->off
702
* is offset within the device */
706
if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
707
pr->flags |= BLKID_FL_TINY_DEV;
709
#ifdef CDROM_GET_CAPABILITY
710
if (S_ISBLK(sb.st_mode) && ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0)
711
pr->flags |= BLKID_FL_CDROM_DEV;
714
DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%jd, size=%jd\n",
716
DBG(DEBUG_LOWPROBE, printf("whole-disk: %s, regfile: %s\n",
717
blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
718
S_ISREG(pr->mode) ? "YES" : "NO"));
723
printf("failed to prepare a device for low-probing\n"));
728
int blkid_probe_get_dimension(blkid_probe pr,
729
blkid_loff_t *off, blkid_loff_t *size)
739
int blkid_probe_set_dimension(blkid_probe pr,
740
blkid_loff_t off, blkid_loff_t size)
745
DBG(DEBUG_LOWPROBE, printf(
746
"changing probing area pr=%p: size=%llu, off=%llu "
747
"-to-> size=%llu, off=%llu\n",
749
(unsigned long long) pr->size,
750
(unsigned long long) pr->off,
751
(unsigned long long) size,
752
(unsigned long long) off));
756
pr->flags &= ~BLKID_FL_TINY_DEV;
758
if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode))
759
pr->flags |= BLKID_FL_TINY_DEV;
761
blkid_probe_reset_buffer(pr);
766
int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
767
blkid_loff_t *offset, const struct blkid_idmag **res)
769
const struct blkid_idmag *mag = NULL;
770
blkid_loff_t off = 0;
773
mag = id->magics ? &id->magics[0] : NULL;
777
/* try to detect by magic string */
778
while(mag && mag->magic) {
781
off = (mag->kboff + (mag->sboff >> 10)) << 10;
782
buf = blkid_probe_get_buffer(pr, off, 1024);
784
if (buf && !memcmp(mag->magic,
785
buf + (mag->sboff & 0x3ff), mag->len)) {
786
DBG(DEBUG_LOWPROBE, printf(
787
"\tmagic sboff=%u, kboff=%ld\n",
788
mag->sboff, mag->kboff));
790
*offset = off + (mag->sboff & 0x3ff);
798
if (id->magics && id->magics[0].magic)
799
/* magic string(s) defined, but not found */
805
static inline void blkid_probe_start(blkid_probe pr)
808
pr->cur_chain = NULL;
810
blkid_probe_set_wiper(pr, 0, 0);
814
static inline void blkid_probe_end(blkid_probe pr)
817
pr->cur_chain = NULL;
819
blkid_probe_set_wiper(pr, 0, 0);
827
* Calls probing functions in all enabled chains. The superblocks chain is
828
* enabled by default. The blkid_do_probe() stores result from only one
829
* probing function. It's necessary to call this routine in a loop to get
830
* results from all probing functions in all chains. The probing is reseted
831
* by blkid_reset_probe() or by filter functions.
833
* This is string-based NAME=value interface only.
836
* <title>basic case - use the first result only</title>
839
* if (blkid_do_probe(pr) == 0) {
840
* int nvals = blkid_probe_numof_values(pr);
841
* for (n = 0; n < nvals; n++) {
842
* if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
843
* printf("%s = %s\n", name, data);
850
* <title>advanced case - probe for all signatures</title>
853
* while (blkid_do_probe(pr) == 0) {
854
* int nvals = blkid_probe_numof_values(pr);
860
* See also blkid_reset_probe().
862
* Returns: 0 on success, 1 when probing is done and -1 in case of error.
864
int blkid_do_probe(blkid_probe pr)
872
struct blkid_chain *chn = pr->cur_chain;
875
blkid_probe_start(pr);
876
chn = pr->cur_chain = &pr->chains[0];
878
/* we go to the next chain only when the previous probing
879
* result was nothing (rc == 1) and when the current chain is
880
* disabled or we are at end of the current chain (chain->idx +
881
* 1 == sizeof chain) or the current chain bailed out right at
882
* the start (chain->idx == -1)
884
else if (rc == 1 && (chn->enabled == FALSE ||
885
chn->idx + 1 == (int) chn->driver->nidinfos ||
888
size_t idx = chn->driver->id + 1;
890
if (idx < BLKID_NCHAINS)
891
chn = pr->cur_chain = &pr->chains[idx];
894
return 1; /* all chains already probed */
898
chn->binary = FALSE; /* for sure... */
900
DBG(DEBUG_LOWPROBE, printf("chain probe %s %s (idx=%d)\n",
902
chn->enabled? "ENABLED" : "DISABLED",
908
/* rc: -1 = error, 0 = success, 1 = no result */
909
rc = chn->driver->probe(pr, chn);
917
* blkid_do_safeprobe:
920
* This function gathers probing results from all enabled chains and checks
921
* for ambivalent results (e.g. more filesystems on the device).
923
* This is string-based NAME=value interface only.
925
* Note about suberblocks chain -- the function does not check for filesystems
926
* when a RAID signature is detected. The function also does not check for
927
* collision between RAIDs. The first detected RAID is returned. The function
928
* checks for collision between partition table and RAID signature -- it's
929
* recommended to enable partitions chain together with superblocks chain.
931
* Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
932
* detected and -1 on case of error.
934
int blkid_do_safeprobe(blkid_probe pr)
936
int i, count = 0, rc = 0;
941
blkid_probe_start(pr);
943
for (i = 0; i < BLKID_NCHAINS; i++) {
944
struct blkid_chain *chn;
946
chn = pr->cur_chain = &pr->chains[i];
947
chn->binary = FALSE; /* for sure... */
949
DBG(DEBUG_LOWPROBE, printf("chain safeprobe %s %s\n",
951
chn->enabled? "ENABLED" : "DISABLED"));
956
blkid_probe_chain_reset_position(chn);
958
rc = chn->driver->safeprobe(pr, chn);
960
blkid_probe_chain_reset_position(chn);
962
/* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
964
goto done; /* error */
966
count++; /* success */
973
return count ? 0 : 1;
977
* blkid_do_fullprobe:
980
* This function gathers probing results from all enabled chains. Same as
981
* blkid_do_safeprobe() but does not check for collision between probing
984
* This is string-based NAME=value interface only.
986
* Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
988
int blkid_do_fullprobe(blkid_probe pr)
990
int i, count = 0, rc = 0;
995
blkid_probe_start(pr);
997
for (i = 0; i < BLKID_NCHAINS; i++) {
999
struct blkid_chain *chn;
1001
chn = pr->cur_chain = &pr->chains[i];
1002
chn->binary = FALSE; /* for sure... */
1004
DBG(DEBUG_LOWPROBE, printf("chain fullprobe %s: %s\n",
1006
chn->enabled? "ENABLED" : "DISABLED"));
1011
blkid_probe_chain_reset_position(chn);
1013
rc = chn->driver->probe(pr, chn);
1015
blkid_probe_chain_reset_position(chn);
1017
/* rc: -1 = error, 0 = success, 1 = no result */
1019
goto done; /* error */
1021
count++; /* success */
1025
blkid_probe_end(pr);
1028
return count ? 0 : 1;
1031
/* same sa blkid_probe_get_buffer() but works with 512-sectors */
1032
unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
1034
return pr ? blkid_probe_get_buffer(pr,
1035
((blkid_loff_t) sector) << 9, 0x200) : NULL;
1038
struct blkid_prval *blkid_probe_assign_value(
1039
blkid_probe pr, const char *name)
1041
struct blkid_prval *v;
1045
if (pr->nvals >= BLKID_NVALS)
1048
v = &pr->vals[pr->nvals];
1050
v->chain = pr->cur_chain;
1054
printf("assigning %s [%s]\n", name, v->chain->driver->name));
1058
int blkid_probe_reset_last_value(blkid_probe pr)
1060
struct blkid_prval *v;
1062
if (pr == NULL || pr->nvals == 0)
1065
v = &pr->vals[pr->nvals - 1];
1068
printf("un-assigning %s [%s]\n", v->name, v->chain->driver->name));
1070
memset(v, 0, sizeof(struct blkid_prval));
1077
int blkid_probe_set_value(blkid_probe pr, const char *name,
1078
unsigned char *data, size_t len)
1080
struct blkid_prval *v;
1082
if (len > BLKID_PROBVAL_BUFSIZ)
1083
len = BLKID_PROBVAL_BUFSIZ;
1085
v = blkid_probe_assign_value(pr, name);
1089
memcpy(v->data, data, len);
1094
int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
1095
const char *fmt, va_list ap)
1097
struct blkid_prval *v;
1100
v = blkid_probe_assign_value(pr, name);
1104
len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap);
1107
blkid_probe_reset_last_value(pr);
1114
int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
1115
const char *fmt, ...)
1121
rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
1128
* blkid_probe_get_devno:
1131
* Returns: block device number, or 0 for regilar files.
1133
dev_t blkid_probe_get_devno(blkid_probe pr)
1139
* blkid_probe_get_wholedisk_devno:
1142
* Returns: device number of the wholedisk, or 0 for regilar files.
1144
dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
1146
if (!pr->disk_devno) {
1147
dev_t devno, disk_devno = 0;
1149
devno = blkid_probe_get_devno(pr);
1153
if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
1154
pr->disk_devno = disk_devno;
1156
return pr->disk_devno;
1160
* blkid_probe_is_wholedisk:
1163
* Returns: 1 if the device is whole-disk or 0.
1165
int blkid_probe_is_wholedisk(blkid_probe pr)
1167
dev_t devno, disk_devno;
1169
devno = blkid_probe_get_devno(pr);
1173
disk_devno = blkid_probe_get_wholedisk_devno(pr);
1177
return devno == disk_devno;
1180
blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
1184
if (blkid_probe_is_wholedisk(pr))
1185
return NULL; /* this is not partition */
1188
/* this is cloned blkid_probe, use parent's stuff */
1189
return blkid_probe_get_wholedisk_probe(pr->parent);
1191
disk = blkid_probe_get_wholedisk_devno(pr);
1193
if (pr->disk_probe && pr->disk_probe->devno != disk) {
1194
/* we have disk prober, but for another disk... close it */
1195
blkid_free_probe(pr->disk_probe);
1196
pr->disk_probe = NULL;
1199
if (!pr->disk_probe) {
1200
/* Open a new disk prober */
1201
char *disk_path = blkid_devno_to_devname(disk);
1206
DBG(DEBUG_LOWPROBE, printf("allocate a wholedisk probe\n"));
1208
pr->disk_probe = blkid_new_probe_from_filename(disk_path);
1209
if (!pr->disk_probe)
1210
return NULL; /* ENOMEM? */
1213
return pr->disk_probe;
1217
* blkid_probe_get_size:
1220
* This function returns size of probing area as defined by blkid_probe_set_device().
1221
* If the size of the probing area is unrestricted then this function returns
1222
* the real size of device. See also blkid_get_dev_size().
1224
* Returns: size in bytes or -1 in case of error.
1226
blkid_loff_t blkid_probe_get_size(blkid_probe pr)
1228
return pr ? pr->size : -1;
1232
* blkid_probe_get_offset:
1235
* This function returns offset of probing area as defined by blkid_probe_set_device().
1237
* Returns: offset in bytes or -1 in case of error.
1239
blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
1241
return pr ? pr->off : -1;
1245
* blkid_probe_get_fd:
1248
* Returns: file descriptor for assigned device/file.
1250
int blkid_probe_get_fd(blkid_probe pr)
1252
return pr ? pr->fd : -1;
1256
* blkid_probe_get_sectorsize:
1257
* @pr: probe or NULL (for NULL returns 512)
1259
* Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
1261
unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
1264
return DEFAULT_SECTOR_SIZE; /*... and good luck! */
1269
if (S_ISBLK(pr->mode) &&
1270
blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
1273
pr->blkssz = DEFAULT_SECTOR_SIZE;
1278
* blkid_probe_get_sectors:
1281
* Returns: 512-byte sector count or -1 in case of error.
1283
blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
1285
return pr ? pr->size >> 9 : -1;
1289
* blkid_probe_numof_values:
1292
* Returns: number of values in probing result or -1 in case of error.
1294
int blkid_probe_numof_values(blkid_probe pr)
1302
* blkid_probe_get_value:
1304
* @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
1305
* @name: pointer to return value name or NULL
1306
* @data: pointer to return value data or NULL
1307
* @len: pointer to return value length or NULL
1309
* Note, the @len returns length of the @data, including the terminating
1312
* Returns: 0 on success, or -1 in case of error.
1314
int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
1315
const char **data, size_t *len)
1317
struct blkid_prval *v = __blkid_probe_get_value(pr, num);
1324
*data = (char *) v->data;
1328
DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
1333
* blkid_probe_lookup_value:
1335
* @name: name of value
1336
* @data: pointer to return value data or NULL
1337
* @len: pointer to return value length or NULL
1339
* Note, the @len returns length of the @data, including the terminating
1342
* Returns: 0 on success, or -1 in case of error.
1344
int blkid_probe_lookup_value(blkid_probe pr, const char *name,
1345
const char **data, size_t *len)
1347
struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);
1352
*data = (char *) v->data;
1359
* blkid_probe_has_value:
1361
* @name: name of value
1363
* Returns: 1 if value exist in probing result, otherwise 0.
1365
int blkid_probe_has_value(blkid_probe pr, const char *name)
1367
if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
1372
struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
1374
if (pr == NULL || num < 0 || num >= pr->nvals)
1377
return &pr->vals[num];
1380
struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
1384
if (pr == NULL || pr->nvals == 0 || name == NULL)
1387
for (i = 0; i < pr->nvals; i++) {
1388
struct blkid_prval *v = &pr->vals[i];
1390
if (v->name && strcmp(name, v->name) == 0) {
1391
DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
1399
/* converts DCE UUID (uuid[16]) to human readable string
1400
* - the @len should be always 37 */
1402
void blkid_unparse_uuid(const unsigned char *uuid, char *str,
1403
size_t len __attribute__((__unused__)))
1405
uuid_unparse(uuid, str);
1408
void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
1411
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1412
uuid[0], uuid[1], uuid[2], uuid[3],
1416
uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
1421
/* Removes whitespace from the right-hand side of a string (trailing
1424
* Returns size of the new string (without \0).
1426
size_t blkid_rtrim_whitespace(unsigned char *str)
1428
size_t i = strlen((char *) str);
1431
if (!isspace(str[i]))
1439
* Some mkfs-like utils wipe some parts (usually begin) of the device.
1440
* For example LVM (pvcreate) or mkswap(8). This information could be used
1441
* for later resolution to conflicts between superblocks.
1443
* For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
1444
* the device. If we found another signature (for example MBR) this wiped area
1445
* then the signature has been added later and LVM superblock should be ignore.
1447
* Note that this heuristic is not 100% reliable, for example "pvcreate --zero
1448
* n" allows to keep the begin of the device unmodified. It's probably better
1449
* to use this heuristic for conflicts between superblocks and partition tables
1450
* than for conflicts between filesystem superblocks -- existence of unwanted
1451
* partition table is very unusual, because PT is pretty visible (parsed and
1452
* interpreted by kernel).
1454
void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
1456
struct blkid_chain *chn;
1462
DBG(DEBUG_LOWPROBE, printf("zeroize wiper\n"));
1463
pr->wipe_size = pr->wipe_off = 0;
1464
pr->wipe_chain = NULL;
1468
chn = pr->cur_chain;
1470
if (!chn || !chn->driver ||
1471
chn->idx < 0 || (size_t) chn->idx >= chn->driver->nidinfos)
1474
pr->wipe_size = size;
1476
pr->wipe_chain = chn;
1479
printf("wiper set to %s::%s off=%jd size=%jd\n",
1481
chn->driver->idinfos[chn->idx]->name,
1482
pr->wipe_off, pr->wipe_size));
1487
* Returns 1 if the <@off,@size> area was wiped
1489
int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn,
1490
blkid_loff_t off, blkid_loff_t size)
1495
if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
1497
*chn = pr->wipe_chain;
1503
void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
1505
struct blkid_chain *chn = NULL;
1507
if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
1508
DBG(DEBUG_LOWPROBE, printf("wiped area detected -- ignore previous results\n"));
1509
blkid_probe_set_wiper(pr, 0, 0);
1510
blkid_probe_chain_reset_vals(pr, chn);