]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/probe.c
libblkid: introduce helper to get offset for idmag
[thirdparty/util-linux.git] / libblkid / src / probe.c
1 /*
2 * Low-level libblkid probing API
3 *
4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
10 /**
11 * SECTION: lowprobe
12 * @title: Low-level probing
13 * @short_description: low-level prober initialization
14 *
15 * The low-level probing routines always and directly read information from
16 * the selected (see blkid_probe_set_device()) device.
17 *
18 * The probing routines are grouped together into separate chains. Currently,
19 * the library provides superblocks, partitions and topology chains.
20 *
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().
27 *
28 * For more details see the chain specific documentation.
29 *
30 * The low-level API provides two ways how access to probing results.
31 *
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.
34 *
35 * 2. The binary interfaces. These interfaces return data in the native formats.
36 * The interface is always specific to the probing chain.
37 *
38 * Note that the previous probing result (binary or NAME=value) is always
39 * zeroized when a chain probing function is called. For example:
40 *
41 * <informalexample>
42 * <programlisting>
43 * blkid_probe_enable_partitions(pr, TRUE);
44 * blkid_probe_enable_superblocks(pr, FALSE);
45 *
46 * blkid_do_safeprobe(pr);
47 * </programlisting>
48 * </informalexample>
49 *
50 * overwrites the previous probing result for the partitions chain, the superblocks
51 * result is not modified.
52 */
53
54 /**
55 * SECTION: lowprobe-tags
56 * @title: Low-level tags
57 * @short_description: generic NAME=value interface.
58 *
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.
63 *
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
66 * documentation.
67 *
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:
71 *
72 * <informalexample>
73 * <programlisting>
74 * while((blkid_do_probe(pr) == BLKID_PROBE_OK)
75 * ... use result ...
76 * </programlisting>
77 * </informalexample>
78 *
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
82 * device).
83 *
84 * The probing result is set of NAME=value pairs (the NAME is always unique).
85 */
86
87 #include <stdio.h>
88 #include <string.h>
89 #include <stdlib.h>
90 #include <unistd.h>
91 #include <fcntl.h>
92 #include <ctype.h>
93 #include <sys/mman.h>
94 #include <sys/types.h>
95 #ifdef HAVE_LINUX_CDROM_H
96 #include <linux/cdrom.h>
97 #endif
98 #ifdef HAVE_LINUX_BLKZONED_H
99 #include <linux/blkzoned.h>
100 #endif
101 #ifdef HAVE_SYS_STAT_H
102 #include <sys/stat.h>
103 #endif
104 #ifdef HAVE_ERRNO_H
105 #include <errno.h>
106 #endif
107 #ifdef HAVE_LINUX_FD_H
108 #include <linux/fd.h>
109 #endif
110 #include <inttypes.h>
111 #include <stdint.h>
112 #include <stdarg.h>
113 #include <limits.h>
114 #ifdef HAVE_OPAL_GET_STATUS
115 #include <linux/sed-opal.h>
116 #endif
117
118 #include "blkidP.h"
119 #include "all-io.h"
120 #include "sysfs.h"
121 #include "strutils.h"
122 #include "list.h"
123 #include "fileutils.h"
124
125 /*
126 * All supported chains
127 */
128 static const struct blkid_chaindrv *chains_drvs[] = {
129 [BLKID_CHAIN_SUBLKS] = &superblocks_drv,
130 [BLKID_CHAIN_TOPLGY] = &topology_drv,
131 [BLKID_CHAIN_PARTS] = &partitions_drv
132 };
133
134 static void blkid_probe_reset_values(blkid_probe pr);
135
136 /**
137 * blkid_new_probe:
138 *
139 * Returns: a pointer to the newly allocated probe struct or NULL in case of error.
140 */
141 blkid_probe blkid_new_probe(void)
142 {
143 int i;
144 blkid_probe pr;
145
146 pr = calloc(1, sizeof(struct blkid_struct_probe));
147 if (!pr)
148 return NULL;
149
150 DBG(LOWPROBE, ul_debug("allocate a new probe"));
151
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;
157 }
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);
162 return pr;
163 }
164
165 /*
166 * Clone @parent, the new clone shares all, but except:
167 *
168 * - probing result
169 * - buffers if another device (or offset) is set to the prober
170 */
171 blkid_probe blkid_clone_probe(blkid_probe parent)
172 {
173 blkid_probe pr;
174
175 if (!parent)
176 return NULL;
177
178 DBG(LOWPROBE, ul_debug("allocate a probe clone"));
179
180 pr = blkid_new_probe();
181 if (!pr)
182 return NULL;
183
184 pr->fd = parent->fd;
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;
193 pr->parent = parent;
194
195 pr->flags &= ~BLKID_FL_PRIVATE_FD;
196
197 return pr;
198 }
199
200
201
202 /**
203 * blkid_new_probe_from_filename:
204 * @filename: device or regular file
205 *
206 * This function is same as call open(filename), blkid_new_probe() and
207 * blkid_probe_set_device(pr, fd, 0, 0).
208 *
209 * The @filename is closed by blkid_free_probe() or by the
210 * blkid_probe_set_device() call.
211 *
212 * Returns: a pointer to the newly allocated probe struct or NULL in case of
213 * error.
214 */
215 blkid_probe blkid_new_probe_from_filename(const char *filename)
216 {
217 int fd;
218 blkid_probe pr = NULL;
219
220 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
221 if (fd < 0)
222 return NULL;
223
224 pr = blkid_new_probe();
225 if (!pr)
226 goto err;
227
228 if (blkid_probe_set_device(pr, fd, 0, 0))
229 goto err;
230
231 pr->flags |= BLKID_FL_PRIVATE_FD;
232 return pr;
233 err:
234 close(fd);
235 blkid_free_probe(pr);
236 return NULL;
237 }
238
239 /**
240 * blkid_free_probe:
241 * @pr: probe
242 *
243 * Deallocates the probe struct, buffers and all allocated
244 * data that are associated with this probing control struct.
245 */
246 void blkid_free_probe(blkid_probe pr)
247 {
248 int i;
249
250 if (!pr)
251 return;
252
253 for (i = 0; i < BLKID_NCHAINS; i++) {
254 struct blkid_chain *ch = &pr->chains[i];
255
256 if (ch->driver->free_data)
257 ch->driver->free_data(pr, ch->data);
258 free(ch->fltr);
259 ch->fltr = NULL;
260 }
261
262 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
263 close(pr->fd);
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);
268
269 DBG(LOWPROBE, ul_debug("free probe"));
270 free(pr);
271 }
272
273 void blkid_probe_free_value(struct blkid_prval *v)
274 {
275 if (!v)
276 return;
277
278 list_del(&v->prvals);
279 free(v->data);
280
281 DBG(LOWPROBE, ul_debug(" free value %s", v->name));
282 free(v);
283 }
284
285 /*
286 * Removes chain values from probing result.
287 */
288 void blkid_probe_chain_reset_values(blkid_probe pr, struct blkid_chain *chn)
289 {
290
291 struct list_head *p, *pnext;
292
293 if (list_empty(&pr->values))
294 return;
295
296 DBG(LOWPROBE, ul_debug("Resetting %s values", chn->driver->name));
297
298 list_for_each_safe(p, pnext, &pr->values) {
299 struct blkid_prval *v = list_entry(p,
300 struct blkid_prval, prvals);
301
302 if (v->chain == chn)
303 blkid_probe_free_value(v);
304 }
305 }
306
307 static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
308 {
309 chn->idx = -1;
310 }
311
312 /*
313 * Move chain values from probing result to @vals
314 */
315 int blkid_probe_chain_save_values(blkid_probe pr, struct blkid_chain *chn,
316 struct list_head *vals)
317 {
318 struct list_head *p, *pnext;
319 struct blkid_prval *v;
320
321 DBG(LOWPROBE, ul_debug("saving %s values", chn->driver->name));
322
323 list_for_each_safe(p, pnext, &pr->values) {
324
325 v = list_entry(p, struct blkid_prval, prvals);
326 if (v->chain != chn)
327 continue;
328
329 list_del_init(&v->prvals);
330 list_add_tail(&v->prvals, vals);
331 }
332 return 0;
333 }
334
335 /*
336 * Appends values from @vals to the probing result
337 */
338 void blkid_probe_append_values_list(blkid_probe pr, struct list_head *vals)
339 {
340 DBG(LOWPROBE, ul_debug("appending values"));
341
342 list_splice(vals, &pr->values);
343 INIT_LIST_HEAD(vals);
344 }
345
346
347 void blkid_probe_free_values_list(struct list_head *vals)
348 {
349 if (!vals)
350 return;
351
352 DBG(LOWPROBE, ul_debug("freeing values list"));
353
354 while (!list_empty(vals)) {
355 struct blkid_prval *v = list_entry(vals->next, struct blkid_prval, prvals);
356 blkid_probe_free_value(v);
357 }
358 }
359
360 struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
361 {
362 return pr->cur_chain;
363 }
364
365 static const char *blkid_probe_get_probername(blkid_probe pr)
366 {
367 struct blkid_chain *chn = blkid_probe_get_chain(pr);
368
369 if (chn && chn->idx >= 0 && (unsigned)chn->idx < chn->driver->nidinfos)
370 return chn->driver->idinfos[chn->idx]->name;
371
372 return NULL;
373 }
374
375 void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
376 {
377 int rc, org_prob_flags;
378 struct blkid_chain *org_chn;
379
380 /* save the current setting -- the binary API has to be completely
381 * independent on the current probing status
382 */
383 org_chn = pr->cur_chain;
384 org_prob_flags = pr->prob_flags;
385
386 pr->cur_chain = chn;
387 pr->prob_flags = 0;
388 chn->binary = TRUE;
389 blkid_probe_chain_reset_position(chn);
390
391 rc = chn->driver->probe(pr, chn);
392
393 chn->binary = FALSE;
394 blkid_probe_chain_reset_position(chn);
395
396 /* restore the original setting
397 */
398 pr->cur_chain = org_chn;
399 pr->prob_flags = org_prob_flags;
400
401 if (rc != 0)
402 return NULL;
403
404 DBG(LOWPROBE, ul_debug("returning %s binary data", chn->driver->name));
405 return chn->data;
406 }
407
408
409 /**
410 * blkid_reset_probe:
411 * @pr: probe
412 *
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.
416 */
417 void blkid_reset_probe(blkid_probe pr)
418 {
419 int i;
420
421 blkid_probe_reset_values(pr);
422 blkid_probe_set_wiper(pr, 0, 0);
423
424 pr->cur_chain = NULL;
425
426 for (i = 0; i < BLKID_NCHAINS; i++)
427 blkid_probe_chain_reset_position(&pr->chains[i]);
428 }
429
430 /***
431 static int blkid_probe_dump_filter(blkid_probe pr, int chain)
432 {
433 struct blkid_chain *chn;
434 int i;
435
436 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
437 return -1;
438
439 chn = &pr->chains[chain];
440
441 if (!chn->fltr)
442 return -1;
443
444 for (i = 0; i < chn->driver->nidinfos; i++) {
445 const struct blkid_idinfo *id = chn->driver->idinfos[i];
446
447 DBG(LOWPROBE, ul_debug("%d: %s: %s",
448 i,
449 id->name,
450 blkid_bmp_get_item(chn->fltr, i)
451 ? "disabled" : "enabled <--"));
452 }
453 return 0;
454 }
455 ***/
456
457 /*
458 * Returns properly initialized chain filter
459 */
460 unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
461 {
462 struct blkid_chain *chn;
463
464 if (chain < 0 || chain >= BLKID_NCHAINS)
465 return NULL;
466
467 chn = &pr->chains[chain];
468
469 /* always when you touch the chain filter all indexes are reset and
470 * probing starts from scratch
471 */
472 blkid_probe_chain_reset_position(chn);
473 pr->cur_chain = NULL;
474
475 if (!chn->driver->has_fltr || (!chn->fltr && !create))
476 return NULL;
477
478 if (!chn->fltr)
479 chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
480 else
481 memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));
482
483 /* blkid_probe_dump_filter(pr, chain); */
484 return chn->fltr;
485 }
486
487 /*
488 * Generic private functions for filter setting
489 */
490 int __blkid_probe_invert_filter(blkid_probe pr, int chain)
491 {
492 size_t i;
493 struct blkid_chain *chn;
494
495 chn = &pr->chains[chain];
496
497 if (!chn->driver->has_fltr || !chn->fltr)
498 return -1;
499
500 for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
501 chn->fltr[i] = ~chn->fltr[i];
502
503 DBG(LOWPROBE, ul_debug("probing filter inverted"));
504 /* blkid_probe_dump_filter(pr, chain); */
505 return 0;
506 }
507
508 int __blkid_probe_reset_filter(blkid_probe pr, int chain)
509 {
510 return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
511 }
512
513 int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
514 {
515 unsigned long *fltr;
516 struct blkid_chain *chn;
517 size_t i;
518
519 fltr = blkid_probe_get_filter(pr, chain, TRUE);
520 if (!fltr)
521 return -1;
522
523 chn = &pr->chains[chain];
524
525 for (i = 0; i < chn->driver->nidinfos; i++) {
526 int has = 0;
527 const struct blkid_idinfo *id = chn->driver->idinfos[i];
528 char **n;
529
530 for (n = names; *n; n++) {
531 if (!strcmp(id->name, *n)) {
532 has = 1;
533 break;
534 }
535 }
536 if (has) {
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);
541 }
542
543 DBG(LOWPROBE, ul_debug("%s: a new probing type-filter initialized",
544 chn->driver->name));
545 /* blkid_probe_dump_filter(pr, chain); */
546 return 0;
547 }
548
549 static void remove_buffer(struct blkid_bufinfo *bf)
550 {
551 list_del(&bf->bufs);
552
553 DBG(BUFFER, ul_debug(" remove buffer: [off=%"PRIu64", len=%"PRIu64"]",
554 bf->off, bf->len));
555 munmap(bf->data, bf->len);
556 free(bf);
557 }
558
559 static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint64_t len)
560 {
561 ssize_t ret;
562 struct blkid_bufinfo *bf = NULL;
563
564 if (lseek(pr->fd, real_off, SEEK_SET) == (off_t) -1) {
565 errno = 0;
566 return NULL;
567 }
568
569 /* someone trying to overflow some buffers? */
570 if (len > ULONG_MAX - sizeof(struct blkid_bufinfo)) {
571 errno = ENOMEM;
572 return NULL;
573 }
574
575 /* allocate info and space for data by one malloc call */
576 bf = calloc(1, sizeof(struct blkid_bufinfo));
577 if (!bf) {
578 errno = ENOMEM;
579 return NULL;
580 }
581
582 bf->data = mmap(NULL, len, PROT_READ | PROT_WRITE,
583 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
584 if (bf->data == MAP_FAILED) {
585 free(bf);
586 errno = ENOMEM;
587 return NULL;
588 }
589
590 bf->len = len;
591 bf->off = real_off;
592 INIT_LIST_HEAD(&bf->bufs);
593
594 DBG(LOWPROBE, ul_debug("\tread: off=%"PRIu64" len=%"PRIu64"",
595 real_off, len));
596
597 ret = read(pr->fd, bf->data, len);
598 if (ret != (ssize_t) len) {
599 DBG(LOWPROBE, ul_debug("\tread failed: %m"));
600 remove_buffer(bf);
601
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))
605 errno = 0;
606 #ifdef HAVE_OPAL_GET_STATUS
607 else {
608 struct opal_status st = { };
609
610 /* If the device is locked with OPAL, we'll fail to read with I/O
611 * errors when probing deep into the block device. Do not return
612 * an error, so that we can move on to different types of checks.*/
613 ret = ioctl(pr->fd, IOC_OPAL_GET_STATUS, &st);
614 if (ret == 0 && (st.flags & OPAL_FL_LOCKED)) {
615 pr->flags |= BLKID_FL_OPAL_LOCKED;
616 errno = 0;
617 }
618 }
619 #endif
620
621 return NULL;
622 }
623
624 if (mprotect(bf->data, len, PROT_READ))
625 DBG(LOWPROBE, ul_debug("\tmprotect failed: %m"));
626
627 return bf;
628 }
629
630 /*
631 * Search in buffers we already have in memory
632 */
633 static struct blkid_bufinfo *get_cached_buffer(blkid_probe pr, uint64_t off, uint64_t len)
634 {
635 uint64_t real_off = pr->off + off;
636 struct list_head *p;
637
638 list_for_each(p, &pr->buffers) {
639 struct blkid_bufinfo *x =
640 list_entry(p, struct blkid_bufinfo, bufs);
641
642 if (real_off >= x->off && real_off + len <= x->off + x->len) {
643 DBG(BUFFER, ul_debug("\treuse: off=%"PRIu64" len=%"PRIu64" (for off=%"PRIu64" len=%"PRIu64")",
644 x->off, x->len, real_off, len));
645 return x;
646 }
647 }
648 return NULL;
649 }
650
651 /*
652 * Mark smaller buffers that can be satisfied by bf as prunable
653 */
654 static void mark_prunable_buffers(blkid_probe pr, const struct blkid_bufinfo *bf)
655 {
656 struct list_head *p, *next;
657
658 list_for_each_safe(p, next, &pr->buffers) {
659 struct blkid_bufinfo *x =
660 list_entry(p, struct blkid_bufinfo, bufs);
661
662 if (bf->off <= x->off && bf->off + bf->len >= x->off + x->len) {
663 list_del(&x->bufs);
664 list_add(&x->bufs, &pr->prunable_buffers);
665 }
666 }
667 }
668
669 /*
670 * Remove buffers that are marked as prunable
671 */
672 void blkid_probe_prune_buffers(blkid_probe pr)
673 {
674 struct list_head *p, *next;
675
676 list_for_each_safe(p, next, &pr->prunable_buffers) {
677 struct blkid_bufinfo *x =
678 list_entry(p, struct blkid_bufinfo, bufs);
679
680 remove_buffer(x);
681 }
682 }
683
684 /*
685 * Zeroize in-memory data in already read buffer. The next blkid_probe_get_buffer()
686 * will return modified buffer. This is usable when you want to call the same probing
687 * function more than once and hide previously detected magic strings.
688 *
689 * See blkid_probe_hide_range().
690 */
691 static int hide_buffer(blkid_probe pr, uint64_t off, uint64_t len)
692 {
693 uint64_t real_off = pr->off + off;
694 struct list_head *p;
695 int ct = 0;
696
697 if (UINT64_MAX - len < off) {
698 DBG(BUFFER, ul_debug("\t hide-buffer overflow (ignore)"));
699 return -EINVAL;
700 }
701
702 list_for_each(p, &pr->buffers) {
703 struct blkid_bufinfo *x =
704 list_entry(p, struct blkid_bufinfo, bufs);
705 unsigned char *data;
706
707 if (real_off >= x->off && real_off + len <= x->off + x->len) {
708
709 assert(x->off <= real_off);
710 assert(x->off + x->len >= real_off + len);
711
712 data = real_off ? x->data + (real_off - x->off) : x->data;
713
714 DBG(BUFFER, ul_debug("\thiding: off=%"PRIu64" len=%"PRIu64,
715 off, len));
716 mprotect(x->data, x->len, PROT_READ | PROT_WRITE);
717 memset(data, 0, len);
718 mprotect(x->data, x->len, PROT_READ);
719 ct++;
720 }
721 }
722 return ct == 0 ? -EINVAL : 0;
723 }
724
725
726 /*
727 * Note that @off is offset within probing area, the probing area is defined by
728 * pr->off and pr->size.
729 */
730 const unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
731 {
732 struct blkid_bufinfo *bf = NULL;
733 uint64_t real_off, bias;
734
735 bias = off % pr->io_size;
736 off -= bias;
737 len += bias;
738 if (len % pr->io_size)
739 len += pr->io_size - (len % pr->io_size);
740
741 real_off = pr->off + off;
742
743 /*
744 DBG(BUFFER, ul_debug("\t>>>> off=%ju, real-off=%ju (probe <%ju..%ju>, len=%ju",
745 off, real_off, pr->off, pr->off + pr->size, len));
746 */
747 if (pr->size == 0 || pr->io_size == 0) {
748 errno = EINVAL;
749 return NULL;
750 }
751
752 if (UINT64_MAX - len < off || UINT64_MAX - len < real_off) {
753 DBG(BUFFER, ul_debug("\t read-buffer overflow (ignore)"));
754 return NULL;
755 }
756
757 if (len > 8388608 /* 8 Mib */ ) {
758 DBG(BUFFER, ul_debug("\t too large read request (ignore)"));
759 return NULL;
760 }
761
762 if (len == 0
763 || (!S_ISCHR(pr->mode) && (pr->size < off || pr->size < len))
764 || (!S_ISCHR(pr->mode) && (pr->off + pr->size < real_off + len))) {
765 DBG(BUFFER, ul_debug("\t read-buffer out of probing area (ignore)"));
766 errno = 0;
767 return NULL;
768 }
769
770 if (pr->parent &&
771 pr->parent->devno == pr->devno &&
772 pr->parent->off <= pr->off &&
773 pr->parent->off + pr->parent->size >= pr->off + pr->size) {
774 /*
775 * This is a cloned prober and points to the same area as
776 * parent. Let's use parent's buffers.
777 *
778 * Note that pr->off (and pr->parent->off) is always from the
779 * begin of the device.
780 */
781 return blkid_probe_get_buffer(pr->parent,
782 pr->off + off - pr->parent->off, len);
783 }
784
785 /* try buffers we already have in memory or read from device */
786 bf = get_cached_buffer(pr, off, len);
787 if (!bf) {
788 bf = read_buffer(pr, real_off, len);
789 if (!bf)
790 return NULL;
791
792 mark_prunable_buffers(pr, bf);
793 list_add_tail(&bf->bufs, &pr->buffers);
794 }
795
796 assert(bf->off <= real_off);
797 assert(bf->off + bf->len >= real_off + len);
798
799 errno = 0;
800 return real_off ? bf->data + (real_off - bf->off + bias) : bf->data + bias;
801 }
802
803 /**
804 * blkid_probe_reset_buffers:
805 * @pr: prober
806 *
807 * libblkid reuse all already read buffers from the device. The buffers may be
808 * modified by blkid_probe_hide_range(). This function reset and free all
809 * cached buffers. The next blkid_do_probe() will read all data from the
810 * device.
811 *
812 * Since: 2.31
813 *
814 * Returns: <0 in case of failure, or 0 on success.
815 */
816 int blkid_probe_reset_buffers(blkid_probe pr)
817 {
818 uint64_t ct = 0, len = 0;
819
820 pr->flags &= ~BLKID_FL_MODIF_BUFF;
821
822 blkid_probe_prune_buffers(pr);
823
824 if (list_empty(&pr->buffers))
825 return 0;
826
827 DBG(BUFFER, ul_debug("Resetting probing buffers"));
828
829 while (!list_empty(&pr->buffers)) {
830 struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
831 struct blkid_bufinfo, bufs);
832 ct++;
833 len += bf->len;
834
835 remove_buffer(bf);
836 }
837
838 DBG(LOWPROBE, ul_debug(" buffers summary: %"PRIu64" bytes by %"PRIu64" read() calls",
839 len, ct));
840
841 INIT_LIST_HEAD(&pr->buffers);
842
843 return 0;
844 }
845
846 /**
847 * blkid_probe_hide_range:
848 * @pr: prober
849 * @off: start of the range
850 * @len: size of the range
851 *
852 * This function modifies in-memory cached data from the device. The specified
853 * range is zeroized. This is usable together with blkid_probe_step_back().
854 * The next blkid_do_probe() will not see specified area.
855 *
856 * Note that this is usable for already (by library) read data, and this
857 * function is not a way how to hide any large areas on your device.
858 *
859 * The function blkid_probe_reset_buffers() reverts all.
860 *
861 * Since: 2.31
862 *
863 * Returns: <0 in case of failure, or 0 on success.
864 */
865 int blkid_probe_hide_range(blkid_probe pr, uint64_t off, uint64_t len)
866 {
867 int rc = hide_buffer(pr, off, len);
868
869 if (rc == 0)
870 pr->flags |= BLKID_FL_MODIF_BUFF;
871 return rc;
872 }
873
874
875 static void blkid_probe_reset_values(blkid_probe pr)
876 {
877 if (list_empty(&pr->values))
878 return;
879
880 DBG(LOWPROBE, ul_debug("resetting results"));
881
882 while (!list_empty(&pr->values)) {
883 struct blkid_prval *v = list_entry(pr->values.next,
884 struct blkid_prval, prvals);
885 blkid_probe_free_value(v);
886 }
887
888 INIT_LIST_HEAD(&pr->values);
889 }
890
891 /*
892 * Small devices need a special care.
893 */
894 int blkid_probe_is_tiny(blkid_probe pr)
895 {
896 return (pr->flags & BLKID_FL_TINY_DEV);
897 }
898
899 /*
900 * CDROMs may fail when probed for RAID (last sector problem)
901 */
902 int blkid_probe_is_cdrom(blkid_probe pr)
903 {
904 return (pr->flags & BLKID_FL_CDROM_DEV);
905 }
906
907 int blkdid_probe_is_opal_locked(blkid_probe pr)
908 {
909 return (pr->flags & BLKID_FL_OPAL_LOCKED);
910 }
911
912 #ifdef CDROM_GET_CAPABILITY
913
914 static int is_sector_readable(int fd, uint64_t sector)
915 {
916 char buf[512];
917 ssize_t sz;
918
919 if (lseek(fd, sector * 512, SEEK_SET) == (off_t) -1)
920 goto failed;
921
922 sz = read(fd, buf, sizeof(buf));
923 if (sz != (ssize_t) sizeof(buf))
924 goto failed;
925
926 return 1;
927 failed:
928 DBG(LOWPROBE, ul_debug("CDROM: read sector %"PRIu64" failed %m", sector));
929 errno = 0;
930 return 0;
931 }
932
933 /*
934 * Linux kernel reports (BLKGETSIZE) cdrom device size greater than area
935 * readable by read(2). We have to reduce the probing area to avoid unwanted
936 * I/O errors in probing functions. It seems that unreadable are always last 2
937 * or 3 CD blocks (CD block size is 2048 bytes, it means 12 in 512-byte
938 * sectors). Linux kernel reports (CDROM_LAST_WRITTEN) also location of last
939 * written block, so we will reduce size based on it too.
940 */
941 static void cdrom_size_correction(blkid_probe pr, uint64_t last_written)
942 {
943 uint64_t n, nsectors = pr->size >> 9;
944
945 if (last_written && nsectors > ((last_written+1) << 2))
946 nsectors = (last_written+1) << 2;
947
948 for (n = nsectors - 12; n < nsectors; n++) {
949 if (!is_sector_readable(pr->fd, n))
950 goto failed;
951 }
952
953 DBG(LOWPROBE, ul_debug("CDROM: full size available"));
954 return;
955 failed:
956 /* 'n' is the failed sector, reduce device size to n-1; */
957 DBG(LOWPROBE, ul_debug("CDROM: reduce size from %ju to %ju.",
958 (uintmax_t) pr->size,
959 (uintmax_t) n << 9));
960 pr->size = n << 9;
961 }
962
963 #endif
964
965 #ifdef BLKIOOPT
966 static uint64_t blkid_get_io_size(int fd)
967 {
968 static const int ioctls[] = { BLKIOOPT, BLKIOMIN, BLKBSZGET };
969 unsigned int s;
970 size_t i;
971 int r;
972
973 for (i = 0; i < ARRAY_SIZE(ioctls); i++) {
974 r = ioctl(fd, ioctls[i], &s);
975 if (r == 0 && is_power_of_2(s) && s >= DEFAULT_SECTOR_SIZE)
976 return min(s, 1U << 16);
977 }
978
979 return DEFAULT_SECTOR_SIZE;
980 }
981 #endif
982
983 /**
984 * blkid_probe_set_device:
985 * @pr: probe
986 * @fd: device file descriptor
987 * @off: begin of probing area
988 * @size: size of probing area (zero means whole device/file)
989 *
990 * Assigns the device to probe control struct, resets internal buffers, resets
991 * the current probing, and close previously associated device (if open by
992 * libblkid).
993 *
994 * If @fd is < 0 than only resets the prober and returns 1. Note that
995 * blkid_reset_probe() keeps the device associated with the prober, but
996 * blkid_probe_set_device() does complete reset.
997 *
998 * Returns: -1 in case of failure, 0 on success and 1 on reset.
999 */
1000 int blkid_probe_set_device(blkid_probe pr, int fd,
1001 blkid_loff_t off, blkid_loff_t size)
1002 {
1003 struct stat sb;
1004 uint64_t devsiz = 0;
1005 char *dm_uuid = NULL;
1006 int is_floppy = 0;
1007
1008 blkid_reset_probe(pr);
1009 blkid_probe_reset_buffers(pr);
1010
1011 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
1012 close(pr->fd);
1013
1014 if (pr->disk_probe) {
1015 blkid_free_probe(pr->disk_probe);
1016 pr->disk_probe = NULL;
1017 }
1018
1019 pr->flags &= ~BLKID_FL_PRIVATE_FD;
1020 pr->flags &= ~BLKID_FL_TINY_DEV;
1021 pr->flags &= ~BLKID_FL_CDROM_DEV;
1022 pr->prob_flags = 0;
1023 pr->fd = fd;
1024 pr->off = (uint64_t) off;
1025 pr->size = 0;
1026 pr->io_size = DEFAULT_SECTOR_SIZE;
1027 pr->devno = 0;
1028 pr->disk_devno = 0;
1029 pr->mode = 0;
1030 pr->blkssz = 0;
1031 pr->wipe_off = 0;
1032 pr->wipe_size = 0;
1033 pr->wipe_chain = NULL;
1034 pr->zone_size = 0;
1035
1036 if (fd < 0)
1037 return 1;
1038
1039
1040 #if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
1041 /* Disable read-ahead */
1042 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
1043 #endif
1044 if (fstat(fd, &sb))
1045 goto err;
1046
1047 if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode)) {
1048 errno = EINVAL;
1049 goto err;
1050 }
1051
1052 pr->mode = sb.st_mode;
1053 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
1054 pr->devno = sb.st_rdev;
1055
1056 if (S_ISBLK(sb.st_mode)) {
1057 if (blkdev_get_size(fd, (unsigned long long *) &devsiz)) {
1058 DBG(LOWPROBE, ul_debug("failed to get device size"));
1059 goto err;
1060 }
1061 } else if (S_ISCHR(sb.st_mode)) {
1062 char buf[PATH_MAX];
1063
1064 if (!sysfs_chrdev_devno_to_devname(sb.st_rdev, buf, sizeof(buf))
1065 || strncmp(buf, "ubi", 3) != 0) {
1066 DBG(LOWPROBE, ul_debug("no UBI char device"));
1067 errno = EINVAL;
1068 goto err;
1069 }
1070 devsiz = 1; /* UBI devices are char... */
1071 } else if (S_ISREG(sb.st_mode))
1072 devsiz = sb.st_size; /* regular file */
1073
1074 pr->size = size ? (uint64_t)size : devsiz;
1075
1076 if (off && size == 0)
1077 /* only offset without size specified */
1078 pr->size -= (uint64_t) off;
1079
1080 if (pr->off + pr->size > devsiz) {
1081 DBG(LOWPROBE, ul_debug("area specified by offset and size is bigger than device"));
1082 errno = EINVAL;
1083 goto err;
1084 }
1085
1086 if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
1087 pr->flags |= BLKID_FL_TINY_DEV;
1088
1089 #ifdef FDGETFDCSTAT
1090 if (S_ISBLK(sb.st_mode)) {
1091 /*
1092 * Re-open without O_NONBLOCK for floppy device.
1093 *
1094 * Since kernel commit c7e9d0020361f4308a70cdfd6d5335e273eb8717
1095 * floppy drive works bad when opened with O_NONBLOCK.
1096 */
1097 struct floppy_fdc_state flst;
1098
1099 if (ioctl(fd, FDGETFDCSTAT, &flst) >= 0) {
1100 int flags = fcntl(fd, F_GETFL, 0);
1101
1102 if (flags < 0)
1103 goto err;
1104 if (flags & O_NONBLOCK) {
1105 flags &= ~O_NONBLOCK;
1106
1107 fd = ul_reopen(fd, flags | O_CLOEXEC);
1108 if (fd < 0)
1109 goto err;
1110
1111 pr->flags |= BLKID_FL_PRIVATE_FD;
1112 pr->fd = fd;
1113 }
1114 is_floppy = 1;
1115 }
1116 errno = 0;
1117 }
1118 #endif
1119 if (S_ISBLK(sb.st_mode) &&
1120 !is_floppy &&
1121 sysfs_devno_is_dm_private(sb.st_rdev, &dm_uuid)) {
1122 DBG(LOWPROBE, ul_debug("ignore private device mapper device"));
1123 pr->flags |= BLKID_FL_NOSCAN_DEV;
1124 }
1125
1126 #ifdef CDROM_GET_CAPABILITY
1127 else if (S_ISBLK(sb.st_mode) &&
1128 !blkid_probe_is_tiny(pr) &&
1129 !dm_uuid &&
1130 !is_floppy &&
1131 blkid_probe_is_wholedisk(pr)) {
1132
1133 long last_written = 0;
1134
1135 /*
1136 * pktcdvd.ko accepts only these ioctls:
1137 * CDROMEJECT CDROMMULTISESSION CDROMREADTOCENTRY
1138 * CDROM_LAST_WRITTEN CDROM_SEND_PACKET SCSI_IOCTL_SEND_COMMAND
1139 * So CDROM_GET_CAPABILITY cannot be used for detecting pktcdvd
1140 * devices. But CDROM_GET_CAPABILITY and CDROM_DRIVE_STATUS are
1141 * fast so use them for detecting if medium is present. In any
1142 * case use last written block form CDROM_LAST_WRITTEN.
1143 */
1144
1145 if (ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) {
1146 # ifdef CDROM_DRIVE_STATUS
1147 switch (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) {
1148 case CDS_TRAY_OPEN:
1149 case CDS_NO_DISC:
1150 errno = ENOMEDIUM;
1151 goto err;
1152 }
1153 # endif
1154 pr->flags |= BLKID_FL_CDROM_DEV;
1155 }
1156
1157 # ifdef CDROM_LAST_WRITTEN
1158 if (ioctl(fd, CDROM_LAST_WRITTEN, &last_written) == 0) {
1159 pr->flags |= BLKID_FL_CDROM_DEV;
1160 } else {
1161 if (errno == ENOMEDIUM)
1162 goto err;
1163 }
1164 # endif
1165
1166 if (pr->flags & BLKID_FL_CDROM_DEV) {
1167 cdrom_size_correction(pr, last_written);
1168
1169 # ifdef CDROMMULTISESSION
1170 if (!pr->off && blkid_probe_get_hint(pr, "session_offset", NULL) < 0) {
1171 struct cdrom_multisession multisession = { .addr_format = CDROM_LBA };
1172 if (ioctl(fd, CDROMMULTISESSION, &multisession) == 0 && multisession.xa_flag)
1173 blkid_probe_set_hint(pr, "session_offset", (multisession.addr.lba << 11));
1174 }
1175 # endif
1176 }
1177 }
1178 #endif
1179 free(dm_uuid);
1180
1181 # ifdef BLKGETZONESZ
1182 if (S_ISBLK(sb.st_mode) && !is_floppy) {
1183 uint32_t zone_size_sector;
1184
1185 if (!ioctl(pr->fd, BLKGETZONESZ, &zone_size_sector))
1186 pr->zone_size = zone_size_sector << 9;
1187 }
1188 # endif
1189
1190 #ifdef BLKIOOPT
1191 if (S_ISBLK(sb.st_mode) && !is_floppy && !blkid_probe_is_tiny(pr))
1192 pr->io_size = blkid_get_io_size(fd);
1193 #endif
1194
1195 DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64", zonesize=%"PRIu64", iosize=%"PRIu64,
1196 pr->off, pr->size, pr->zone_size, pr->io_size));
1197 DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s",
1198 blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
1199 S_ISREG(pr->mode) ? "YES" : "NO"));
1200
1201 return 0;
1202 err:
1203 DBG(LOWPROBE, ul_debug("failed to prepare a device for low-probing"));
1204 return -1;
1205
1206 }
1207
1208 int blkid_probe_get_dimension(blkid_probe pr, uint64_t *off, uint64_t *size)
1209 {
1210 *off = pr->off;
1211 *size = pr->size;
1212 return 0;
1213 }
1214
1215 int blkid_probe_set_dimension(blkid_probe pr, uint64_t off, uint64_t size)
1216 {
1217 DBG(LOWPROBE, ul_debug(
1218 "changing probing area: size=%"PRIu64", off=%"PRIu64" "
1219 "-to-> size=%"PRIu64", off=%"PRIu64"",
1220 pr->size, pr->off, size, off));
1221
1222 pr->off = off;
1223 pr->size = size;
1224 pr->flags &= ~BLKID_FL_TINY_DEV;
1225
1226 if (pr->size <= 1440ULL * 1024ULL && !S_ISCHR(pr->mode))
1227 pr->flags |= BLKID_FL_TINY_DEV;
1228
1229 blkid_probe_reset_buffers(pr);
1230
1231 return 0;
1232 }
1233
1234 const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size)
1235 {
1236 uint64_t hint_offset, off;
1237
1238 if (mag->kboff >= 0) {
1239 if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0)
1240 hint_offset = 0;
1241
1242 off = hint_offset + (mag->kboff << 10);
1243 } else {
1244 off = pr->size - (-mag->kboff << 10);
1245 }
1246
1247 return blkid_probe_get_buffer(pr, off, size);
1248 }
1249
1250 uint64_t blkid_probe_get_idmag_off(blkid_probe pr, const struct blkid_idmag *mag)
1251 {
1252 if (mag->kboff >= 0)
1253 return mag->kboff << 10;
1254 else
1255 return pr->size - (-mag->kboff << 10);
1256 }
1257
1258 /*
1259 * Check for matching magic value.
1260 * Returns BLKID_PROBE_OK if found, BLKID_PROBE_NONE if not found
1261 * or no magic present, or negative value on error.
1262 */
1263 int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
1264 uint64_t *offset, const struct blkid_idmag **res)
1265 {
1266 const struct blkid_idmag *mag = NULL;
1267 uint64_t off = 0;
1268
1269 if (id)
1270 mag = &id->magics[0];
1271 if (res)
1272 *res = NULL;
1273
1274 /* try to detect by magic string */
1275 while(mag && mag->magic) {
1276 const unsigned char *buf;
1277 long kboff;
1278 uint64_t hint_offset;
1279
1280 if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0)
1281 hint_offset = 0;
1282
1283 /* If the magic is for zoned device, skip non-zoned device */
1284 if (mag->is_zoned && !pr->zone_size) {
1285 mag++;
1286 continue;
1287 }
1288
1289 if (!mag->is_zoned)
1290 kboff = mag->kboff;
1291 else
1292 kboff = ((mag->zonenum * pr->zone_size) >> 10) + mag->kboff_inzone;
1293
1294 if (kboff >= 0)
1295 off = hint_offset + (kboff << 10) + mag->sboff;
1296 else
1297 off = pr->size - (-kboff << 10) + mag->sboff;
1298 buf = blkid_probe_get_buffer(pr, off, mag->len);
1299
1300 if (!buf && errno)
1301 return -errno;
1302
1303 if (buf && !memcmp(mag->magic, buf, mag->len)) {
1304 DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld",
1305 mag->sboff, kboff));
1306 if (offset)
1307 *offset = off;
1308 if (res)
1309 *res = mag;
1310 return BLKID_PROBE_OK;
1311 }
1312 mag++;
1313 }
1314
1315 if (id && id->magics[0].magic)
1316 /* magic string(s) defined, but not found */
1317 return BLKID_PROBE_NONE;
1318
1319 return BLKID_PROBE_OK;
1320 }
1321
1322 static inline void blkid_probe_start(blkid_probe pr)
1323 {
1324 DBG(LOWPROBE, ul_debug("start probe"));
1325 pr->cur_chain = NULL;
1326 pr->prob_flags = 0;
1327 blkid_probe_set_wiper(pr, 0, 0);
1328 }
1329
1330 static inline void blkid_probe_end(blkid_probe pr)
1331 {
1332 DBG(LOWPROBE, ul_debug("end probe"));
1333 pr->cur_chain = NULL;
1334 pr->prob_flags = 0;
1335 blkid_probe_set_wiper(pr, 0, 0);
1336 }
1337
1338 /**
1339 * blkid_do_probe:
1340 * @pr: prober
1341 *
1342 * Calls probing functions in all enabled chains. The superblocks chain is
1343 * enabled by default. The blkid_do_probe() stores result from only one
1344 * probing function. It's necessary to call this routine in a loop to get
1345 * results from all probing functions in all chains. The probing is reset
1346 * by blkid_reset_probe() or by filter functions.
1347 *
1348 * This is string-based NAME=value interface only.
1349 *
1350 * <example>
1351 * <title>basic case - use the first result only</title>
1352 * <programlisting>
1353 * if (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1354 * int nvals = blkid_probe_numof_values(pr);
1355 * for (n = 0; n < nvals; n++) {
1356 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
1357 * printf("%s = %s\n", name, data);
1358 * }
1359 * }
1360 * </programlisting>
1361 * </example>
1362 *
1363 * <example>
1364 * <title>advanced case - probe for all signatures</title>
1365 * <programlisting>
1366 * while (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1367 * int nvals = blkid_probe_numof_values(pr);
1368 * ...
1369 * }
1370 * </programlisting>
1371 * </example>
1372 *
1373 * See also blkid_reset_probe().
1374 *
1375 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
1376 */
1377 int blkid_do_probe(blkid_probe pr)
1378 {
1379 int rc = 1;
1380
1381 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1382 return BLKID_PROBE_NONE;
1383
1384 do {
1385 struct blkid_chain *chn = pr->cur_chain;
1386
1387 if (!chn) {
1388 blkid_probe_start(pr);
1389 chn = pr->cur_chain = &pr->chains[0];
1390 }
1391 /* we go to the next chain only when the previous probing
1392 * result was nothing (rc == 1) and when the current chain is
1393 * disabled or we are at end of the current chain (chain->idx +
1394 * 1 == sizeof chain) or the current chain bailed out right at
1395 * the start (chain->idx == -1)
1396 */
1397 else if (rc == 1 && (chn->enabled == FALSE ||
1398 chn->idx + 1 == (int) chn->driver->nidinfos ||
1399 chn->idx == -1)) {
1400
1401 size_t idx = chn->driver->id + 1;
1402
1403 if (idx < BLKID_NCHAINS)
1404 chn = pr->cur_chain = &pr->chains[idx];
1405 else {
1406 blkid_probe_end(pr);
1407 return BLKID_PROBE_NONE; /* all chains already probed */
1408 }
1409 }
1410
1411 chn->binary = FALSE; /* for sure... */
1412
1413 DBG(LOWPROBE, ul_debug("chain probe %s %s (idx=%d)",
1414 chn->driver->name,
1415 chn->enabled? "ENABLED" : "DISABLED",
1416 chn->idx));
1417
1418 if (!chn->enabled)
1419 continue;
1420
1421 /* rc: -1 = error, 0 = success, 1 = no result */
1422 rc = chn->driver->probe(pr, chn);
1423
1424 } while (rc == BLKID_PROBE_NONE);
1425
1426 if (rc < 0)
1427 return BLKID_PROBE_ERROR;
1428
1429 return rc;
1430 }
1431
1432 #ifdef HAVE_LINUX_BLKZONED_H
1433 static int is_conventional(blkid_probe pr, uint64_t offset)
1434 {
1435 struct blk_zone_report *rep = NULL;
1436 int ret;
1437 uint64_t zone_mask;
1438
1439 if (!pr->zone_size)
1440 return 1;
1441
1442 zone_mask = ~(pr->zone_size - 1);
1443 rep = blkdev_get_zonereport(blkid_probe_get_fd(pr),
1444 (offset & zone_mask) >> 9, 1);
1445 if (!rep)
1446 return -1;
1447
1448 if (rep->zones[0].type == BLK_ZONE_TYPE_CONVENTIONAL)
1449 ret = 1;
1450 else
1451 ret = 0;
1452
1453 free(rep);
1454
1455 return ret;
1456 }
1457 #else
1458 static inline int is_conventional(blkid_probe pr __attribute__((__unused__)),
1459 uint64_t offset __attribute__((__unused__)))
1460 {
1461 return 1;
1462 }
1463 #endif
1464
1465 /**
1466 * blkid_do_wipe:
1467 * @pr: prober
1468 * @dryrun: if TRUE then don't touch the device.
1469 *
1470 * This function erases the current signature detected by @pr. The @pr has to
1471 * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
1472 * has to be enabled (if you want to erase also superblock with broken check
1473 * sums then use BLKID_SUBLKS_BADCSUM too).
1474 *
1475 * After successful signature removing the @pr prober will be moved one step
1476 * back and the next blkid_do_probe() call will again call previously called
1477 * probing function. All in-memory cached data from the device are always
1478 * reset.
1479 *
1480 * <example>
1481 * <title>wipe all filesystems or raids from the device</title>
1482 * <programlisting>
1483 * fd = open(devname, O_RDWR|O_CLOEXEC);
1484 * blkid_probe_set_device(pr, fd, 0, 0);
1485 *
1486 * blkid_probe_enable_superblocks(pr, 1);
1487 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1488 *
1489 * while (blkid_do_probe(pr) == 0)
1490 * blkid_do_wipe(pr, FALSE);
1491 * </programlisting>
1492 * </example>
1493 *
1494 * See also blkid_probe_step_back() if you cannot use this built-in wipe
1495 * function, but you want to use libblkid probing as a source for wiping.
1496 *
1497 * See also blkid_wipe_all() which works the same as the example above.
1498 *
1499 * Returns: 0 on success, and -1 in case of error.
1500 */
1501 int blkid_do_wipe(blkid_probe pr, int dryrun)
1502 {
1503 const char *off = NULL;
1504 size_t len = 0;
1505 uint64_t offset, magoff;
1506 int conventional;
1507 char buf[BUFSIZ];
1508 int fd, rc = 0;
1509 struct blkid_chain *chn;
1510
1511 chn = pr->cur_chain;
1512 if (!chn)
1513 return BLKID_PROBE_ERROR;
1514
1515 switch (chn->driver->id) {
1516 case BLKID_CHAIN_SUBLKS:
1517 rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
1518 if (!rc)
1519 rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1520 break;
1521 case BLKID_CHAIN_PARTS:
1522 rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
1523 if (!rc)
1524 rc = blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1525 break;
1526 default:
1527 return BLKID_PROBE_OK;
1528 }
1529
1530 if (rc || len == 0 || off == NULL)
1531 return BLKID_PROBE_OK;
1532
1533 errno = 0;
1534 magoff = strtoumax(off, NULL, 10);
1535 if (errno)
1536 return BLKID_PROBE_OK;
1537
1538 offset = magoff + pr->off;
1539 fd = blkid_probe_get_fd(pr);
1540 if (fd < 0)
1541 return BLKID_PROBE_ERROR;
1542
1543 if (len > sizeof(buf))
1544 len = sizeof(buf);
1545
1546 rc = is_conventional(pr, offset);
1547 if (rc < 0)
1548 return BLKID_PROBE_ERROR;
1549 conventional = rc == 1;
1550
1551 DBG(LOWPROBE, ul_debug(
1552 "do_wipe [offset=0x%"PRIx64" (%"PRIu64"), len=%zu, chain=%s, idx=%d, dryrun=%s]\n",
1553 offset, offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));
1554
1555 if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
1556 return BLKID_PROBE_ERROR;
1557
1558 if (!dryrun && len) {
1559 if (conventional) {
1560 memset(buf, 0, len);
1561
1562 /* wipen on device */
1563 if (write_all(fd, buf, len))
1564 return BLKID_PROBE_ERROR;
1565 if (fsync(fd) != 0)
1566 return BLKID_PROBE_ERROR;
1567 } else {
1568 #ifdef HAVE_LINUX_BLKZONED_H
1569 uint64_t zone_mask = ~(pr->zone_size - 1);
1570 struct blk_zone_range range = {
1571 .sector = (offset & zone_mask) >> 9,
1572 .nr_sectors = pr->zone_size >> 9,
1573 };
1574
1575 rc = ioctl(fd, BLKRESETZONE, &range);
1576 if (rc < 0)
1577 return BLKID_PROBE_ERROR;
1578 #else
1579 /* Should not reach here */
1580 assert(0);
1581 #endif
1582 }
1583
1584 pr->flags &= ~BLKID_FL_MODIF_BUFF; /* be paranoid */
1585
1586 return blkid_probe_step_back(pr);
1587
1588 }
1589
1590 if (dryrun) {
1591 /* wipe in memory only */
1592 blkid_probe_hide_range(pr, magoff, len);
1593 return blkid_probe_step_back(pr);
1594 }
1595
1596 return BLKID_PROBE_OK;
1597 }
1598
1599 /**
1600 * blkid_wipe_all:
1601 * @pr: prober
1602 *
1603 * This function erases all detectable signatures from &pr.
1604 * The @pr has to be open in O_RDWR mode. All other necessary configurations
1605 * will be enabled automatically.
1606 *
1607 * <example>
1608 * <title>wipe all filesystems or raids from the device</title>
1609 * <programlisting>
1610 * fd = open(devname, O_RDWR|O_CLOEXEC);
1611 * blkid_probe_set_device(pr, fd, 0, 0);
1612 *
1613 * blkid_wipe_all(pr);
1614 * </programlisting>
1615 * </example>
1616 *
1617 * Returns: 0 on success, and -1 in case of error.
1618 */
1619 int blkid_wipe_all(blkid_probe pr)
1620 {
1621 DBG(LOWPROBE, ul_debug("wiping all signatures"));
1622
1623 blkid_probe_enable_superblocks(pr, 1);
1624 blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |
1625 BLKID_SUBLKS_BADCSUM);
1626
1627 blkid_probe_enable_partitions(pr, 1);
1628 blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC |
1629 BLKID_PARTS_FORCE_GPT);
1630
1631 while (blkid_do_probe(pr) == 0) {
1632 DBG(LOWPROBE, ul_debug("wiping one signature"));
1633 blkid_do_wipe(pr, 0);
1634 }
1635
1636 return BLKID_PROBE_OK;
1637 }
1638
1639 /**
1640 * blkid_probe_step_back:
1641 * @pr: prober
1642 *
1643 * This function move pointer to the probing chain one step back -- it means
1644 * that the previously used probing function will be called again in the next
1645 * blkid_do_probe() call.
1646 *
1647 * This is necessary for example if you erase or modify on-disk superblock
1648 * according to the current libblkid probing result.
1649 *
1650 * Note that blkid_probe_hide_range() changes semantic of this function and
1651 * cached buffers are not reset, but library uses in-memory modified
1652 * buffers to call the next probing function.
1653 *
1654 * <example>
1655 * <title>wipe all superblock, but use libblkid only for probing</title>
1656 * <programlisting>
1657 * pr = blkid_new_probe_from_filename(devname);
1658 *
1659 * blkid_probe_enable_superblocks(pr, 1);
1660 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1661 *
1662 * blkid_probe_enable_partitions(pr, 1);
1663 * blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
1664 *
1665 * while (blkid_do_probe(pr) == BLKID_PROBE_OK) {
1666 * const char *ostr = NULL;
1667 * size_t len = 0;
1668 *
1669 * // superblocks
1670 * if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &ostr, NULL) == 0)
1671 * blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1672 *
1673 * // partition tables
1674 * if (len == 0 && blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &ostr, NULL) == 0)
1675 * blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1676 *
1677 * if (!len || !str)
1678 * continue;
1679 *
1680 * // convert ostr to the real offset by off = strtoll(ostr, NULL, 10);
1681 * // use your stuff to erase @len bytes at the @off
1682 * ....
1683 *
1684 * // retry the last probing to check for backup superblocks ..etc.
1685 * blkid_probe_step_back(pr);
1686 * }
1687 * </programlisting>
1688 * </example>
1689 *
1690 * Returns: 0 on success, and -1 in case of error.
1691 */
1692 int blkid_probe_step_back(blkid_probe pr)
1693 {
1694 struct blkid_chain *chn;
1695
1696 chn = pr->cur_chain;
1697 if (!chn)
1698 return -1;
1699
1700 if (!(pr->flags & BLKID_FL_MODIF_BUFF))
1701 blkid_probe_reset_buffers(pr);
1702
1703 if (chn->idx >= 0) {
1704 chn->idx--;
1705 DBG(LOWPROBE, ul_debug("step back: moving %s chain index to %d",
1706 chn->driver->name,
1707 chn->idx));
1708 }
1709
1710 if (chn->idx == -1) {
1711 /* blkid_do_probe() goes to the next chain if the index
1712 * of the current chain is -1, so we have to set the
1713 * chain pointer to the previous chain.
1714 */
1715 size_t idx = chn->driver->id > 0 ? chn->driver->id - 1 : 0;
1716
1717 DBG(LOWPROBE, ul_debug("step back: moving to previous chain"));
1718
1719 if (idx > 0)
1720 pr->cur_chain = &pr->chains[idx];
1721 else if (idx == 0)
1722 pr->cur_chain = NULL;
1723 }
1724
1725 return 0;
1726 }
1727
1728 /**
1729 * blkid_do_safeprobe:
1730 * @pr: prober
1731 *
1732 * This function gathers probing results from all enabled chains and checks
1733 * for ambivalent results (e.g. more filesystems on the device).
1734 *
1735 * This is string-based NAME=value interface only.
1736 *
1737 * Note about superblocks chain -- the function does not check for filesystems
1738 * when a RAID signature is detected. The function also does not check for
1739 * collision between RAIDs. The first detected RAID is returned. The function
1740 * checks for collision between partition table and RAID signature -- it's
1741 * recommended to enable partitions chain together with superblocks chain.
1742 *
1743 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalent result is
1744 * detected and -1 on case of error.
1745 */
1746 int blkid_do_safeprobe(blkid_probe pr)
1747 {
1748 int i, count = 0, rc = 0;
1749
1750 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1751 return BLKID_PROBE_NONE;
1752
1753 blkid_probe_start(pr);
1754
1755 for (i = 0; i < BLKID_NCHAINS; i++) {
1756 struct blkid_chain *chn;
1757
1758 chn = pr->cur_chain = &pr->chains[i];
1759 chn->binary = FALSE; /* for sure... */
1760
1761 DBG(LOWPROBE, ul_debug("chain safeprobe %s %s",
1762 chn->driver->name,
1763 chn->enabled? "ENABLED" : "DISABLED"));
1764
1765 if (!chn->enabled)
1766 continue;
1767
1768 blkid_probe_chain_reset_position(chn);
1769
1770 rc = chn->driver->safeprobe(pr, chn);
1771
1772 blkid_probe_chain_reset_position(chn);
1773
1774 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
1775 if (rc < 0)
1776 goto done; /* error */
1777 if (rc == 0)
1778 count++; /* success */
1779 }
1780
1781 done:
1782 blkid_probe_end(pr);
1783 if (rc < 0)
1784 return BLKID_PROBE_ERROR;
1785
1786 return count == 0 ? BLKID_PROBE_NONE : BLKID_PROBE_OK;
1787 }
1788
1789 /**
1790 * blkid_do_fullprobe:
1791 * @pr: prober
1792 *
1793 * This function gathers probing results from all enabled chains. Same as
1794 * blkid_do_safeprobe() but does not check for collision between probing
1795 * result.
1796 *
1797 * This is string-based NAME=value interface only.
1798 *
1799 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
1800 */
1801 int blkid_do_fullprobe(blkid_probe pr)
1802 {
1803 int i, count = 0, rc = 0;
1804
1805 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1806 return BLKID_PROBE_NONE;
1807
1808 blkid_probe_start(pr);
1809
1810 for (i = 0; i < BLKID_NCHAINS; i++) {
1811 struct blkid_chain *chn;
1812
1813 chn = pr->cur_chain = &pr->chains[i];
1814 chn->binary = FALSE; /* for sure... */
1815
1816 DBG(LOWPROBE, ul_debug("chain fullprobe %s: %s",
1817 chn->driver->name,
1818 chn->enabled? "ENABLED" : "DISABLED"));
1819
1820 if (!chn->enabled)
1821 continue;
1822
1823 blkid_probe_chain_reset_position(chn);
1824
1825 rc = chn->driver->probe(pr, chn);
1826
1827 blkid_probe_chain_reset_position(chn);
1828
1829 /* rc: -1 = error, 0 = success, 1 = no result */
1830 if (rc < 0)
1831 goto done; /* error */
1832 if (rc == 0)
1833 count++; /* success */
1834 }
1835
1836 done:
1837 blkid_probe_end(pr);
1838 if (rc < 0)
1839 return BLKID_PROBE_ERROR;
1840
1841 return count == 0 ? BLKID_PROBE_NONE : BLKID_PROBE_OK;
1842 }
1843
1844 /* same sa blkid_probe_get_buffer() but works with 512-sectors */
1845 const unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
1846 {
1847 return blkid_probe_get_buffer(pr, ((uint64_t) sector) << 9, 0x200);
1848 }
1849
1850 struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, const char *name)
1851 {
1852 struct blkid_prval *v;
1853
1854 v = calloc(1, sizeof(struct blkid_prval));
1855 if (!v)
1856 return NULL;
1857
1858 INIT_LIST_HEAD(&v->prvals);
1859 v->name = name;
1860 v->chain = pr->cur_chain;
1861 list_add_tail(&v->prvals, &pr->values);
1862
1863 DBG(LOWPROBE, ul_debug("assigning %s [%s]", name, v->chain->driver->name));
1864 return v;
1865 }
1866
1867 /* Note that value data is always terminated by zero to keep things robust,
1868 * this extra zero is not count to the value length. It's caller responsibility
1869 * to set proper value length (for strings we count terminator to the length,
1870 * for binary data it's without terminator).
1871 */
1872 int blkid_probe_value_set_data(struct blkid_prval *v,
1873 const unsigned char *data, size_t len)
1874 {
1875 v->data = calloc(1, len + 1); /* always terminate by \0 */
1876
1877 if (!v->data)
1878 return -ENOMEM;
1879 memcpy(v->data, data, len);
1880 v->len = len;
1881 return 0;
1882 }
1883
1884 int blkid_probe_set_value(blkid_probe pr, const char *name,
1885 const unsigned char *data, size_t len)
1886 {
1887 struct blkid_prval *v;
1888
1889 v = blkid_probe_assign_value(pr, name);
1890 if (!v)
1891 return -1;
1892
1893 return blkid_probe_value_set_data(v, data, len);
1894 }
1895
1896 int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
1897 const char *fmt, va_list ap)
1898 {
1899 struct blkid_prval *v;
1900 ssize_t len;
1901
1902 v = blkid_probe_assign_value(pr, name);
1903 if (!v)
1904 return -ENOMEM;
1905
1906 len = vasprintf((char **) &v->data, fmt, ap);
1907
1908 if (len <= 0) {
1909 blkid_probe_free_value(v);
1910 return len == 0 ? -EINVAL : -ENOMEM;
1911 }
1912 v->len = len + 1;
1913 return 0;
1914 }
1915
1916 int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
1917 const char *fmt, ...)
1918 {
1919 int rc;
1920 va_list ap;
1921
1922 va_start(ap, fmt);
1923 rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
1924 va_end(ap);
1925
1926 return rc;
1927 }
1928
1929 int blkid_probe_set_magic(blkid_probe pr, uint64_t offset,
1930 size_t len, const unsigned char *magic)
1931 {
1932 int rc = 0;
1933 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1934
1935 if (!chn || !len || chn->binary)
1936 return 0;
1937
1938 switch (chn->driver->id) {
1939 case BLKID_CHAIN_SUBLKS:
1940 if (!(chn->flags & BLKID_SUBLKS_MAGIC))
1941 return 0;
1942 rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
1943 if (!rc)
1944 rc = blkid_probe_sprintf_value(pr,
1945 "SBMAGIC_OFFSET", "%llu", (unsigned long long)offset);
1946 break;
1947 case BLKID_CHAIN_PARTS:
1948 if (!(chn->flags & BLKID_PARTS_MAGIC))
1949 return 0;
1950 rc = blkid_probe_set_value(pr, "PTMAGIC", magic, len);
1951 if (!rc)
1952 rc = blkid_probe_sprintf_value(pr,
1953 "PTMAGIC_OFFSET", "%llu", (unsigned long long)offset);
1954 break;
1955 default:
1956 break;
1957 }
1958
1959 return rc;
1960 }
1961
1962 static void blkid_probe_log_csum_mismatch(blkid_probe pr, size_t n, const void *csum,
1963 const void *expected)
1964 {
1965 char csum_hex[256];
1966 char expected_hex[sizeof(csum_hex)];
1967 int hex_size = min(sizeof(csum_hex), n * 2);
1968
1969 for (int i = 0; i < hex_size; i+=2) {
1970 sprintf(&csum_hex[i], "%02X", ((const unsigned char *) csum)[i / 2]);
1971 sprintf(&expected_hex[i], "%02X", ((const unsigned char *) expected)[i / 2]);
1972 }
1973
1974 ul_debug(
1975 "incorrect checksum for type %s,"
1976 " got %*s, expected %*s",
1977 blkid_probe_get_probername(pr),
1978 hex_size, csum_hex, hex_size, expected_hex);
1979 }
1980
1981
1982 int blkid_probe_verify_csum_buf(blkid_probe pr, size_t n, const void *csum,
1983 const void *expected)
1984 {
1985 if (memcmp(csum, expected, n) != 0) {
1986 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1987
1988 ON_DBG(LOWPROBE, blkid_probe_log_csum_mismatch(pr, n, csum, expected));
1989
1990 /*
1991 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
1992 */
1993 if (chn && chn->driver->id == BLKID_CHAIN_SUBLKS
1994 && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
1995 blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
1996 goto accept;
1997 }
1998 return 0; /* bad checksum */
1999 }
2000
2001 accept:
2002 return 1;
2003 }
2004
2005 int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
2006 {
2007 return blkid_probe_verify_csum_buf(pr, sizeof(csum), &csum, &expected);
2008 }
2009
2010 /**
2011 * blkid_probe_get_devno:
2012 * @pr: probe
2013 *
2014 * Returns: block device number, or 0 for regular files.
2015 */
2016 dev_t blkid_probe_get_devno(blkid_probe pr)
2017 {
2018 return pr->devno;
2019 }
2020
2021 /**
2022 * blkid_probe_get_wholedisk_devno:
2023 * @pr: probe
2024 *
2025 * Returns: device number of the wholedisk, or 0 for regular files.
2026 */
2027 dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
2028 {
2029 if (!pr->disk_devno) {
2030 dev_t devno, disk_devno = 0;
2031
2032 devno = blkid_probe_get_devno(pr);
2033 if (!devno)
2034 return 0;
2035
2036 if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
2037 pr->disk_devno = disk_devno;
2038 }
2039 return pr->disk_devno;
2040 }
2041
2042 /**
2043 * blkid_probe_is_wholedisk:
2044 * @pr: probe
2045 *
2046 * Returns: 1 if the device is whole-disk or 0.
2047 */
2048 int blkid_probe_is_wholedisk(blkid_probe pr)
2049 {
2050 dev_t devno, disk_devno;
2051
2052 devno = blkid_probe_get_devno(pr);
2053 if (!devno)
2054 return 0;
2055
2056 disk_devno = blkid_probe_get_wholedisk_devno(pr);
2057 if (!disk_devno)
2058 return 0;
2059
2060 return devno == disk_devno;
2061 }
2062
2063 blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
2064 {
2065 dev_t disk;
2066
2067 if (blkid_probe_is_wholedisk(pr))
2068 return NULL; /* this is not partition */
2069
2070 if (pr->parent)
2071 /* this is cloned blkid_probe, use parent's stuff */
2072 return blkid_probe_get_wholedisk_probe(pr->parent);
2073
2074 disk = blkid_probe_get_wholedisk_devno(pr);
2075
2076 if (pr->disk_probe && pr->disk_probe->devno != disk) {
2077 /* we have disk prober, but for another disk... close it */
2078 blkid_free_probe(pr->disk_probe);
2079 pr->disk_probe = NULL;
2080 }
2081
2082 if (!pr->disk_probe) {
2083 /* Open a new disk prober */
2084 char *disk_path = blkid_devno_to_devname(disk);
2085 int flags;
2086
2087 if (!disk_path)
2088 return NULL;
2089
2090 DBG(LOWPROBE, ul_debug("allocate a wholedisk probe"));
2091
2092 pr->disk_probe = blkid_new_probe_from_filename(disk_path);
2093
2094 free(disk_path);
2095
2096 if (!pr->disk_probe)
2097 return NULL; /* ENOMEM? */
2098
2099 flags = blkid_probe_get_partitions_flags(pr);
2100 if (flags & BLKID_PARTS_FORCE_GPT)
2101 blkid_probe_set_partitions_flags(pr->disk_probe,
2102 BLKID_PARTS_FORCE_GPT);
2103 }
2104
2105 return pr->disk_probe;
2106 }
2107
2108 /**
2109 * blkid_probe_get_size:
2110 * @pr: probe
2111 *
2112 * This function returns size of probing area as defined by blkid_probe_set_device().
2113 * If the size of the probing area is unrestricted then this function returns
2114 * the real size of device. See also blkid_get_dev_size().
2115 *
2116 * Returns: size in bytes or -1 in case of error.
2117 */
2118 blkid_loff_t blkid_probe_get_size(blkid_probe pr)
2119 {
2120 return (blkid_loff_t) pr->size;
2121 }
2122
2123 /**
2124 * blkid_probe_get_offset:
2125 * @pr: probe
2126 *
2127 * This function returns offset of probing area as defined by blkid_probe_set_device().
2128 *
2129 * Returns: offset in bytes or -1 in case of error.
2130 */
2131 blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
2132 {
2133 return (blkid_loff_t) pr->off;
2134 }
2135
2136 /**
2137 * blkid_probe_get_fd:
2138 * @pr: probe
2139 *
2140 * Returns: file descriptor for assigned device/file or -1 in case of error.
2141 */
2142 int blkid_probe_get_fd(blkid_probe pr)
2143 {
2144 return pr->fd;
2145 }
2146
2147 /**
2148 * blkid_probe_get_sectorsize:
2149 * @pr: probe or NULL (for NULL returns 512)
2150 *
2151 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
2152 */
2153 unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
2154 {
2155 if (pr->blkssz)
2156 return pr->blkssz;
2157
2158 if (S_ISBLK(pr->mode) &&
2159 blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
2160 return pr->blkssz;
2161
2162 pr->blkssz = DEFAULT_SECTOR_SIZE;
2163 return pr->blkssz;
2164 }
2165
2166 /**
2167 * blkid_probe_set_sectorsize:
2168 * @pr: probe
2169 * @sz: new size (to overwrite system default)
2170 *
2171 * Note that blkid_probe_set_device() resets this setting. Use it after
2172 * blkid_probe_set_device() and before any probing call.
2173 *
2174 * Since: 2.30
2175 *
2176 * Returns: 0 or <0 in case of error
2177 */
2178 int blkid_probe_set_sectorsize(blkid_probe pr, unsigned int sz)
2179 {
2180 pr->blkssz = sz;
2181 return 0;
2182 }
2183
2184 /**
2185 * blkid_probe_get_sectors:
2186 * @pr: probe
2187 *
2188 * Returns: 512-byte sector count or -1 in case of error.
2189 */
2190 blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
2191 {
2192 return (blkid_loff_t) (pr->size >> 9);
2193 }
2194
2195 /**
2196 * blkid_probe_numof_values:
2197 * @pr: probe
2198 *
2199 * Returns: number of values in probing result or -1 in case of error.
2200 */
2201 int blkid_probe_numof_values(blkid_probe pr)
2202 {
2203 int i = 0;
2204 struct list_head *p;
2205
2206 list_for_each(p, &pr->values)
2207 ++i;
2208 return i;
2209 }
2210
2211 /**
2212 * blkid_probe_get_value:
2213 * @pr: probe
2214 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
2215 * @name: pointer to return value name or NULL
2216 * @data: pointer to return value data or NULL
2217 * @len: pointer to return value length or NULL
2218 *
2219 * Note, the @len returns length of the @data, including the terminating
2220 * '\0' character.
2221 *
2222 * Returns: 0 on success, or -1 in case of error.
2223 */
2224 int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
2225 const char **data, size_t *len)
2226 {
2227 struct blkid_prval *v = __blkid_probe_get_value(pr, num);
2228
2229 if (!v)
2230 return -1;
2231 if (name)
2232 *name = v->name;
2233 if (data)
2234 *data = (char *) v->data;
2235 if (len)
2236 *len = v->len;
2237
2238 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
2239 return 0;
2240 }
2241
2242 /**
2243 * blkid_probe_lookup_value:
2244 * @pr: probe
2245 * @name: name of value
2246 * @data: pointer to return value data or NULL
2247 * @len: pointer to return value length or NULL
2248 *
2249 * Note, the @len returns length of the @data, including the terminating
2250 * '\0' character.
2251 *
2252 * Returns: 0 on success, or -1 in case of error.
2253 */
2254 int blkid_probe_lookup_value(blkid_probe pr, const char *name,
2255 const char **data, size_t *len)
2256 {
2257 struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);
2258
2259 if (!v)
2260 return -1;
2261 if (data)
2262 *data = (char *) v->data;
2263 if (len)
2264 *len = v->len;
2265 return 0;
2266 }
2267
2268 /**
2269 * blkid_probe_has_value:
2270 * @pr: probe
2271 * @name: name of value
2272 *
2273 * Returns: 1 if value exist in probing result, otherwise 0.
2274 */
2275 int blkid_probe_has_value(blkid_probe pr, const char *name)
2276 {
2277 if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
2278 return 1;
2279 return 0;
2280 }
2281
2282 struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
2283 {
2284 int i = 0;
2285 struct list_head *p;
2286
2287 if (num < 0)
2288 return NULL;
2289
2290 list_for_each(p, &pr->values) {
2291 if (i++ != num)
2292 continue;
2293 return list_entry(p, struct blkid_prval, prvals);
2294 }
2295 return NULL;
2296 }
2297
2298 struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
2299 {
2300 struct list_head *p;
2301
2302 if (list_empty(&pr->values))
2303 return NULL;
2304
2305 list_for_each(p, &pr->values) {
2306 struct blkid_prval *v = list_entry(p, struct blkid_prval,
2307 prvals);
2308
2309 if (v->name && strcmp(name, v->name) == 0) {
2310 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
2311 return v;
2312 }
2313 }
2314 return NULL;
2315 }
2316
2317
2318 /* converts DCE UUID (uuid[16]) to human readable string
2319 * - the @len should be always 37 */
2320 void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
2321 {
2322 snprintf(str, len,
2323 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2324 uuid[0], uuid[1], uuid[2], uuid[3],
2325 uuid[4], uuid[5],
2326 uuid[6], uuid[7],
2327 uuid[8], uuid[9],
2328 uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
2329 }
2330
2331 /* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
2332 int blkid_uuid_is_empty(const unsigned char *buf, size_t len)
2333 {
2334 size_t i;
2335
2336 for (i = 0; i < len; i++)
2337 if (buf[i])
2338 return 0;
2339 return 1;
2340 }
2341
2342 /* Removes whitespace from the right-hand side of a string (trailing
2343 * whitespace).
2344 *
2345 * Returns size of the new string (without \0).
2346 */
2347 size_t blkid_rtrim_whitespace(unsigned char *str)
2348 {
2349 return rtrim_whitespace(str);
2350 }
2351
2352 /* Removes whitespace from the left-hand side of a string.
2353 *
2354 * Returns size of the new string (without \0).
2355 */
2356 size_t blkid_ltrim_whitespace(unsigned char *str)
2357 {
2358 return ltrim_whitespace(str);
2359 }
2360
2361 /*
2362 * Some mkfs-like utils wipe some parts (usually begin) of the device.
2363 * For example LVM (pvcreate) or mkswap(8). This information could be used
2364 * for later resolution to conflicts between superblocks.
2365 *
2366 * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
2367 * the device. If we found another signature (for example MBR) within the
2368 * wiped area then the signature has been added later and LVM superblock
2369 * should be ignore.
2370 *
2371 * Note that this heuristic is not 100% reliable, for example "pvcreate --zero n"
2372 * can be used to keep the begin of the device unmodified. It's probably better
2373 * to use this heuristic for conflicts between superblocks and partition tables
2374 * than for conflicts between filesystem superblocks -- existence of unwanted
2375 * partition table is very unusual, because PT is pretty visible (parsed and
2376 * interpreted by kernel).
2377 *
2378 * Note that we usually expect only one signature on the device, it means that
2379 * we have to remember only one wiped area from previously successfully
2380 * detected signature.
2381 *
2382 * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM)
2383 * blkid_probe_use_wiper() -- try to use area (e.g. MBR)
2384 *
2385 * Note that there is not relation between _wiper and blkid_to_wipe().
2386 *
2387 */
2388 void blkid_probe_set_wiper(blkid_probe pr, uint64_t off, uint64_t size)
2389 {
2390 struct blkid_chain *chn;
2391
2392 if (!size) {
2393 DBG(LOWPROBE, ul_debug("zeroize wiper"));
2394 pr->wipe_size = pr->wipe_off = 0;
2395 pr->wipe_chain = NULL;
2396 return;
2397 }
2398
2399 chn = pr->cur_chain;
2400
2401 if (!chn || !chn->driver ||
2402 chn->idx < 0 || (size_t) chn->idx >= chn->driver->nidinfos)
2403 return;
2404
2405 pr->wipe_size = size;
2406 pr->wipe_off = off;
2407 pr->wipe_chain = chn;
2408
2409 DBG(LOWPROBE,
2410 ul_debug("wiper set to %s::%s off=%"PRIu64" size=%"PRIu64"",
2411 chn->driver->name,
2412 chn->driver->idinfos[chn->idx]->name,
2413 pr->wipe_off, pr->wipe_size));
2414 }
2415
2416 /*
2417 * Returns 1 if the <@off,@size> area was wiped
2418 */
2419 int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, uint64_t off, uint64_t size)
2420 {
2421 if (!size)
2422 return 0;
2423
2424 if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
2425 *chn = pr->wipe_chain;
2426 return 1;
2427 }
2428 return 0;
2429 }
2430
2431 /*
2432 * Try to use any area -- if the area has been previously wiped then the
2433 * previous probing result should be ignored (reset).
2434 */
2435 void blkid_probe_use_wiper(blkid_probe pr, uint64_t off, uint64_t size)
2436 {
2437 struct blkid_chain *chn = NULL;
2438
2439 if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
2440 DBG(LOWPROBE, ul_debug("previously wiped area modified "
2441 " -- ignore previous results"));
2442 blkid_probe_set_wiper(pr, 0, 0);
2443 blkid_probe_chain_reset_values(pr, chn);
2444 }
2445 }
2446
2447 static struct blkid_hint *get_hint(blkid_probe pr, const char *name)
2448 {
2449 struct list_head *p;
2450
2451 if (list_empty(&pr->hints))
2452 return NULL;
2453
2454 list_for_each(p, &pr->hints) {
2455 struct blkid_hint *h = list_entry(p, struct blkid_hint, hints);
2456
2457 if (h->name && strcmp(name, h->name) == 0)
2458 return h;
2459 }
2460 return NULL;
2461 }
2462
2463 /**
2464 * blkid_probe_set_hint:
2465 * @pr: probe
2466 * @name: hint name or NAME=value
2467 * @value: offset or another number
2468 *
2469 * Sets extra hint for low-level prober. If the hint is set by NAME=value
2470 * notation than @value is ignored. The functions blkid_probe_set_device()
2471 * and blkid_reset_probe() resets all hints.
2472 *
2473 * The hints are optional way how to force libblkid probing functions to check
2474 * for example another location.
2475 *
2476 * Returns: 0 on success, or -1 in case of error.
2477 */
2478 int blkid_probe_set_hint(blkid_probe pr, const char *name, uint64_t value)
2479 {
2480 struct blkid_hint *hint = NULL;
2481 char *n = NULL, *v = NULL;
2482
2483 if (strchr(name, '=')) {
2484 char *end = NULL;
2485
2486 if (blkid_parse_tag_string(name, &n, &v) != 0)
2487 goto done;
2488
2489 errno = 0;
2490 value = strtoumax(v, &end, 10);
2491
2492 if (errno || v == end || (end && *end))
2493 goto done;
2494 }
2495
2496 hint = get_hint(pr, n ? n : name);
2497 if (hint) {
2498 /* alter old hint */
2499 hint->value = value;
2500 DBG(LOWPROBE,
2501 ul_debug("updated hint '%s' to %"PRIu64"", hint->name, hint->value));
2502 } else {
2503 /* add a new hint */
2504 if (!n) {
2505 n = strdup(name);
2506 if (!n)
2507 goto done;
2508 }
2509 hint = malloc(sizeof(*hint));
2510 if (!hint)
2511 goto done;
2512
2513 hint->name = n;
2514 hint->value = value;
2515
2516 INIT_LIST_HEAD(&hint->hints);
2517 list_add_tail(&hint->hints, &pr->hints);
2518
2519 DBG(LOWPROBE,
2520 ul_debug("new hint '%s' is %"PRIu64"", hint->name, hint->value));
2521 n = NULL;
2522 }
2523 done:
2524 free(n);
2525 free(v);
2526
2527 if (!hint)
2528 return errno ? -errno : -EINVAL;
2529 return 0;
2530 }
2531
2532 int blkid_probe_get_hint(blkid_probe pr, const char *name, uint64_t *value)
2533 {
2534 struct blkid_hint *h = get_hint(pr, name);
2535
2536 if (!h)
2537 return -EINVAL;
2538 if (value)
2539 *value = h->value;
2540 return 0;
2541 }
2542
2543 /**
2544 * blkid_probe_reset_hints:
2545 * @pr: probe
2546 *
2547 * Removes all previously defined probinig hints. See also blkid_probe_set_hint().
2548 */
2549 void blkid_probe_reset_hints(blkid_probe pr)
2550 {
2551 if (list_empty(&pr->hints))
2552 return;
2553
2554 DBG(LOWPROBE, ul_debug("resetting hints"));
2555
2556 while (!list_empty(&pr->hints)) {
2557 struct blkid_hint *h = list_entry(pr->hints.next,
2558 struct blkid_hint, hints);
2559 list_del(&h->hints);
2560 free(h->name);
2561 free(h);
2562 }
2563
2564 INIT_LIST_HEAD(&pr->hints);
2565 }