]> git.ipfire.org Git - thirdparty/util-linux.git/blame - libblkid/src/probe.c
setpriv: add --ambient-caps to usage()
[thirdparty/util-linux.git] / libblkid / src / probe.c
CommitLineData
a0948ffe 1/*
4d72b337 2 * Low-level libblkid probing API
a0948ffe 3 *
4d72b337 4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
a0948ffe 5 *
a0948ffe
KZ
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
a0948ffe
KZ
8 */
9
4d72b337
KZ
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,
e9c2d185 19 * the library provides superblocks, partitions and topology chains.
4d72b337
KZ
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).
488e52be 23 * These filters are per-chain. Note that always when you touch the chain
3b159691 24 * filter the current probing position is reset and probing starts from
488e52be
KZ
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.
4d72b337
KZ
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.
488e52be 37 *
e9c2d185 38 * Note that the previous probing result (binary or NAME=value) is always
3b159691 39 * zeroized when a chain probing function is called. For example:
e9c2d185
KZ
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.
4d72b337
KZ
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
488e52be 66 * documentation.
4d72b337
KZ
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) == 0)
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
a0948ffe
KZ
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/types.h>
55113b15
C
94#ifdef HAVE_LINUX_CDROM_H
95#include <linux/cdrom.h>
96#endif
a0948ffe
KZ
97#ifdef HAVE_SYS_STAT_H
98#include <sys/stat.h>
99#endif
a0948ffe
KZ
100#ifdef HAVE_ERRNO_H
101#include <errno.h>
102#endif
c4206331 103#include <inttypes.h>
51410fc6 104#include <stdint.h>
8c0dc071 105#include <stdarg.h>
109df14f 106#include <limits.h>
8c0dc071 107
51410fc6 108#ifdef HAVE_LIBUUID
7ee96990 109# include <uuid.h>
51410fc6 110#endif
a0948ffe 111
51410fc6 112#include "blkidP.h"
e12c9866 113#include "all-io.h"
25472aaf 114#include "sysfs.h"
22e9e9c8 115#include "strutils.h"
6c4a7811 116#include "list.h"
219227c2 117
52448df8
KZ
118/*
119 * All supported chains
120 */
121static const struct blkid_chaindrv *chains_drvs[] = {
122 [BLKID_CHAIN_SUBLKS] = &superblocks_drv,
cc33d693 123 [BLKID_CHAIN_TOPLGY] = &topology_drv,
e4799a35 124 [BLKID_CHAIN_PARTS] = &partitions_drv
52448df8
KZ
125};
126
af17d349 127static void blkid_probe_reset_values(blkid_probe pr);
15a8fb42 128static void blkid_probe_reset_buffer(blkid_probe pr);
52448df8 129
52448df8
KZ
130/**
131 * blkid_new_probe:
132 *
3b159691 133 * Returns: a pointer to the newly allocated probe struct or NULL in case of error.
a0948ffe 134 */
51410fc6 135blkid_probe blkid_new_probe(void)
a0948ffe 136{
52448df8
KZ
137 int i;
138 blkid_probe pr;
139
7a458332 140 blkid_init_debug(0);
52448df8
KZ
141 pr = calloc(1, sizeof(struct blkid_struct_probe));
142 if (!pr)
143 return NULL;
144
c62a6311 145 DBG(LOWPROBE, ul_debug("allocate a new probe %p", pr));
fd9f45e1 146
52448df8
KZ
147 /* initialize chains */
148 for (i = 0; i < BLKID_NCHAINS; i++) {
149 pr->chains[i].driver = chains_drvs[i];
150 pr->chains[i].flags = chains_drvs[i]->dflt_flags;
151 pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
152 }
15a8fb42 153 INIT_LIST_HEAD(&pr->buffers);
af17d349 154 INIT_LIST_HEAD(&pr->values);
52448df8 155 return pr;
a0948ffe
KZ
156}
157
fd9f45e1
KZ
158/*
159 * Clone @parent, the new clone shares all, but except:
160 *
161 * - probing result
9e930041 162 * - buffers if another device (or offset) is set to the prober
fd9f45e1
KZ
163 */
164blkid_probe blkid_clone_probe(blkid_probe parent)
165{
166 blkid_probe pr;
167
168 if (!parent)
169 return NULL;
170
c62a6311 171 DBG(LOWPROBE, ul_debug("allocate a probe clone"));
fd9f45e1
KZ
172
173 pr = blkid_new_probe();
174 if (!pr)
175 return NULL;
176
177 pr->fd = parent->fd;
178 pr->off = parent->off;
179 pr->size = parent->size;
180 pr->devno = parent->devno;
181 pr->disk_devno = parent->disk_devno;
182 pr->blkssz = parent->blkssz;
183 pr->flags = parent->flags;
184 pr->parent = parent;
185
6e650f88
KZ
186 pr->flags &= ~BLKID_FL_PRIVATE_FD;
187
fd9f45e1
KZ
188 return pr;
189}
190
191
192
f38db0cf
KZ
193/**
194 * blkid_new_probe_from_filename:
195 * @filename: device or regular file
196 *
197 * This function is same as call open(filename), blkid_new_probe() and
198 * blkid_probe_set_device(pr, fd, 0, 0).
199 *
200 * The @filename is closed by blkid_free_probe() or by the
201 * blkid_probe_set_device() call.
202 *
203 * Returns: a pointer to the newly allocated probe struct or NULL in case of
204 * error.
205 */
206blkid_probe blkid_new_probe_from_filename(const char *filename)
207{
1b504263 208 int fd;
f38db0cf
KZ
209 blkid_probe pr = NULL;
210
49a8f58e 211 fd = open(filename, O_RDONLY|O_CLOEXEC);
f38db0cf
KZ
212 if (fd < 0)
213 return NULL;
214
215 pr = blkid_new_probe();
216 if (!pr)
217 goto err;
218
219 if (blkid_probe_set_device(pr, fd, 0, 0))
220 goto err;
221
a9eef56c 222 pr->flags |= BLKID_FL_PRIVATE_FD;
f38db0cf
KZ
223 return pr;
224err:
225 if (fd >= 0)
226 close(fd);
227 blkid_free_probe(pr);
228 return NULL;
229}
230
52448df8
KZ
231/**
232 * blkid_free_probe:
233 * @pr: probe
234 *
235 * Deallocates the probe struct, buffers and all allocated
51410fc6 236 * data that are associated with this probing control struct.
a0948ffe 237 */
51410fc6 238void blkid_free_probe(blkid_probe pr)
a0948ffe 239{
52448df8
KZ
240 int i;
241
51410fc6
KZ
242 if (!pr)
243 return;
52448df8
KZ
244
245 for (i = 0; i < BLKID_NCHAINS; i++) {
246 struct blkid_chain *ch = &pr->chains[i];
247
248 if (ch->driver->free_data)
249 ch->driver->free_data(pr, ch->data);
250 free(ch->fltr);
251 }
f38db0cf 252
a9eef56c 253 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
f38db0cf 254 close(pr->fd);
15a8fb42 255 blkid_probe_reset_buffer(pr);
af17d349 256 blkid_probe_reset_values(pr);
fd9f45e1
KZ
257 blkid_free_probe(pr->disk_probe);
258
c62a6311 259 DBG(LOWPROBE, ul_debug("free probe %p", pr));
51410fc6 260 free(pr);
a0948ffe
KZ
261}
262
af17d349 263void blkid_probe_free_value(struct blkid_prval *v)
6c4a7811
OO
264{
265 if (!v)
266 return;
267
268 list_del(&v->prvals);
269 free(v->data);
af17d349
KZ
270
271 DBG(LOWPROBE, ul_debug(" free value %s", v->name));
6c4a7811
OO
272 free(v);
273}
52448df8 274
9bdf6885
KZ
275/*
276 * Removes chain values from probing result.
277 */
af17d349 278void blkid_probe_chain_reset_values(blkid_probe pr, struct blkid_chain *chn)
9bdf6885 279{
9bdf6885 280
6c4a7811 281 struct list_head *p, *pnext;
9bdf6885 282
7f787ced 283 if (list_empty(&pr->values))
6c4a7811
OO
284 return;
285
9e930041 286 DBG(LOWPROBE, ul_debug("Resetting %s values", chn->driver->name));
af17d349
KZ
287
288 list_for_each_safe(p, pnext, &pr->values) {
6c4a7811
OO
289 struct blkid_prval *v = list_entry(p,
290 struct blkid_prval, prvals);
291
292 if (v->chain == chn)
af17d349 293 blkid_probe_free_value(v);
9bdf6885 294 }
9bdf6885
KZ
295}
296
9e0f7bda
KZ
297static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
298{
7f787ced 299 chn->idx = -1;
9e0f7bda
KZ
300}
301
9bdf6885 302/*
af17d349 303 * Move chain values from probing result to @vals
9bdf6885 304 */
af17d349
KZ
305int blkid_probe_chain_save_values(blkid_probe pr, struct blkid_chain *chn,
306 struct list_head *vals)
9bdf6885 307{
af17d349
KZ
308 struct list_head *p, *pnext;
309 struct blkid_prval *v;
6c4a7811 310
af17d349 311 DBG(LOWPROBE, ul_debug("saving %s values", chn->driver->name));
6c4a7811 312
af17d349 313 list_for_each_safe(p, pnext, &pr->values) {
9bdf6885 314
af17d349 315 v = list_entry(p, struct blkid_prval, prvals);
9bdf6885
KZ
316 if (v->chain != chn)
317 continue;
6c4a7811 318
af17d349
KZ
319 list_del(&v->prvals);
320 INIT_LIST_HEAD(&v->prvals);
6c4a7811 321
af17d349 322 list_add_tail(&v->prvals, vals);
9bdf6885 323 }
6c4a7811 324 return 0;
9bdf6885
KZ
325}
326
327/*
328 * Appends values from @vals to the probing result
329 */
af17d349
KZ
330void blkid_probe_append_values_list(blkid_probe pr, struct list_head *vals)
331{
332 DBG(LOWPROBE, ul_debug("appending values"));
333
334 list_splice(vals, &pr->values);
335 INIT_LIST_HEAD(vals);
336}
337
338
339void blkid_probe_free_values_list(struct list_head *vals)
9bdf6885 340{
af17d349
KZ
341 if (!vals)
342 return;
343
344 DBG(LOWPROBE, ul_debug("freeing values list"));
345
346 while (!list_empty(vals)) {
347 struct blkid_prval *v = list_entry(vals->next, struct blkid_prval, prvals);
348 blkid_probe_free_value(v);
349 }
a0948ffe
KZ
350}
351
1c1726a7
KZ
352struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
353{
354 return pr->cur_chain;
355}
356
c89a1def
KZ
357static const char *blkid_probe_get_probername(blkid_probe pr)
358{
359 struct blkid_chain *chn = blkid_probe_get_chain(pr);
360
b9710f1f 361 if (chn && chn->idx >= 0 && (unsigned)chn->idx < chn->driver->nidinfos)
c89a1def
KZ
362 return chn->driver->idinfos[chn->idx]->name;
363
364 return NULL;
365}
366
22571ebb
KZ
367void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
368{
c81e7008
KZ
369 int rc, org_prob_flags;
370 struct blkid_chain *org_chn;
22571ebb 371
c81e7008
KZ
372 /* save the current setting -- the binary API has to be completely
373 * independent on the current probing status
374 */
375 org_chn = pr->cur_chain;
376 org_prob_flags = pr->prob_flags;
377
22571ebb 378 pr->cur_chain = chn;
c81e7008 379 pr->prob_flags = 0;
22571ebb 380 chn->binary = TRUE;
9e0f7bda 381 blkid_probe_chain_reset_position(chn);
22571ebb
KZ
382
383 rc = chn->driver->probe(pr, chn);
384
385 chn->binary = FALSE;
9e0f7bda 386 blkid_probe_chain_reset_position(chn);
22571ebb 387
c81e7008
KZ
388 /* restore the original setting
389 */
390 pr->cur_chain = org_chn;
391 pr->prob_flags = org_prob_flags;
392
d7be1a74 393 if (rc != 0)
22571ebb
KZ
394 return NULL;
395
c62a6311 396 DBG(LOWPROBE, ul_debug("returning %s binary data", chn->driver->name));
22571ebb
KZ
397 return chn->data;
398}
399
400
52448df8
KZ
401/**
402 * blkid_reset_probe:
403 * @pr: probe
404 *
44ef90bc
KZ
405 * Zeroize probing results and resets the current probing (this has impact to
406 * blkid_do_probe() only). This function does not touch probing filters and
407 * keeps assigned device.
52448df8 408 */
51410fc6 409void blkid_reset_probe(blkid_probe pr)
a0948ffe 410{
52448df8
KZ
411 int i;
412
af17d349 413 blkid_probe_reset_values(pr);
89d39d22 414 blkid_probe_set_wiper(pr, 0, 0);
52448df8 415
44ef90bc
KZ
416 pr->cur_chain = NULL;
417
52448df8 418 for (i = 0; i < BLKID_NCHAINS; i++)
9e0f7bda 419 blkid_probe_chain_reset_position(&pr->chains[i]);
a0948ffe
KZ
420}
421
46a734fd
KZ
422/***
423static int blkid_probe_dump_filter(blkid_probe pr, int chain)
424{
425 struct blkid_chain *chn;
426 int i;
427
428 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
429 return -1;
430
431 chn = &pr->chains[chain];
432
433 if (!chn->fltr)
434 return -1;
435
436 for (i = 0; i < chn->driver->nidinfos; i++) {
437 const struct blkid_idinfo *id = chn->driver->idinfos[i];
438
c62a6311 439 DBG(LOWPROBE, ul_debug("%d: %s: %s",
46a734fd
KZ
440 i,
441 id->name,
442 blkid_bmp_get_item(chn->fltr, i)
443 ? "disabled" : "enabled <--"));
46a734fd
KZ
444 }
445 return 0;
446}
447***/
448
449/*
450 * Returns properly initialized chain filter
451 */
452unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
453{
454 struct blkid_chain *chn;
455
7f787ced 456 if (chain < 0 || chain >= BLKID_NCHAINS)
46a734fd
KZ
457 return NULL;
458
459 chn = &pr->chains[chain];
460
3b159691 461 /* always when you touch the chain filter all indexes are reset and
46a734fd
KZ
462 * probing starts from scratch
463 */
9e0f7bda 464 blkid_probe_chain_reset_position(chn);
46a734fd
KZ
465 pr->cur_chain = NULL;
466
467 if (!chn->driver->has_fltr || (!chn->fltr && !create))
468 return NULL;
469
470 if (!chn->fltr)
471 chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
472 else
473 memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));
474
475 /* blkid_probe_dump_filter(pr, chain); */
476 return chn->fltr;
477}
478
479/*
480 * Generic private functions for filter setting
481 */
482int __blkid_probe_invert_filter(blkid_probe pr, int chain)
483{
c9f51c71 484 size_t i;
46a734fd 485 struct blkid_chain *chn;
46a734fd 486
46a734fd
KZ
487 chn = &pr->chains[chain];
488
e8fc977a
KZ
489 if (!chn->driver->has_fltr || !chn->fltr)
490 return -1;
491
46a734fd 492 for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
e8fc977a 493 chn->fltr[i] = ~chn->fltr[i];
46a734fd 494
c62a6311 495 DBG(LOWPROBE, ul_debug("probing filter inverted"));
46a734fd
KZ
496 /* blkid_probe_dump_filter(pr, chain); */
497 return 0;
498}
499
500int __blkid_probe_reset_filter(blkid_probe pr, int chain)
501{
502 return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
503}
504
505int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
506{
507 unsigned long *fltr;
508 struct blkid_chain *chn;
c9f51c71 509 size_t i;
46a734fd
KZ
510
511 fltr = blkid_probe_get_filter(pr, chain, TRUE);
512 if (!fltr)
513 return -1;
514
515 chn = &pr->chains[chain];
516
517 for (i = 0; i < chn->driver->nidinfos; i++) {
518 int has = 0;
519 const struct blkid_idinfo *id = chn->driver->idinfos[i];
520 char **n;
521
522 for (n = names; *n; n++) {
523 if (!strcmp(id->name, *n)) {
524 has = 1;
525 break;
526 }
527 }
92a4d098
SK
528 if (has) {
529 if (flag & BLKID_FLTR_NOTIN)
46a734fd 530 blkid_bmp_set_item(fltr, i);
92a4d098
SK
531 } else if (flag & BLKID_FLTR_ONLYIN)
532 blkid_bmp_set_item(fltr, i);
46a734fd
KZ
533 }
534
c62a6311 535 DBG(LOWPROBE, ul_debug("%s: a new probing type-filter initialized",
46a734fd
KZ
536 chn->driver->name));
537 /* blkid_probe_dump_filter(pr, chain); */
538 return 0;
539}
540
f12cd8d1 541static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint64_t len)
2355dd6a
KZ
542{
543 ssize_t ret;
544 struct blkid_bufinfo *bf = NULL;
545
546 if (blkid_llseek(pr->fd, real_off, SEEK_SET) < 0) {
547 errno = 0;
548 return NULL;
549 }
550
551 /* someone trying to overflow some buffers? */
552 if (len > ULONG_MAX - sizeof(struct blkid_bufinfo)) {
553 errno = ENOMEM;
554 return NULL;
555 }
556
557 /* allocate info and space for data by one malloc call */
558 bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
559 if (!bf) {
560 errno = ENOMEM;
561 return NULL;
562 }
563
564 bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
565 bf->len = len;
566 bf->off = real_off;
567 INIT_LIST_HEAD(&bf->bufs);
568
fdbd7bb9
RM
569 DBG(LOWPROBE, ul_debug("\tread %p: off=%"PRIu64" len=%"PRIu64"",
570 bf->data, real_off, len));
2355dd6a
KZ
571
572 ret = read(pr->fd, bf->data, len);
573 if (ret != (ssize_t) len) {
574 DBG(LOWPROBE, ul_debug("\tread failed: %m"));
575 free(bf);
55ad13c2
KZ
576
577 /* I/O errors on CDROMs are non-fatal to work with hybrid
578 * audio+data disks */
579 if (ret >= 0 || blkid_probe_is_cdrom(pr))
2355dd6a
KZ
580 errno = 0;
581 return NULL;
582 }
583
584 return bf;
585}
586
a674a0ab
KZ
587/*
588 * Note that @off is offset within probing area, the probing area is defined by
589 * pr->off and pr->size.
590 */
f12cd8d1 591unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
1ca17f91 592{
15a8fb42
KZ
593 struct list_head *p;
594 struct blkid_bufinfo *bf = NULL;
f12cd8d1 595 uint64_t real_off = pr->off + off;
a674a0ab
KZ
596
597 /*
598 DBG(BUFFER, ul_debug("\t>>>> off=%ju, real-off=%ju (probe <%ju..%ju>, len=%ju",
599 off, real_off, pr->off, pr->off + pr->size, len));
600 */
15a8fb42 601
f12cd8d1 602 if (pr->size == 0) {
00749bc3 603 errno = EINVAL;
88923b08 604 return NULL;
00749bc3 605 }
88923b08 606
a674a0ab
KZ
607 if (len == 0 || pr->off + pr->size < real_off + len) {
608 DBG(BUFFER, ul_debug("\t ignore: request out of probing area"));
609 errno = 0;
610 return NULL;
611 }
612
fd9f45e1
KZ
613 if (pr->parent &&
614 pr->parent->devno == pr->devno &&
ac8874ca
KZ
615 pr->parent->off <= pr->off &&
616 pr->parent->off + pr->parent->size >= pr->off + pr->size) {
fd9f45e1
KZ
617 /*
618 * This is a cloned prober and points to the same area as
ac8874ca
KZ
619 * parent. Let's use parent's buffers.
620 *
621 * Note that pr->off (and pr->parent->off) is always from the
a674a0ab 622 * begin of the device.
fd9f45e1 623 */
ac8874ca
KZ
624 return blkid_probe_get_buffer(pr->parent,
625 pr->off + off - pr->parent->off, len);
626 }
fd9f45e1 627
9e930041 628 /* try buffers we already have in memory */
15a8fb42
KZ
629 list_for_each(p, &pr->buffers) {
630 struct blkid_bufinfo *x =
631 list_entry(p, struct blkid_bufinfo, bufs);
632
a674a0ab 633 if (real_off >= x->off && real_off + len <= x->off + x->len) {
fdbd7bb9 634 DBG(BUFFER, ul_debug("\treuse %p: off=%"PRIu64" len=%"PRIu64" (for off=%"PRIu64" len=%"PRIu64")",
f12cd8d1 635 x->data, x->off, x->len, real_off, len));
15a8fb42
KZ
636 bf = x;
637 break;
638 }
1ca17f91 639 }
1ca17f91 640
a674a0ab
KZ
641 /* not found; read from disk */
642 if (!bf) {
e04f3860 643 bf = read_buffer(pr, real_off, len);
a674a0ab 644 if (!bf)
1ca17f91 645 return NULL;
1ca17f91 646
15a8fb42 647 list_add_tail(&bf->bufs, &pr->buffers);
1ca17f91 648 }
15a8fb42 649
a674a0ab
KZ
650 assert(bf->off <= real_off);
651 assert(bf->off + bf->len >= real_off + len);
652
00749bc3 653 errno = 0;
a674a0ab 654 return real_off ? bf->data + (real_off - bf->off) : bf->data;
1ca17f91
KZ
655}
656
15a8fb42 657static void blkid_probe_reset_buffer(blkid_probe pr)
a0948ffe 658{
2355dd6a 659 uint64_t ct = 0, len = 0;
15a8fb42 660
7f787ced 661 if (list_empty(&pr->buffers))
15a8fb42
KZ
662 return;
663
9e930041 664 DBG(BUFFER, ul_debug("Resetting probing buffers pr=%p", pr));
15a8fb42
KZ
665
666 while (!list_empty(&pr->buffers)) {
667 struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
668 struct blkid_bufinfo, bufs);
2355dd6a
KZ
669 ct++;
670 len += bf->len;
15a8fb42 671 list_del(&bf->bufs);
a674a0ab 672
fdbd7bb9
RM
673 DBG(BUFFER, ul_debug(" remove buffer: %p [off=%"PRIu64", len=%"PRIu64"]",
674 bf->data, bf->off, bf->len));
15a8fb42 675 free(bf);
4884729a 676 }
15a8fb42 677
e04f3860 678 DBG(LOWPROBE, ul_debug(" buffers summary: %"PRIu64" bytes by %"PRIu64" read() calls",
2355dd6a 679 len, ct));
15a8fb42
KZ
680
681 INIT_LIST_HEAD(&pr->buffers);
a0948ffe
KZ
682}
683
af17d349 684static void blkid_probe_reset_values(blkid_probe pr)
6c4a7811 685{
7f787ced 686 if (list_empty(&pr->values))
6c4a7811
OO
687 return;
688
689 DBG(LOWPROBE, ul_debug("resetting results pr=%p", pr));
690
af17d349
KZ
691 while (!list_empty(&pr->values)) {
692 struct blkid_prval *v = list_entry(pr->values.next,
6c4a7811 693 struct blkid_prval, prvals);
af17d349 694 blkid_probe_free_value(v);
6c4a7811
OO
695 }
696
af17d349 697 INIT_LIST_HEAD(&pr->values);
6c4a7811
OO
698}
699
108013b4
KZ
700/*
701 * Small devices need a special care.
702 */
703int blkid_probe_is_tiny(blkid_probe pr)
704{
7f787ced 705 return (pr->flags & BLKID_FL_TINY_DEV);
108013b4
KZ
706}
707
55113b15
C
708/*
709 * CDROMs may fail when probed for RAID (last sector problem)
710 */
711int blkid_probe_is_cdrom(blkid_probe pr)
712{
7f787ced 713 return (pr->flags & BLKID_FL_CDROM_DEV);
55113b15
C
714}
715
332123f2
RM
716#ifdef CDROM_GET_CAPABILITY
717
bfebe74e
KZ
718static int is_sector_readable(int fd, uint64_t sector)
719{
720 char buf[512];
721 ssize_t sz;
722
723 if (blkid_llseek(fd, sector * 512, SEEK_SET) < 0)
724 goto failed;
725
726 sz = read(fd, buf, sizeof(buf));
727 if (sz != (ssize_t) sizeof(buf))
728 goto failed;
729
730 return 1;
731failed:
eaaf0e7e 732 DBG(LOWPROBE, ul_debug("CDROM: read sector %"PRIu64" failed %m", sector));
bfebe74e
KZ
733 errno = 0;
734 return 0;
735}
736
737/*
6548ac6a
KZ
738 * Linux kernel reports (BLKGETSIZE) cdrom device size greater than area
739 * readable by read(2). We have to reduce the probing area to avoid unwanted
740 * I/O errors in probing functions. It seems that unreadable are always last 2
741 * or 3 CD blocks (CD block size is 2048 bytes, it means 12 in 512-byte
742 * sectors).
bfebe74e
KZ
743 */
744static void cdrom_size_correction(blkid_probe pr)
745{
6548ac6a 746 uint64_t n, nsectors = pr->size >> 9;
bfebe74e
KZ
747
748 for (n = nsectors - 12; n < nsectors; n++) {
749 if (!is_sector_readable(pr->fd, n))
750 goto failed;
751 }
752
753 DBG(LOWPROBE, ul_debug("CDROM: full size available"));
754 return;
755failed:
756 /* 'n' is the failed sector, reduce device size to n-1; */
757 DBG(LOWPROBE, ul_debug("CDROM: reduce size from %ju to %ju.",
758 (uintmax_t) pr->size,
1bd62f72 759 (uintmax_t) n << 9));
bfebe74e
KZ
760 pr->size = n << 9;
761}
762
332123f2
RM
763#endif
764
52448df8
KZ
765/**
766 * blkid_probe_set_device:
767 * @pr: probe
768 * @fd: device file descriptor
769 * @off: begin of probing area
f38db0cf 770 * @size: size of probing area (zero means whole device/file)
52448df8
KZ
771 *
772 * Assigns the device to probe control struct, resets internal buffers and
44ef90bc 773 * resets the current probing.
51410fc6 774 *
52448df8 775 * Returns: -1 in case of failure, or 0 on success.
51410fc6
KZ
776 */
777int blkid_probe_set_device(blkid_probe pr, int fd,
778 blkid_loff_t off, blkid_loff_t size)
a0948ffe 779{
90ec8d9c 780 struct stat sb;
f12cd8d1 781 uint64_t devsiz = 0;
90ec8d9c 782
51410fc6 783 blkid_reset_probe(pr);
ccdf9fda 784 blkid_probe_reset_buffer(pr);
a0948ffe 785
a9eef56c 786 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
f38db0cf
KZ
787 close(pr->fd);
788
a9eef56c
KZ
789 pr->flags &= ~BLKID_FL_PRIVATE_FD;
790 pr->flags &= ~BLKID_FL_TINY_DEV;
791 pr->flags &= ~BLKID_FL_CDROM_DEV;
ccdf9fda 792 pr->prob_flags = 0;
51410fc6 793 pr->fd = fd;
f12cd8d1 794 pr->off = (uint64_t) off;
bb6c6673 795 pr->size = 0;
52448df8 796 pr->devno = 0;
ccdf9fda 797 pr->disk_devno = 0;
52448df8
KZ
798 pr->mode = 0;
799 pr->blkssz = 0;
ccdf9fda
KZ
800 pr->wipe_off = 0;
801 pr->wipe_size = 0;
802 pr->wipe_chain = NULL;
dc61d909 803
a67bb3bf
LT
804#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
805 /* Disable read-ahead */
806 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
807#endif
90ec8d9c
KZ
808 if (fstat(fd, &sb))
809 goto err;
810
a674a0ab 811 if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode)) {
2355dd6a 812 errno = EINVAL;
26eb5a59 813 goto err;
a674a0ab 814 }
20e1c3dc 815
90ec8d9c
KZ
816 pr->mode = sb.st_mode;
817 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
818 pr->devno = sb.st_rdev;
819
a674a0ab
KZ
820 if (S_ISBLK(sb.st_mode)) {
821 if (blkdev_get_size(fd, (unsigned long long *) &devsiz)) {
822 DBG(LOWPROBE, ul_debug("failed to get device size"));
108013b4 823 goto err;
a674a0ab
KZ
824 }
825 } else if (S_ISCHR(sb.st_mode))
826 devsiz = 1; /* UBI devices are char... */
827 else if (S_ISREG(sb.st_mode))
828 devsiz = sb.st_size; /* regular file */
829
b9710f1f 830 pr->size = size ? (uint64_t)size : devsiz;
108013b4 831
a674a0ab
KZ
832 if (off && size == 0)
833 /* only offset without size specified */
f12cd8d1 834 pr->size -= (uint64_t) off;
a674a0ab
KZ
835
836 if (pr->off + pr->size > devsiz) {
837 DBG(LOWPROBE, ul_debug("area specified by offset and size is bigger than device"));
838 errno = EINVAL;
839 goto err;
bb6c6673 840 }
c1ba7962 841
90ec8d9c 842 if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
a9eef56c 843 pr->flags |= BLKID_FL_TINY_DEV;
d0465c3c 844
39866431 845 if (S_ISBLK(sb.st_mode) && sysfs_devno_is_lvm_private(sb.st_rdev)) {
20e1c3dc
KZ
846 DBG(LOWPROBE, ul_debug("ignore private LVM device"));
847 pr->flags |= BLKID_FL_NOSCAN_DEV;
848 }
849
55113b15 850#ifdef CDROM_GET_CAPABILITY
20e1c3dc 851 else if (S_ISBLK(sb.st_mode) &&
a3ab71cf
KZ
852 !blkid_probe_is_tiny(pr) &&
853 blkid_probe_is_wholedisk(pr) &&
bfebe74e
KZ
854 ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) {
855
a9eef56c 856 pr->flags |= BLKID_FL_CDROM_DEV;
bfebe74e
KZ
857 cdrom_size_correction(pr);
858 }
55113b15 859#endif
508e438b 860
fdbd7bb9 861 DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64"",
508e438b 862 pr->off, pr->size));
c62a6311 863 DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s",
508e438b
KZ
864 blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
865 S_ISREG(pr->mode) ? "YES" : "NO"));
866
a0948ffe 867 return 0;
0d17b1cf 868err:
c62a6311 869 DBG(LOWPROBE, ul_debug("failed to prepare a device for low-probing"));
0d17b1cf
KZ
870 return -1;
871
a0948ffe
KZ
872}
873
f12cd8d1 874int blkid_probe_get_dimension(blkid_probe pr, uint64_t *off, uint64_t *size)
f319b5ca 875{
f319b5ca
KZ
876 *off = pr->off;
877 *size = pr->size;
878 return 0;
879}
880
f12cd8d1 881int blkid_probe_set_dimension(blkid_probe pr, uint64_t off, uint64_t size)
f319b5ca 882{
c62a6311 883 DBG(LOWPROBE, ul_debug(
fdbd7bb9
RM
884 "changing probing area pr=%p: size=%"PRIu64", off=%"PRIu64" "
885 "-to-> size=%"PRIu64", off=%"PRIu64"",
f12cd8d1 886 pr, pr->size, pr->off, size, off));
f319b5ca
KZ
887
888 pr->off = off;
889 pr->size = size;
a9eef56c 890 pr->flags &= ~BLKID_FL_TINY_DEV;
88923b08 891
f12cd8d1 892 if (pr->size <= 1440ULL * 1024ULL && !S_ISCHR(pr->mode))
a9eef56c 893 pr->flags |= BLKID_FL_TINY_DEV;
f319b5ca
KZ
894
895 blkid_probe_reset_buffer(pr);
896
897 return 0;
898}
899
8d0ce083 900/*
296d96e2
HR
901 * Check for matching magic value.
902 * Returns BLKID_PROBE_OK if found, BLKID_PROBE_NONE if not found
903 * or no magic present, or negative value on error.
904 */
c76e710b 905int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
f12cd8d1 906 uint64_t *offset, const struct blkid_idmag **res)
c76e710b
KZ
907{
908 const struct blkid_idmag *mag = NULL;
f12cd8d1 909 uint64_t off = 0;
c76e710b
KZ
910
911 if (id)
c03d12d8 912 mag = &id->magics[0];
c76e710b
KZ
913 if (res)
914 *res = NULL;
915
916 /* try to detect by magic string */
917 while(mag && mag->magic) {
918 unsigned char *buf;
919
920 off = (mag->kboff + (mag->sboff >> 10)) << 10;
921 buf = blkid_probe_get_buffer(pr, off, 1024);
922
296d96e2
HR
923 if (!buf && errno)
924 return -errno;
a674a0ab 925
c76e710b
KZ
926 if (buf && !memcmp(mag->magic,
927 buf + (mag->sboff & 0x3ff), mag->len)) {
a674a0ab 928
c62a6311 929 DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld",
c76e710b
KZ
930 mag->sboff, mag->kboff));
931 if (offset)
932 *offset = off + (mag->sboff & 0x3ff);
933 if (res)
934 *res = mag;
296d96e2 935 return BLKID_PROBE_OK;
c76e710b
KZ
936 }
937 mag++;
938 }
939
c03d12d8 940 if (id && id->magics[0].magic)
c76e710b 941 /* magic string(s) defined, but not found */
296d96e2 942 return BLKID_PROBE_NONE;
c76e710b 943
296d96e2 944 return BLKID_PROBE_OK;
c76e710b
KZ
945}
946
c81e7008
KZ
947static inline void blkid_probe_start(blkid_probe pr)
948{
7f787ced
KZ
949 DBG(LOWPROBE, ul_debug("%p: start probe", pr));
950 pr->cur_chain = NULL;
951 pr->prob_flags = 0;
952 blkid_probe_set_wiper(pr, 0, 0);
c81e7008
KZ
953}
954
955static inline void blkid_probe_end(blkid_probe pr)
956{
7f787ced
KZ
957 DBG(LOWPROBE, ul_debug("%p: end probe", pr));
958 pr->cur_chain = NULL;
959 pr->prob_flags = 0;
960 blkid_probe_set_wiper(pr, 0, 0);
c81e7008
KZ
961}
962
0bffad47
KZ
963/**
964 * blkid_do_probe:
965 * @pr: prober
966 *
967 * Calls probing functions in all enabled chains. The superblocks chain is
968 * enabled by default. The blkid_do_probe() stores result from only one
969 * probing function. It's necessary to call this routine in a loop to get
3b159691 970 * results from all probing functions in all chains. The probing is reset
44ef90bc 971 * by blkid_reset_probe() or by filter functions.
a0fc685c 972 *
0bffad47
KZ
973 * This is string-based NAME=value interface only.
974 *
975 * <example>
976 * <title>basic case - use the first result only</title>
977 * <programlisting>
a0fc685c
KZ
978 * if (blkid_do_probe(pr) == 0) {
979 * int nvals = blkid_probe_numof_values(pr);
980 * for (n = 0; n < nvals; n++) {
981 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
982 * printf("%s = %s\n", name, data);
983 * }
984 * }
0bffad47
KZ
985 * </programlisting>
986 * </example>
a0fc685c 987 *
0bffad47
KZ
988 * <example>
989 * <title>advanced case - probe for all signatures</title>
990 * <programlisting>
a0fc685c
KZ
991 * while (blkid_do_probe(pr) == 0) {
992 * int nvals = blkid_probe_numof_values(pr);
993 * ...
994 * }
0bffad47
KZ
995 * </programlisting>
996 * </example>
a0fc685c 997 *
0bffad47 998 * See also blkid_reset_probe().
a0fc685c 999 *
0bffad47 1000 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
a0fc685c 1001 */
51410fc6 1002int blkid_do_probe(blkid_probe pr)
a0948ffe 1003{
0bffad47 1004 int rc = 1;
a0948ffe 1005
20e1c3dc
KZ
1006 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1007 return 1;
1008
0bffad47 1009 do {
44ef90bc
KZ
1010 struct blkid_chain *chn = pr->cur_chain;
1011
c81e7008
KZ
1012 if (!chn) {
1013 blkid_probe_start(pr);
44ef90bc 1014 chn = pr->cur_chain = &pr->chains[0];
c81e7008 1015 }
44ef90bc
KZ
1016 /* we go to the next chain only when the previous probing
1017 * result was nothing (rc == 1) and when the current chain is
1018 * disabled or we are at end of the current chain (chain->idx +
046959cc
CW
1019 * 1 == sizeof chain) or the current chain bailed out right at
1020 * the start (chain->idx == -1)
44ef90bc
KZ
1021 */
1022 else if (rc == 1 && (chn->enabled == FALSE ||
c9f51c71 1023 chn->idx + 1 == (int) chn->driver->nidinfos ||
046959cc 1024 chn->idx == -1)) {
a0948ffe 1025
c9f51c71 1026 size_t idx = chn->driver->id + 1;
bd635f86
KZ
1027
1028 if (idx < BLKID_NCHAINS)
44ef90bc 1029 chn = pr->cur_chain = &pr->chains[idx];
c81e7008
KZ
1030 else {
1031 blkid_probe_end(pr);
bd635f86 1032 return 1; /* all chains already probed */
c81e7008 1033 }
bd635f86 1034 }
a0fc685c 1035
0bffad47 1036 chn->binary = FALSE; /* for sure... */
6644688a 1037
c62a6311 1038 DBG(LOWPROBE, ul_debug("chain probe %s %s (idx=%d)",
0bffad47 1039 chn->driver->name,
44ef90bc
KZ
1040 chn->enabled? "ENABLED" : "DISABLED",
1041 chn->idx));
a0948ffe 1042
0bffad47 1043 if (!chn->enabled)
51410fc6 1044 continue;
a0948ffe 1045
0bffad47
KZ
1046 /* rc: -1 = error, 0 = success, 1 = no result */
1047 rc = chn->driver->probe(pr, chn);
a0948ffe 1048
0bffad47 1049 } while (rc == 1);
a0948ffe 1050
0bffad47
KZ
1051 return rc;
1052}
a0948ffe 1053
2b89be6c
KZ
1054/**
1055 * blkid_do_wipe:
1056 * @pr: prober
1057 * @dryrun: if TRUE then don't touch the device.
1058 *
1059 * This function erases the current signature detected by @pr. The @pr has to
476b508e 1060 * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
9e930041 1061 * has to be enabled (if you want to erase also superblock with broken check
c93c2030 1062 * sums then use BLKID_SUBLKS_BADCSUM too).
2b89be6c
KZ
1063 *
1064 * After successful signature removing the @pr prober will be moved one step
1065 * back and the next blkid_do_probe() call will again call previously called
1066 * probing function.
1067 *
1068 * <example>
1069 * <title>wipe all filesystems or raids from the device</title>
1070 * <programlisting>
49a8f58e 1071 * fd = open(devname, O_RDWR|O_CLOEXEC);
2b89be6c
KZ
1072 * blkid_probe_set_device(pr, fd, 0, 0);
1073 *
1074 * blkid_probe_enable_superblocks(pr, 1);
1075 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1076 *
1077 * while (blkid_do_probe(pr) == 0)
1078 * blkid_do_wipe(pr, FALSE);
1079 * </programlisting>
1080 * </example>
1081 *
cd0fe5c1
KZ
1082 * See also blkid_probe_step_back() if you cannot use this build-in wipe
1083 * function, but you want to use libblkid probing as a source for wiping.
1084 *
1085 * Returns: 0 on success, and -1 in case of error.
2b89be6c
KZ
1086 */
1087int blkid_do_wipe(blkid_probe pr, int dryrun)
1088{
44765fdd 1089 const char *off = NULL;
2b89be6c 1090 size_t len = 0;
f12cd8d1 1091 uint64_t offset, l;
2b89be6c 1092 char buf[BUFSIZ];
f8054232 1093 int fd, rc = 0;
2b89be6c
KZ
1094 struct blkid_chain *chn;
1095
2b89be6c
KZ
1096 chn = pr->cur_chain;
1097 if (!chn)
1098 return -1;
1099
44765fdd
KZ
1100 switch (chn->driver->id) {
1101 case BLKID_CHAIN_SUBLKS:
1102 rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
1103 if (!rc)
1104 rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1105 break;
1106 case BLKID_CHAIN_PARTS:
1107 rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
1108 if (!rc)
1109 rc = blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1110 break;
1111 default:
1112 return 0;
1113 }
1114
1115 if (rc || len == 0 || off == NULL)
2b89be6c
KZ
1116 return 0;
1117
445e6b1e 1118 offset = strtoumax(off, NULL, 10) + pr->off;
2b89be6c
KZ
1119 fd = blkid_probe_get_fd(pr);
1120 if (fd < 0)
1121 return -1;
1122
1123 if (len > sizeof(buf))
1124 len = sizeof(buf);
1125
c62a6311 1126 DBG(LOWPROBE, ul_debug(
fdbd7bb9 1127 "do_wipe [offset=0x%"PRIx64" (%"PRIu64"), len=%zu, chain=%s, idx=%d, dryrun=%s]\n",
f12cd8d1 1128 offset, offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));
2b89be6c 1129
f12cd8d1 1130 l = blkid_llseek(fd, offset, SEEK_SET);
b9710f1f 1131 if ((blkid_loff_t)l == (off_t) -1)
2b89be6c
KZ
1132 return -1;
1133
1134 memset(buf, 0, len);
1135
1136 if (!dryrun && len) {
1137 if (write_all(fd, buf, len))
1138 return -1;
1139 fsync(fd);
cd0fe5c1
KZ
1140 return blkid_probe_step_back(pr);
1141 }
2b89be6c 1142
cd0fe5c1
KZ
1143 return 0;
1144}
2b89be6c 1145
cd0fe5c1 1146/**
c0055e2a 1147 * blkid_probe_step_back:
cd0fe5c1
KZ
1148 * @pr: prober
1149 *
1150 * This function move pointer to the probing chain one step back -- it means
1151 * that the previously used probing function will be called again in the next
1152 * blkid_do_probe() call.
1153 *
1154 * This is necessary for example if you erase or modify on-disk superblock
1155 * according to the current libblkid probing result.
1156 *
1157 * <example>
1158 * <title>wipe all superblock, but use libblkid only for probing</title>
1159 * <programlisting>
1160 * pr = blkid_new_probe_from_filename(devname);
1161 *
1162 * blkid_probe_enable_superblocks(pr, 1);
1163 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1164 *
2bb7a706
KZ
1165 * blkid_probe_enable_partitions(pr, 1);
1166 * blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
1167 *
cd0fe5c1
KZ
1168 * while (blkid_do_probe(pr) == 0) {
1169 * const char *ostr = NULL;
1170 * size_t len = 0;
1171 *
1172 * // superblocks
1173 * if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &ostr, NULL) == 0)
1174 * blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1175 *
1176 * // partition tables
1177 * if (len == 0 && blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &ostr, NULL) == 0)
1178 * blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1179 *
1180 * if (!len || !str)
1181 * continue;
1182 *
1183 * // convert ostr to the real offset by off = strtoll(ostr, NULL, 10);
9e930041 1184 * // use your stuff to erase @len bytes at the @off
cd0fe5c1
KZ
1185 * ....
1186 *
1187 * // retry the last probing to check for backup superblocks ..etc.
1188 * blkid_probe_step_back(pr);
1189 * }
1190 * </programlisting>
1191 * </example>
1192 *
1193 * Returns: 0 on success, and -1 in case of error.
1194 */
1195int blkid_probe_step_back(blkid_probe pr)
1196{
1197 struct blkid_chain *chn;
1198
cd0fe5c1
KZ
1199 chn = pr->cur_chain;
1200 if (!chn)
1201 return -1;
1202
1203 blkid_probe_reset_buffer(pr);
1204
1205 if (chn->idx >= 0) {
1206 chn->idx--;
c62a6311 1207 DBG(LOWPROBE, ul_debug("step back: moving %s chain index to %d",
cd0fe5c1
KZ
1208 chn->driver->name,
1209 chn->idx));
2b89be6c 1210 }
cd0fe5c1
KZ
1211
1212 if (chn->idx == -1) {
1213 /* blkid_do_probe() goes to the next chain if the index
1214 * of the current chain is -1, so we have to set the
1215 * chain pointer to the previous chain.
1216 */
1217 size_t idx = chn->driver->id > 0 ? chn->driver->id - 1 : 0;
1218
c62a6311 1219 DBG(LOWPROBE, ul_debug("step back: moving to previous chain"));
cd0fe5c1
KZ
1220
1221 if (idx > 0)
1222 pr->cur_chain = &pr->chains[idx];
1223 else if (idx == 0)
1224 pr->cur_chain = NULL;
1225 }
1226
2b89be6c
KZ
1227 return 0;
1228}
1229
0bffad47
KZ
1230/**
1231 * blkid_do_safeprobe:
1232 * @pr: prober
1233 *
1234 * This function gathers probing results from all enabled chains and checks
1235 * for ambivalent results (e.g. more filesystems on the device).
1236 *
1237 * This is string-based NAME=value interface only.
1238 *
9e930041 1239 * Note about superblocks chain -- the function does not check for filesystems
0bffad47 1240 * when a RAID signature is detected. The function also does not check for
c81e7008
KZ
1241 * collision between RAIDs. The first detected RAID is returned. The function
1242 * checks for collision between partition table and RAID signature -- it's
1243 * recommended to enable partitions chain together with superblocks chain.
0bffad47 1244 *
9e930041 1245 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalent result is
0bffad47
KZ
1246 * detected and -1 on case of error.
1247 */
1248int blkid_do_safeprobe(blkid_probe pr)
1249{
1250 int i, count = 0, rc = 0;
a0948ffe 1251
20e1c3dc
KZ
1252 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1253 return 1;
a0948ffe 1254
c81e7008
KZ
1255 blkid_probe_start(pr);
1256
0bffad47
KZ
1257 for (i = 0; i < BLKID_NCHAINS; i++) {
1258 struct blkid_chain *chn;
a0948ffe 1259
0bffad47
KZ
1260 chn = pr->cur_chain = &pr->chains[i];
1261 chn->binary = FALSE; /* for sure... */
a0948ffe 1262
c62a6311 1263 DBG(LOWPROBE, ul_debug("chain safeprobe %s %s",
0bffad47
KZ
1264 chn->driver->name,
1265 chn->enabled? "ENABLED" : "DISABLED"));
1266
1267 if (!chn->enabled)
1268 continue;
1269
9e0f7bda 1270 blkid_probe_chain_reset_position(chn);
0bffad47 1271
0bffad47 1272 rc = chn->driver->safeprobe(pr, chn);
9e0f7bda
KZ
1273
1274 blkid_probe_chain_reset_position(chn);
1275
1276 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
0bffad47
KZ
1277 if (rc < 0)
1278 goto done; /* error */
1279 if (rc == 0)
1280 count++; /* success */
51410fc6 1281 }
0bffad47
KZ
1282
1283done:
c81e7008 1284 blkid_probe_end(pr);
0bffad47
KZ
1285 if (rc < 0)
1286 return rc;
1287 return count ? 0 : 1;
a0948ffe
KZ
1288}
1289
0bffad47
KZ
1290/**
1291 * blkid_do_fullprobe:
1292 * @pr: prober
1293 *
1294 * This function gathers probing results from all enabled chains. Same as
fd7c9e35 1295 * blkid_do_safeprobe() but does not check for collision between probing
0bffad47
KZ
1296 * result.
1297 *
1298 * This is string-based NAME=value interface only.
7103157c 1299 *
0bffad47 1300 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
a2f01a1c 1301 */
0bffad47 1302int blkid_do_fullprobe(blkid_probe pr)
a2f01a1c 1303{
0bffad47 1304 int i, count = 0, rc = 0;
7103157c 1305
20e1c3dc
KZ
1306 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1307 return 1;
a2f01a1c 1308
c81e7008
KZ
1309 blkid_probe_start(pr);
1310
0bffad47 1311 for (i = 0; i < BLKID_NCHAINS; i++) {
0bffad47 1312 struct blkid_chain *chn;
a2f01a1c 1313
0bffad47
KZ
1314 chn = pr->cur_chain = &pr->chains[i];
1315 chn->binary = FALSE; /* for sure... */
1316
c62a6311 1317 DBG(LOWPROBE, ul_debug("chain fullprobe %s: %s",
0bffad47
KZ
1318 chn->driver->name,
1319 chn->enabled? "ENABLED" : "DISABLED"));
1320
1321 if (!chn->enabled)
1322 continue;
1323
9e0f7bda 1324 blkid_probe_chain_reset_position(chn);
0bffad47 1325
0bffad47 1326 rc = chn->driver->probe(pr, chn);
9e0f7bda
KZ
1327
1328 blkid_probe_chain_reset_position(chn);
1329
1330 /* rc: -1 = error, 0 = success, 1 = no result */
0bffad47
KZ
1331 if (rc < 0)
1332 goto done; /* error */
1333 if (rc == 0)
1334 count++; /* success */
1335 }
1336
1337done:
c81e7008 1338 blkid_probe_end(pr);
0bffad47
KZ
1339 if (rc < 0)
1340 return rc;
1341 return count ? 0 : 1;
a2f01a1c
KZ
1342}
1343
ce011388
KZ
1344/* same sa blkid_probe_get_buffer() but works with 512-sectors */
1345unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
1346{
7f787ced 1347 return blkid_probe_get_buffer(pr, ((uint64_t) sector) << 9, 0x200);
ce011388
KZ
1348}
1349
7f787ced 1350struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, const char *name)
a0948ffe 1351{
51410fc6 1352 struct blkid_prval *v;
6c4a7811 1353
08029093 1354 v = calloc(1, sizeof(struct blkid_prval));
6c4a7811 1355 if (!v)
51410fc6 1356 return NULL;
a0948ffe 1357
08029093 1358 INIT_LIST_HEAD(&v->prvals);
51410fc6 1359 v->name = name;
9bdf6885 1360 v->chain = pr->cur_chain;
af17d349 1361 list_add_tail(&v->prvals, &pr->values);
6644688a 1362
c62a6311 1363 DBG(LOWPROBE, ul_debug("assigning %s [%s]", name, v->chain->driver->name));
51410fc6 1364 return v;
a0948ffe
KZ
1365}
1366
6c4a7811 1367/* Note that value data is always terminated by zero to keep things robust,
3fd1f771
RM
1368 * this extra zero is not count to the value length. It's caller responsibility
1369 * to set proper value length (for strings we count terminator to the length,
6c4a7811
OO
1370 * for binary data it's without terminator).
1371 */
1372int blkid_probe_value_set_data(struct blkid_prval *v,
1373 unsigned char *data, size_t len)
1374{
1375 v->data = calloc(1, len + 1); /* always terminate by \0 */
cdd5bada 1376
6c4a7811
OO
1377 if (!v->data)
1378 return -ENOMEM;
1379 memcpy(v->data, data, len);
1380 v->len = len;
cdd5bada 1381 return 0;
cdd5bada
KZ
1382}
1383
51410fc6
KZ
1384int blkid_probe_set_value(blkid_probe pr, const char *name,
1385 unsigned char *data, size_t len)
a0948ffe 1386{
51410fc6 1387 struct blkid_prval *v;
a0948ffe 1388
51410fc6
KZ
1389 v = blkid_probe_assign_value(pr, name);
1390 if (!v)
1391 return -1;
a0948ffe 1392
6c4a7811 1393 return blkid_probe_value_set_data(v, data, len);
a0948ffe
KZ
1394}
1395
51410fc6
KZ
1396int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
1397 const char *fmt, va_list ap)
a0948ffe 1398{
51410fc6 1399 struct blkid_prval *v;
a23facd6 1400 ssize_t len;
a0948ffe 1401
51410fc6
KZ
1402 v = blkid_probe_assign_value(pr, name);
1403 if (!v)
6c4a7811 1404 return -ENOMEM;
a0948ffe 1405
6c4a7811 1406 len = vasprintf((char **) &v->data, fmt, ap);
a0948ffe 1407
6c4a7811 1408 if (len <= 0) {
af17d349 1409 blkid_probe_free_value(v);
6c4a7811 1410 return len == 0 ? -EINVAL : -ENOMEM;
a0948ffe 1411 }
51410fc6 1412 v->len = len + 1;
a0948ffe
KZ
1413 return 0;
1414}
1415
cc33d693
KZ
1416int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
1417 const char *fmt, ...)
1418{
1419 int rc;
1420 va_list ap;
1421
1422 va_start(ap, fmt);
1423 rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
1424 va_end(ap);
1425
1426 return rc;
1427}
1428
f12cd8d1 1429int blkid_probe_set_magic(blkid_probe pr, uint64_t offset,
3c83b3b2
KZ
1430 size_t len, unsigned char *magic)
1431{
1432 int rc = 0;
1433 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1434
7f787ced 1435 if (!chn || !len || chn->binary)
3c83b3b2
KZ
1436 return 0;
1437
1438 switch (chn->driver->id) {
1439 case BLKID_CHAIN_SUBLKS:
1440 if (!(chn->flags & BLKID_SUBLKS_MAGIC))
1441 return 0;
1442 rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
1443 if (!rc)
1444 rc = blkid_probe_sprintf_value(pr,
44064b3c 1445 "SBMAGIC_OFFSET", "%llu", (unsigned long long)offset);
3c83b3b2
KZ
1446 break;
1447 case BLKID_CHAIN_PARTS:
1448 if (!(chn->flags & BLKID_PARTS_MAGIC))
1449 return 0;
1450 rc = blkid_probe_set_value(pr, "PTMAGIC", magic, len);
1451 if (!rc)
1452 rc = blkid_probe_sprintf_value(pr,
44064b3c 1453 "PTMAGIC_OFFSET", "%llu", (unsigned long long)offset);
3c83b3b2
KZ
1454 break;
1455 default:
1456 break;
1457 }
1458
1459 return rc;
1460}
1461
c89a1def
KZ
1462int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
1463{
1464 if (csum != expected) {
02f3c12a
GP
1465 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1466
c62a6311 1467 DBG(LOWPROBE, ul_debug(
c89a1def 1468 "incorrect checksum for type %s,"
fdbd7bb9 1469 " got %"PRIX64", expected %"PRIX64"",
c89a1def
KZ
1470 blkid_probe_get_probername(pr),
1471 csum, expected));
d88803a4
KZ
1472 /*
1473 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
1474 */
1475 if (chn->driver->id == BLKID_CHAIN_SUBLKS
1476 && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
1477 blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
1478 goto accept;
1479 }
1480 return 0; /* bad checksum */
c89a1def
KZ
1481 }
1482
d88803a4
KZ
1483accept:
1484 return 1;
c89a1def
KZ
1485}
1486
b3ee97a3
KZ
1487/**
1488 * blkid_probe_get_devno:
1489 * @pr: probe
1490 *
3b159691 1491 * Returns: block device number, or 0 for regular files.
b3ee97a3
KZ
1492 */
1493dev_t blkid_probe_get_devno(blkid_probe pr)
1494{
b3ee97a3
KZ
1495 return pr->devno;
1496}
1497
601fb1c1
KZ
1498/**
1499 * blkid_probe_get_wholedisk_devno:
1500 * @pr: probe
1501 *
3b159691 1502 * Returns: device number of the wholedisk, or 0 for regular files.
601fb1c1
KZ
1503 */
1504dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
1505{
1506 if (!pr->disk_devno) {
1507 dev_t devno, disk_devno = 0;
1508
1509 devno = blkid_probe_get_devno(pr);
1510 if (!devno)
1511 return 0;
1512
2bf68c93 1513 if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
601fb1c1
KZ
1514 pr->disk_devno = disk_devno;
1515 }
1516 return pr->disk_devno;
1517}
1518
1519/**
1520 * blkid_probe_is_wholedisk:
1521 * @pr: probe
1522 *
1523 * Returns: 1 if the device is whole-disk or 0.
1524 */
1525int blkid_probe_is_wholedisk(blkid_probe pr)
1526{
1527 dev_t devno, disk_devno;
1528
1529 devno = blkid_probe_get_devno(pr);
1530 if (!devno)
1531 return 0;
1532
1533 disk_devno = blkid_probe_get_wholedisk_devno(pr);
1534 if (!disk_devno)
1535 return 0;
1536
1537 return devno == disk_devno;
1538}
1539
fd9f45e1
KZ
1540blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
1541{
1542 dev_t disk;
1543
1544 if (blkid_probe_is_wholedisk(pr))
1545 return NULL; /* this is not partition */
1546
1547 if (pr->parent)
1548 /* this is cloned blkid_probe, use parent's stuff */
1549 return blkid_probe_get_wholedisk_probe(pr->parent);
1550
1551 disk = blkid_probe_get_wholedisk_devno(pr);
1552
1553 if (pr->disk_probe && pr->disk_probe->devno != disk) {
1554 /* we have disk prober, but for another disk... close it */
1555 blkid_free_probe(pr->disk_probe);
1556 pr->disk_probe = NULL;
1557 }
1558
1559 if (!pr->disk_probe) {
1560 /* Open a new disk prober */
1561 char *disk_path = blkid_devno_to_devname(disk);
1562
1563 if (!disk_path)
1564 return NULL;
1565
c62a6311 1566 DBG(LOWPROBE, ul_debug("allocate a wholedisk probe"));
fd9f45e1
KZ
1567
1568 pr->disk_probe = blkid_new_probe_from_filename(disk_path);
7eac65fc
KZ
1569
1570 free(disk_path);
1571
fd9f45e1
KZ
1572 if (!pr->disk_probe)
1573 return NULL; /* ENOMEM? */
1574 }
1575
1576 return pr->disk_probe;
1577}
1578
b3ee97a3
KZ
1579/**
1580 * blkid_probe_get_size:
1581 * @pr: probe
1582 *
30696241
KZ
1583 * This function returns size of probing area as defined by blkid_probe_set_device().
1584 * If the size of the probing area is unrestricted then this function returns
1585 * the real size of device. See also blkid_get_dev_size().
1586 *
1587 * Returns: size in bytes or -1 in case of error.
b3ee97a3
KZ
1588 */
1589blkid_loff_t blkid_probe_get_size(blkid_probe pr)
1590{
7f787ced 1591 return (blkid_loff_t) pr->size;
b3ee97a3
KZ
1592}
1593
56e961e2
KZ
1594/**
1595 * blkid_probe_get_offset:
1596 * @pr: probe
1597 *
1598 * This function returns offset of probing area as defined by blkid_probe_set_device().
1599 *
1600 * Returns: offset in bytes or -1 in case of error.
1601 */
1602blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
1603{
7f787ced 1604 return (blkid_loff_t) pr->off;
56e961e2
KZ
1605}
1606
1607/**
1608 * blkid_probe_get_fd:
1609 * @pr: probe
1610 *
e3436956 1611 * Returns: file descriptor for assigned device/file or -1 in case of error.
56e961e2
KZ
1612 */
1613int blkid_probe_get_fd(blkid_probe pr)
1614{
7f787ced 1615 return pr->fd;
56e961e2
KZ
1616}
1617
b3ee97a3
KZ
1618/**
1619 * blkid_probe_get_sectorsize:
90ec8d9c 1620 * @pr: probe or NULL (for NULL returns 512)
b3ee97a3 1621 *
2a1dfbad 1622 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
b3ee97a3
KZ
1623 */
1624unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
1625{
b3ee97a3
KZ
1626 if (pr->blkssz)
1627 return pr->blkssz;
b3ee97a3 1628
90ec8d9c
KZ
1629 if (S_ISBLK(pr->mode) &&
1630 blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
1631 return pr->blkssz;
b3ee97a3 1632
b3ee97a3
KZ
1633 pr->blkssz = DEFAULT_SECTOR_SIZE;
1634 return pr->blkssz;
1635}
1636
76fab513
KZ
1637/**
1638 * blkid_probe_set_sectorsize:
1639 * @pr: probe
1640 * @sz: new size (to overwrite system default)
1641 *
1642 * Note that blkid_probe_set_device() resets this setting. Use it after
1643 * blkid_probe_set_device() and before any probing call.
1644 *
ae4e2abc
KZ
1645 * Since: 2.30
1646 *
76fab513
KZ
1647 * Returns: 0 or <0 in case of error
1648 */
1649int blkid_probe_set_sectorsize(blkid_probe pr, unsigned int sz)
1650{
1651 pr->blkssz = sz;
1652 return 0;
1653}
1654
e8ae4947
DB
1655/**
1656 * blkid_probe_get_sectors:
1657 * @pr: probe
1658 *
1659 * Returns: 512-byte sector count or -1 in case of error.
1660 */
1661blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
1662{
7f787ced 1663 return (blkid_loff_t) (pr->size >> 9);
e8ae4947
DB
1664}
1665
4d72b337
KZ
1666/**
1667 * blkid_probe_numof_values:
1668 * @pr: probe
1669 *
1670 * Returns: number of values in probing result or -1 in case of error.
1671 */
1672int blkid_probe_numof_values(blkid_probe pr)
1673{
6c4a7811
OO
1674 int i = 0;
1675 struct list_head *p;
6c4a7811 1676
af17d349 1677 list_for_each(p, &pr->values)
6c4a7811
OO
1678 ++i;
1679 return i;
4d72b337
KZ
1680}
1681
81f73792
KZ
1682/**
1683 * blkid_probe_get_value:
1684 * @pr: probe
1685 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
1686 * @name: pointer to return value name or NULL
1687 * @data: pointer to return value data or NULL
1688 * @len: pointer to return value length or NULL
1689 *
c2dbd49b
KZ
1690 * Note, the @len returns length of the @data, including the terminating
1691 * '\0' character.
1692 *
81f73792
KZ
1693 * Returns: 0 on success, or -1 in case of error.
1694 */
51410fc6 1695int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
6d042d0d 1696 const char **data, size_t *len)
a0948ffe 1697{
81f73792 1698 struct blkid_prval *v = __blkid_probe_get_value(pr, num);
a0948ffe 1699
81f73792 1700 if (!v)
51410fc6 1701 return -1;
51410fc6
KZ
1702 if (name)
1703 *name = v->name;
1704 if (data)
6d042d0d 1705 *data = (char *) v->data;
51410fc6
KZ
1706 if (len)
1707 *len = v->len;
6644688a 1708
c62a6311 1709 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
a0948ffe
KZ
1710 return 0;
1711}
a0948ffe 1712
81f73792
KZ
1713/**
1714 * blkid_probe_lookup_value:
1715 * @pr: probe
1716 * @name: name of value
1717 * @data: pointer to return value data or NULL
1718 * @len: pointer to return value length or NULL
1719 *
c2dbd49b
KZ
1720 * Note, the @len returns length of the @data, including the terminating
1721 * '\0' character.
1722 *
81f73792
KZ
1723 * Returns: 0 on success, or -1 in case of error.
1724 */
51410fc6 1725int blkid_probe_lookup_value(blkid_probe pr, const char *name,
6d042d0d 1726 const char **data, size_t *len)
a0948ffe 1727{
81f73792 1728 struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);
a0948ffe 1729
81f73792 1730 if (!v)
51410fc6 1731 return -1;
81f73792
KZ
1732 if (data)
1733 *data = (char *) v->data;
1734 if (len)
1735 *len = v->len;
81f73792 1736 return 0;
a0948ffe
KZ
1737}
1738
81f73792
KZ
1739/**
1740 * blkid_probe_has_value:
1741 * @pr: probe
1742 * @name: name of value
1743 *
1744 * Returns: 1 if value exist in probing result, otherwise 0.
1745 */
51410fc6 1746int blkid_probe_has_value(blkid_probe pr, const char *name)
a0948ffe 1747{
51410fc6
KZ
1748 if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
1749 return 1;
a0948ffe
KZ
1750 return 0;
1751}
1752
1c1726a7
KZ
1753struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
1754{
6c4a7811
OO
1755 int i = 0;
1756 struct list_head *p;
1757
7f787ced 1758 if (num < 0)
1c1726a7
KZ
1759 return NULL;
1760
af17d349 1761 list_for_each(p, &pr->values) {
6c4a7811
OO
1762 if (i++ != num)
1763 continue;
1764 return list_entry(p, struct blkid_prval, prvals);
1765 }
1766 return NULL;
1c1726a7
KZ
1767}
1768
1769struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
1770{
6c4a7811 1771 struct list_head *p;
1c1726a7 1772
7f787ced 1773 if (list_empty(&pr->values))
1c1726a7
KZ
1774 return NULL;
1775
af17d349 1776 list_for_each(p, &pr->values) {
6c4a7811
OO
1777 struct blkid_prval *v = list_entry(p, struct blkid_prval,
1778 prvals);
1c1726a7
KZ
1779
1780 if (v->name && strcmp(name, v->name) == 0) {
c62a6311 1781 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
1c1726a7
KZ
1782 return v;
1783 }
1784 }
1785 return NULL;
1786}
1787
201529bd
KZ
1788
1789/* converts DCE UUID (uuid[16]) to human readable string
1790 * - the @len should be always 37 */
201529bd 1791#ifdef HAVE_LIBUUID
c9f51c71
KZ
1792void blkid_unparse_uuid(const unsigned char *uuid, char *str,
1793 size_t len __attribute__((__unused__)))
1794{
201529bd 1795 uuid_unparse(uuid, str);
c9f51c71 1796}
201529bd 1797#else
c9f51c71
KZ
1798void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
1799{
201529bd
KZ
1800 snprintf(str, len,
1801 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1802 uuid[0], uuid[1], uuid[2], uuid[3],
1803 uuid[4], uuid[5],
1804 uuid[6], uuid[7],
1805 uuid[8], uuid[9],
1806 uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
201529bd 1807}
c9f51c71 1808#endif
201529bd 1809
9c06cdbf
KZ
1810/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
1811int blkid_uuid_is_empty(const unsigned char *buf, size_t len)
1812{
1813 size_t i;
1814
1815 for (i = 0; i < len; i++)
1816 if (buf[i])
1817 return 0;
1818 return 1;
1819}
c2dbd49b
KZ
1820
1821/* Removes whitespace from the right-hand side of a string (trailing
1822 * whitespace).
1823 *
1824 * Returns size of the new string (without \0).
1825 */
1826size_t blkid_rtrim_whitespace(unsigned char *str)
1827{
22e9e9c8 1828 return rtrim_whitespace(str);
c2dbd49b
KZ
1829}
1830
fafe46bc
ZAK
1831/* Removes whitespace from the left-hand side of a string.
1832 *
1833 * Returns size of the new string (without \0).
1834 */
1835size_t blkid_ltrim_whitespace(unsigned char *str)
1836{
22e9e9c8 1837 return ltrim_whitespace(str);
fafe46bc 1838}
22e9e9c8 1839
8b7eae45
KZ
1840/*
1841 * Some mkfs-like utils wipe some parts (usually begin) of the device.
1842 * For example LVM (pvcreate) or mkswap(8). This information could be used
1843 * for later resolution to conflicts between superblocks.
1844 *
1845 * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
89d39d22
KZ
1846 * the device. If we found another signature (for example MBR) within the
1847 * wiped area then the signature has been added later and LVM superblock
1848 * should be ignore.
8b7eae45
KZ
1849 *
1850 * Note that this heuristic is not 100% reliable, for example "pvcreate --zero
1851 * n" allows to keep the begin of the device unmodified. It's probably better
1852 * to use this heuristic for conflicts between superblocks and partition tables
1853 * than for conflicts between filesystem superblocks -- existence of unwanted
1854 * partition table is very unusual, because PT is pretty visible (parsed and
1855 * interpreted by kernel).
89d39d22
KZ
1856 *
1857 * Note that we usually expect only one signature on the device, it means that
1858 * we have to remember only one wiped area from previously successfully
1859 * detected signature.
1860 *
1861 * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM)
1862 * blkid_probe_use_wiper() -- try to use area (e.g. MBR)
1863 *
1864 * Note that there is not relation between _wiper and blkid_to_wipe().
1865 *
8b7eae45 1866 */
f12cd8d1 1867void blkid_probe_set_wiper(blkid_probe pr, uint64_t off, uint64_t size)
8b7eae45
KZ
1868{
1869 struct blkid_chain *chn;
1870
8b7eae45 1871 if (!size) {
c62a6311 1872 DBG(LOWPROBE, ul_debug("zeroize wiper"));
8b7eae45
KZ
1873 pr->wipe_size = pr->wipe_off = 0;
1874 pr->wipe_chain = NULL;
1875 return;
1876 }
1877
1878 chn = pr->cur_chain;
1879
1880 if (!chn || !chn->driver ||
c9f51c71 1881 chn->idx < 0 || (size_t) chn->idx >= chn->driver->nidinfos)
8b7eae45
KZ
1882 return;
1883
1884 pr->wipe_size = size;
1885 pr->wipe_off = off;
1886 pr->wipe_chain = chn;
1887
0540ea54 1888 DBG(LOWPROBE,
fdbd7bb9 1889 ul_debug("wiper set to %s::%s off=%"PRIu64" size=%"PRIu64"",
8b7eae45
KZ
1890 chn->driver->name,
1891 chn->driver->idinfos[chn->idx]->name,
1892 pr->wipe_off, pr->wipe_size));
1893 return;
1894}
1895
1896/*
1897 * Returns 1 if the <@off,@size> area was wiped
1898 */
f12cd8d1 1899int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, uint64_t off, uint64_t size)
8b7eae45 1900{
7f787ced 1901 if (!size)
8b7eae45
KZ
1902 return 0;
1903
1904 if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
7f787ced 1905 *chn = pr->wipe_chain;
8b7eae45
KZ
1906 return 1;
1907 }
1908 return 0;
1909}
1910
89d39d22
KZ
1911/*
1912 * Try to use any area -- if the area has been previously wiped then the
9e930041 1913 * previous probing result should be ignored (reset).
89d39d22 1914 */
f12cd8d1 1915void blkid_probe_use_wiper(blkid_probe pr, uint64_t off, uint64_t size)
8b7eae45
KZ
1916{
1917 struct blkid_chain *chn = NULL;
1918
1919 if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
c62a6311 1920 DBG(LOWPROBE, ul_debug("previously wiped area modified "
0540ea54 1921 " -- ignore previous results"));
8b7eae45 1922 blkid_probe_set_wiper(pr, 0, 0);
af17d349 1923 blkid_probe_chain_reset_values(pr, chn);
8b7eae45
KZ
1924 }
1925}