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
100 #ifdef HAVE_SYS_MKDEV_H
101 #include <sys/mkdev.h>
106 #include <inttypes.h>
111 # ifdef HAVE_UUID_UUID_H
112 # include <uuid/uuid.h>
122 extern const struct blkid_chaindrv superblocks_drv
;
123 extern const struct blkid_chaindrv topology_drv
;
124 extern const struct blkid_chaindrv partitions_drv
;
127 * All supported chains
129 static const struct blkid_chaindrv
*chains_drvs
[] = {
130 [BLKID_CHAIN_SUBLKS
] = &superblocks_drv
,
131 [BLKID_CHAIN_TOPLGY
] = &topology_drv
,
132 [BLKID_CHAIN_PARTS
] = &partitions_drv
135 static void blkid_probe_reset_vals(blkid_probe pr
);
136 static void blkid_probe_reset_buffer(blkid_probe pr
);
141 * Returns: a pointer to the newly allocated probe struct.
143 blkid_probe
blkid_new_probe(void)
149 pr
= calloc(1, sizeof(struct blkid_struct_probe
));
153 /* initialize chains */
154 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
155 pr
->chains
[i
].driver
= chains_drvs
[i
];
156 pr
->chains
[i
].flags
= chains_drvs
[i
]->dflt_flags
;
157 pr
->chains
[i
].enabled
= chains_drvs
[i
]->dflt_enabled
;
159 INIT_LIST_HEAD(&pr
->buffers
);
164 * blkid_new_probe_from_filename:
165 * @filename: device or regular file
167 * This function is same as call open(filename), blkid_new_probe() and
168 * blkid_probe_set_device(pr, fd, 0, 0).
170 * The @filename is closed by blkid_free_probe() or by the
171 * blkid_probe_set_device() call.
173 * Returns: a pointer to the newly allocated probe struct or NULL in case of
176 blkid_probe
blkid_new_probe_from_filename(const char *filename
)
179 blkid_probe pr
= NULL
;
184 fd
= open(filename
, O_RDONLY
);
188 pr
= blkid_new_probe();
192 if (blkid_probe_set_device(pr
, fd
, 0, 0))
195 pr
->flags
|= BLKID_PRIVATE_FD
;
200 blkid_free_probe(pr
);
208 * Deallocates the probe struct, buffers and all allocated
209 * data that are associated with this probing control struct.
211 void blkid_free_probe(blkid_probe pr
)
218 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
219 struct blkid_chain
*ch
= &pr
->chains
[i
];
221 if (ch
->driver
->free_data
)
222 ch
->driver
->free_data(pr
, ch
->data
);
226 if ((pr
->flags
& BLKID_PRIVATE_FD
) && pr
->fd
>= 0)
228 blkid_probe_reset_buffer(pr
);
234 * Removes chain values from probing result.
236 void blkid_probe_chain_reset_vals(blkid_probe pr
, struct blkid_chain
*chn
)
238 int nvals
= pr
->nvals
;
241 for (x
= 0, i
= 0; i
< pr
->nvals
; i
++) {
242 struct blkid_prval
*v
= &pr
->vals
[i
];
244 if (v
->chain
!= chn
&& x
== i
) {
248 if (v
->chain
== chn
) {
252 memcpy(&pr
->vals
[x
++], v
, sizeof(struct blkid_prval
));
257 static void blkid_probe_chain_reset_position(struct blkid_chain
*chn
)
264 * Copies chain values from probing result to @vals, the max size of @vals is
265 * @nvals and returns real number of values.
267 int blkid_probe_chain_copy_vals(blkid_probe pr
, struct blkid_chain
*chn
,
268 struct blkid_prval
*vals
, int nvals
)
272 for (x
= 0, i
= 0; i
< pr
->nvals
&& x
< nvals
; i
++) {
273 struct blkid_prval
*v
= &pr
->vals
[i
];
277 memcpy(&vals
[x
++], v
, sizeof(struct blkid_prval
));
283 * Appends values from @vals to the probing result
285 void blkid_probe_append_vals(blkid_probe pr
, struct blkid_prval
*vals
, int nvals
)
289 while (i
< nvals
&& pr
->nvals
< BLKID_NVALS
) {
290 memcpy(&pr
->vals
[pr
->nvals
++], &vals
[i
++],
291 sizeof(struct blkid_prval
));
295 static void blkid_probe_reset_vals(blkid_probe pr
)
297 memset(pr
->vals
, 0, sizeof(pr
->vals
));
301 struct blkid_chain
*blkid_probe_get_chain(blkid_probe pr
)
303 return pr
->cur_chain
;
306 void *blkid_probe_get_binary_data(blkid_probe pr
, struct blkid_chain
*chn
)
308 int rc
, org_prob_flags
;
309 struct blkid_chain
*org_chn
;
314 /* save the current setting -- the binary API has to be completely
315 * independent on the current probing status
317 org_chn
= pr
->cur_chain
;
318 org_prob_flags
= pr
->prob_flags
;
323 blkid_probe_chain_reset_position(chn
);
325 rc
= chn
->driver
->probe(pr
, chn
);
328 blkid_probe_chain_reset_position(chn
);
330 /* restore the original setting
332 pr
->cur_chain
= org_chn
;
333 pr
->prob_flags
= org_prob_flags
;
339 printf("returning %s binary data\n", chn
->driver
->name
));
348 * Zeroize probing results and resets the current probing (this has impact to
349 * blkid_do_probe() only). This function does not touch probing filters and
350 * keeps assigned device.
352 void blkid_reset_probe(blkid_probe pr
)
359 blkid_probe_reset_buffer(pr
);
360 blkid_probe_reset_vals(pr
);
362 pr
->cur_chain
= NULL
;
364 for (i
= 0; i
< BLKID_NCHAINS
; i
++)
365 blkid_probe_chain_reset_position(&pr
->chains
[i
]);
369 static int blkid_probe_dump_filter(blkid_probe pr, int chain)
371 struct blkid_chain *chn;
374 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
377 chn = &pr->chains[chain];
382 for (i = 0; i < chn->driver->nidinfos; i++) {
383 const struct blkid_idinfo *id = chn->driver->idinfos[i];
385 DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n",
388 blkid_bmp_get_item(chn->fltr, i)
389 ? "disabled" : "enabled <--"));
396 * Returns properly initialized chain filter
398 unsigned long *blkid_probe_get_filter(blkid_probe pr
, int chain
, int create
)
400 struct blkid_chain
*chn
;
402 if (!pr
|| chain
< 0 || chain
>= BLKID_NCHAINS
)
405 chn
= &pr
->chains
[chain
];
407 /* always when you touch the chain filter all indexes are reseted and
408 * probing starts from scratch
410 blkid_probe_chain_reset_position(chn
);
411 pr
->cur_chain
= NULL
;
413 if (!chn
->driver
->has_fltr
|| (!chn
->fltr
&& !create
))
417 chn
->fltr
= calloc(1, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
419 memset(chn
->fltr
, 0, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
421 /* blkid_probe_dump_filter(pr, chain); */
426 * Generic private functions for filter setting
428 int __blkid_probe_invert_filter(blkid_probe pr
, int chain
)
431 struct blkid_chain
*chn
;
434 fltr
= blkid_probe_get_filter(pr
, chain
, FALSE
);
438 chn
= &pr
->chains
[chain
];
440 for (i
= 0; i
< blkid_bmp_nwords(chn
->driver
->nidinfos
); i
++)
443 DBG(DEBUG_LOWPROBE
, printf("probing filter inverted\n"));
444 /* blkid_probe_dump_filter(pr, chain); */
448 int __blkid_probe_reset_filter(blkid_probe pr
, int chain
)
450 return blkid_probe_get_filter(pr
, chain
, FALSE
) ? 0 : -1;
453 int __blkid_probe_filter_types(blkid_probe pr
, int chain
, int flag
, char *names
[])
456 struct blkid_chain
*chn
;
459 fltr
= blkid_probe_get_filter(pr
, chain
, TRUE
);
463 chn
= &pr
->chains
[chain
];
465 for (i
= 0; i
< chn
->driver
->nidinfos
; i
++) {
467 const struct blkid_idinfo
*id
= chn
->driver
->idinfos
[i
];
470 for (n
= names
; *n
; n
++) {
471 if (!strcmp(id
->name
, *n
)) {
476 if (flag
& BLKID_FLTR_ONLYIN
) {
478 blkid_bmp_set_item(fltr
, i
);
479 } else if (flag
& BLKID_FLTR_NOTIN
) {
481 blkid_bmp_set_item(fltr
, i
);
486 printf("%s: a new probing type-filter initialized\n",
488 /* blkid_probe_dump_filter(pr, chain); */
492 unsigned char *blkid_probe_get_buffer(blkid_probe pr
,
493 blkid_loff_t off
, blkid_loff_t len
)
496 struct blkid_bufinfo
*bf
= NULL
;
501 list_for_each(p
, &pr
->buffers
) {
502 struct blkid_bufinfo
*x
=
503 list_entry(p
, struct blkid_bufinfo
, bufs
);
505 if (x
->off
<= off
&& off
+ len
<= x
->off
+ x
->len
) {
507 printf("\treuse buffer: off=%jd len=%jd\n",
516 if (blkid_llseek(pr
->fd
, pr
->off
+ off
, SEEK_SET
) < 0)
519 /* allocate info and space for data by why call */
520 bf
= calloc(1, sizeof(struct blkid_bufinfo
) + len
);
524 bf
->data
= ((unsigned char *) bf
) + sizeof(struct blkid_bufinfo
);
527 INIT_LIST_HEAD(&bf
->bufs
);
530 printf("\tbuffer read: off=%jd len=%jd\n", off
, len
));
532 ret
= read(pr
->fd
, bf
->data
, len
);
533 if (ret
!= (ssize_t
) len
) {
537 list_add_tail(&bf
->bufs
, &pr
->buffers
);
540 return off
? bf
->data
+ (off
- bf
->off
) : bf
->data
;
544 static void blkid_probe_reset_buffer(blkid_probe pr
)
546 uint64_t read_ct
= 0, len_ct
= 0;
548 if (!pr
|| list_empty(&pr
->buffers
))
551 DBG(DEBUG_LOWPROBE
, printf("reseting probing buffers\n"));
553 while (!list_empty(&pr
->buffers
)) {
554 struct blkid_bufinfo
*bf
= list_entry(pr
->buffers
.next
,
555 struct blkid_bufinfo
, bufs
);
564 printf("buffers summary: %"PRIu64
" bytes "
565 "by %"PRIu64
" read() call(s)\n",
568 INIT_LIST_HEAD(&pr
->buffers
);
572 * Small devices need a special care.
574 int blkid_probe_is_tiny(blkid_probe pr
)
576 return pr
&& (pr
->flags
& BLKID_TINY_DEV
);
580 * CDROMs may fail when probed for RAID (last sector problem)
582 int blkid_probe_is_cdrom(blkid_probe pr
)
584 return pr
&& (pr
->flags
& BLKID_CDROM_DEV
);
588 * blkid_probe_set_device:
590 * @fd: device file descriptor
591 * @off: begin of probing area
592 * @size: size of probing area (zero means whole device/file)
594 * Assigns the device to probe control struct, resets internal buffers and
595 * resets the current probing.
597 * Returns: -1 in case of failure, or 0 on success.
599 int blkid_probe_set_device(blkid_probe pr
, int fd
,
600 blkid_loff_t off
, blkid_loff_t size
)
607 blkid_reset_probe(pr
);
609 if ((pr
->flags
& BLKID_PRIVATE_FD
) && pr
->fd
>= 0)
612 pr
->flags
&= ~BLKID_PRIVATE_FD
;
613 pr
->flags
&= ~BLKID_TINY_DEV
;
614 pr
->flags
&= ~BLKID_CDROM_DEV
;
622 #if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
623 /* Disable read-ahead */
624 posix_fadvise(fd
, 0, 0, POSIX_FADV_RANDOM
);
629 if (!S_ISBLK(sb
.st_mode
) && !S_ISCHR(sb
.st_mode
) && !S_ISREG(sb
.st_mode
))
632 pr
->mode
= sb
.st_mode
;
633 if (S_ISBLK(sb
.st_mode
) || S_ISCHR(sb
.st_mode
))
634 pr
->devno
= sb
.st_rdev
;
639 if (S_ISBLK(sb
.st_mode
)) {
640 if (blkdev_get_size(fd
, (unsigned long long *) &pr
->size
)) {
641 DBG(DEBUG_LOWPROBE
, printf(
642 "failed to get device size\n"));
645 } else if (S_ISCHR(sb
.st_mode
))
646 pr
->size
= 1; /* UBI devices are char... */
647 else if (S_ISREG(sb
.st_mode
))
648 pr
->size
= sb
.st_size
; /* regular file */
650 if (pr
->off
> pr
->size
)
653 /* The probing area cannot be larger than whole device, pr->off
654 * is offset within the device */
658 if (pr
->size
<= 1440 * 1024 && !S_ISCHR(sb
.st_mode
))
659 pr
->flags
|= BLKID_TINY_DEV
;
661 #ifdef CDROM_GET_CAPABILITY
662 if (S_ISBLK(sb
.st_mode
) && ioctl(fd
, CDROM_GET_CAPABILITY
, NULL
) >= 0)
663 pr
->flags
|= BLKID_CDROM_DEV
;
666 DBG(DEBUG_LOWPROBE
, printf("ready for low-probing, offset=%jd, size=%jd\n",
668 DBG(DEBUG_LOWPROBE
, printf("whole-disk: %s, regfile: %s\n",
669 blkid_probe_is_wholedisk(pr
) ?"YES" : "NO",
670 S_ISREG(pr
->mode
) ? "YES" : "NO"));
675 printf("failed to prepare a device for low-probing\n"));
680 int blkid_probe_get_dimension(blkid_probe pr
,
681 blkid_loff_t
*off
, blkid_loff_t
*size
)
691 int blkid_probe_set_dimension(blkid_probe pr
,
692 blkid_loff_t off
, blkid_loff_t size
)
697 DBG(DEBUG_LOWPROBE
, printf(
698 "changing probing area: size=%llu, off=%llu "
699 "-to-> size=%llu, off=%llu\n",
700 (unsigned long long) pr
->size
,
701 (unsigned long long) pr
->off
,
702 (unsigned long long) size
,
703 (unsigned long long) off
));
707 pr
->flags
&= ~BLKID_TINY_DEV
;
709 if (pr
->size
<= 1440 * 1024 && !S_ISCHR(pr
->mode
))
710 pr
->flags
|= BLKID_TINY_DEV
;
712 blkid_probe_reset_buffer(pr
);
717 int blkid_probe_get_idmag(blkid_probe pr
, const struct blkid_idinfo
*id
,
718 blkid_loff_t
*offset
, const struct blkid_idmag
**res
)
720 const struct blkid_idmag
*mag
= NULL
;
721 blkid_loff_t off
= 0;
724 mag
= id
->magics
? &id
->magics
[0] : NULL
;
728 /* try to detect by magic string */
729 while(mag
&& mag
->magic
) {
732 off
= (mag
->kboff
+ (mag
->sboff
>> 10)) << 10;
733 buf
= blkid_probe_get_buffer(pr
, off
, 1024);
735 if (buf
&& !memcmp(mag
->magic
,
736 buf
+ (mag
->sboff
& 0x3ff), mag
->len
)) {
737 DBG(DEBUG_LOWPROBE
, printf(
738 "\tmagic sboff=%u, kboff=%ld\n",
739 mag
->sboff
, mag
->kboff
));
741 *offset
= off
+ (mag
->sboff
& 0x3ff);
749 if (id
->magics
&& id
->magics
[0].magic
)
750 /* magic string(s) defined, but not found */
756 static inline void blkid_probe_start(blkid_probe pr
)
759 pr
->cur_chain
= NULL
;
764 static inline void blkid_probe_end(blkid_probe pr
)
767 pr
->cur_chain
= NULL
;
776 * Calls probing functions in all enabled chains. The superblocks chain is
777 * enabled by default. The blkid_do_probe() stores result from only one
778 * probing function. It's necessary to call this routine in a loop to get
779 * results from all probing functions in all chains. The probing is reseted
780 * by blkid_reset_probe() or by filter functions.
782 * This is string-based NAME=value interface only.
785 * <title>basic case - use the first result only</title>
788 * if (blkid_do_probe(pr) == 0) {
789 * int nvals = blkid_probe_numof_values(pr);
790 * for (n = 0; n < nvals; n++) {
791 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
792 * printf("%s = %s\n", name, data);
799 * <title>advanced case - probe for all signatures</title>
802 * while (blkid_do_probe(pr) == 0) {
803 * int nvals = blkid_probe_numof_values(pr);
809 * See also blkid_reset_probe().
811 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
813 int blkid_do_probe(blkid_probe pr
)
821 struct blkid_chain
*chn
= pr
->cur_chain
;
824 blkid_probe_start(pr
);
825 chn
= pr
->cur_chain
= &pr
->chains
[0];
827 /* we go to the next chain only when the previous probing
828 * result was nothing (rc == 1) and when the current chain is
829 * disabled or we are at end of the current chain (chain->idx +
830 * 1 == sizeof chain) or the current chain bailed out right at
831 * the start (chain->idx == -1)
833 else if (rc
== 1 && (chn
->enabled
== FALSE
||
834 chn
->idx
+ 1 == chn
->driver
->nidinfos
||
837 int idx
= chn
->driver
->id
+ 1;
839 if (idx
< BLKID_NCHAINS
)
840 chn
= pr
->cur_chain
= &pr
->chains
[idx
];
843 return 1; /* all chains already probed */
847 chn
->binary
= FALSE
; /* for sure... */
849 DBG(DEBUG_LOWPROBE
, printf("chain probe %s %s (idx=%d)\n",
851 chn
->enabled
? "ENABLED" : "DISABLED",
857 /* rc: -1 = error, 0 = success, 1 = no result */
858 rc
= chn
->driver
->probe(pr
, chn
);
866 * blkid_do_safeprobe:
869 * This function gathers probing results from all enabled chains and checks
870 * for ambivalent results (e.g. more filesystems on the device).
872 * This is string-based NAME=value interface only.
874 * Note about suberblocks chain -- the function does not check for filesystems
875 * when a RAID signature is detected. The function also does not check for
876 * collision between RAIDs. The first detected RAID is returned. The function
877 * checks for collision between partition table and RAID signature -- it's
878 * recommended to enable partitions chain together with superblocks chain.
880 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
881 * detected and -1 on case of error.
883 int blkid_do_safeprobe(blkid_probe pr
)
885 int i
, count
= 0, rc
= 0;
890 blkid_probe_start(pr
);
892 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
893 struct blkid_chain
*chn
;
895 chn
= pr
->cur_chain
= &pr
->chains
[i
];
896 chn
->binary
= FALSE
; /* for sure... */
898 DBG(DEBUG_LOWPROBE
, printf("chain safeprobe %s %s\n",
900 chn
->enabled
? "ENABLED" : "DISABLED"));
905 blkid_probe_chain_reset_position(chn
);
907 rc
= chn
->driver
->safeprobe(pr
, chn
);
909 blkid_probe_chain_reset_position(chn
);
911 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
913 goto done
; /* error */
915 count
++; /* success */
922 return count
? 0 : 1;
926 * blkid_do_fullprobe:
929 * This function gathers probing results from all enabled chains. Same as
930 * blkid_so_safeprobe() but does not check for collision between probing
933 * This is string-based NAME=value interface only.
935 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
937 int blkid_do_fullprobe(blkid_probe pr
)
939 int i
, count
= 0, rc
= 0;
944 blkid_probe_start(pr
);
946 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
948 struct blkid_chain
*chn
;
950 chn
= pr
->cur_chain
= &pr
->chains
[i
];
951 chn
->binary
= FALSE
; /* for sure... */
953 DBG(DEBUG_LOWPROBE
, printf("chain fullprobe %s: %s\n",
955 chn
->enabled
? "ENABLED" : "DISABLED"));
960 blkid_probe_chain_reset_position(chn
);
962 rc
= chn
->driver
->probe(pr
, chn
);
964 blkid_probe_chain_reset_position(chn
);
966 /* rc: -1 = error, 0 = success, 1 = no result */
968 goto done
; /* error */
970 count
++; /* success */
977 return count
? 0 : 1;
980 /* same sa blkid_probe_get_buffer() but works with 512-sectors */
981 unsigned char *blkid_probe_get_sector(blkid_probe pr
, unsigned int sector
)
983 return pr
? blkid_probe_get_buffer(pr
,
984 ((blkid_loff_t
) sector
) << 9, 0x200) : NULL
;
987 struct blkid_prval
*blkid_probe_assign_value(
988 blkid_probe pr
, const char *name
)
990 struct blkid_prval
*v
;
994 if (pr
->nvals
>= BLKID_NVALS
)
997 v
= &pr
->vals
[pr
->nvals
];
999 v
->chain
= pr
->cur_chain
;
1003 printf("assigning %s [%s]\n", name
, v
->chain
->driver
->name
));
1007 int blkid_probe_reset_last_value(blkid_probe pr
)
1009 struct blkid_prval
*v
;
1011 if (pr
== NULL
|| pr
->nvals
== 0)
1014 v
= &pr
->vals
[pr
->nvals
- 1];
1017 printf("un-assigning %s [%s]\n", v
->name
, v
->chain
->driver
->name
));
1019 memset(v
, 0, sizeof(struct blkid_prval
));
1026 int blkid_probe_set_value(blkid_probe pr
, const char *name
,
1027 unsigned char *data
, size_t len
)
1029 struct blkid_prval
*v
;
1031 if (len
> BLKID_PROBVAL_BUFSIZ
)
1032 len
= BLKID_PROBVAL_BUFSIZ
;
1034 v
= blkid_probe_assign_value(pr
, name
);
1038 memcpy(v
->data
, data
, len
);
1043 int blkid_probe_vsprintf_value(blkid_probe pr
, const char *name
,
1044 const char *fmt
, va_list ap
)
1046 struct blkid_prval
*v
;
1049 v
= blkid_probe_assign_value(pr
, name
);
1053 len
= vsnprintf((char *) v
->data
, sizeof(v
->data
), fmt
, ap
);
1056 blkid_probe_reset_last_value(pr
);
1063 int blkid_probe_sprintf_value(blkid_probe pr
, const char *name
,
1064 const char *fmt
, ...)
1070 rc
= blkid_probe_vsprintf_value(pr
, name
, fmt
, ap
);
1077 * blkid_probe_get_devno:
1080 * Returns: block device number, or 0 for regilar files.
1082 dev_t
blkid_probe_get_devno(blkid_probe pr
)
1088 * blkid_probe_get_wholedisk_devno:
1091 * Returns: device number of the wholedisk, or 0 for regilar files.
1093 dev_t
blkid_probe_get_wholedisk_devno(blkid_probe pr
)
1095 if (!pr
->disk_devno
) {
1096 dev_t devno
, disk_devno
= 0;
1098 devno
= blkid_probe_get_devno(pr
);
1102 if (blkid_devno_to_wholedisk(devno
, NULL
, 0, &disk_devno
) == 0)
1103 pr
->disk_devno
= disk_devno
;
1105 return pr
->disk_devno
;
1109 * blkid_probe_is_wholedisk:
1112 * Returns: 1 if the device is whole-disk or 0.
1114 int blkid_probe_is_wholedisk(blkid_probe pr
)
1116 dev_t devno
, disk_devno
;
1118 devno
= blkid_probe_get_devno(pr
);
1122 disk_devno
= blkid_probe_get_wholedisk_devno(pr
);
1126 return devno
== disk_devno
;
1130 * blkid_probe_get_size:
1133 * This function returns size of probing area as defined by blkid_probe_set_device().
1134 * If the size of the probing area is unrestricted then this function returns
1135 * the real size of device. See also blkid_get_dev_size().
1137 * Returns: size in bytes or -1 in case of error.
1139 blkid_loff_t
blkid_probe_get_size(blkid_probe pr
)
1141 return pr
? pr
->size
: -1;
1145 * blkid_probe_get_offset:
1148 * This function returns offset of probing area as defined by blkid_probe_set_device().
1150 * Returns: offset in bytes or -1 in case of error.
1152 blkid_loff_t
blkid_probe_get_offset(blkid_probe pr
)
1154 return pr
? pr
->off
: -1;
1158 * blkid_probe_get_fd:
1161 * Returns: file descriptor for assigned device/file.
1163 int blkid_probe_get_fd(blkid_probe pr
)
1165 return pr
? pr
->fd
: -1;
1169 * blkid_probe_get_sectorsize:
1170 * @pr: probe or NULL (for NULL returns 512)
1172 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
1174 unsigned int blkid_probe_get_sectorsize(blkid_probe pr
)
1177 return DEFAULT_SECTOR_SIZE
; /*... and good luck! */
1182 if (S_ISBLK(pr
->mode
) &&
1183 blkdev_get_sector_size(pr
->fd
, (int *) &pr
->blkssz
) == 0)
1186 pr
->blkssz
= DEFAULT_SECTOR_SIZE
;
1191 * blkid_probe_get_sectors:
1194 * Returns: 512-byte sector count or -1 in case of error.
1196 blkid_loff_t
blkid_probe_get_sectors(blkid_probe pr
)
1198 return pr
? pr
->size
>> 9 : -1;
1202 * blkid_probe_numof_values:
1205 * Returns: number of values in probing result or -1 in case of error.
1207 int blkid_probe_numof_values(blkid_probe pr
)
1215 * blkid_probe_get_value:
1217 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
1218 * @name: pointer to return value name or NULL
1219 * @data: pointer to return value data or NULL
1220 * @len: pointer to return value length or NULL
1222 * Note, the @len returns length of the @data, including the terminating
1225 * Returns: 0 on success, or -1 in case of error.
1227 int blkid_probe_get_value(blkid_probe pr
, int num
, const char **name
,
1228 const char **data
, size_t *len
)
1230 struct blkid_prval
*v
= __blkid_probe_get_value(pr
, num
);
1237 *data
= (char *) v
->data
;
1241 DBG(DEBUG_LOWPROBE
, printf("returning %s value\n", v
->name
));
1246 * blkid_probe_lookup_value:
1248 * @name: name of value
1249 * @data: pointer to return value data or NULL
1250 * @len: pointer to return value length or NULL
1252 * Note, the @len returns length of the @data, including the terminating
1255 * Returns: 0 on success, or -1 in case of error.
1257 int blkid_probe_lookup_value(blkid_probe pr
, const char *name
,
1258 const char **data
, size_t *len
)
1260 struct blkid_prval
*v
= __blkid_probe_lookup_value(pr
, name
);
1265 *data
= (char *) v
->data
;
1272 * blkid_probe_has_value:
1274 * @name: name of value
1276 * Returns: 1 if value exist in probing result, otherwise 0.
1278 int blkid_probe_has_value(blkid_probe pr
, const char *name
)
1280 if (blkid_probe_lookup_value(pr
, name
, NULL
, NULL
) == 0)
1285 struct blkid_prval
*__blkid_probe_get_value(blkid_probe pr
, int num
)
1287 if (pr
== NULL
|| num
< 0 || num
>= pr
->nvals
)
1290 return &pr
->vals
[num
];
1293 struct blkid_prval
*__blkid_probe_lookup_value(blkid_probe pr
, const char *name
)
1297 if (pr
== NULL
|| pr
->nvals
== 0 || name
== NULL
)
1300 for (i
= 0; i
< pr
->nvals
; i
++) {
1301 struct blkid_prval
*v
= &pr
->vals
[i
];
1303 if (v
->name
&& strcmp(name
, v
->name
) == 0) {
1304 DBG(DEBUG_LOWPROBE
, printf("returning %s value\n", v
->name
));
1312 /* converts DCE UUID (uuid[16]) to human readable string
1313 * - the @len should be always 37 */
1314 void blkid_unparse_uuid(const unsigned char *uuid
, char *str
, size_t len
)
1317 uuid_unparse(uuid
, str
);
1320 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1321 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
1325 uuid
[10], uuid
[11], uuid
[12], uuid
[13], uuid
[14],uuid
[15]);
1330 /* Removes whitespace from the right-hand side of a string (trailing
1333 * Returns size of the new string (without \0).
1335 size_t blkid_rtrim_whitespace(unsigned char *str
)
1337 size_t i
= strlen((char *) str
);
1340 if (!isspace(str
[i
]))