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 reset 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) == BLKID_PROBE_OK)
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).
94 #include <sys/types.h>
95 #ifdef HAVE_LINUX_CDROM_H
96 #include <linux/cdrom.h>
98 #ifdef HAVE_LINUX_BLKZONED_H
99 #include <linux/blkzoned.h>
101 #ifdef HAVE_SYS_STAT_H
102 #include <sys/stat.h>
107 #ifdef HAVE_LINUX_FD_H
108 #include <linux/fd.h>
110 #include <inttypes.h>
114 #ifdef HAVE_OPAL_GET_STATUS
115 #include <linux/sed-opal.h>
121 #include "strutils.h"
123 #include "fileutils.h"
126 * All supported chains
128 static const struct blkid_chaindrv
*const chains_drvs
[] = {
129 [BLKID_CHAIN_SUBLKS
] = &superblocks_drv
,
130 [BLKID_CHAIN_TOPLGY
] = &topology_drv
,
131 [BLKID_CHAIN_PARTS
] = &partitions_drv
134 static void blkid_probe_reset_values(blkid_probe pr
);
139 * Returns: a pointer to the newly allocated probe struct or NULL in case of error.
141 blkid_probe
blkid_new_probe(void)
146 pr
= calloc(1, sizeof(struct blkid_struct_probe
));
150 DBG(LOWPROBE
, ul_debug("allocate a new probe"));
152 /* initialize chains */
153 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
154 pr
->chains
[i
].driver
= chains_drvs
[i
];
155 pr
->chains
[i
].flags
= chains_drvs
[i
]->dflt_flags
;
156 pr
->chains
[i
].enabled
= chains_drvs
[i
]->dflt_enabled
;
158 INIT_LIST_HEAD(&pr
->buffers
);
159 INIT_LIST_HEAD(&pr
->prunable_buffers
);
160 INIT_LIST_HEAD(&pr
->values
);
161 INIT_LIST_HEAD(&pr
->hints
);
166 * Clone @parent, the new clone shares all, but except:
169 * - buffers if another device (or offset) is set to the prober
171 blkid_probe
blkid_clone_probe(blkid_probe parent
)
178 DBG(LOWPROBE
, ul_debug("allocate a probe clone"));
180 pr
= blkid_new_probe();
185 pr
->off
= parent
->off
;
186 pr
->size
= parent
->size
;
187 pr
->io_size
= parent
->io_size
;
188 pr
->devno
= parent
->devno
;
189 pr
->disk_devno
= parent
->disk_devno
;
190 pr
->blkssz
= parent
->blkssz
;
191 pr
->flags
= parent
->flags
;
192 pr
->zone_size
= parent
->zone_size
;
195 pr
->flags
&= ~BLKID_FL_PRIVATE_FD
;
203 * blkid_new_probe_from_filename:
204 * @filename: device or regular file
206 * This function is same as call open(filename), blkid_new_probe() and
207 * blkid_probe_set_device(pr, fd, 0, 0).
209 * The @filename is closed by blkid_free_probe() or by the
210 * blkid_probe_set_device() call.
212 * Returns: a pointer to the newly allocated probe struct or NULL in case of
215 blkid_probe
blkid_new_probe_from_filename(const char *filename
)
218 blkid_probe pr
= NULL
;
220 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NONBLOCK
);
224 pr
= blkid_new_probe();
228 if (blkid_probe_set_device(pr
, fd
, 0, 0))
231 pr
->flags
|= BLKID_FL_PRIVATE_FD
;
235 blkid_free_probe(pr
);
243 * Deallocates the probe struct, buffers and all allocated
244 * data that are associated with this probing control struct.
246 void blkid_free_probe(blkid_probe pr
)
253 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
254 struct blkid_chain
*ch
= &pr
->chains
[i
];
256 if (ch
->driver
->free_data
)
257 ch
->driver
->free_data(pr
, ch
->data
);
262 if ((pr
->flags
& BLKID_FL_PRIVATE_FD
) && pr
->fd
>= 0)
264 blkid_probe_reset_buffers(pr
);
265 blkid_probe_reset_values(pr
);
266 blkid_probe_reset_hints(pr
);
267 blkid_free_probe(pr
->disk_probe
);
269 DBG(LOWPROBE
, ul_debug("free probe"));
273 void blkid_probe_free_value(struct blkid_prval
*v
)
278 list_del(&v
->prvals
);
281 DBG(LOWPROBE
, ul_debug(" free value %s", v
->name
));
286 * Removes chain values from probing result.
288 void blkid_probe_chain_reset_values(blkid_probe pr
, struct blkid_chain
*chn
)
291 struct list_head
*p
, *pnext
;
293 if (list_empty(&pr
->values
))
296 DBG(LOWPROBE
, ul_debug("Resetting %s values", chn
->driver
->name
));
298 list_for_each_safe(p
, pnext
, &pr
->values
) {
299 struct blkid_prval
*v
= list_entry(p
,
300 struct blkid_prval
, prvals
);
303 blkid_probe_free_value(v
);
307 static void blkid_probe_chain_reset_position(struct blkid_chain
*chn
)
313 * Move chain values from probing result to @vals
315 int blkid_probe_chain_save_values(blkid_probe pr
, struct blkid_chain
*chn
,
316 struct list_head
*vals
)
318 struct list_head
*p
, *pnext
;
319 struct blkid_prval
*v
;
321 DBG(LOWPROBE
, ul_debug("saving %s values", chn
->driver
->name
));
323 list_for_each_safe(p
, pnext
, &pr
->values
) {
325 v
= list_entry(p
, struct blkid_prval
, prvals
);
329 list_del_init(&v
->prvals
);
330 list_add_tail(&v
->prvals
, vals
);
336 * Appends values from @vals to the probing result
338 void blkid_probe_append_values_list(blkid_probe pr
, struct list_head
*vals
)
340 DBG(LOWPROBE
, ul_debug("appending values"));
342 list_splice(vals
, &pr
->values
);
343 INIT_LIST_HEAD(vals
);
347 void blkid_probe_free_values_list(struct list_head
*vals
)
352 DBG(LOWPROBE
, ul_debug("freeing values list"));
354 while (!list_empty(vals
)) {
355 struct blkid_prval
*v
= list_entry(vals
->next
, struct blkid_prval
, prvals
);
356 blkid_probe_free_value(v
);
360 struct blkid_chain
*blkid_probe_get_chain(blkid_probe pr
)
362 return pr
->cur_chain
;
365 static const char *blkid_probe_get_probername(blkid_probe pr
)
367 struct blkid_chain
*chn
= blkid_probe_get_chain(pr
);
369 if (chn
&& chn
->idx
>= 0 && (unsigned)chn
->idx
< chn
->driver
->nidinfos
)
370 return chn
->driver
->idinfos
[chn
->idx
]->name
;
375 void *blkid_probe_get_binary_data(blkid_probe pr
, struct blkid_chain
*chn
)
377 int rc
, org_prob_flags
;
378 struct blkid_chain
*org_chn
;
380 /* save the current setting -- the binary API has to be completely
381 * independent on the current probing status
383 org_chn
= pr
->cur_chain
;
384 org_prob_flags
= pr
->prob_flags
;
389 blkid_probe_chain_reset_position(chn
);
391 rc
= chn
->driver
->probe(pr
, chn
);
394 blkid_probe_chain_reset_position(chn
);
396 /* restore the original setting
398 pr
->cur_chain
= org_chn
;
399 pr
->prob_flags
= org_prob_flags
;
404 DBG(LOWPROBE
, ul_debug("returning %s binary data", chn
->driver
->name
));
413 * Zeroize probing results and resets the current probing (this has impact to
414 * blkid_do_probe() only). This function does not touch probing filters and
415 * keeps assigned device.
417 void blkid_reset_probe(blkid_probe pr
)
421 blkid_probe_reset_values(pr
);
422 blkid_probe_set_wiper(pr
, 0, 0);
424 pr
->cur_chain
= NULL
;
426 for (i
= 0; i
< BLKID_NCHAINS
; i
++)
427 blkid_probe_chain_reset_position(&pr
->chains
[i
]);
431 static int blkid_probe_dump_filter(blkid_probe pr, int chain)
433 struct blkid_chain *chn;
436 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
439 chn = &pr->chains[chain];
444 for (i = 0; i < chn->driver->nidinfos; i++) {
445 const struct blkid_idinfo *id = chn->driver->idinfos[i];
447 DBG(LOWPROBE, ul_debug("%d: %s: %s",
450 blkid_bmp_get_item(chn->fltr, i)
451 ? "disabled" : "enabled <--"));
458 * Returns properly initialized chain filter
460 unsigned long *blkid_probe_get_filter(blkid_probe pr
, int chain
, int create
)
462 struct blkid_chain
*chn
;
464 if (chain
< 0 || chain
>= BLKID_NCHAINS
)
467 chn
= &pr
->chains
[chain
];
469 /* always when you touch the chain filter all indexes are reset and
470 * probing starts from scratch
472 blkid_probe_chain_reset_position(chn
);
473 pr
->cur_chain
= NULL
;
475 if (!chn
->driver
->has_fltr
|| (!chn
->fltr
&& !create
))
479 chn
->fltr
= calloc(1, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
481 memset(chn
->fltr
, 0, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
483 /* blkid_probe_dump_filter(pr, chain); */
488 * Generic private functions for filter setting
490 int __blkid_probe_invert_filter(blkid_probe pr
, int chain
)
493 struct blkid_chain
*chn
;
495 chn
= &pr
->chains
[chain
];
497 if (!chn
->driver
->has_fltr
|| !chn
->fltr
)
500 for (i
= 0; i
< blkid_bmp_nwords(chn
->driver
->nidinfos
); i
++)
501 chn
->fltr
[i
] = ~chn
->fltr
[i
];
503 DBG(LOWPROBE
, ul_debug("probing filter inverted"));
504 /* blkid_probe_dump_filter(pr, chain); */
508 int __blkid_probe_reset_filter(blkid_probe pr
, int chain
)
510 return blkid_probe_get_filter(pr
, chain
, FALSE
) ? 0 : -1;
513 int __blkid_probe_filter_types(blkid_probe pr
, int chain
, int flag
, char *names
[])
516 struct blkid_chain
*chn
;
519 fltr
= blkid_probe_get_filter(pr
, chain
, TRUE
);
523 chn
= &pr
->chains
[chain
];
525 for (i
= 0; i
< chn
->driver
->nidinfos
; i
++) {
527 const struct blkid_idinfo
*id
= chn
->driver
->idinfos
[i
];
530 for (n
= names
; *n
; n
++) {
531 if (!strcmp(id
->name
, *n
)) {
537 if (flag
& BLKID_FLTR_NOTIN
)
538 blkid_bmp_set_item(fltr
, i
);
539 } else if (flag
& BLKID_FLTR_ONLYIN
)
540 blkid_bmp_set_item(fltr
, i
);
543 DBG(LOWPROBE
, ul_debug("%s: a new probing type-filter initialized",
545 /* blkid_probe_dump_filter(pr, chain); */
549 static void remove_buffer(struct blkid_bufinfo
*bf
)
553 DBG(BUFFER
, ul_debug(" remove buffer: [off=%"PRIu64
", len=%"PRIu64
"]",
555 munmap(bf
->data
, bf
->len
);
559 static struct blkid_bufinfo
*read_buffer(blkid_probe pr
, uint64_t real_off
, uint64_t len
)
562 struct blkid_bufinfo
*bf
= NULL
;
564 if (lseek(pr
->fd
, real_off
, SEEK_SET
) == (off_t
) -1) {
569 /* someone trying to overflow some buffers? */
570 if (len
> ULONG_MAX
- sizeof(struct blkid_bufinfo
)) {
575 /* allocate info and space for data by one malloc call */
576 bf
= calloc(1, sizeof(struct blkid_bufinfo
));
582 bf
->data
= mmap(NULL
, len
, PROT_READ
| PROT_WRITE
,
583 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
584 if (bf
->data
== MAP_FAILED
) {
592 INIT_LIST_HEAD(&bf
->bufs
);
594 DBG(LOWPROBE
, ul_debug("\tread: off=%"PRIu64
" len=%"PRIu64
"",
597 ret
= read(pr
->fd
, bf
->data
, len
);
598 if (ret
!= (ssize_t
) len
) {
599 DBG(LOWPROBE
, ul_debug("\tread failed: %m"));
602 /* I/O errors on CDROMs are non-fatal to work with hybrid
603 * audio+data disks */
604 if (ret
>= 0 || blkid_probe_is_cdrom(pr
) || blkdid_probe_is_opal_locked(pr
))
610 if (mprotect(bf
->data
, len
, PROT_READ
))
611 DBG(LOWPROBE
, ul_debug("\tmprotect failed: %m"));
617 * Search in buffers we already have in memory
619 static struct blkid_bufinfo
*get_cached_buffer(blkid_probe pr
, uint64_t off
, uint64_t len
)
621 uint64_t real_off
= pr
->off
+ off
;
624 list_for_each(p
, &pr
->buffers
) {
625 struct blkid_bufinfo
*x
=
626 list_entry(p
, struct blkid_bufinfo
, bufs
);
628 if (real_off
>= x
->off
&& real_off
+ len
<= x
->off
+ x
->len
) {
629 DBG(BUFFER
, ul_debug("\treuse: off=%"PRIu64
" len=%"PRIu64
" (for off=%"PRIu64
" len=%"PRIu64
")",
630 x
->off
, x
->len
, real_off
, len
));
638 * Mark smaller buffers that can be satisfied by bf as prunable
640 static void mark_prunable_buffers(blkid_probe pr
, const struct blkid_bufinfo
*bf
)
642 struct list_head
*p
, *next
;
644 list_for_each_safe(p
, next
, &pr
->buffers
) {
645 struct blkid_bufinfo
*x
=
646 list_entry(p
, struct blkid_bufinfo
, bufs
);
648 if (bf
->off
<= x
->off
&& bf
->off
+ bf
->len
>= x
->off
+ x
->len
) {
650 list_add(&x
->bufs
, &pr
->prunable_buffers
);
656 * Remove buffers that are marked as prunable
658 void blkid_probe_prune_buffers(blkid_probe pr
)
660 struct list_head
*p
, *next
;
662 list_for_each_safe(p
, next
, &pr
->prunable_buffers
) {
663 struct blkid_bufinfo
*x
=
664 list_entry(p
, struct blkid_bufinfo
, bufs
);
671 * Zeroize in-memory data in already read buffer. The next blkid_probe_get_buffer()
672 * will return modified buffer. This is usable when you want to call the same probing
673 * function more than once and hide previously detected magic strings.
675 * See blkid_probe_hide_range().
677 static int hide_buffer(blkid_probe pr
, uint64_t off
, uint64_t len
)
679 uint64_t real_off
= pr
->off
+ off
;
683 if (UINT64_MAX
- len
< off
) {
684 DBG(BUFFER
, ul_debug("\t hide-buffer overflow (ignore)"));
688 list_for_each(p
, &pr
->buffers
) {
689 struct blkid_bufinfo
*x
=
690 list_entry(p
, struct blkid_bufinfo
, bufs
);
693 if (real_off
>= x
->off
&& real_off
+ len
<= x
->off
+ x
->len
) {
695 assert(x
->off
<= real_off
);
696 assert(x
->off
+ x
->len
>= real_off
+ len
);
698 data
= real_off
? x
->data
+ (real_off
- x
->off
) : x
->data
;
700 DBG(BUFFER
, ul_debug("\thiding: off=%"PRIu64
" len=%"PRIu64
,
702 mprotect(x
->data
, x
->len
, PROT_READ
| PROT_WRITE
);
703 memset(data
, 0, len
);
704 mprotect(x
->data
, x
->len
, PROT_READ
);
708 return ct
== 0 ? -EINVAL
: 0;
713 * Note that @off is offset within probing area, the probing area is defined by
714 * pr->off and pr->size.
716 const unsigned char *blkid_probe_get_buffer(blkid_probe pr
, uint64_t off
, uint64_t len
)
718 struct blkid_bufinfo
*bf
= NULL
;
719 uint64_t real_off
, bias
, len_align
;
721 bias
= off
% pr
->io_size
;
725 if (len
% pr
->io_size
) {
726 len_align
= pr
->io_size
- (len
% pr
->io_size
);
728 if (pr
->off
+ off
+ len
+ len_align
<= pr
->size
)
732 real_off
= pr
->off
+ off
;
735 DBG(BUFFER, ul_debug("\t>>>> off=%ju, real-off=%ju (probe <%ju..%ju>, len=%ju",
736 off, real_off, pr->off, pr->off + pr->size, len));
738 if (pr
->size
== 0 || pr
->io_size
== 0) {
743 if (UINT64_MAX
- len
< off
|| UINT64_MAX
- len
< real_off
) {
744 DBG(BUFFER
, ul_debug("\t read-buffer overflow (ignore)"));
748 if (len
> 8388608 /* 8 Mib */ ) {
749 DBG(BUFFER
, ul_debug("\t too large read request (ignore)"));
754 || (!S_ISCHR(pr
->mode
) && (pr
->size
< off
|| pr
->size
< len
))
755 || (!S_ISCHR(pr
->mode
) && (pr
->off
+ pr
->size
< real_off
+ len
))) {
756 DBG(BUFFER
, ul_debug("\t read-buffer out of probing area (ignore)"));
762 pr
->parent
->devno
== pr
->devno
&&
763 pr
->parent
->off
<= pr
->off
&&
764 pr
->parent
->off
+ pr
->parent
->size
>= pr
->off
+ pr
->size
) {
766 * This is a cloned prober and points to the same area as
767 * parent. Let's use parent's buffers.
769 * Note that pr->off (and pr->parent->off) is always from the
770 * begin of the device.
772 return blkid_probe_get_buffer(pr
->parent
,
773 pr
->off
+ off
- pr
->parent
->off
, len
);
776 /* try buffers we already have in memory or read from device */
777 bf
= get_cached_buffer(pr
, off
, len
);
779 bf
= read_buffer(pr
, real_off
, len
);
783 mark_prunable_buffers(pr
, bf
);
784 list_add_tail(&bf
->bufs
, &pr
->buffers
);
787 assert(bf
->off
<= real_off
);
788 assert(bf
->off
+ bf
->len
>= real_off
+ len
);
791 return real_off
? bf
->data
+ (real_off
- bf
->off
+ bias
) : bf
->data
+ bias
;
796 * This is blkid_probe_get_buffer with the read done as an O_DIRECT operation.
797 * Note that @off is offset within probing area, the probing area is defined by
798 * pr->off and pr->size.
800 const unsigned char *blkid_probe_get_buffer_direct(blkid_probe pr
, uint64_t off
, uint64_t len
)
802 const unsigned char *ret
= NULL
;
803 int flags
, rc
, olderrno
;
805 flags
= fcntl(pr
->fd
, F_GETFL
);
806 rc
= fcntl(pr
->fd
, F_SETFL
, flags
| O_DIRECT
);
808 DBG(LOWPROBE
, ul_debug("fcntl F_SETFL failed to set O_DIRECT"));
812 ret
= blkid_probe_get_buffer(pr
, off
, len
);
814 rc
= fcntl(pr
->fd
, F_SETFL
, flags
);
816 DBG(LOWPROBE
, ul_debug("fcntl F_SETFL failed to clear O_DIRECT"));
824 * blkid_probe_reset_buffers:
827 * libblkid reuse all already read buffers from the device. The buffers may be
828 * modified by blkid_probe_hide_range(). This function reset and free all
829 * cached buffers. The next blkid_do_probe() will read all data from the
834 * Returns: <0 in case of failure, or 0 on success.
836 int blkid_probe_reset_buffers(blkid_probe pr
)
838 uint64_t ct
= 0, len
= 0;
840 pr
->flags
&= ~BLKID_FL_MODIF_BUFF
;
842 blkid_probe_prune_buffers(pr
);
844 if (list_empty(&pr
->buffers
))
847 DBG(BUFFER
, ul_debug("Resetting probing buffers"));
849 while (!list_empty(&pr
->buffers
)) {
850 struct blkid_bufinfo
*bf
= list_entry(pr
->buffers
.next
,
851 struct blkid_bufinfo
, bufs
);
858 DBG(LOWPROBE
, ul_debug(" buffers summary: %"PRIu64
" bytes by %"PRIu64
" read() calls",
861 INIT_LIST_HEAD(&pr
->buffers
);
867 * blkid_probe_hide_range:
869 * @off: start of the range
870 * @len: size of the range
872 * This function modifies in-memory cached data from the device. The specified
873 * range is zeroized. This is usable together with blkid_probe_step_back().
874 * The next blkid_do_probe() will not see specified area.
876 * Note that this is usable for already (by library) read data, and this
877 * function is not a way how to hide any large areas on your device.
879 * The function blkid_probe_reset_buffers() reverts all.
883 * Returns: <0 in case of failure, or 0 on success.
885 int blkid_probe_hide_range(blkid_probe pr
, uint64_t off
, uint64_t len
)
887 int rc
= hide_buffer(pr
, off
, len
);
890 pr
->flags
|= BLKID_FL_MODIF_BUFF
;
895 static void blkid_probe_reset_values(blkid_probe pr
)
897 if (list_empty(&pr
->values
))
900 DBG(LOWPROBE
, ul_debug("resetting results"));
902 while (!list_empty(&pr
->values
)) {
903 struct blkid_prval
*v
= list_entry(pr
->values
.next
,
904 struct blkid_prval
, prvals
);
905 blkid_probe_free_value(v
);
908 INIT_LIST_HEAD(&pr
->values
);
912 * Small devices need a special care.
914 int blkid_probe_is_tiny(blkid_probe pr
)
916 return (pr
->flags
& BLKID_FL_TINY_DEV
);
920 * CDROMs may fail when probed for RAID (last sector problem)
922 int blkid_probe_is_cdrom(blkid_probe pr
)
924 return (pr
->flags
& BLKID_FL_CDROM_DEV
);
927 int blkdid_probe_is_opal_locked(blkid_probe pr
)
929 if (!(pr
->flags
& BLKID_FL_OPAL_CHECKED
)) {
930 pr
->flags
|= BLKID_FL_OPAL_CHECKED
;
932 #ifdef HAVE_OPAL_GET_STATUS
934 struct opal_status st
= { };
937 /* If the device is locked with OPAL, we'll fail to read with I/O
938 * errors when probing deep into the block device. */
939 ret
= ioctl(pr
->fd
, IOC_OPAL_GET_STATUS
, &st
);
940 if (ret
== 0 && (st
.flags
& OPAL_FL_LOCKED
)) {
941 pr
->flags
|= BLKID_FL_OPAL_LOCKED
;
948 return (pr
->flags
& BLKID_FL_OPAL_LOCKED
);
951 #ifdef CDROM_GET_CAPABILITY
953 static int is_sector_readable(int fd
, uint64_t sector
)
958 if (lseek(fd
, sector
* 512, SEEK_SET
) == (off_t
) -1)
961 sz
= read(fd
, buf
, sizeof(buf
));
962 if (sz
!= (ssize_t
) sizeof(buf
))
967 DBG(LOWPROBE
, ul_debug("CDROM: read sector %"PRIu64
" failed %m", sector
));
973 * Linux kernel reports (BLKGETSIZE) cdrom device size greater than area
974 * readable by read(2). We have to reduce the probing area to avoid unwanted
975 * I/O errors in probing functions. It seems that unreadable are always last 2
976 * or 3 CD blocks (CD block size is 2048 bytes, it means 12 in 512-byte
977 * sectors). Linux kernel reports (CDROM_LAST_WRITTEN) also location of last
978 * written block, so we will reduce size based on it too.
980 static void cdrom_size_correction(blkid_probe pr
, uint64_t last_written
)
982 uint64_t n
, nsectors
= pr
->size
>> 9;
984 if (last_written
&& nsectors
> ((last_written
+1) << 2))
985 nsectors
= (last_written
+1) << 2;
987 for (n
= nsectors
- 12; n
< nsectors
; n
++) {
988 if (!is_sector_readable(pr
->fd
, n
))
992 DBG(LOWPROBE
, ul_debug("CDROM: full size available"));
995 /* 'n' is the failed sector, reduce device size to n-1; */
996 DBG(LOWPROBE
, ul_debug("CDROM: reduce size from %ju to %ju.",
997 (uintmax_t) pr
->size
,
998 (uintmax_t) n
<< 9));
1004 static uint64_t blkid_get_io_size(int fd
)
1006 static const int ioctls
[] = {
1021 for (i
= 0; i
< ARRAY_SIZE(ioctls
); i
++) {
1022 r
= ioctl(fd
, ioctls
[i
], &s
);
1023 if (r
== 0 && is_power_of_2(s
) && s
>= DEFAULT_SECTOR_SIZE
)
1024 return min(s
, 1U << 16);
1027 return DEFAULT_SECTOR_SIZE
;
1031 * blkid_probe_set_device:
1033 * @fd: device file descriptor
1034 * @off: begin of probing area
1035 * @size: size of probing area (zero means whole device/file)
1037 * Assigns the device to probe control struct, resets internal buffers, resets
1038 * the current probing, and close previously associated device (if open by
1041 * If @fd is < 0 than only resets the prober and returns 1. Note that
1042 * blkid_reset_probe() keeps the device associated with the prober, but
1043 * blkid_probe_set_device() does complete reset.
1045 * Returns: -1 in case of failure, 0 on success and 1 on reset.
1047 int blkid_probe_set_device(blkid_probe pr
, int fd
,
1048 blkid_loff_t off
, blkid_loff_t size
)
1051 uint64_t devsiz
= 0;
1052 char *dm_uuid
= NULL
;
1055 blkid_reset_probe(pr
);
1056 blkid_probe_reset_buffers(pr
);
1058 if ((pr
->flags
& BLKID_FL_PRIVATE_FD
) && pr
->fd
>= 0)
1061 if (pr
->disk_probe
) {
1062 blkid_free_probe(pr
->disk_probe
);
1063 pr
->disk_probe
= NULL
;
1066 pr
->flags
&= ~BLKID_FL_PRIVATE_FD
;
1067 pr
->flags
&= ~BLKID_FL_TINY_DEV
;
1068 pr
->flags
&= ~BLKID_FL_CDROM_DEV
;
1071 pr
->off
= (uint64_t) off
;
1073 pr
->io_size
= DEFAULT_SECTOR_SIZE
;
1080 pr
->wipe_chain
= NULL
;
1087 #if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
1088 /* Disable read-ahead */
1089 posix_fadvise(fd
, 0, 0, POSIX_FADV_RANDOM
);
1094 if (!S_ISBLK(sb
.st_mode
) && !S_ISCHR(sb
.st_mode
) && !S_ISREG(sb
.st_mode
)) {
1099 pr
->mode
= sb
.st_mode
;
1100 if (S_ISBLK(sb
.st_mode
) || S_ISCHR(sb
.st_mode
))
1101 pr
->devno
= sb
.st_rdev
;
1103 if (S_ISBLK(sb
.st_mode
)) {
1104 if (blkdev_get_size(fd
, (unsigned long long *) &devsiz
)) {
1105 DBG(LOWPROBE
, ul_debug("failed to get device size"));
1108 } else if (S_ISCHR(sb
.st_mode
)) {
1111 if (!sysfs_chrdev_devno_to_devname(sb
.st_rdev
, buf
, sizeof(buf
))
1112 || strncmp(buf
, "ubi", 3) != 0) {
1113 DBG(LOWPROBE
, ul_debug("no UBI char device"));
1117 devsiz
= 1; /* UBI devices are char... */
1118 } else if (S_ISREG(sb
.st_mode
))
1119 devsiz
= sb
.st_size
; /* regular file */
1121 pr
->size
= size
? (uint64_t)size
: devsiz
;
1123 if (off
&& size
== 0)
1124 /* only offset without size specified */
1125 pr
->size
-= (uint64_t) off
;
1127 if (pr
->off
+ pr
->size
> devsiz
) {
1128 DBG(LOWPROBE
, ul_debug("area specified by offset and size is bigger than device"));
1133 if (pr
->size
<= 1440 * 1024 && !S_ISCHR(sb
.st_mode
))
1134 pr
->flags
|= BLKID_FL_TINY_DEV
;
1137 if (S_ISBLK(sb
.st_mode
)) {
1139 * Re-open without O_NONBLOCK for floppy device.
1141 * Since kernel commit c7e9d0020361f4308a70cdfd6d5335e273eb8717
1142 * floppy drive works bad when opened with O_NONBLOCK.
1144 struct floppy_fdc_state flst
;
1146 if (ioctl(fd
, FDGETFDCSTAT
, &flst
) >= 0) {
1147 int flags
= fcntl(fd
, F_GETFL
, 0);
1151 if (flags
& O_NONBLOCK
) {
1152 flags
&= ~O_NONBLOCK
;
1154 fd
= ul_reopen(fd
, flags
| O_CLOEXEC
);
1158 pr
->flags
|= BLKID_FL_PRIVATE_FD
;
1166 if (S_ISBLK(sb
.st_mode
) &&
1168 sysfs_devno_is_dm_private(sb
.st_rdev
, &dm_uuid
)) {
1169 DBG(LOWPROBE
, ul_debug("ignore private device mapper device"));
1170 pr
->flags
|= BLKID_FL_NOSCAN_DEV
;
1173 #ifdef CDROM_GET_CAPABILITY
1174 else if (S_ISBLK(sb
.st_mode
) &&
1175 !blkid_probe_is_tiny(pr
) &&
1178 blkid_probe_is_wholedisk(pr
)) {
1180 long last_written
= 0;
1183 * pktcdvd.ko accepts only these ioctls:
1184 * CDROMEJECT CDROMMULTISESSION CDROMREADTOCENTRY
1185 * CDROM_LAST_WRITTEN CDROM_SEND_PACKET SCSI_IOCTL_SEND_COMMAND
1186 * So CDROM_GET_CAPABILITY cannot be used for detecting pktcdvd
1187 * devices. But CDROM_GET_CAPABILITY and CDROM_DRIVE_STATUS are
1188 * fast so use them for detecting if medium is present. In any
1189 * case use last written block form CDROM_LAST_WRITTEN.
1192 if (ioctl(fd
, CDROM_GET_CAPABILITY
, NULL
) >= 0) {
1193 # ifdef CDROM_DRIVE_STATUS
1194 switch (ioctl(fd
, CDROM_DRIVE_STATUS
, CDSL_CURRENT
)) {
1201 pr
->flags
|= BLKID_FL_CDROM_DEV
;
1204 # ifdef CDROM_LAST_WRITTEN
1205 if (ioctl(fd
, CDROM_LAST_WRITTEN
, &last_written
) == 0) {
1206 pr
->flags
|= BLKID_FL_CDROM_DEV
;
1208 if (errno
== ENOMEDIUM
)
1213 if (pr
->flags
& BLKID_FL_CDROM_DEV
) {
1214 cdrom_size_correction(pr
, last_written
);
1216 # ifdef CDROMMULTISESSION
1217 if (!pr
->off
&& blkid_probe_get_hint(pr
, "session_offset", NULL
) < 0) {
1218 struct cdrom_multisession multisession
= { .addr_format
= CDROM_LBA
};
1219 if (ioctl(fd
, CDROMMULTISESSION
, &multisession
) == 0 && multisession
.xa_flag
)
1220 blkid_probe_set_hint(pr
, "session_offset", (multisession
.addr
.lba
<< 11));
1228 # ifdef BLKGETZONESZ
1229 if (S_ISBLK(sb
.st_mode
) && !is_floppy
) {
1230 uint32_t zone_size_sector
;
1232 if (!ioctl(pr
->fd
, BLKGETZONESZ
, &zone_size_sector
))
1233 pr
->zone_size
= zone_size_sector
<< 9;
1237 if (S_ISBLK(sb
.st_mode
) && !is_floppy
&& !blkid_probe_is_tiny(pr
))
1238 pr
->io_size
= blkid_get_io_size(fd
);
1240 DBG(LOWPROBE
, ul_debug("ready for low-probing, offset=%"PRIu64
", size=%"PRIu64
", zonesize=%"PRIu64
", iosize=%"PRIu64
,
1241 pr
->off
, pr
->size
, pr
->zone_size
, pr
->io_size
));
1242 DBG(LOWPROBE
, ul_debug("whole-disk: %s, regfile: %s",
1243 blkid_probe_is_wholedisk(pr
) ?"YES" : "NO",
1244 S_ISREG(pr
->mode
) ? "YES" : "NO"));
1248 DBG(LOWPROBE
, ul_debug("failed to prepare a device for low-probing"));
1253 int blkid_probe_get_dimension(blkid_probe pr
, uint64_t *off
, uint64_t *size
)
1260 int blkid_probe_set_dimension(blkid_probe pr
, uint64_t off
, uint64_t size
)
1262 DBG(LOWPROBE
, ul_debug(
1263 "changing probing area: size=%"PRIu64
", off=%"PRIu64
" "
1264 "-to-> size=%"PRIu64
", off=%"PRIu64
"",
1265 pr
->size
, pr
->off
, size
, off
));
1269 pr
->flags
&= ~BLKID_FL_TINY_DEV
;
1271 if (pr
->size
<= 1440ULL * 1024ULL && !S_ISCHR(pr
->mode
))
1272 pr
->flags
|= BLKID_FL_TINY_DEV
;
1274 blkid_probe_reset_buffers(pr
);
1279 const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr
, const struct blkid_idmag
*mag
, size_t size
)
1281 uint64_t hint_offset
, off
;
1283 if (mag
->kboff
>= 0) {
1284 if (!mag
->hoff
|| blkid_probe_get_hint(pr
, mag
->hoff
, &hint_offset
) < 0)
1287 off
= hint_offset
+ (mag
->kboff
<< 10);
1289 off
= pr
->size
- (-mag
->kboff
<< 10);
1292 return blkid_probe_get_buffer(pr
, off
, size
);
1295 uint64_t blkid_probe_get_idmag_off(blkid_probe pr
, const struct blkid_idmag
*mag
)
1297 if (mag
->kboff
>= 0)
1298 return mag
->kboff
<< 10;
1300 return pr
->size
- (-mag
->kboff
<< 10);
1304 * Check for matching magic value.
1305 * Returns BLKID_PROBE_OK if found, BLKID_PROBE_NONE if not found
1306 * or no magic present, or negative value on error.
1308 int blkid_probe_get_idmag(blkid_probe pr
, const struct blkid_idinfo
*id
,
1309 uint64_t *offset
, const struct blkid_idmag
**res
)
1311 const struct blkid_idmag
*mag
= NULL
;
1315 mag
= &id
->magics
[0];
1319 /* try to detect by magic string */
1320 while(mag
&& mag
->magic
) {
1321 const unsigned char *buf
;
1323 uint64_t hint_offset
;
1325 if (!mag
->hoff
|| blkid_probe_get_hint(pr
, mag
->hoff
, &hint_offset
) < 0)
1328 /* If the magic is for zoned device, skip non-zoned device */
1329 if (mag
->is_zoned
&& !pr
->zone_size
) {
1337 kboff
= ((mag
->zonenum
* pr
->zone_size
) >> 10) + mag
->kboff_inzone
;
1340 off
= hint_offset
+ (kboff
<< 10) + mag
->sboff
;
1342 off
= pr
->size
- (-kboff
<< 10) + mag
->sboff
;
1343 buf
= blkid_probe_get_buffer(pr
, off
, mag
->len
);
1348 if (buf
&& !memcmp(mag
->magic
, buf
, mag
->len
)) {
1349 DBG(LOWPROBE
, ul_debug("\tmagic sboff=%u, kboff=%ld",
1350 mag
->sboff
, kboff
));
1355 return BLKID_PROBE_OK
;
1360 if (id
&& id
->magics
[0].magic
)
1361 /* magic string(s) defined, but not found */
1362 return BLKID_PROBE_NONE
;
1364 return BLKID_PROBE_OK
;
1367 static inline void blkid_probe_start(blkid_probe pr
)
1369 DBG(LOWPROBE
, ul_debug("start probe"));
1370 pr
->cur_chain
= NULL
;
1372 blkid_probe_set_wiper(pr
, 0, 0);
1375 static inline void blkid_probe_end(blkid_probe pr
)
1377 DBG(LOWPROBE
, ul_debug("end probe"));
1378 pr
->cur_chain
= NULL
;
1380 blkid_probe_set_wiper(pr
, 0, 0);
1387 * Calls probing functions in all enabled chains. The superblocks chain is
1388 * enabled by default. The blkid_do_probe() stores result from only one
1389 * probing function. It's necessary to call this routine in a loop to get
1390 * results from all probing functions in all chains. The probing is reset
1391 * by blkid_reset_probe() or by filter functions.
1393 * This is string-based NAME=value interface only.
1396 * <title>basic case - use the first result only</title>
1398 * if (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1399 * int nvals = blkid_probe_numof_values(pr);
1400 * for (n = 0; n < nvals; n++) {
1401 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
1402 * printf("%s = %s\n", name, data);
1409 * <title>advanced case - probe for all signatures</title>
1411 * while (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1412 * int nvals = blkid_probe_numof_values(pr);
1418 * See also blkid_reset_probe().
1420 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
1422 int blkid_do_probe(blkid_probe pr
)
1426 if (pr
->flags
& BLKID_FL_NOSCAN_DEV
)
1427 return BLKID_PROBE_NONE
;
1430 struct blkid_chain
*chn
= pr
->cur_chain
;
1433 blkid_probe_start(pr
);
1434 chn
= pr
->cur_chain
= &pr
->chains
[0];
1436 /* we go to the next chain only when the previous probing
1437 * result was nothing (rc == 1) and when the current chain is
1438 * disabled or we are at end of the current chain (chain->idx +
1439 * 1 == sizeof chain) or the current chain bailed out right at
1440 * the start (chain->idx == -1)
1442 else if (rc
== 1 && (chn
->enabled
== FALSE
||
1443 chn
->idx
+ 1 == (int) chn
->driver
->nidinfos
||
1446 size_t idx
= chn
->driver
->id
+ 1;
1448 if (idx
< BLKID_NCHAINS
)
1449 chn
= pr
->cur_chain
= &pr
->chains
[idx
];
1451 blkid_probe_end(pr
);
1452 return BLKID_PROBE_NONE
; /* all chains already probed */
1456 chn
->binary
= FALSE
; /* for sure... */
1458 DBG(LOWPROBE
, ul_debug("chain probe %s %s (idx=%d)",
1460 chn
->enabled
? "ENABLED" : "DISABLED",
1466 /* rc: -1 = error, 0 = success, 1 = no result */
1467 rc
= chn
->driver
->probe(pr
, chn
);
1469 } while (rc
== BLKID_PROBE_NONE
);
1472 return BLKID_PROBE_ERROR
;
1477 #ifdef HAVE_LINUX_BLKZONED_H
1478 static int is_conventional(blkid_probe pr
, uint64_t offset
)
1480 struct blk_zone_report
*rep
= NULL
;
1487 zone_mask
= ~(pr
->zone_size
- 1);
1488 rep
= blkdev_get_zonereport(blkid_probe_get_fd(pr
),
1489 (offset
& zone_mask
) >> 9, 1);
1493 if (rep
->zones
[0].type
== BLK_ZONE_TYPE_CONVENTIONAL
)
1503 static inline int is_conventional(blkid_probe pr
__attribute__((__unused__
)),
1504 uint64_t offset
__attribute__((__unused__
)))
1513 * @dryrun: if TRUE then don't touch the device.
1515 * This function erases the current signature detected by @pr. The @pr has to
1516 * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
1517 * has to be enabled (if you want to erase also superblock with broken check
1518 * sums then use BLKID_SUBLKS_BADCSUM too).
1520 * After successful signature removing the @pr prober will be moved one step
1521 * back and the next blkid_do_probe() call will again call previously called
1522 * probing function. All in-memory cached data from the device are always
1526 * <title>wipe all filesystems or raids from the device</title>
1528 * fd = open(devname, O_RDWR|O_CLOEXEC);
1529 * blkid_probe_set_device(pr, fd, 0, 0);
1531 * blkid_probe_enable_superblocks(pr, 1);
1532 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1534 * while (blkid_do_probe(pr) == 0)
1535 * blkid_do_wipe(pr, FALSE);
1539 * See also blkid_probe_step_back() if you cannot use this built-in wipe
1540 * function, but you want to use libblkid probing as a source for wiping.
1542 * See also blkid_wipe_all() which works the same as the example above.
1544 * Returns: 0 on success, and -1 in case of error.
1546 int blkid_do_wipe(blkid_probe pr
, int dryrun
)
1548 const char *off
= NULL
;
1550 uint64_t offset
, magoff
;
1554 struct blkid_chain
*chn
;
1556 chn
= pr
->cur_chain
;
1558 return BLKID_PROBE_ERROR
;
1560 switch (chn
->driver
->id
) {
1561 case BLKID_CHAIN_SUBLKS
:
1562 rc
= blkid_probe_lookup_value(pr
, "SBMAGIC_OFFSET", &off
, NULL
);
1564 rc
= blkid_probe_lookup_value(pr
, "SBMAGIC", NULL
, &len
);
1566 case BLKID_CHAIN_PARTS
:
1567 rc
= blkid_probe_lookup_value(pr
, "PTMAGIC_OFFSET", &off
, NULL
);
1569 rc
= blkid_probe_lookup_value(pr
, "PTMAGIC", NULL
, &len
);
1572 return BLKID_PROBE_OK
;
1575 if (rc
|| len
== 0 || off
== NULL
)
1576 return BLKID_PROBE_OK
;
1579 magoff
= strtoumax(off
, NULL
, 10);
1581 return BLKID_PROBE_OK
;
1583 offset
= magoff
+ pr
->off
;
1584 fd
= blkid_probe_get_fd(pr
);
1586 return BLKID_PROBE_ERROR
;
1588 if (len
> sizeof(buf
))
1591 rc
= is_conventional(pr
, offset
);
1593 return BLKID_PROBE_ERROR
;
1594 conventional
= rc
== 1;
1596 DBG(LOWPROBE
, ul_debug(
1597 "do_wipe [offset=0x%"PRIx64
" (%"PRIu64
"), len=%zu, chain=%s, idx=%d, dryrun=%s]\n",
1598 offset
, offset
, len
, chn
->driver
->name
, chn
->idx
, dryrun
? "yes" : "not"));
1600 if (lseek(fd
, offset
, SEEK_SET
) == (off_t
) -1)
1601 return BLKID_PROBE_ERROR
;
1603 if (!dryrun
&& len
) {
1605 memset(buf
, 0, len
);
1607 /* wipen on device */
1608 if (write_all(fd
, buf
, len
))
1609 return BLKID_PROBE_ERROR
;
1611 return BLKID_PROBE_ERROR
;
1613 #ifdef HAVE_LINUX_BLKZONED_H
1614 uint64_t zone_mask
= ~(pr
->zone_size
- 1);
1615 struct blk_zone_range range
= {
1616 .sector
= (offset
& zone_mask
) >> 9,
1617 .nr_sectors
= pr
->zone_size
>> 9,
1620 rc
= ioctl(fd
, BLKRESETZONE
, &range
);
1622 return BLKID_PROBE_ERROR
;
1624 /* Should not reach here */
1629 pr
->flags
&= ~BLKID_FL_MODIF_BUFF
; /* be paranoid */
1631 return blkid_probe_step_back(pr
);
1636 /* wipe in memory only */
1637 blkid_probe_hide_range(pr
, magoff
, len
);
1638 return blkid_probe_step_back(pr
);
1641 return BLKID_PROBE_OK
;
1648 * This function erases all detectable signatures from &pr.
1649 * The @pr has to be open in O_RDWR mode. All other necessary configurations
1650 * will be enabled automatically.
1653 * <title>wipe all filesystems or raids from the device</title>
1655 * fd = open(devname, O_RDWR|O_CLOEXEC);
1656 * blkid_probe_set_device(pr, fd, 0, 0);
1658 * blkid_wipe_all(pr);
1662 * Returns: 0 on success, and -1 in case of error.
1664 int blkid_wipe_all(blkid_probe pr
)
1666 DBG(LOWPROBE
, ul_debug("wiping all signatures"));
1668 blkid_probe_enable_superblocks(pr
, 1);
1669 blkid_probe_set_superblocks_flags(pr
, BLKID_SUBLKS_MAGIC
|
1670 BLKID_SUBLKS_BADCSUM
);
1672 blkid_probe_enable_partitions(pr
, 1);
1673 blkid_probe_set_partitions_flags(pr
, BLKID_PARTS_MAGIC
|
1674 BLKID_PARTS_FORCE_GPT
);
1676 while (blkid_do_probe(pr
) == 0) {
1677 DBG(LOWPROBE
, ul_debug("wiping one signature"));
1678 blkid_do_wipe(pr
, 0);
1681 return BLKID_PROBE_OK
;
1685 * blkid_probe_step_back:
1688 * This function move pointer to the probing chain one step back -- it means
1689 * that the previously used probing function will be called again in the next
1690 * blkid_do_probe() call.
1692 * This is necessary for example if you erase or modify on-disk superblock
1693 * according to the current libblkid probing result.
1695 * Note that blkid_probe_hide_range() changes semantic of this function and
1696 * cached buffers are not reset, but library uses in-memory modified
1697 * buffers to call the next probing function.
1700 * <title>wipe all superblock, but use libblkid only for probing</title>
1702 * pr = blkid_new_probe_from_filename(devname);
1704 * blkid_probe_enable_superblocks(pr, 1);
1705 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1707 * blkid_probe_enable_partitions(pr, 1);
1708 * blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
1710 * while (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1711 * const char *ostr = NULL;
1715 * if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &ostr, NULL) == 0)
1716 * blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1718 * // partition tables
1719 * if (len == 0 && blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &ostr, NULL) == 0)
1720 * blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1725 * // convert ostr to the real offset by off = strtoll(ostr, NULL, 10);
1726 * // use your stuff to erase @len bytes at the @off
1729 * // retry the last probing to check for backup superblocks ..etc.
1730 * blkid_probe_step_back(pr);
1735 * Returns: 0 on success, and -1 in case of error.
1737 int blkid_probe_step_back(blkid_probe pr
)
1739 struct blkid_chain
*chn
;
1741 chn
= pr
->cur_chain
;
1745 if (!(pr
->flags
& BLKID_FL_MODIF_BUFF
))
1746 blkid_probe_reset_buffers(pr
);
1748 if (chn
->idx
>= 0) {
1750 DBG(LOWPROBE
, ul_debug("step back: moving %s chain index to %d",
1755 if (chn
->idx
== -1) {
1756 /* blkid_do_probe() goes to the next chain if the index
1757 * of the current chain is -1, so we have to set the
1758 * chain pointer to the previous chain.
1760 size_t idx
= chn
->driver
->id
> 0 ? chn
->driver
->id
- 1 : 0;
1762 DBG(LOWPROBE
, ul_debug("step back: moving to previous chain"));
1765 pr
->cur_chain
= &pr
->chains
[idx
];
1767 pr
->cur_chain
= NULL
;
1774 * blkid_do_safeprobe:
1777 * This function gathers probing results from all enabled chains and checks
1778 * for ambivalent results (e.g. more filesystems on the device).
1780 * This is string-based NAME=value interface only.
1782 * Note about superblocks chain -- the function does not check for filesystems
1783 * when a RAID signature is detected. The function also does not check for
1784 * collision between RAIDs. The first detected RAID is returned. The function
1785 * checks for collision between partition table and RAID signature -- it's
1786 * recommended to enable partitions chain together with superblocks chain.
1788 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalent result is
1789 * detected and -1 on case of error.
1791 int blkid_do_safeprobe(blkid_probe pr
)
1793 int i
, count
= 0, rc
= 0;
1795 if (pr
->flags
& BLKID_FL_NOSCAN_DEV
)
1796 return BLKID_PROBE_NONE
;
1798 blkid_probe_start(pr
);
1800 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
1801 struct blkid_chain
*chn
;
1803 chn
= pr
->cur_chain
= &pr
->chains
[i
];
1804 chn
->binary
= FALSE
; /* for sure... */
1806 DBG(LOWPROBE
, ul_debug("chain safeprobe %s %s",
1808 chn
->enabled
? "ENABLED" : "DISABLED"));
1813 blkid_probe_chain_reset_position(chn
);
1815 rc
= chn
->driver
->safeprobe(pr
, chn
);
1817 blkid_probe_chain_reset_position(chn
);
1819 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
1821 goto done
; /* error */
1823 count
++; /* success */
1827 blkid_probe_end(pr
);
1829 return BLKID_PROBE_ERROR
;
1831 return count
== 0 ? BLKID_PROBE_NONE
: BLKID_PROBE_OK
;
1835 * blkid_do_fullprobe:
1838 * This function gathers probing results from all enabled chains. Same as
1839 * blkid_do_safeprobe() but does not check for collision between probing
1842 * This is string-based NAME=value interface only.
1844 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
1846 int blkid_do_fullprobe(blkid_probe pr
)
1848 int i
, count
= 0, rc
= 0;
1850 if (pr
->flags
& BLKID_FL_NOSCAN_DEV
)
1851 return BLKID_PROBE_NONE
;
1853 blkid_probe_start(pr
);
1855 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
1856 struct blkid_chain
*chn
;
1858 chn
= pr
->cur_chain
= &pr
->chains
[i
];
1859 chn
->binary
= FALSE
; /* for sure... */
1861 DBG(LOWPROBE
, ul_debug("chain fullprobe %s: %s",
1863 chn
->enabled
? "ENABLED" : "DISABLED"));
1868 blkid_probe_chain_reset_position(chn
);
1870 rc
= chn
->driver
->probe(pr
, chn
);
1872 blkid_probe_chain_reset_position(chn
);
1874 /* rc: -1 = error, 0 = success, 1 = no result */
1876 goto done
; /* error */
1878 count
++; /* success */
1882 blkid_probe_end(pr
);
1884 return BLKID_PROBE_ERROR
;
1886 return count
== 0 ? BLKID_PROBE_NONE
: BLKID_PROBE_OK
;
1889 /* same sa blkid_probe_get_buffer() but works with 512-sectors */
1890 const unsigned char *blkid_probe_get_sector(blkid_probe pr
, unsigned int sector
)
1892 return blkid_probe_get_buffer(pr
, ((uint64_t) sector
) << 9, 0x200);
1895 struct blkid_prval
*blkid_probe_assign_value(blkid_probe pr
, const char *name
)
1897 struct blkid_prval
*v
;
1899 v
= calloc(1, sizeof(struct blkid_prval
));
1903 INIT_LIST_HEAD(&v
->prvals
);
1905 v
->chain
= pr
->cur_chain
;
1906 list_add_tail(&v
->prvals
, &pr
->values
);
1908 DBG(LOWPROBE
, ul_debug("assigning %s [%s]", name
, v
->chain
->driver
->name
));
1912 /* Note that value data is always terminated by zero to keep things robust,
1913 * this extra zero is not count to the value length. It's caller responsibility
1914 * to set proper value length (for strings we count terminator to the length,
1915 * for binary data it's without terminator).
1917 int blkid_probe_value_set_data(struct blkid_prval
*v
,
1918 const unsigned char *data
, size_t len
)
1920 v
->data
= calloc(1, len
+ 1); /* always terminate by \0 */
1924 memcpy(v
->data
, data
, len
);
1929 int blkid_probe_set_value(blkid_probe pr
, const char *name
,
1930 const unsigned char *data
, size_t len
)
1932 struct blkid_prval
*v
;
1934 v
= blkid_probe_assign_value(pr
, name
);
1938 return blkid_probe_value_set_data(v
, data
, len
);
1941 int blkid_probe_vsprintf_value(blkid_probe pr
, const char *name
,
1942 const char *fmt
, va_list ap
)
1944 struct blkid_prval
*v
;
1947 v
= blkid_probe_assign_value(pr
, name
);
1951 len
= vasprintf((char **) &v
->data
, fmt
, ap
);
1954 blkid_probe_free_value(v
);
1955 return len
== 0 ? -EINVAL
: -ENOMEM
;
1961 int blkid_probe_sprintf_value(blkid_probe pr
, const char *name
,
1962 const char *fmt
, ...)
1968 rc
= blkid_probe_vsprintf_value(pr
, name
, fmt
, ap
);
1974 int blkid_probe_set_magic(blkid_probe pr
, uint64_t offset
,
1975 size_t len
, const unsigned char *magic
)
1978 struct blkid_chain
*chn
= blkid_probe_get_chain(pr
);
1980 if (!chn
|| !len
|| chn
->binary
)
1983 switch (chn
->driver
->id
) {
1984 case BLKID_CHAIN_SUBLKS
:
1985 if (!(chn
->flags
& BLKID_SUBLKS_MAGIC
))
1987 rc
= blkid_probe_set_value(pr
, "SBMAGIC", magic
, len
);
1989 rc
= blkid_probe_sprintf_value(pr
,
1990 "SBMAGIC_OFFSET", "%llu", (unsigned long long)offset
);
1992 case BLKID_CHAIN_PARTS
:
1993 if (!(chn
->flags
& BLKID_PARTS_MAGIC
))
1995 rc
= blkid_probe_set_value(pr
, "PTMAGIC", magic
, len
);
1997 rc
= blkid_probe_sprintf_value(pr
,
1998 "PTMAGIC_OFFSET", "%llu", (unsigned long long)offset
);
2007 static void blkid_probe_log_csum_mismatch(blkid_probe pr
, size_t n
, const void *csum
,
2008 const void *expected
)
2011 char expected_hex
[sizeof(csum_hex
)];
2012 int hex_size
= min(sizeof(csum_hex
), n
* 2);
2014 for (int i
= 0; i
< hex_size
; i
+=2) {
2015 sprintf(&csum_hex
[i
], "%02X", ((const unsigned char *) csum
)[i
/ 2]);
2016 sprintf(&expected_hex
[i
], "%02X", ((const unsigned char *) expected
)[i
/ 2]);
2019 DBG(LOWPROBE
, ul_debug(
2020 "incorrect checksum for type %s,"
2021 " got %*s, expected %*s",
2022 blkid_probe_get_probername(pr
),
2023 hex_size
, csum_hex
, hex_size
, expected_hex
));
2027 int blkid_probe_verify_csum_buf(blkid_probe pr
, size_t n
, const void *csum
,
2028 const void *expected
)
2030 if (memcmp(csum
, expected
, n
) != 0) {
2031 struct blkid_chain
*chn
= blkid_probe_get_chain(pr
);
2033 ON_DBG(LOWPROBE
, blkid_probe_log_csum_mismatch(pr
, n
, csum
, expected
));
2036 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
2038 if (chn
&& chn
->driver
->id
== BLKID_CHAIN_SUBLKS
2039 && (chn
->flags
& BLKID_SUBLKS_BADCSUM
)) {
2040 blkid_probe_set_value(pr
, "SBBADCSUM", (unsigned char *) "1", 2);
2043 return 0; /* bad checksum */
2050 int blkid_probe_verify_csum(blkid_probe pr
, uint64_t csum
, uint64_t expected
)
2052 return blkid_probe_verify_csum_buf(pr
, sizeof(csum
), &csum
, &expected
);
2056 * blkid_probe_get_devno:
2059 * Returns: block device number, or 0 for regular files.
2061 dev_t
blkid_probe_get_devno(blkid_probe pr
)
2067 * blkid_probe_get_wholedisk_devno:
2070 * Returns: device number of the wholedisk, or 0 for regular files.
2072 dev_t
blkid_probe_get_wholedisk_devno(blkid_probe pr
)
2074 if (!pr
->disk_devno
) {
2075 dev_t devno
, disk_devno
= 0;
2077 devno
= blkid_probe_get_devno(pr
);
2081 if (blkid_devno_to_wholedisk(devno
, NULL
, 0, &disk_devno
) == 0)
2082 pr
->disk_devno
= disk_devno
;
2084 return pr
->disk_devno
;
2088 * blkid_probe_is_wholedisk:
2091 * Returns: 1 if the device is whole-disk or 0.
2093 int blkid_probe_is_wholedisk(blkid_probe pr
)
2095 dev_t devno
, disk_devno
;
2097 devno
= blkid_probe_get_devno(pr
);
2101 disk_devno
= blkid_probe_get_wholedisk_devno(pr
);
2105 return devno
== disk_devno
;
2108 blkid_probe
blkid_probe_get_wholedisk_probe(blkid_probe pr
)
2112 if (blkid_probe_is_wholedisk(pr
))
2113 return NULL
; /* this is not partition */
2116 /* this is cloned blkid_probe, use parent's stuff */
2117 return blkid_probe_get_wholedisk_probe(pr
->parent
);
2119 disk
= blkid_probe_get_wholedisk_devno(pr
);
2121 if (pr
->disk_probe
&& pr
->disk_probe
->devno
!= disk
) {
2122 /* we have disk prober, but for another disk... close it */
2123 blkid_free_probe(pr
->disk_probe
);
2124 pr
->disk_probe
= NULL
;
2127 if (!pr
->disk_probe
) {
2128 /* Open a new disk prober */
2129 char *disk_path
= blkid_devno_to_devname(disk
);
2135 DBG(LOWPROBE
, ul_debug("allocate a wholedisk probe"));
2137 pr
->disk_probe
= blkid_new_probe_from_filename(disk_path
);
2141 if (!pr
->disk_probe
)
2142 return NULL
; /* ENOMEM? */
2144 flags
= blkid_probe_get_partitions_flags(pr
);
2145 if (flags
& BLKID_PARTS_FORCE_GPT
)
2146 blkid_probe_set_partitions_flags(pr
->disk_probe
,
2147 BLKID_PARTS_FORCE_GPT
);
2150 return pr
->disk_probe
;
2154 * blkid_probe_get_size:
2157 * This function returns size of probing area as defined by blkid_probe_set_device().
2158 * If the size of the probing area is unrestricted then this function returns
2159 * the real size of device. See also blkid_get_dev_size().
2161 * Returns: size in bytes or -1 in case of error.
2163 blkid_loff_t
blkid_probe_get_size(blkid_probe pr
)
2165 return (blkid_loff_t
) pr
->size
;
2169 * blkid_probe_get_offset:
2172 * This function returns offset of probing area as defined by blkid_probe_set_device().
2174 * Returns: offset in bytes or -1 in case of error.
2176 blkid_loff_t
blkid_probe_get_offset(blkid_probe pr
)
2178 return (blkid_loff_t
) pr
->off
;
2182 * blkid_probe_get_fd:
2185 * Returns: file descriptor for assigned device/file or -1 in case of error.
2187 int blkid_probe_get_fd(blkid_probe pr
)
2193 * blkid_probe_get_sectorsize:
2194 * @pr: probe or NULL (for NULL returns 512)
2196 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
2198 unsigned int blkid_probe_get_sectorsize(blkid_probe pr
)
2203 if (S_ISBLK(pr
->mode
) &&
2204 blkdev_get_sector_size(pr
->fd
, (int *) &pr
->blkssz
) == 0)
2207 pr
->blkssz
= DEFAULT_SECTOR_SIZE
;
2212 * blkid_probe_set_sectorsize:
2214 * @sz: new size (to overwrite system default)
2216 * Note that blkid_probe_set_device() resets this setting. Use it after
2217 * blkid_probe_set_device() and before any probing call.
2221 * Returns: 0 or <0 in case of error
2223 int blkid_probe_set_sectorsize(blkid_probe pr
, unsigned int sz
)
2230 * blkid_probe_get_sectors:
2233 * Returns: 512-byte sector count or -1 in case of error.
2235 blkid_loff_t
blkid_probe_get_sectors(blkid_probe pr
)
2237 return (blkid_loff_t
) (pr
->size
>> 9);
2241 * blkid_probe_numof_values:
2244 * Returns: number of values in probing result or -1 in case of error.
2246 int blkid_probe_numof_values(blkid_probe pr
)
2249 struct list_head
*p
;
2251 list_for_each(p
, &pr
->values
)
2257 * blkid_probe_get_value:
2259 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
2260 * @name: pointer to return value name or NULL
2261 * @data: pointer to return value data or NULL
2262 * @len: pointer to return value length or NULL
2264 * Note, the @len returns length of the @data, including the terminating
2267 * Returns: 0 on success, or -1 in case of error.
2269 int blkid_probe_get_value(blkid_probe pr
, int num
, const char **name
,
2270 const char **data
, size_t *len
)
2272 struct blkid_prval
*v
= __blkid_probe_get_value(pr
, num
);
2279 *data
= (char *) v
->data
;
2283 DBG(LOWPROBE
, ul_debug("returning %s value", v
->name
));
2288 * blkid_probe_lookup_value:
2290 * @name: name of value
2291 * @data: pointer to return value data or NULL
2292 * @len: pointer to return value length or NULL
2294 * Note, the @len returns length of the @data, including the terminating
2297 * Returns: 0 on success, or -1 in case of error.
2299 int blkid_probe_lookup_value(blkid_probe pr
, const char *name
,
2300 const char **data
, size_t *len
)
2302 struct blkid_prval
*v
= __blkid_probe_lookup_value(pr
, name
);
2307 *data
= (char *) v
->data
;
2314 * blkid_probe_has_value:
2316 * @name: name of value
2318 * Returns: 1 if value exist in probing result, otherwise 0.
2320 int blkid_probe_has_value(blkid_probe pr
, const char *name
)
2322 if (blkid_probe_lookup_value(pr
, name
, NULL
, NULL
) == 0)
2327 struct blkid_prval
*__blkid_probe_get_value(blkid_probe pr
, int num
)
2330 struct list_head
*p
;
2335 list_for_each(p
, &pr
->values
) {
2338 return list_entry(p
, struct blkid_prval
, prvals
);
2343 struct blkid_prval
*__blkid_probe_lookup_value(blkid_probe pr
, const char *name
)
2345 struct list_head
*p
;
2347 if (list_empty(&pr
->values
))
2350 list_for_each(p
, &pr
->values
) {
2351 struct blkid_prval
*v
= list_entry(p
, struct blkid_prval
,
2354 if (v
->name
&& strcmp(name
, v
->name
) == 0) {
2355 DBG(LOWPROBE
, ul_debug("returning %s value", v
->name
));
2363 /* converts DCE UUID (uuid[16]) to human readable string
2364 * - the @len should be always 37 */
2365 void blkid_unparse_uuid(const unsigned char *uuid
, char *str
, size_t len
)
2368 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2369 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
2373 uuid
[10], uuid
[11], uuid
[12], uuid
[13], uuid
[14],uuid
[15]);
2376 /* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
2377 int blkid_uuid_is_empty(const unsigned char *buf
, size_t len
)
2381 for (i
= 0; i
< len
; i
++)
2387 /* Removes whitespace from the right-hand side of a string (trailing
2390 * Returns size of the new string (without \0).
2392 size_t blkid_rtrim_whitespace(unsigned char *str
)
2394 return rtrim_whitespace(str
);
2397 /* Removes whitespace from the left-hand side of a string.
2399 * Returns size of the new string (without \0).
2401 size_t blkid_ltrim_whitespace(unsigned char *str
)
2403 return ltrim_whitespace(str
);
2407 * Some mkfs-like utils wipe some parts (usually begin) of the device.
2408 * For example LVM (pvcreate) or mkswap(8). This information could be used
2409 * for later resolution to conflicts between superblocks.
2411 * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
2412 * the device. If we found another signature (for example MBR) within the
2413 * wiped area then the signature has been added later and LVM superblock
2416 * Note that this heuristic is not 100% reliable, for example "pvcreate --zero n"
2417 * can be used to keep the begin of the device unmodified. It's probably better
2418 * to use this heuristic for conflicts between superblocks and partition tables
2419 * than for conflicts between filesystem superblocks -- existence of unwanted
2420 * partition table is very unusual, because PT is pretty visible (parsed and
2421 * interpreted by kernel).
2423 * Note that we usually expect only one signature on the device, it means that
2424 * we have to remember only one wiped area from previously successfully
2425 * detected signature.
2427 * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM)
2428 * blkid_probe_use_wiper() -- try to use area (e.g. MBR)
2430 * Note that there is not relation between _wiper and blkid_to_wipe().
2433 void blkid_probe_set_wiper(blkid_probe pr
, uint64_t off
, uint64_t size
)
2435 struct blkid_chain
*chn
;
2438 DBG(LOWPROBE
, ul_debug("zeroize wiper"));
2439 pr
->wipe_size
= pr
->wipe_off
= 0;
2440 pr
->wipe_chain
= NULL
;
2444 chn
= pr
->cur_chain
;
2446 if (!chn
|| !chn
->driver
||
2447 chn
->idx
< 0 || (size_t) chn
->idx
>= chn
->driver
->nidinfos
)
2450 pr
->wipe_size
= size
;
2452 pr
->wipe_chain
= chn
;
2455 ul_debug("wiper set to %s::%s off=%"PRIu64
" size=%"PRIu64
"",
2457 chn
->driver
->idinfos
[chn
->idx
]->name
,
2458 pr
->wipe_off
, pr
->wipe_size
));
2462 * Returns 1 if the <@off,@size> area was wiped
2464 int blkid_probe_is_wiped(blkid_probe pr
, struct blkid_chain
**chn
, uint64_t off
, uint64_t size
)
2469 if (pr
->wipe_off
<= off
&& off
+ size
<= pr
->wipe_off
+ pr
->wipe_size
) {
2470 *chn
= pr
->wipe_chain
;
2477 * Try to use any area -- if the area has been previously wiped then the
2478 * previous probing result should be ignored (reset).
2480 void blkid_probe_use_wiper(blkid_probe pr
, uint64_t off
, uint64_t size
)
2482 struct blkid_chain
*chn
= NULL
;
2484 if (blkid_probe_is_wiped(pr
, &chn
, off
, size
) && chn
) {
2485 DBG(LOWPROBE
, ul_debug("previously wiped area modified "
2486 " -- ignore previous results"));
2487 blkid_probe_set_wiper(pr
, 0, 0);
2488 blkid_probe_chain_reset_values(pr
, chn
);
2492 static struct blkid_hint
*get_hint(blkid_probe pr
, const char *name
)
2494 struct list_head
*p
;
2496 if (list_empty(&pr
->hints
))
2499 list_for_each(p
, &pr
->hints
) {
2500 struct blkid_hint
*h
= list_entry(p
, struct blkid_hint
, hints
);
2502 if (h
->name
&& strcmp(name
, h
->name
) == 0)
2509 * blkid_probe_set_hint:
2511 * @name: hint name or NAME=value
2512 * @value: offset or another number
2514 * Sets extra hint for low-level prober. If the hint is set by NAME=value
2515 * notation than @value is ignored. The functions blkid_probe_set_device()
2516 * and blkid_reset_probe() resets all hints.
2518 * The hints are optional way how to force libblkid probing functions to check
2519 * for example another location.
2521 * Returns: 0 on success, or -1 in case of error.
2523 int blkid_probe_set_hint(blkid_probe pr
, const char *name
, uint64_t value
)
2525 struct blkid_hint
*hint
= NULL
;
2526 char *n
= NULL
, *v
= NULL
;
2528 if (strchr(name
, '=')) {
2531 if (blkid_parse_tag_string(name
, &n
, &v
) != 0)
2535 value
= strtoumax(v
, &end
, 10);
2537 if (errno
|| v
== end
|| (end
&& *end
))
2541 hint
= get_hint(pr
, n
? n
: name
);
2543 /* alter old hint */
2544 hint
->value
= value
;
2546 ul_debug("updated hint '%s' to %"PRIu64
"", hint
->name
, hint
->value
));
2548 /* add a new hint */
2554 hint
= malloc(sizeof(*hint
));
2559 hint
->value
= value
;
2561 INIT_LIST_HEAD(&hint
->hints
);
2562 list_add_tail(&hint
->hints
, &pr
->hints
);
2565 ul_debug("new hint '%s' is %"PRIu64
"", hint
->name
, hint
->value
));
2573 return errno
? -errno
: -EINVAL
;
2577 int blkid_probe_get_hint(blkid_probe pr
, const char *name
, uint64_t *value
)
2579 struct blkid_hint
*h
= get_hint(pr
, name
);
2589 * blkid_probe_reset_hints:
2592 * Removes all previously defined probinig hints. See also blkid_probe_set_hint().
2594 void blkid_probe_reset_hints(blkid_probe pr
)
2596 if (list_empty(&pr
->hints
))
2599 DBG(LOWPROBE
, ul_debug("resetting hints"));
2601 while (!list_empty(&pr
->hints
)) {
2602 struct blkid_hint
*h
= list_entry(pr
->hints
.next
,
2603 struct blkid_hint
, hints
);
2604 list_del(&h
->hints
);
2609 INIT_LIST_HEAD(&pr
->hints
);