2 * probe.c - reads tags (LABEL, UUID, FS type, ..) from a block device
4 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
16 #include <sys/types.h>
17 #ifdef HAVE_SYS_STAT_H
20 #ifdef HAVE_SYS_MKDEV_H
21 #include <sys/mkdev.h>
30 # ifdef HAVE_UUID_UUID_H
31 # include <uuid/uuid.h>
40 #include "superblocks/superblocks.h"
43 extern const struct blkid_chaindrv superblocks_drv
;
46 * All supported chains
48 static const struct blkid_chaindrv
*chains_drvs
[] = {
49 [BLKID_CHAIN_SUBLKS
] = &superblocks_drv
,
52 static void blkid_probe_reset_vals(blkid_probe pr
);
54 static const struct blkid_idinfo
*idinfos
[] =
112 # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
115 #define BLKID_FLTR_ITEMS ARRAY_SIZE(idinfos)
116 #define BLKID_FLTR_SIZE blkid_bmp_nwords(BLKID_FLTR_ITEMS)
118 static int blkid_probe_set_usage(blkid_probe pr
, int usage
);
123 * Returns: a pointer to the newly allocated probe struct.
125 blkid_probe
blkid_new_probe(void)
131 pr
= calloc(1, sizeof(struct blkid_struct_probe
));
135 /* initialize chains */
136 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
137 pr
->chains
[i
].driver
= chains_drvs
[i
];
138 pr
->chains
[i
].flags
= chains_drvs
[i
]->dflt_flags
;
139 pr
->chains
[i
].enabled
= chains_drvs
[i
]->dflt_enabled
;
148 * Deallocates the probe struct, buffers and all allocated
149 * data that are associated with this probing control struct.
151 void blkid_free_probe(blkid_probe pr
)
158 for (i
= 0; i
< BLKID_NCHAINS
; i
++) {
159 struct blkid_chain
*ch
= &pr
->chains
[i
];
161 if (ch
->driver
->free_data
)
162 ch
->driver
->free_data(pr
, ch
->data
);
170 static void blkid_probe_reset_buffer(blkid_probe pr
)
172 DBG(DEBUG_LOWPROBE
, printf("reseting blkid probe buffer\n"));
174 memset(pr
->buf
, 0, pr
->buf_max
);
178 memset(pr
->sbbuf
, 0, BLKID_SB_BUFSIZ
);
184 * Removes chain values from probing result.
186 void blkid_probe_chain_reset_vals(blkid_probe pr
, struct blkid_chain
*chn
)
188 int nvals
= pr
->nvals
;
191 for (x
= 0, i
= 0; i
< pr
->nvals
; i
++) {
192 struct blkid_prval
*v
= &pr
->vals
[i
];
194 if (v
->chain
!= chn
&& x
== i
) {
198 if (v
->chain
== chn
) {
202 memcpy(&pr
->vals
[x
++], v
, sizeof(struct blkid_prval
));
208 * Copies chain values from probing result to @vals, the max size of @vals is
209 * @nvals and returns real number of values.
211 int blkid_probe_chain_copy_vals(blkid_probe pr
, struct blkid_chain
*chn
,
212 struct blkid_prval
*vals
, int nvals
)
216 for (x
= 0, i
= 0; i
< pr
->nvals
&& x
< nvals
; i
++) {
217 struct blkid_prval
*v
= &pr
->vals
[i
];
221 memcpy(&vals
[x
++], v
, sizeof(struct blkid_prval
));
227 * Appends values from @vals to the probing result
229 void blkid_probe_append_vals(blkid_probe pr
, struct blkid_prval
*vals
, int nvals
)
233 while (i
< nvals
&& pr
->nvals
< BLKID_NVALS
) {
234 memcpy(&pr
->vals
[pr
->nvals
++], &vals
[i
++],
235 sizeof(struct blkid_prval
));
239 static void blkid_probe_reset_vals(blkid_probe pr
)
241 memset(pr
->vals
, 0, sizeof(pr
->vals
));
245 struct blkid_chain
*blkid_probe_get_chain(blkid_probe pr
)
247 return pr
->cur_chain
;
254 * Cleanup probing result. This function does not touch probing filters
255 * and keeps assigned device.
257 void blkid_reset_probe(blkid_probe pr
)
264 blkid_probe_reset_buffer(pr
);
265 blkid_probe_reset_vals(pr
);
267 for (i
= 0; i
< BLKID_NCHAINS
; i
++)
268 pr
->chains
[i
].idx
= -1;
272 static int blkid_probe_dump_filter(blkid_probe pr, int chain)
274 struct blkid_chain *chn;
277 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
280 chn = &pr->chains[chain];
285 for (i = 0; i < chn->driver->nidinfos; i++) {
286 const struct blkid_idinfo *id = chn->driver->idinfos[i];
288 DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n",
291 blkid_bmp_get_item(chn->fltr, i)
292 ? "disabled" : "enabled <--"));
299 * Returns properly initialized chain filter
301 unsigned long *blkid_probe_get_filter(blkid_probe pr
, int chain
, int create
)
303 struct blkid_chain
*chn
;
305 if (!pr
|| chain
< 0 || chain
>= BLKID_NCHAINS
)
308 chn
= &pr
->chains
[chain
];
310 /* always when you touch the chain filter all indexes are reseted and
311 * probing starts from scratch
314 pr
->cur_chain
= NULL
;
316 if (!chn
->driver
->has_fltr
|| (!chn
->fltr
&& !create
))
320 chn
->fltr
= calloc(1, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
322 memset(chn
->fltr
, 0, blkid_bmp_nbytes(chn
->driver
->nidinfos
));
324 /* blkid_probe_dump_filter(pr, chain); */
329 * Generic private functions for filter setting
331 int __blkid_probe_invert_filter(blkid_probe pr
, int chain
)
334 struct blkid_chain
*chn
;
337 fltr
= blkid_probe_get_filter(pr
, chain
, FALSE
);
341 chn
= &pr
->chains
[chain
];
343 for (i
= 0; i
< blkid_bmp_nwords(chn
->driver
->nidinfos
); i
++)
346 DBG(DEBUG_LOWPROBE
, printf("probing filter inverted\n"));
347 /* blkid_probe_dump_filter(pr, chain); */
351 int __blkid_probe_reset_filter(blkid_probe pr
, int chain
)
353 return blkid_probe_get_filter(pr
, chain
, FALSE
) ? 0 : -1;
356 int __blkid_probe_filter_types(blkid_probe pr
, int chain
, int flag
, char *names
[])
359 struct blkid_chain
*chn
;
362 fltr
= blkid_probe_get_filter(pr
, chain
, TRUE
);
366 chn
= &pr
->chains
[chain
];
368 for (i
= 0; i
< chn
->driver
->nidinfos
; i
++) {
370 const struct blkid_idinfo
*id
= chn
->driver
->idinfos
[i
];
373 for (n
= names
; *n
; n
++) {
374 if (!strcmp(id
->name
, *n
)) {
379 if (flag
& BLKID_FLTR_ONLYIN
) {
381 blkid_bmp_set_item(fltr
, i
);
382 } else if (flag
& BLKID_FLTR_NOTIN
) {
384 blkid_bmp_set_item(fltr
, i
);
389 printf("%s: a new probing type-filter initialized\n",
391 /* blkid_probe_dump_filter(pr, chain); */
396 * Note that we have two offsets:
398 * 1/ general device offset (pr->off), that's useful for example when we
399 * probe a partition from whole disk image:
400 * blkid-low --offset <partition_position> disk.img
402 * 2/ buffer offset (the 'off' argument), that useful for offsets in
405 * That means never use lseek(fd, 0, SEEK_SET), the zero position is always
406 * pr->off, so lseek(fd, pr->off, SEEK_SET).
409 unsigned char *blkid_probe_get_buffer(blkid_probe pr
,
410 blkid_loff_t off
, blkid_loff_t len
)
412 ssize_t ret_read
= 0;
414 if (off
< 0 || len
< 0) {
416 printf("unexpected offset or length of buffer requested\n"));
419 if (off
+ len
<= BLKID_SB_BUFSIZ
) {
421 pr
->sbbuf
= malloc(BLKID_SB_BUFSIZ
);
425 if (!pr
->sbbuf_len
) {
426 if (lseek(pr
->fd
, pr
->off
, SEEK_SET
) < 0)
428 ret_read
= read(pr
->fd
, pr
->sbbuf
, BLKID_SB_BUFSIZ
);
431 pr
->sbbuf_len
= ret_read
;
433 if (off
+ len
> pr
->sbbuf_len
)
435 return pr
->sbbuf
+ off
;
437 unsigned char *newbuf
= NULL
;
439 if (len
> pr
->buf_max
) {
440 newbuf
= realloc(pr
->buf
, len
);
448 if (newbuf
|| off
< pr
->buf_off
||
449 off
+ len
> pr
->buf_off
+ pr
->buf_len
) {
451 if (blkid_llseek(pr
->fd
, pr
->off
+ off
, SEEK_SET
) < 0)
454 ret_read
= read(pr
->fd
, pr
->buf
, len
);
455 if (ret_read
!= (ssize_t
) len
)
460 return off
? pr
->buf
+ (off
- pr
->buf_off
) : pr
->buf
;
465 * blkid_probe_set_device:
467 * @fd: device file descriptor
468 * @off: begin of probing area
469 * @size: size of probing area
471 * Assigns the device to probe control struct, resets internal buffers and
472 * reads 512 bytes from device to the buffers.
474 * Returns: -1 in case of failure, or 0 on success.
476 int blkid_probe_set_device(blkid_probe pr
, int fd
,
477 blkid_loff_t off
, blkid_loff_t size
)
482 blkid_reset_probe(pr
);
499 pr
->mode
= sb
.st_mode
;
501 if (S_ISBLK(sb
.st_mode
)) {
502 blkdev_get_size(fd
, (unsigned long long *) &pr
->size
);
503 pr
->devno
= sb
.st_rdev
;
505 pr
->size
= sb
.st_size
;
510 /* read SB to test if the device is readable */
511 if (!blkid_probe_get_buffer(pr
, 0, 0x200)) {
513 printf("failed to prepare a device for low-probing\n"));
517 DBG(DEBUG_LOWPROBE
, printf("ready for low-probing, offset=%zd, size=%zd\n",
525 * The blkid_do_probe() calls the probe functions. This routine could be used
526 * in a loop when you need to probe for all possible filesystems/raids.
528 * 1/ basic case -- use the first result:
530 * if (blkid_do_probe(pr) == 0) {
531 * int nvals = blkid_probe_numof_values(pr);
532 * for (n = 0; n < nvals; n++) {
533 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
534 * printf("%s = %s\n", name, data);
538 * 2/ advanced case -- probe for all signatures (don't forget that some
539 * filesystems can co-exist on one volume (e.g. CD-ROM).
541 * while (blkid_do_probe(pr) == 0) {
542 * int nvals = blkid_probe_numof_values(pr);
546 * The internal probing index (pointer to the last probing function) is
547 * always reseted when you touch probing filter or set a new device. It
548 * means you cannot use:
550 * blkid_probe_invert_filter()
551 * blkid_probe_filter_usage()
552 * blkid_probe_filter_types()
553 * blkid_probe_reset_filter()
554 * blkid_probe_set_device()
556 * in the loop (e.g while()) when you iterate on all signatures.
558 int blkid_do_probe(blkid_probe pr
)
562 if (!pr
|| pr
->idx
< -1)
565 blkid_probe_reset_vals(pr
);
568 printf("--> starting probing loop [idx=%d]\n",
573 for ( ; i
< ARRAY_SIZE(idinfos
); i
++) {
574 const struct blkid_idinfo
*id
;
575 const struct blkid_idmag
*mag
;
580 if (pr
->fltr
&& blkid_bmp_get_item(pr
->fltr
, i
))
584 mag
= id
->magics
? &id
->magics
[0] : NULL
;
586 /* try to detect by magic string */
587 while(mag
&& mag
->magic
) {
591 idx
= mag
->kboff
+ (mag
->sboff
>> 10);
592 buf
= blkid_probe_get_buffer(pr
, idx
<< 10, 1024);
594 if (buf
&& !memcmp(mag
->magic
,
595 buf
+ (mag
->sboff
& 0x3ff), mag
->len
)) {
596 DBG(DEBUG_LOWPROBE
, printf(
597 "%s: magic sboff=%u, kboff=%ld\n",
598 id
->name
, mag
->sboff
, mag
->kboff
));
605 if (hasmag
== 0 && id
->magics
&& id
->magics
[0].magic
)
606 /* magic string(s) defined, but not found */
609 /* final check by probing function */
611 DBG(DEBUG_LOWPROBE
, printf(
612 "%s: call probefunc()\n", id
->name
));
613 if (id
->probefunc(pr
, mag
) != 0)
617 /* all cheks passed */
618 if (pr
->probreq
& BLKID_PROBREQ_TYPE
)
619 blkid_probe_set_value(pr
, "TYPE",
620 (unsigned char *) id
->name
,
621 strlen(id
->name
) + 1);
622 if (pr
->probreq
& BLKID_PROBREQ_USAGE
)
623 blkid_probe_set_usage(pr
, id
->usage
);
626 printf("<-- leaving probing loop (type=%s) [idx=%d]\n",
631 printf("<-- leaving probing loop (failed) [idx=%d]\n",
637 * This is the same function as blkid_do_probe(), but returns only one result
638 * (cannot be used in while()) and checks for ambivalen results (more
639 * filesystems on the device) -- in such case returns -2.
641 * The function does not check for filesystems when a RAID signature is
642 * detected. The function also does not check for collision between RAIDs. The
643 * first detected RAID is returned.
645 int blkid_do_safeprobe(blkid_probe pr
)
647 struct blkid_struct_probe first
;
652 while ((rc
= blkid_do_probe(pr
)) == 0) {
654 /* store the fist result */
655 memcpy(first
.vals
, pr
->vals
, sizeof(first
.vals
));
656 first
.nvals
= pr
->nvals
;
661 if (idinfos
[pr
->idx
]->usage
& BLKID_USAGE_RAID
)
663 if (!(idinfos
[pr
->idx
]->flags
& BLKID_IDINFO_TOLERANT
))
667 return rc
; /* error */
668 if (count
> 1 && intol
) {
670 printf("ERROR: ambivalent result detected (%d filesystems)!\n",
672 return -2; /* error, ambivalent result (more FS) */
675 return 1; /* nothing detected */
677 /* restore the first result */
678 memcpy(pr
->vals
, first
.vals
, sizeof(first
.vals
));
679 pr
->nvals
= first
.nvals
;
685 int blkid_probe_numof_values(blkid_probe pr
)
692 struct blkid_prval
*blkid_probe_assign_value(
693 blkid_probe pr
, const char *name
)
695 struct blkid_prval
*v
;
699 if (pr
->nvals
>= BLKID_NVALS
)
702 v
= &pr
->vals
[pr
->nvals
];
704 v
->chain
= pr
->cur_chain
;
708 printf("assigning %s [%s]\n", name
, v
->chain
->driver
->name
));
712 int blkid_probe_set_value(blkid_probe pr
, const char *name
,
713 unsigned char *data
, size_t len
)
715 struct blkid_prval
*v
;
717 if (len
> BLKID_PROBVAL_BUFSIZ
)
718 len
= BLKID_PROBVAL_BUFSIZ
;
720 v
= blkid_probe_assign_value(pr
, name
);
724 memcpy(v
->data
, data
, len
);
729 int blkid_probe_vsprintf_value(blkid_probe pr
, const char *name
,
730 const char *fmt
, va_list ap
)
732 struct blkid_prval
*v
;
735 v
= blkid_probe_assign_value(pr
, name
);
739 len
= vsnprintf((char *) v
->data
, sizeof(v
->data
), fmt
, ap
);
742 pr
->nvals
--; /* reset the latest assigned value */
749 static int blkid_probe_set_usage(blkid_probe pr
, int usage
)
753 if (usage
& BLKID_USAGE_FILESYSTEM
)
755 else if (usage
& BLKID_USAGE_RAID
)
757 else if (usage
& BLKID_USAGE_CRYPTO
)
759 else if (usage
& BLKID_USAGE_OTHER
)
764 return blkid_probe_set_value(pr
, "USAGE", (unsigned char *) u
, strlen(u
) + 1);
768 * blkid_probe_get_value:
770 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
771 * @name: pointer to return value name or NULL
772 * @data: pointer to return value data or NULL
773 * @len: pointer to return value length or NULL
775 * Returns: 0 on success, or -1 in case of error.
777 int blkid_probe_get_value(blkid_probe pr
, int num
, const char **name
,
778 const char **data
, size_t *len
)
780 struct blkid_prval
*v
= __blkid_probe_get_value(pr
, num
);
787 *data
= (char *) v
->data
;
791 DBG(DEBUG_LOWPROBE
, printf("returning %s value\n", v
->name
));
796 * blkid_probe_lookup_value:
798 * @name: name of value
799 * @data: pointer to return value data or NULL
800 * @len: pointer to return value length or NULL
802 * Returns: 0 on success, or -1 in case of error.
804 int blkid_probe_lookup_value(blkid_probe pr
, const char *name
,
805 const char **data
, size_t *len
)
807 struct blkid_prval
*v
= __blkid_probe_lookup_value(pr
, name
);
812 *data
= (char *) v
->data
;
815 DBG(DEBUG_LOWPROBE
, printf("returning %s value\n", v
->name
));
820 * blkid_probe_has_value:
822 * @name: name of value
824 * Returns: 1 if value exist in probing result, otherwise 0.
826 int blkid_probe_has_value(blkid_probe pr
, const char *name
)
828 if (blkid_probe_lookup_value(pr
, name
, NULL
, NULL
) == 0)
833 struct blkid_prval
*__blkid_probe_get_value(blkid_probe pr
, int num
)
835 if (pr
== NULL
|| num
< 0 || num
>= pr
->nvals
)
838 return &pr
->vals
[num
];
841 struct blkid_prval
*__blkid_probe_lookup_value(blkid_probe pr
, const char *name
)
845 if (pr
== NULL
|| pr
->nvals
== 0 || name
== NULL
)
848 for (i
= 0; i
< pr
->nvals
; i
++) {
849 struct blkid_prval
*v
= &pr
->vals
[i
];
851 if (v
->name
&& strcmp(name
, v
->name
) == 0) {
852 DBG(DEBUG_LOWPROBE
, printf("returning %s value\n", v
->name
));
860 /* converts DCE UUID (uuid[16]) to human readable string
861 * - the @len should be always 37 */
862 void blkid_unparse_uuid(const unsigned char *uuid
, char *str
, size_t len
)
865 uuid_unparse(uuid
, str
);
868 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
869 uuid
[0], uuid
[1], uuid
[2], uuid
[3],
873 uuid
[10], uuid
[11], uuid
[12], uuid
[13], uuid
[14],uuid
[15]);