blob: b2e7435aa7e49343699bd18c5755849d26316998 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * Low-level libblkid probing API
3 *
4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
10/**
11 * SECTION: lowprobe
12 * @title: Low-level probing
13 * @short_description: low-level prober initialization
14 *
15 * The low-level probing routines always and directly read information from
16 * the selected (see blkid_probe_set_device()) device.
17 *
18 * The probing routines are grouped together into separate chains. Currently,
19 * the library provides superblocks, partitions and topology chains.
20 *
21 * The probing routines is possible to filter (enable/disable) by type (e.g.
22 * fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID).
23 * These filters are per-chain. Note that always when you touch the chain
24 * filter the current probing position is reset and probing starts from
25 * scratch. It means that the chain filter should not be modified during
26 * probing, for example in loop where you call blkid_do_probe().
27 *
28 * For more details see the chain specific documentation.
29 *
30 * The low-level API provides two ways how access to probing results.
31 *
32 * 1. The NAME=value (tag) interface. This interface is older and returns all data
33 * as strings. This interface is generic for all chains.
34 *
35 * 2. The binary interfaces. These interfaces return data in the native formats.
36 * The interface is always specific to the probing chain.
37 *
38 * Note that the previous probing result (binary or NAME=value) is always
39 * zeroized when a chain probing function is called. For example:
40 *
41 * <informalexample>
42 * <programlisting>
43 * blkid_probe_enable_partitions(pr, TRUE);
44 * blkid_probe_enable_superblocks(pr, FALSE);
45 *
46 * blkid_do_safeprobe(pr);
47 * </programlisting>
48 * </informalexample>
49 *
50 * overwrites the previous probing result for the partitions chain, the superblocks
51 * result is not modified.
52 */
53
54/**
55 * SECTION: lowprobe-tags
56 * @title: Low-level tags
57 * @short_description: generic NAME=value interface.
58 *
59 * The probing routines inside the chain are mutually exclusive by default --
60 * only few probing routines are marked as "tolerant". The "tolerant" probing
61 * routines are used for filesystem which can share the same device with any
62 * other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag.
63 *
64 * The SUPERBLOCKS chain is enabled by default. The all others chains is
65 * necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific
66 * documentation.
67 *
68 * The blkid_do_probe() function returns a result from only one probing
69 * routine, and the next call from the next probing routine. It means you need
70 * to call the function in loop, for example:
71 *
72 * <informalexample>
73 * <programlisting>
74 * while((blkid_do_probe(pr) == 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
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>
94#ifdef HAVE_LINUX_CDROM_H
95#include <linux/cdrom.h>
96#endif
97#ifdef HAVE_SYS_STAT_H
98#include <sys/stat.h>
99#endif
100#ifdef HAVE_ERRNO_H
101#include <errno.h>
102#endif
103#include <inttypes.h>
104#include <stdint.h>
105#include <stdarg.h>
bigbiff7b4c7a62015-01-01 19:44:14 -0500106#include <limits.h>
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500107
108#ifdef HAVE_LIBUUID
109# include <uuid.h>
110#endif
111
112#include "blkidP.h"
bigbiff7b4c7a62015-01-01 19:44:14 -0500113#include <blkid.h>
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500114#include "all-io.h"
bigbiff7b4c7a62015-01-01 19:44:14 -0500115#include "sysfs.h"
116#include "strutils.h"
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500117
118/* chains */
119extern const struct blkid_chaindrv superblocks_drv;
120extern const struct blkid_chaindrv topology_drv;
121extern const struct blkid_chaindrv partitions_drv;
122
123/*
124 * All supported chains
125 */
126static const struct blkid_chaindrv *chains_drvs[] = {
127 [BLKID_CHAIN_SUBLKS] = &superblocks_drv,
128 [BLKID_CHAIN_TOPLGY] = &topology_drv,
129 [BLKID_CHAIN_PARTS] = &partitions_drv
130};
131
132static void blkid_probe_reset_vals(blkid_probe pr);
133static void blkid_probe_reset_buffer(blkid_probe pr);
134
135/**
136 * blkid_new_probe:
137 *
138 * Returns: a pointer to the newly allocated probe struct or NULL in case of error.
139 */
140blkid_probe blkid_new_probe(void)
141{
142 int i;
143 blkid_probe pr;
144
145 blkid_init_debug(0);
146 pr = calloc(1, sizeof(struct blkid_struct_probe));
147 if (!pr)
148 return NULL;
149
bigbiff7b4c7a62015-01-01 19:44:14 -0500150 DBG(LOWPROBE, ul_debug("allocate a new probe %p", pr));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500151
152 /* initialize chains */
153 for (i = 0; i < BLKID_NCHAINS; i++) {
154 pr->chains[i].driver = chains_drvs[i];
155 pr->chains[i].flags = chains_drvs[i]->dflt_flags;
156 pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
157 }
158 INIT_LIST_HEAD(&pr->buffers);
159 return pr;
160}
161
162/*
163 * Clone @parent, the new clone shares all, but except:
164 *
165 * - probing result
166 * - bufferes if another device (or offset) is set to the prober
167 */
168blkid_probe blkid_clone_probe(blkid_probe parent)
169{
170 blkid_probe pr;
171
172 if (!parent)
173 return NULL;
174
bigbiff7b4c7a62015-01-01 19:44:14 -0500175 DBG(LOWPROBE, ul_debug("allocate a probe clone"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500176
177 pr = blkid_new_probe();
178 if (!pr)
179 return NULL;
180
181 pr->fd = parent->fd;
182 pr->off = parent->off;
183 pr->size = parent->size;
184 pr->devno = parent->devno;
185 pr->disk_devno = parent->disk_devno;
186 pr->blkssz = parent->blkssz;
187 pr->flags = parent->flags;
188 pr->parent = parent;
189
190 pr->flags &= ~BLKID_FL_PRIVATE_FD;
191
192 return pr;
193}
194
195
196
197/**
198 * blkid_new_probe_from_filename:
199 * @filename: device or regular file
200 *
201 * This function is same as call open(filename), blkid_new_probe() and
202 * blkid_probe_set_device(pr, fd, 0, 0).
203 *
204 * The @filename is closed by blkid_free_probe() or by the
205 * blkid_probe_set_device() call.
206 *
207 * Returns: a pointer to the newly allocated probe struct or NULL in case of
208 * error.
209 */
210blkid_probe blkid_new_probe_from_filename(const char *filename)
211{
212 int fd = -1;
213 blkid_probe pr = NULL;
214
215 if (!filename)
216 return NULL;
217
218 fd = open(filename, O_RDONLY|O_CLOEXEC);
219 if (fd < 0)
220 return NULL;
221
222 pr = blkid_new_probe();
223 if (!pr)
224 goto err;
225
226 if (blkid_probe_set_device(pr, fd, 0, 0))
227 goto err;
228
229 pr->flags |= BLKID_FL_PRIVATE_FD;
230 return pr;
231err:
232 if (fd >= 0)
233 close(fd);
234 blkid_free_probe(pr);
235 return NULL;
236}
237
238/**
239 * blkid_free_probe:
240 * @pr: probe
241 *
242 * Deallocates the probe struct, buffers and all allocated
243 * data that are associated with this probing control struct.
244 */
245void blkid_free_probe(blkid_probe pr)
246{
247 int i;
248
249 if (!pr)
250 return;
251
252 for (i = 0; i < BLKID_NCHAINS; i++) {
253 struct blkid_chain *ch = &pr->chains[i];
254
255 if (ch->driver->free_data)
256 ch->driver->free_data(pr, ch->data);
257 free(ch->fltr);
258 }
259
260 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
261 close(pr->fd);
262 blkid_probe_reset_buffer(pr);
263 blkid_free_probe(pr->disk_probe);
264
bigbiff7b4c7a62015-01-01 19:44:14 -0500265 DBG(LOWPROBE, ul_debug("free probe %p", pr));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500266 free(pr);
267}
268
269
270/*
271 * Removes chain values from probing result.
272 */
273void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn)
274{
275 int nvals = pr->nvals;
276 int i, x;
277
278 for (x = 0, i = 0; i < pr->nvals; i++) {
279 struct blkid_prval *v = &pr->vals[i];
280
281 if (v->chain != chn && x == i) {
282 x++;
283 continue;
284 }
285 if (v->chain == chn) {
286 --nvals;
287 continue;
288 }
289 memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval));
290 }
291 pr->nvals = nvals;
292}
293
294static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
295{
296 if (chn)
297 chn->idx = -1;
298}
299
300/*
301 * Copies chain values from probing result to @vals, the max size of @vals is
302 * @nvals and returns real number of values.
303 */
304int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn,
305 struct blkid_prval *vals, int nvals)
306{
307 int i, x;
308
309 for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) {
310 struct blkid_prval *v = &pr->vals[i];
311
312 if (v->chain != chn)
313 continue;
314 memcpy(&vals[x++], v, sizeof(struct blkid_prval));
315 }
316 return x;
317}
318
319/*
320 * Appends values from @vals to the probing result
321 */
322void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals)
323{
324 int i = 0;
325
326 while (i < nvals && pr->nvals < BLKID_NVALS) {
327 memcpy(&pr->vals[pr->nvals++], &vals[i++],
328 sizeof(struct blkid_prval));
329 }
330}
331
332static void blkid_probe_reset_vals(blkid_probe pr)
333{
334 memset(pr->vals, 0, sizeof(pr->vals));
335 pr->nvals = 0;
336}
337
338struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
339{
340 return pr->cur_chain;
341}
342
bigbiff7b4c7a62015-01-01 19:44:14 -0500343static const char *blkid_probe_get_probername(blkid_probe pr)
344{
345 struct blkid_chain *chn = blkid_probe_get_chain(pr);
346
347 if (chn && chn->idx >= 0 && chn->idx < chn->driver->nidinfos)
348 return chn->driver->idinfos[chn->idx]->name;
349
350 return NULL;
351}
352
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500353void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
354{
355 int rc, org_prob_flags;
356 struct blkid_chain *org_chn;
357
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500358 /* save the current setting -- the binary API has to be completely
359 * independent on the current probing status
360 */
361 org_chn = pr->cur_chain;
362 org_prob_flags = pr->prob_flags;
363
364 pr->cur_chain = chn;
365 pr->prob_flags = 0;
366 chn->binary = TRUE;
367 blkid_probe_chain_reset_position(chn);
368
369 rc = chn->driver->probe(pr, chn);
370
371 chn->binary = FALSE;
372 blkid_probe_chain_reset_position(chn);
373
374 /* restore the original setting
375 */
376 pr->cur_chain = org_chn;
377 pr->prob_flags = org_prob_flags;
378
379 if (rc != 0)
380 return NULL;
381
bigbiff7b4c7a62015-01-01 19:44:14 -0500382 DBG(LOWPROBE, ul_debug("returning %s binary data", chn->driver->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500383 return chn->data;
384}
385
386
387/**
388 * blkid_reset_probe:
389 * @pr: probe
390 *
391 * Zeroize probing results and resets the current probing (this has impact to
392 * blkid_do_probe() only). This function does not touch probing filters and
393 * keeps assigned device.
394 */
395void blkid_reset_probe(blkid_probe pr)
396{
397 int i;
398
399 if (!pr)
400 return;
401
402 blkid_probe_reset_vals(pr);
403 blkid_probe_set_wiper(pr, 0, 0);
404
405 pr->cur_chain = NULL;
406
407 for (i = 0; i < BLKID_NCHAINS; i++)
408 blkid_probe_chain_reset_position(&pr->chains[i]);
409}
410
411/***
412static int blkid_probe_dump_filter(blkid_probe pr, int chain)
413{
414 struct blkid_chain *chn;
415 int i;
416
417 if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
418 return -1;
419
420 chn = &pr->chains[chain];
421
422 if (!chn->fltr)
423 return -1;
424
425 for (i = 0; i < chn->driver->nidinfos; i++) {
426 const struct blkid_idinfo *id = chn->driver->idinfos[i];
427
bigbiff7b4c7a62015-01-01 19:44:14 -0500428 DBG(LOWPROBE, ul_debug("%d: %s: %s",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500429 i,
430 id->name,
431 blkid_bmp_get_item(chn->fltr, i)
432 ? "disabled" : "enabled <--"));
433 }
434 return 0;
435}
436***/
437
438/*
439 * Returns properly initialized chain filter
440 */
441unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
442{
443 struct blkid_chain *chn;
444
Dan Pasanen7ac17cc2015-11-11 11:26:25 -0600445 if (chain < 0 || chain >= BLKID_NCHAINS)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500446 return NULL;
447
448 chn = &pr->chains[chain];
449
450 /* always when you touch the chain filter all indexes are reset and
451 * probing starts from scratch
452 */
453 blkid_probe_chain_reset_position(chn);
454 pr->cur_chain = NULL;
455
456 if (!chn->driver->has_fltr || (!chn->fltr && !create))
457 return NULL;
458
459 if (!chn->fltr)
460 chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
461 else
462 memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));
463
464 /* blkid_probe_dump_filter(pr, chain); */
465 return chn->fltr;
466}
467
468/*
469 * Generic private functions for filter setting
470 */
471int __blkid_probe_invert_filter(blkid_probe pr, int chain)
472{
473 size_t i;
474 struct blkid_chain *chn;
475
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500476 chn = &pr->chains[chain];
477
478 if (!chn->driver->has_fltr || !chn->fltr)
479 return -1;
480
481 for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
482 chn->fltr[i] = ~chn->fltr[i];
483
bigbiff7b4c7a62015-01-01 19:44:14 -0500484 DBG(LOWPROBE, ul_debug("probing filter inverted"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500485 /* blkid_probe_dump_filter(pr, chain); */
486 return 0;
487}
488
489int __blkid_probe_reset_filter(blkid_probe pr, int chain)
490{
491 return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
492}
493
494int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
495{
496 unsigned long *fltr;
497 struct blkid_chain *chn;
498 size_t i;
499
500 fltr = blkid_probe_get_filter(pr, chain, TRUE);
501 if (!fltr)
502 return -1;
503
504 chn = &pr->chains[chain];
505
506 for (i = 0; i < chn->driver->nidinfos; i++) {
507 int has = 0;
508 const struct blkid_idinfo *id = chn->driver->idinfos[i];
509 char **n;
510
511 for (n = names; *n; n++) {
512 if (!strcmp(id->name, *n)) {
513 has = 1;
514 break;
515 }
516 }
517 if (flag & BLKID_FLTR_ONLYIN) {
518 if (!has)
519 blkid_bmp_set_item(fltr, i);
520 } else if (flag & BLKID_FLTR_NOTIN) {
521 if (has)
522 blkid_bmp_set_item(fltr, i);
523 }
524 }
525
bigbiff7b4c7a62015-01-01 19:44:14 -0500526 DBG(LOWPROBE, ul_debug("%s: a new probing type-filter initialized",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500527 chn->driver->name));
528 /* blkid_probe_dump_filter(pr, chain); */
529 return 0;
530}
531
532unsigned char *blkid_probe_get_buffer(blkid_probe pr,
533 blkid_loff_t off, blkid_loff_t len)
534{
535 struct list_head *p;
536 struct blkid_bufinfo *bf = NULL;
537
bigbiff7b4c7a62015-01-01 19:44:14 -0500538 if (pr->size <= 0) {
539 errno = EINVAL;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500540 return NULL;
bigbiff7b4c7a62015-01-01 19:44:14 -0500541 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500542
543 if (pr->parent &&
544 pr->parent->devno == pr->devno &&
545 pr->parent->off <= pr->off &&
546 pr->parent->off + pr->parent->size >= pr->off + pr->size) {
547 /*
548 * This is a cloned prober and points to the same area as
549 * parent. Let's use parent's buffers.
550 *
551 * Note that pr->off (and pr->parent->off) is always from the
552 * beginig of the device.
553 */
554 return blkid_probe_get_buffer(pr->parent,
555 pr->off + off - pr->parent->off, len);
556 }
557
558 list_for_each(p, &pr->buffers) {
559 struct blkid_bufinfo *x =
560 list_entry(p, struct blkid_bufinfo, bufs);
561
562 if (x->off <= off && off + len <= x->off + x->len) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500563 DBG(LOWPROBE, ul_debug("\treuse buffer: off=%jd len=%jd pr=%p",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500564 x->off, x->len, pr));
565 bf = x;
566 break;
567 }
568 }
569 if (!bf) {
570 ssize_t ret;
571
bigbiff7b4c7a62015-01-01 19:44:14 -0500572 if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0) {
573 errno = 0;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500574 return NULL;
bigbiff7b4c7a62015-01-01 19:44:14 -0500575 }
576
577 /* someone trying to overflow some buffers? */
578 if (len > ULONG_MAX - sizeof(struct blkid_bufinfo)) {
579 errno = ENOMEM;
580 return NULL;
581 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500582
583 /* allocate info and space for data by why call */
584 bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
bigbiff7b4c7a62015-01-01 19:44:14 -0500585 if (!bf) {
586 errno = ENOMEM;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500587 return NULL;
bigbiff7b4c7a62015-01-01 19:44:14 -0500588 }
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500589
590 bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
591 bf->len = len;
592 bf->off = off;
593 INIT_LIST_HEAD(&bf->bufs);
594
bigbiff7b4c7a62015-01-01 19:44:14 -0500595 DBG(LOWPROBE, ul_debug("\tbuffer read: off=%jd len=%jd pr=%p",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500596 off, len, pr));
597
598 ret = read(pr->fd, bf->data, len);
599 if (ret != (ssize_t) len) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500600 DBG(LOWPROBE, ul_debug("\tbuffer read: return %zd error %m", ret));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500601 free(bf);
bigbiff7b4c7a62015-01-01 19:44:14 -0500602 if (ret >= 0)
603 errno = 0;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500604 return NULL;
605 }
606 list_add_tail(&bf->bufs, &pr->buffers);
607 }
608
bigbiff7b4c7a62015-01-01 19:44:14 -0500609 errno = 0;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500610 return off ? bf->data + (off - bf->off) : bf->data;
611}
612
613
614static void blkid_probe_reset_buffer(blkid_probe pr)
615{
616 uint64_t read_ct = 0, len_ct = 0;
617
618 if (!pr || list_empty(&pr->buffers))
619 return;
620
bigbiff7b4c7a62015-01-01 19:44:14 -0500621 DBG(LOWPROBE, ul_debug("reseting probing buffers pr=%p", pr));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500622
623 while (!list_empty(&pr->buffers)) {
624 struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
625 struct blkid_bufinfo, bufs);
626 read_ct++;
627 len_ct += bf->len;
628 list_del(&bf->bufs);
629 free(bf);
630 }
631
bigbiff7b4c7a62015-01-01 19:44:14 -0500632 DBG(LOWPROBE, ul_debug("buffers summary: %"PRIu64" bytes "
633 "by %"PRIu64" read() call(s)",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500634 len_ct, read_ct));
635
636 INIT_LIST_HEAD(&pr->buffers);
637}
638
639/*
640 * Small devices need a special care.
641 */
642int blkid_probe_is_tiny(blkid_probe pr)
643{
Dan Pasanen7ac17cc2015-11-11 11:26:25 -0600644 return pr->flags & BLKID_FL_TINY_DEV;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500645}
646
647/*
648 * CDROMs may fail when probed for RAID (last sector problem)
649 */
650int blkid_probe_is_cdrom(blkid_probe pr)
651{
Dan Pasanen7ac17cc2015-11-11 11:26:25 -0600652 return pr->flags & BLKID_FL_CDROM_DEV;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500653}
654
655/**
656 * blkid_probe_set_device:
657 * @pr: probe
658 * @fd: device file descriptor
659 * @off: begin of probing area
660 * @size: size of probing area (zero means whole device/file)
661 *
662 * Assigns the device to probe control struct, resets internal buffers and
663 * resets the current probing.
664 *
665 * Returns: -1 in case of failure, or 0 on success.
666 */
667int blkid_probe_set_device(blkid_probe pr, int fd,
668 blkid_loff_t off, blkid_loff_t size)
669{
670 struct stat sb;
671
672 if (!pr)
673 return -1;
674
675 blkid_reset_probe(pr);
676 blkid_probe_reset_buffer(pr);
677
678 if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
679 close(pr->fd);
680
681 pr->flags &= ~BLKID_FL_PRIVATE_FD;
682 pr->flags &= ~BLKID_FL_TINY_DEV;
683 pr->flags &= ~BLKID_FL_CDROM_DEV;
684 pr->prob_flags = 0;
685 pr->fd = fd;
686 pr->off = off;
687 pr->size = 0;
688 pr->devno = 0;
689 pr->disk_devno = 0;
690 pr->mode = 0;
691 pr->blkssz = 0;
692 pr->wipe_off = 0;
693 pr->wipe_size = 0;
694 pr->wipe_chain = NULL;
695
696#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
697 /* Disable read-ahead */
698 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
699#endif
700 if (fstat(fd, &sb))
701 goto err;
702
703 if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode))
704 goto err;
705
bigbiff7b4c7a62015-01-01 19:44:14 -0500706
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500707 pr->mode = sb.st_mode;
708 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
709 pr->devno = sb.st_rdev;
710
711 if (size)
712 pr->size = size;
713 else {
714 if (S_ISBLK(sb.st_mode)) {
715 if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500716 DBG(LOWPROBE, ul_debug("failed to get device size"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500717 goto err;
718 }
719 } else if (S_ISCHR(sb.st_mode))
720 pr->size = 1; /* UBI devices are char... */
721 else if (S_ISREG(sb.st_mode))
722 pr->size = sb.st_size; /* regular file */
723
724 if (pr->off > pr->size)
725 goto err;
726
727 /* The probing area cannot be larger than whole device, pr->off
728 * is offset within the device */
729 pr->size -= pr->off;
730 }
731
732 if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
733 pr->flags |= BLKID_FL_TINY_DEV;
734
bigbiff7b4c7a62015-01-01 19:44:14 -0500735 if (S_ISBLK(sb.st_mode) && sysfs_devno_is_lvm_private(sb.st_rdev)) {
736 DBG(LOWPROBE, ul_debug("ignore private LVM device"));
737 pr->flags |= BLKID_FL_NOSCAN_DEV;
738 }
739
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500740#ifdef CDROM_GET_CAPABILITY
bigbiff7b4c7a62015-01-01 19:44:14 -0500741 else if (S_ISBLK(sb.st_mode) &&
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500742 !blkid_probe_is_tiny(pr) &&
743 blkid_probe_is_wholedisk(pr) &&
744 ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0)
745 pr->flags |= BLKID_FL_CDROM_DEV;
746#endif
747
bigbiff7b4c7a62015-01-01 19:44:14 -0500748 DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%jd, size=%jd",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500749 pr->off, pr->size));
bigbiff7b4c7a62015-01-01 19:44:14 -0500750 DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500751 blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
752 S_ISREG(pr->mode) ? "YES" : "NO"));
753
754 return 0;
755err:
bigbiff7b4c7a62015-01-01 19:44:14 -0500756 DBG(LOWPROBE, ul_debug("failed to prepare a device for low-probing"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500757 return -1;
758
759}
760
761int blkid_probe_get_dimension(blkid_probe pr,
762 blkid_loff_t *off, blkid_loff_t *size)
763{
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500764 *off = pr->off;
765 *size = pr->size;
766 return 0;
767}
768
769int blkid_probe_set_dimension(blkid_probe pr,
770 blkid_loff_t off, blkid_loff_t size)
771{
bigbiff7b4c7a62015-01-01 19:44:14 -0500772 DBG(LOWPROBE, ul_debug(
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500773 "changing probing area pr=%p: size=%llu, off=%llu "
bigbiff7b4c7a62015-01-01 19:44:14 -0500774 "-to-> size=%llu, off=%llu",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500775 pr,
776 (unsigned long long) pr->size,
777 (unsigned long long) pr->off,
778 (unsigned long long) size,
779 (unsigned long long) off));
780
781 pr->off = off;
782 pr->size = size;
783 pr->flags &= ~BLKID_FL_TINY_DEV;
784
785 if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode))
786 pr->flags |= BLKID_FL_TINY_DEV;
787
788 blkid_probe_reset_buffer(pr);
789
790 return 0;
791}
792
bigbiff7b4c7a62015-01-01 19:44:14 -0500793/*
794 * Check for matching magic value.
795 * Returns BLKID_PROBE_OK if found, BLKID_PROBE_NONE if not found
796 * or no magic present, or negative value on error.
797 */
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500798int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
799 blkid_loff_t *offset, const struct blkid_idmag **res)
800{
801 const struct blkid_idmag *mag = NULL;
802 blkid_loff_t off = 0;
803
804 if (id)
805 mag = &id->magics[0];
806 if (res)
807 *res = NULL;
808
809 /* try to detect by magic string */
810 while(mag && mag->magic) {
811 unsigned char *buf;
812
813 off = (mag->kboff + (mag->sboff >> 10)) << 10;
814 buf = blkid_probe_get_buffer(pr, off, 1024);
815
bigbiff7b4c7a62015-01-01 19:44:14 -0500816 if (!buf && errno)
817 return -errno;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500818 if (buf && !memcmp(mag->magic,
819 buf + (mag->sboff & 0x3ff), mag->len)) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500820 DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500821 mag->sboff, mag->kboff));
822 if (offset)
823 *offset = off + (mag->sboff & 0x3ff);
824 if (res)
825 *res = mag;
bigbiff7b4c7a62015-01-01 19:44:14 -0500826 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500827 }
828 mag++;
829 }
830
831 if (id && id->magics[0].magic)
832 /* magic string(s) defined, but not found */
bigbiff7b4c7a62015-01-01 19:44:14 -0500833 return BLKID_PROBE_NONE;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500834
bigbiff7b4c7a62015-01-01 19:44:14 -0500835 return BLKID_PROBE_OK;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500836}
837
838static inline void blkid_probe_start(blkid_probe pr)
839{
840 if (pr) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500841 DBG(LOWPROBE, ul_debug("%p: start probe", pr));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500842 pr->cur_chain = NULL;
843 pr->prob_flags = 0;
844 blkid_probe_set_wiper(pr, 0, 0);
845 }
846}
847
848static inline void blkid_probe_end(blkid_probe pr)
849{
850 if (pr) {
bigbiff7b4c7a62015-01-01 19:44:14 -0500851 DBG(LOWPROBE, ul_debug("%p: end probe", pr));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500852 pr->cur_chain = NULL;
853 pr->prob_flags = 0;
854 blkid_probe_set_wiper(pr, 0, 0);
855 }
856}
857
858/**
859 * blkid_do_probe:
860 * @pr: prober
861 *
862 * Calls probing functions in all enabled chains. The superblocks chain is
863 * enabled by default. The blkid_do_probe() stores result from only one
864 * probing function. It's necessary to call this routine in a loop to get
865 * results from all probing functions in all chains. The probing is reset
866 * by blkid_reset_probe() or by filter functions.
867 *
868 * This is string-based NAME=value interface only.
869 *
870 * <example>
871 * <title>basic case - use the first result only</title>
872 * <programlisting>
873 *
874 * if (blkid_do_probe(pr) == 0) {
875 * int nvals = blkid_probe_numof_values(pr);
876 * for (n = 0; n < nvals; n++) {
877 * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
878 * printf("%s = %s\n", name, data);
879 * }
880 * }
881 * </programlisting>
882 * </example>
883 *
884 * <example>
885 * <title>advanced case - probe for all signatures</title>
886 * <programlisting>
887 *
888 * while (blkid_do_probe(pr) == 0) {
889 * int nvals = blkid_probe_numof_values(pr);
890 * ...
891 * }
892 * </programlisting>
893 * </example>
894 *
895 * See also blkid_reset_probe().
896 *
897 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
898 */
899int blkid_do_probe(blkid_probe pr)
900{
901 int rc = 1;
902
903 if (!pr)
904 return -1;
905
bigbiff7b4c7a62015-01-01 19:44:14 -0500906 if (pr->flags & BLKID_FL_NOSCAN_DEV)
907 return 1;
908
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500909 do {
910 struct blkid_chain *chn = pr->cur_chain;
911
912 if (!chn) {
913 blkid_probe_start(pr);
914 chn = pr->cur_chain = &pr->chains[0];
915 }
916 /* we go to the next chain only when the previous probing
917 * result was nothing (rc == 1) and when the current chain is
918 * disabled or we are at end of the current chain (chain->idx +
919 * 1 == sizeof chain) or the current chain bailed out right at
920 * the start (chain->idx == -1)
921 */
922 else if (rc == 1 && (chn->enabled == FALSE ||
923 chn->idx + 1 == (int) chn->driver->nidinfos ||
924 chn->idx == -1)) {
925
926 size_t idx = chn->driver->id + 1;
927
928 if (idx < BLKID_NCHAINS)
929 chn = pr->cur_chain = &pr->chains[idx];
930 else {
931 blkid_probe_end(pr);
932 return 1; /* all chains already probed */
933 }
934 }
935
936 chn->binary = FALSE; /* for sure... */
937
bigbiff7b4c7a62015-01-01 19:44:14 -0500938 DBG(LOWPROBE, ul_debug("chain probe %s %s (idx=%d)",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500939 chn->driver->name,
940 chn->enabled? "ENABLED" : "DISABLED",
941 chn->idx));
942
943 if (!chn->enabled)
944 continue;
945
946 /* rc: -1 = error, 0 = success, 1 = no result */
947 rc = chn->driver->probe(pr, chn);
948
949 } while (rc == 1);
950
951 return rc;
952}
953
954/**
955 * blkid_do_wipe:
956 * @pr: prober
957 * @dryrun: if TRUE then don't touch the device.
958 *
959 * This function erases the current signature detected by @pr. The @pr has to
960 * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
bigbiff7b4c7a62015-01-01 19:44:14 -0500961 * has to be enabled (if you want to errase also superblock with broken check
962 * sums then use BLKID_SUBLKS_BADCSUM too).
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500963 *
964 * After successful signature removing the @pr prober will be moved one step
965 * back and the next blkid_do_probe() call will again call previously called
966 * probing function.
967 *
968 * <example>
969 * <title>wipe all filesystems or raids from the device</title>
970 * <programlisting>
971 * fd = open(devname, O_RDWR|O_CLOEXEC);
972 * blkid_probe_set_device(pr, fd, 0, 0);
973 *
974 * blkid_probe_enable_superblocks(pr, 1);
975 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
976 *
977 * while (blkid_do_probe(pr) == 0)
978 * blkid_do_wipe(pr, FALSE);
979 * </programlisting>
980 * </example>
981 *
982 * See also blkid_probe_step_back() if you cannot use this build-in wipe
983 * function, but you want to use libblkid probing as a source for wiping.
984 *
985 * Returns: 0 on success, and -1 in case of error.
986 */
987int blkid_do_wipe(blkid_probe pr, int dryrun)
988{
989 const char *off = NULL;
990 size_t len = 0;
991 loff_t offset, l;
992 char buf[BUFSIZ];
993 int fd, rc = 0;
994 struct blkid_chain *chn;
995
996 if (!pr)
997 return -1;
998
999 chn = pr->cur_chain;
1000 if (!chn)
1001 return -1;
1002
1003 switch (chn->driver->id) {
1004 case BLKID_CHAIN_SUBLKS:
1005 rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
1006 if (!rc)
1007 rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1008 break;
1009 case BLKID_CHAIN_PARTS:
1010 rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
1011 if (!rc)
1012 rc = blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1013 break;
1014 default:
1015 return 0;
1016 }
1017
1018 if (rc || len == 0 || off == NULL)
1019 return 0;
1020
1021 offset = strtoll(off, NULL, 10);
1022 fd = blkid_probe_get_fd(pr);
1023 if (fd < 0)
1024 return -1;
1025
1026 if (len > sizeof(buf))
1027 len = sizeof(buf);
1028
bigbiff7b4c7a62015-01-01 19:44:14 -05001029 DBG(LOWPROBE, ul_debug(
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001030 "do_wipe [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n",
1031 offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));
1032
1033 l = lseek(fd, offset, SEEK_SET);
1034 if (l == (off_t) -1)
1035 return -1;
1036
1037 memset(buf, 0, len);
1038
1039 if (!dryrun && len) {
1040 if (write_all(fd, buf, len))
1041 return -1;
1042 fsync(fd);
1043 return blkid_probe_step_back(pr);
1044 }
1045
1046 return 0;
1047}
1048
1049/**
bigbiff7b4c7a62015-01-01 19:44:14 -05001050 * blkid_probe_step_back:
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001051 * @pr: prober
1052 *
1053 * This function move pointer to the probing chain one step back -- it means
1054 * that the previously used probing function will be called again in the next
1055 * blkid_do_probe() call.
1056 *
1057 * This is necessary for example if you erase or modify on-disk superblock
1058 * according to the current libblkid probing result.
1059 *
1060 * <example>
1061 * <title>wipe all superblock, but use libblkid only for probing</title>
1062 * <programlisting>
1063 * pr = blkid_new_probe_from_filename(devname);
1064 *
1065 * blkid_probe_enable_superblocks(pr, 1);
1066 * blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
1067 *
bigbiff7b4c7a62015-01-01 19:44:14 -05001068 * blkid_probe_enable_partitions(pr, 1);
1069 * blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
1070 *
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001071 * while (blkid_do_probe(pr) == 0) {
1072 * const char *ostr = NULL;
1073 * size_t len = 0;
1074 *
1075 * // superblocks
1076 * if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &ostr, NULL) == 0)
1077 * blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
1078 *
1079 * // partition tables
1080 * if (len == 0 && blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &ostr, NULL) == 0)
1081 * blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
1082 *
1083 * if (!len || !str)
1084 * continue;
1085 *
1086 * // convert ostr to the real offset by off = strtoll(ostr, NULL, 10);
1087 * // use your stuff to errase @len bytes at the @off
1088 * ....
1089 *
1090 * // retry the last probing to check for backup superblocks ..etc.
1091 * blkid_probe_step_back(pr);
1092 * }
1093 * </programlisting>
1094 * </example>
1095 *
1096 * Returns: 0 on success, and -1 in case of error.
1097 */
1098int blkid_probe_step_back(blkid_probe pr)
1099{
1100 struct blkid_chain *chn;
1101
1102 if (!pr)
1103 return -1;
1104
1105 chn = pr->cur_chain;
1106 if (!chn)
1107 return -1;
1108
1109 blkid_probe_reset_buffer(pr);
1110
1111 if (chn->idx >= 0) {
1112 chn->idx--;
bigbiff7b4c7a62015-01-01 19:44:14 -05001113 DBG(LOWPROBE, ul_debug("step back: moving %s chain index to %d",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001114 chn->driver->name,
1115 chn->idx));
1116 }
1117
1118 if (chn->idx == -1) {
1119 /* blkid_do_probe() goes to the next chain if the index
1120 * of the current chain is -1, so we have to set the
1121 * chain pointer to the previous chain.
1122 */
1123 size_t idx = chn->driver->id > 0 ? chn->driver->id - 1 : 0;
1124
bigbiff7b4c7a62015-01-01 19:44:14 -05001125 DBG(LOWPROBE, ul_debug("step back: moving to previous chain"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001126
1127 if (idx > 0)
1128 pr->cur_chain = &pr->chains[idx];
1129 else if (idx == 0)
1130 pr->cur_chain = NULL;
1131 }
1132
1133 return 0;
1134}
1135
1136/**
1137 * blkid_do_safeprobe:
1138 * @pr: prober
1139 *
1140 * This function gathers probing results from all enabled chains and checks
1141 * for ambivalent results (e.g. more filesystems on the device).
1142 *
1143 * This is string-based NAME=value interface only.
1144 *
1145 * Note about suberblocks chain -- the function does not check for filesystems
1146 * when a RAID signature is detected. The function also does not check for
1147 * collision between RAIDs. The first detected RAID is returned. The function
1148 * checks for collision between partition table and RAID signature -- it's
1149 * recommended to enable partitions chain together with superblocks chain.
1150 *
1151 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
1152 * detected and -1 on case of error.
1153 */
1154int blkid_do_safeprobe(blkid_probe pr)
1155{
1156 int i, count = 0, rc = 0;
1157
1158 if (!pr)
1159 return -1;
bigbiff7b4c7a62015-01-01 19:44:14 -05001160 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1161 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001162
1163 blkid_probe_start(pr);
1164
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001165 for (i = 0; i < BLKID_NCHAINS; i++) {
1166 struct blkid_chain *chn;
1167
1168 chn = pr->cur_chain = &pr->chains[i];
1169 chn->binary = FALSE; /* for sure... */
1170
bigbiff7b4c7a62015-01-01 19:44:14 -05001171 DBG(LOWPROBE, ul_debug("chain safeprobe %s %s",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001172 chn->driver->name,
1173 chn->enabled? "ENABLED" : "DISABLED"));
1174
1175 if (!chn->enabled)
1176 continue;
1177
1178 blkid_probe_chain_reset_position(chn);
1179
1180 rc = chn->driver->safeprobe(pr, chn);
1181
1182 blkid_probe_chain_reset_position(chn);
1183
1184 /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
1185 if (rc < 0)
1186 goto done; /* error */
1187 if (rc == 0)
1188 count++; /* success */
1189 }
1190
1191done:
1192 blkid_probe_end(pr);
1193 if (rc < 0)
1194 return rc;
1195 return count ? 0 : 1;
1196}
1197
1198/**
1199 * blkid_do_fullprobe:
1200 * @pr: prober
1201 *
1202 * This function gathers probing results from all enabled chains. Same as
1203 * blkid_do_safeprobe() but does not check for collision between probing
1204 * result.
1205 *
1206 * This is string-based NAME=value interface only.
1207 *
1208 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
1209 */
1210int blkid_do_fullprobe(blkid_probe pr)
1211{
1212 int i, count = 0, rc = 0;
1213
1214 if (!pr)
1215 return -1;
bigbiff7b4c7a62015-01-01 19:44:14 -05001216 if (pr->flags & BLKID_FL_NOSCAN_DEV)
1217 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001218
1219 blkid_probe_start(pr);
1220
1221 for (i = 0; i < BLKID_NCHAINS; i++) {
1222 struct blkid_chain *chn;
1223
1224 chn = pr->cur_chain = &pr->chains[i];
1225 chn->binary = FALSE; /* for sure... */
1226
bigbiff7b4c7a62015-01-01 19:44:14 -05001227 DBG(LOWPROBE, ul_debug("chain fullprobe %s: %s",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001228 chn->driver->name,
1229 chn->enabled? "ENABLED" : "DISABLED"));
1230
1231 if (!chn->enabled)
1232 continue;
1233
1234 blkid_probe_chain_reset_position(chn);
1235
1236 rc = chn->driver->probe(pr, chn);
1237
1238 blkid_probe_chain_reset_position(chn);
1239
1240 /* rc: -1 = error, 0 = success, 1 = no result */
1241 if (rc < 0)
1242 goto done; /* error */
1243 if (rc == 0)
1244 count++; /* success */
1245 }
1246
1247done:
1248 blkid_probe_end(pr);
1249 if (rc < 0)
1250 return rc;
1251 return count ? 0 : 1;
1252}
1253
1254/* same sa blkid_probe_get_buffer() but works with 512-sectors */
1255unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
1256{
1257 return pr ? blkid_probe_get_buffer(pr,
1258 ((blkid_loff_t) sector) << 9, 0x200) : NULL;
1259}
1260
1261struct blkid_prval *blkid_probe_assign_value(
1262 blkid_probe pr, const char *name)
1263{
1264 struct blkid_prval *v;
1265
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001266 if (pr->nvals >= BLKID_NVALS)
1267 return NULL;
1268
1269 v = &pr->vals[pr->nvals];
1270 v->name = name;
1271 v->chain = pr->cur_chain;
1272 pr->nvals++;
1273
bigbiff7b4c7a62015-01-01 19:44:14 -05001274 DBG(LOWPROBE, ul_debug("assigning %s [%s]", name, v->chain->driver->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001275 return v;
1276}
1277
1278int blkid_probe_reset_last_value(blkid_probe pr)
1279{
1280 struct blkid_prval *v;
1281
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001282 if (pr->nvals == 0)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001283 return -1;
1284
1285 v = &pr->vals[pr->nvals - 1];
1286
bigbiff7b4c7a62015-01-01 19:44:14 -05001287 DBG(LOWPROBE, ul_debug("un-assigning %s [%s]", v->name, v->chain->driver->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001288
1289 memset(v, 0, sizeof(struct blkid_prval));
1290 pr->nvals--;
1291
1292 return 0;
1293
1294}
1295
1296int blkid_probe_set_value(blkid_probe pr, const char *name,
1297 unsigned char *data, size_t len)
1298{
1299 struct blkid_prval *v;
1300
1301 if (len > BLKID_PROBVAL_BUFSIZ)
1302 len = BLKID_PROBVAL_BUFSIZ;
1303
1304 v = blkid_probe_assign_value(pr, name);
1305 if (!v)
1306 return -1;
1307
1308 memcpy(v->data, data, len);
1309 v->len = len;
1310 return 0;
1311}
1312
1313int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
1314 const char *fmt, va_list ap)
1315{
1316 struct blkid_prval *v;
1317 ssize_t len;
1318
1319 v = blkid_probe_assign_value(pr, name);
1320 if (!v)
1321 return -1;
1322
1323 len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap);
1324
1325 if (len <= 0 || (size_t) len >= sizeof(v->data)) {
1326 blkid_probe_reset_last_value(pr);
1327 return -1;
1328 }
1329 v->len = len + 1;
1330 return 0;
1331}
1332
1333int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
1334 const char *fmt, ...)
1335{
1336 int rc;
1337 va_list ap;
1338
1339 va_start(ap, fmt);
1340 rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
1341 va_end(ap);
1342
1343 return rc;
1344}
1345
1346int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
1347 size_t len, unsigned char *magic)
1348{
1349 int rc = 0;
1350 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1351
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001352 if (!chn || !len || chn->binary)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001353 return 0;
1354
1355 switch (chn->driver->id) {
1356 case BLKID_CHAIN_SUBLKS:
1357 if (!(chn->flags & BLKID_SUBLKS_MAGIC))
1358 return 0;
1359 rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
1360 if (!rc)
1361 rc = blkid_probe_sprintf_value(pr,
1362 "SBMAGIC_OFFSET", "%llu", (unsigned long long)offset);
1363 break;
1364 case BLKID_CHAIN_PARTS:
1365 if (!(chn->flags & BLKID_PARTS_MAGIC))
1366 return 0;
1367 rc = blkid_probe_set_value(pr, "PTMAGIC", magic, len);
1368 if (!rc)
1369 rc = blkid_probe_sprintf_value(pr,
1370 "PTMAGIC_OFFSET", "%llu", (unsigned long long)offset);
1371 break;
1372 default:
1373 break;
1374 }
1375
1376 return rc;
1377}
1378
bigbiff7b4c7a62015-01-01 19:44:14 -05001379int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
1380{
1381 if (csum != expected) {
1382 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1383
1384 DBG(LOWPROBE, ul_debug(
1385 "incorrect checksum for type %s,"
1386 " got %jX, expected %jX",
1387 blkid_probe_get_probername(pr),
1388 csum, expected));
1389 /*
1390 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
1391 */
1392 if (chn->driver->id == BLKID_CHAIN_SUBLKS
1393 && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
1394 blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
1395 goto accept;
1396 }
1397 return 0; /* bad checksum */
1398 }
1399
1400accept:
1401 return 1;
1402}
1403
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001404/**
1405 * blkid_probe_get_devno:
1406 * @pr: probe
1407 *
1408 * Returns: block device number, or 0 for regular files.
1409 */
1410dev_t blkid_probe_get_devno(blkid_probe pr)
1411{
1412 return pr->devno;
1413}
1414
1415/**
1416 * blkid_probe_get_wholedisk_devno:
1417 * @pr: probe
1418 *
1419 * Returns: device number of the wholedisk, or 0 for regular files.
1420 */
1421dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
1422{
1423 if (!pr->disk_devno) {
1424 dev_t devno, disk_devno = 0;
1425
1426 devno = blkid_probe_get_devno(pr);
1427 if (!devno)
1428 return 0;
1429
1430 if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
1431 pr->disk_devno = disk_devno;
1432 }
1433 return pr->disk_devno;
1434}
1435
1436/**
1437 * blkid_probe_is_wholedisk:
1438 * @pr: probe
1439 *
1440 * Returns: 1 if the device is whole-disk or 0.
1441 */
1442int blkid_probe_is_wholedisk(blkid_probe pr)
1443{
1444 dev_t devno, disk_devno;
1445
1446 devno = blkid_probe_get_devno(pr);
1447 if (!devno)
1448 return 0;
1449
1450 disk_devno = blkid_probe_get_wholedisk_devno(pr);
1451 if (!disk_devno)
1452 return 0;
1453
1454 return devno == disk_devno;
1455}
1456
1457blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
1458{
1459 dev_t disk;
1460
1461 if (blkid_probe_is_wholedisk(pr))
1462 return NULL; /* this is not partition */
1463
1464 if (pr->parent)
1465 /* this is cloned blkid_probe, use parent's stuff */
1466 return blkid_probe_get_wholedisk_probe(pr->parent);
1467
1468 disk = blkid_probe_get_wholedisk_devno(pr);
1469
1470 if (pr->disk_probe && pr->disk_probe->devno != disk) {
1471 /* we have disk prober, but for another disk... close it */
1472 blkid_free_probe(pr->disk_probe);
1473 pr->disk_probe = NULL;
1474 }
1475
1476 if (!pr->disk_probe) {
1477 /* Open a new disk prober */
1478 char *disk_path = blkid_devno_to_devname(disk);
1479
1480 if (!disk_path)
1481 return NULL;
1482
bigbiff7b4c7a62015-01-01 19:44:14 -05001483 DBG(LOWPROBE, ul_debug("allocate a wholedisk probe"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001484
1485 pr->disk_probe = blkid_new_probe_from_filename(disk_path);
1486
1487 free(disk_path);
1488
1489 if (!pr->disk_probe)
1490 return NULL; /* ENOMEM? */
1491 }
1492
1493 return pr->disk_probe;
1494}
1495
1496/**
1497 * blkid_probe_get_size:
1498 * @pr: probe
1499 *
1500 * This function returns size of probing area as defined by blkid_probe_set_device().
1501 * If the size of the probing area is unrestricted then this function returns
1502 * the real size of device. See also blkid_get_dev_size().
1503 *
1504 * Returns: size in bytes or -1 in case of error.
1505 */
1506blkid_loff_t blkid_probe_get_size(blkid_probe pr)
1507{
1508 return pr ? pr->size : -1;
1509}
1510
1511/**
1512 * blkid_probe_get_offset:
1513 * @pr: probe
1514 *
1515 * This function returns offset of probing area as defined by blkid_probe_set_device().
1516 *
1517 * Returns: offset in bytes or -1 in case of error.
1518 */
1519blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
1520{
1521 return pr ? pr->off : -1;
1522}
1523
1524/**
1525 * blkid_probe_get_fd:
1526 * @pr: probe
1527 *
1528 * Returns: file descriptor for assigned device/file or -1 in case of error.
1529 */
1530int blkid_probe_get_fd(blkid_probe pr)
1531{
1532 return pr ? pr->fd : -1;
1533}
1534
1535/**
1536 * blkid_probe_get_sectorsize:
1537 * @pr: probe or NULL (for NULL returns 512)
1538 *
1539 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
1540 */
1541unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
1542{
1543 if (!pr)
1544 return DEFAULT_SECTOR_SIZE; /*... and good luck! */
1545
1546 if (pr->blkssz)
1547 return pr->blkssz;
1548
1549 if (S_ISBLK(pr->mode) &&
1550 blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
1551 return pr->blkssz;
1552
1553 pr->blkssz = DEFAULT_SECTOR_SIZE;
1554 return pr->blkssz;
1555}
1556
1557/**
1558 * blkid_probe_get_sectors:
1559 * @pr: probe
1560 *
1561 * Returns: 512-byte sector count or -1 in case of error.
1562 */
1563blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
1564{
1565 return pr ? pr->size >> 9 : -1;
1566}
1567
1568/**
1569 * blkid_probe_numof_values:
1570 * @pr: probe
1571 *
1572 * Returns: number of values in probing result or -1 in case of error.
1573 */
1574int blkid_probe_numof_values(blkid_probe pr)
1575{
1576 if (!pr)
1577 return -1;
1578 return pr->nvals;
1579}
1580
1581/**
1582 * blkid_probe_get_value:
1583 * @pr: probe
1584 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
1585 * @name: pointer to return value name or NULL
1586 * @data: pointer to return value data or NULL
1587 * @len: pointer to return value length or NULL
1588 *
1589 * Note, the @len returns length of the @data, including the terminating
1590 * '\0' character.
1591 *
1592 * Returns: 0 on success, or -1 in case of error.
1593 */
1594int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
1595 const char **data, size_t *len)
1596{
1597 struct blkid_prval *v = __blkid_probe_get_value(pr, num);
1598
1599 if (!v)
1600 return -1;
1601 if (name)
1602 *name = v->name;
1603 if (data)
1604 *data = (char *) v->data;
1605 if (len)
1606 *len = v->len;
1607
bigbiff7b4c7a62015-01-01 19:44:14 -05001608 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001609 return 0;
1610}
1611
1612/**
1613 * blkid_probe_lookup_value:
1614 * @pr: probe
1615 * @name: name of value
1616 * @data: pointer to return value data or NULL
1617 * @len: pointer to return value length or NULL
1618 *
1619 * Note, the @len returns length of the @data, including the terminating
1620 * '\0' character.
1621 *
1622 * Returns: 0 on success, or -1 in case of error.
1623 */
1624int blkid_probe_lookup_value(blkid_probe pr, const char *name,
1625 const char **data, size_t *len)
1626{
1627 struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);
1628
1629 if (!v)
1630 return -1;
1631 if (data)
1632 *data = (char *) v->data;
1633 if (len)
1634 *len = v->len;
1635 return 0;
1636}
1637
1638/**
1639 * blkid_probe_has_value:
1640 * @pr: probe
1641 * @name: name of value
1642 *
1643 * Returns: 1 if value exist in probing result, otherwise 0.
1644 */
1645int blkid_probe_has_value(blkid_probe pr, const char *name)
1646{
1647 if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
1648 return 1;
1649 return 0;
1650}
1651
1652struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
1653{
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001654 if (num < 0 || num >= pr->nvals)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001655 return NULL;
1656
1657 return &pr->vals[num];
1658}
1659
1660struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
1661{
1662 int i;
1663
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001664 if (!pr->nvals)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001665 return NULL;
1666
1667 for (i = 0; i < pr->nvals; i++) {
1668 struct blkid_prval *v = &pr->vals[i];
1669
1670 if (v->name && strcmp(name, v->name) == 0) {
bigbiff7b4c7a62015-01-01 19:44:14 -05001671 DBG(LOWPROBE, ul_debug("returning %s value", v->name));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001672 return v;
1673 }
1674 }
1675 return NULL;
1676}
1677
1678
1679/* converts DCE UUID (uuid[16]) to human readable string
1680 * - the @len should be always 37 */
1681#ifdef HAVE_LIBUUID
1682void blkid_unparse_uuid(const unsigned char *uuid, char *str,
1683 size_t len __attribute__((__unused__)))
1684{
1685 uuid_unparse(uuid, str);
1686}
1687#else
1688void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
1689{
1690 snprintf(str, len,
1691 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1692 uuid[0], uuid[1], uuid[2], uuid[3],
1693 uuid[4], uuid[5],
1694 uuid[6], uuid[7],
1695 uuid[8], uuid[9],
1696 uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
1697}
1698#endif
1699
bigbiff7b4c7a62015-01-01 19:44:14 -05001700/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
1701int blkid_uuid_is_empty(const unsigned char *buf, size_t len)
1702{
1703 size_t i;
1704
1705 for (i = 0; i < len; i++)
1706 if (buf[i])
1707 return 0;
1708 return 1;
1709}
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001710
1711/* Removes whitespace from the right-hand side of a string (trailing
1712 * whitespace).
1713 *
1714 * Returns size of the new string (without \0).
1715 */
1716size_t blkid_rtrim_whitespace(unsigned char *str)
1717{
bigbiff7b4c7a62015-01-01 19:44:14 -05001718 return rtrim_whitespace(str);
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001719}
1720
1721/* Removes whitespace from the left-hand side of a string.
1722 *
1723 * Returns size of the new string (without \0).
1724 */
1725size_t blkid_ltrim_whitespace(unsigned char *str)
1726{
bigbiff7b4c7a62015-01-01 19:44:14 -05001727 return ltrim_whitespace(str);
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001728}
bigbiff7b4c7a62015-01-01 19:44:14 -05001729
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001730/*
1731 * Some mkfs-like utils wipe some parts (usually begin) of the device.
1732 * For example LVM (pvcreate) or mkswap(8). This information could be used
1733 * for later resolution to conflicts between superblocks.
1734 *
1735 * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
1736 * the device. If we found another signature (for example MBR) within the
1737 * wiped area then the signature has been added later and LVM superblock
1738 * should be ignore.
1739 *
1740 * Note that this heuristic is not 100% reliable, for example "pvcreate --zero
1741 * n" allows to keep the begin of the device unmodified. It's probably better
1742 * to use this heuristic for conflicts between superblocks and partition tables
1743 * than for conflicts between filesystem superblocks -- existence of unwanted
1744 * partition table is very unusual, because PT is pretty visible (parsed and
1745 * interpreted by kernel).
1746 *
1747 * Note that we usually expect only one signature on the device, it means that
1748 * we have to remember only one wiped area from previously successfully
1749 * detected signature.
1750 *
1751 * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM)
1752 * blkid_probe_use_wiper() -- try to use area (e.g. MBR)
1753 *
1754 * Note that there is not relation between _wiper and blkid_to_wipe().
1755 *
1756 */
1757void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
1758{
1759 struct blkid_chain *chn;
1760
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001761 if (!size) {
bigbiff7b4c7a62015-01-01 19:44:14 -05001762 DBG(LOWPROBE, ul_debug("zeroize wiper"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001763 pr->wipe_size = pr->wipe_off = 0;
1764 pr->wipe_chain = NULL;
1765 return;
1766 }
1767
1768 chn = pr->cur_chain;
1769
1770 if (!chn || !chn->driver ||
1771 chn->idx < 0 || (size_t) chn->idx >= chn->driver->nidinfos)
1772 return;
1773
1774 pr->wipe_size = size;
1775 pr->wipe_off = off;
1776 pr->wipe_chain = chn;
1777
bigbiff7b4c7a62015-01-01 19:44:14 -05001778 DBG(LOWPROBE,
1779 ul_debug("wiper set to %s::%s off=%jd size=%jd",
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001780 chn->driver->name,
1781 chn->driver->idinfos[chn->idx]->name,
1782 pr->wipe_off, pr->wipe_size));
1783 return;
1784}
1785
1786/*
1787 * Returns 1 if the <@off,@size> area was wiped
1788 */
1789int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn,
1790 blkid_loff_t off, blkid_loff_t size)
1791{
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001792 if (!size)
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001793 return 0;
1794
1795 if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
Dan Pasanen7ac17cc2015-11-11 11:26:25 -06001796 *chn = pr->wipe_chain;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001797 return 1;
1798 }
1799 return 0;
1800}
1801
1802/*
1803 * Try to use any area -- if the area has been previously wiped then the
1804 * previous probing result should be ignored (reseted).
1805 */
1806void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
1807{
1808 struct blkid_chain *chn = NULL;
1809
1810 if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
bigbiff7b4c7a62015-01-01 19:44:14 -05001811 DBG(LOWPROBE, ul_debug("previously wiped area modified "
1812 " -- ignore previous results"));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001813 blkid_probe_set_wiper(pr, 0, 0);
1814 blkid_probe_chain_reset_vals(pr, chn);
1815 }
1816}