#include "blkdev.h"
#include "blkidP.h"
-#include "superblocks/superblocks.h"
-
/* chains */
extern const struct blkid_chaindrv superblocks_drv;
static void blkid_probe_reset_vals(blkid_probe pr);
-static const struct blkid_idinfo *idinfos[] =
-{
- /* RAIDs */
- &linuxraid_idinfo,
- &ddfraid_idinfo,
- &iswraid_idinfo,
- &lsiraid_idinfo,
- &viaraid_idinfo,
- &silraid_idinfo,
- &nvraid_idinfo,
- &pdcraid_idinfo,
- &highpoint45x_idinfo,
- &highpoint37x_idinfo,
- &adraid_idinfo,
- &jmraid_idinfo,
- &lvm2_idinfo,
- &lvm1_idinfo,
- &snapcow_idinfo,
- &luks_idinfo,
-
- /* Filesystems */
- &vfat_idinfo,
- &swsuspend_idinfo,
- &swap_idinfo,
- &xfs_idinfo,
- &ext4dev_idinfo,
- &ext4_idinfo,
- &ext3_idinfo,
- &ext2_idinfo,
- &jbd_idinfo,
- &reiser_idinfo,
- &reiser4_idinfo,
- &jfs_idinfo,
- &udf_idinfo,
- &iso9660_idinfo,
- &zfs_idinfo,
- &hfsplus_idinfo,
- &hfs_idinfo,
- &ufs_idinfo,
- &hpfs_idinfo,
- &sysv_idinfo,
- &xenix_idinfo,
- &ntfs_idinfo,
- &cramfs_idinfo,
- &romfs_idinfo,
- &minix_idinfo,
- &gfs_idinfo,
- &gfs2_idinfo,
- &ocfs_idinfo,
- &ocfs2_idinfo,
- &oracleasm_idinfo,
- &vxfs_idinfo,
- &squashfs_idinfo,
- &netware_idinfo,
- &btrfs_idinfo
-};
-
-#ifndef ARRAY_SIZE
-# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-#endif
-
-#define BLKID_FLTR_ITEMS ARRAY_SIZE(idinfos)
-#define BLKID_FLTR_SIZE blkid_bmp_nwords(BLKID_FLTR_ITEMS)
-
-static int blkid_probe_set_usage(blkid_probe pr, int usage);
-
/**
* blkid_new_probe:
*
return 0;
}
-
-
-/*
- * The blkid_do_probe() calls the probe functions. This routine could be used
- * in a loop when you need to probe for all possible filesystems/raids.
+/**
+ * blkid_do_probe:
+ * @pr: prober
+ *
+ * Calls probing functions in all enabled chains. The superblocks chain is
+ * enabled by default. The blkid_do_probe() stores result from only one
+ * probing function. It's necessary to call this routine in a loop to get
+ * resuluts from all probing functions in all chains.
*
- * 1/ basic case -- use the first result:
+ * This is string-based NAME=value interface only.
+ *
+ * <example>
+ * <title>basic case - use the first result only</title>
+ * <programlisting>
*
* if (blkid_do_probe(pr) == 0) {
* int nvals = blkid_probe_numof_values(pr);
* printf("%s = %s\n", name, data);
* }
* }
+ * </programlisting>
+ * </example>
*
- * 2/ advanced case -- probe for all signatures (don't forget that some
- * filesystems can co-exist on one volume (e.g. CD-ROM).
+ * <example>
+ * <title>advanced case - probe for all signatures</title>
+ * <programlisting>
*
* while (blkid_do_probe(pr) == 0) {
* int nvals = blkid_probe_numof_values(pr);
* ...
* }
+ * </programlisting>
+ * </example>
*
- * The internal probing index (pointer to the last probing function) is
- * always reseted when you touch probing filter or set a new device. It
- * means you cannot use:
- *
- * blkid_probe_invert_filter()
- * blkid_probe_filter_usage()
- * blkid_probe_filter_types()
- * blkid_probe_reset_filter()
- * blkid_probe_set_device()
+ * See also blkid_reset_probe().
*
- * in the loop (e.g while()) when you iterate on all signatures.
+ * Returns: 0 on success, 1 when probing is done and -1 in case of error.
*/
int blkid_do_probe(blkid_probe pr)
{
- int i = 0;
+ int rc = 1;
- if (!pr || pr->idx < -1)
+ if (!pr)
return -1;
- blkid_probe_reset_vals(pr);
+ do {
+ struct blkid_chain *chn;
- DBG(DEBUG_LOWPROBE,
- printf("--> starting probing loop [idx=%d]\n",
- pr->idx));
+ if (!pr->cur_chain)
+ pr->cur_chain = &pr->chains[0];
+ else if (pr->cur_chain < &pr->chains[BLKID_NCHAINS - 1])
+ pr->cur_chain += sizeof(struct blkid_chain);
+ else
+ return 1; /* all chains already probed */
- i = pr->idx + 1;
+ chn = pr->cur_chain;
+ chn->binary = FALSE; /* for sure... */
- for ( ; i < ARRAY_SIZE(idinfos); i++) {
- const struct blkid_idinfo *id;
- const struct blkid_idmag *mag;
- int hasmag = 0;
+ DBG(DEBUG_LOWPROBE, printf("chain probe %s %s\n",
+ chn->driver->name,
+ chn->enabled? "ENABLED" : "DISABLED"));
- pr->idx = i;
-
- if (pr->fltr && blkid_bmp_get_item(pr->fltr, i))
+ if (!chn->enabled)
continue;
- id = idinfos[i];
- mag = id->magics ? &id->magics[0] : NULL;
+ /* rc: -1 = error, 0 = success, 1 = no result */
+ rc = chn->driver->probe(pr, chn);
- /* try to detect by magic string */
- while(mag && mag->magic) {
- int idx;
- unsigned char *buf;
+ } while (rc == 1);
- idx = mag->kboff + (mag->sboff >> 10);
- buf = blkid_probe_get_buffer(pr, idx << 10, 1024);
+ return rc;
+}
- if (buf && !memcmp(mag->magic,
- buf + (mag->sboff & 0x3ff), mag->len)) {
- DBG(DEBUG_LOWPROBE, printf(
- "%s: magic sboff=%u, kboff=%ld\n",
- id->name, mag->sboff, mag->kboff));
- hasmag = 1;
- break;
- }
- mag++;
- }
+/**
+ * blkid_do_safeprobe:
+ * @pr: prober
+ *
+ * This function gathers probing results from all enabled chains and checks
+ * for ambivalent results (e.g. more filesystems on the device).
+ *
+ * This is string-based NAME=value interface only.
+ *
+ * Note about suberblocks chain -- the function does not check for filesystems
+ * when a RAID signature is detected. The function also does not check for
+ * collision between RAIDs. The first detected RAID is returned.
+ *
+ * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
+ * detected and -1 on case of error.
+ */
+int blkid_do_safeprobe(blkid_probe pr)
+{
+ int i, count = 0, rc = 0;
- if (hasmag == 0 && id->magics && id->magics[0].magic)
- /* magic string(s) defined, but not found */
- continue;
+ if (!pr)
+ return -1;
- /* final check by probing function */
- if (id->probefunc) {
- DBG(DEBUG_LOWPROBE, printf(
- "%s: call probefunc()\n", id->name));
- if (id->probefunc(pr, mag) != 0)
- continue;
- }
+ for (i = 0; i < BLKID_NCHAINS; i++) {
+ struct blkid_chain *chn;
- /* all cheks passed */
- if (pr->probreq & BLKID_PROBREQ_TYPE)
- blkid_probe_set_value(pr, "TYPE",
- (unsigned char *) id->name,
- strlen(id->name) + 1);
- if (pr->probreq & BLKID_PROBREQ_USAGE)
- blkid_probe_set_usage(pr, id->usage);
+ chn = pr->cur_chain = &pr->chains[i];
+ chn->binary = FALSE; /* for sure... */
- DBG(DEBUG_LOWPROBE,
- printf("<-- leaving probing loop (type=%s) [idx=%d]\n",
- id->name, pr->idx));
- return 0;
+ DBG(DEBUG_LOWPROBE, printf("chain safeprobe %s %s\n",
+ chn->driver->name,
+ chn->enabled? "ENABLED" : "DISABLED"));
+
+ if (!chn->enabled)
+ continue;
+
+ chn->idx = - 1;
+
+ /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
+ rc = chn->driver->safeprobe(pr, chn);
+ if (rc < 0)
+ goto done; /* error */
+ if (rc == 0)
+ count++; /* success */
}
- DBG(DEBUG_LOWPROBE,
- printf("<-- leaving probing loop (failed) [idx=%d]\n",
- pr->idx));
- return 1;
+
+done:
+ pr->cur_chain = NULL;
+ if (rc < 0)
+ return rc;
+ return count ? 0 : 1;
}
-/*
- * This is the same function as blkid_do_probe(), but returns only one result
- * (cannot be used in while()) and checks for ambivalen results (more
- * filesystems on the device) -- in such case returns -2.
+/**
+ * blkid_do_fullprobe:
+ * @pr: prober
+ *
+ * This function gathers probing results from all enabled chains. Same as
+ * blkid_so_safeprobe() but does not check for collision between probing
+ * result.
+ *
+ * This is string-based NAME=value interface only.
*
- * The function does not check for filesystems when a RAID signature is
- * detected. The function also does not check for collision between RAIDs. The
- * first detected RAID is returned.
+ * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
*/
-int blkid_do_safeprobe(blkid_probe pr)
+int blkid_do_fullprobe(blkid_probe pr)
{
- struct blkid_struct_probe first;
- int count = 0;
- int intol = 0;
- int rc;
-
- while ((rc = blkid_do_probe(pr)) == 0) {
- if (!count) {
- /* store the fist result */
- memcpy(first.vals, pr->vals, sizeof(first.vals));
- first.nvals = pr->nvals;
- first.idx = pr->idx;
- }
- count++;
+ int i, count = 0, rc = 0;
- if (idinfos[pr->idx]->usage & BLKID_USAGE_RAID)
- break;
- if (!(idinfos[pr->idx]->flags & BLKID_IDINFO_TOLERANT))
- intol++;
- }
- if (rc < 0)
- return rc; /* error */
- if (count > 1 && intol) {
- DBG(DEBUG_LOWPROBE,
- printf("ERROR: ambivalent result detected (%d filesystems)!\n",
- count));
- return -2; /* error, ambivalent result (more FS) */
- }
- if (!count)
- return 1; /* nothing detected */
+ if (!pr)
+ return -1;
- /* restore the first result */
- memcpy(pr->vals, first.vals, sizeof(first.vals));
- pr->nvals = first.nvals;
- pr->idx = first.idx;
+ for (i = 0; i < BLKID_NCHAINS; i++) {
+ int rc;
+ struct blkid_chain *chn;
- return 0;
+ chn = pr->cur_chain = &pr->chains[i];
+ chn->binary = FALSE; /* for sure... */
+
+ DBG(DEBUG_LOWPROBE, printf("chain fullprobe %s: %s\n",
+ chn->driver->name,
+ chn->enabled? "ENABLED" : "DISABLED"));
+
+ if (!chn->enabled)
+ continue;
+
+ chn->idx = - 1;
+
+ /* rc: -1 = error, 0 = success, 1 = no result */
+ rc = chn->driver->probe(pr, chn);
+ if (rc < 0)
+ goto done; /* error */
+ if (rc == 0)
+ count++; /* success */
+ }
+
+done:
+ pr->cur_chain = NULL;
+ if (rc < 0)
+ return rc;
+ return count ? 0 : 1;
}
int blkid_probe_numof_values(blkid_probe pr)
return 0;
}
-static int blkid_probe_set_usage(blkid_probe pr, int usage)
-{
- char *u = NULL;
-
- if (usage & BLKID_USAGE_FILESYSTEM)
- u = "filesystem";
- else if (usage & BLKID_USAGE_RAID)
- u = "raid";
- else if (usage & BLKID_USAGE_CRYPTO)
- u = "crypto";
- else if (usage & BLKID_USAGE_OTHER)
- u = "other";
- else
- u = "unknown";
-
- return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
-}
-
/**
* blkid_probe_get_value:
* @pr: probe