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