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