From 40672152dcbd17ce41aa3f6670f9898402990a5c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 14 May 2009 15:38:50 +0200 Subject: build-sys: rename /libs to /shlibs On Wed, May 13, 2009 at 05:38:49AM -0400, Christoph Hellwig wrote: > Also the lib vs libs toplevel directories probably aren't a too good > choice. Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 919 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 919 insertions(+) create mode 100644 shlibs/blkid/src/probe.c (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c new file mode 100644 index 00000000..0e4745ac --- /dev/null +++ b/shlibs/blkid/src/probe.c @@ -0,0 +1,919 @@ +/* + * probe.c - reads tags (LABEL, UUID, FS type, ..) from a block device + * + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_SYS_MKDEV_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_LIBUUID +#include +#endif +#include + +#include "blkdev.h" +#include "blkidP.h" +#include "probers/probers.h" + +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, + &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 + +/* filter bitmap macros */ +#define blkid_bmp_wordsize (8 * sizeof(unsigned long)) +#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize)) +#define blkid_bmp_idx_byte(item) ((item) / blkid_bmp_wordsize) + +#define blkid_bmp_set_item(bmp, item) \ + ((bmp)[ blkid_bmp_idx_byte(item) ] |= blkid_bmp_idx_bit(item)) + +#define blkid_bmp_unset_item(bmp, item) \ + ((bmp)[ bmp_idx_byte(item) ] &= ~bmp_idx_bit(item)) + +#define blkid_bmp_get_item(bmp, item) \ + ((bmp)[ blkid_bmp_idx_byte(item) ] & blkid_bmp_idx_bit(item)) + +#define blkid_bmp_size(max_items) \ + (((max_items) + blkid_bmp_wordsize) / blkid_bmp_wordsize) + +#define BLKID_FLTR_ITEMS ARRAY_SIZE(idinfos) +#define BLKID_FLTR_SIZE blkid_bmp_size(BLKID_FLTR_ITEMS) + + +static int blkid_probe_set_usage(blkid_probe pr, int usage); + +int blkid_known_fstype(const char *fstype) +{ + int i; + + if (!fstype) + return 0; + + for (i = 0; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; + if (strcmp(id->name, fstype) == 0) + return 1; + } + return 0; +} + +/* + * Returns a pointer to the newly allocated probe struct + */ +blkid_probe blkid_new_probe(void) +{ + blkid_init_debug(0); + return calloc(1, sizeof(struct blkid_struct_probe)); +} + +/* + * Deallocates probe struct, buffers and all allocated + * data that are associated with this probing control struct. + */ +void blkid_free_probe(blkid_probe pr) +{ + if (!pr) + return; + free(pr->fltr); + free(pr->buf); + free(pr->sbbuf); + free(pr); +} + +static void blkid_probe_reset_vals(blkid_probe pr) +{ + memset(pr->vals, 0, sizeof(pr->vals)); + pr->nvals = 0; +} + +void blkid_reset_probe(blkid_probe pr) +{ + if (!pr) + return; + DBG(DEBUG_LOWPROBE, printf("reseting blkid_probe\n")); + if (pr->buf) + memset(pr->buf, 0, pr->buf_max); + pr->buf_off = 0; + pr->buf_len = 0; + pr->idx = 0; + if (pr->sbbuf) + memset(pr->sbbuf, 0, BLKID_SB_BUFSIZ); + pr->sbbuf_len = 0; + blkid_probe_reset_vals(pr); +} + + +/* + * Note that we have two offsets: + * + * 1/ general device offset (pr->off), that's useful for example when we + * probe a partition from whole disk image: + * blkid-low --offset disk.img + * + * 2/ buffer offset (the 'off' argument), that useful for offsets in + * superbloks, ... + * + * That means never use lseek(fd, 0, SEEK_SET), the zero position is always + * pr->off, so lseek(fd, pr->off, SEEK_SET). + * + */ +unsigned char *blkid_probe_get_buffer(blkid_probe pr, + blkid_loff_t off, blkid_loff_t len) +{ + ssize_t ret_read = 0; + + if (off < 0 || len < 0) { + DBG(DEBUG_LOWPROBE, + printf("unexpected offset or length of buffer requested\n")); + return NULL; + } + if (off + len <= BLKID_SB_BUFSIZ) { + if (!pr->sbbuf) { + pr->sbbuf = malloc(BLKID_SB_BUFSIZ); + if (!pr->sbbuf) + return NULL; + } + if (!pr->sbbuf_len) { + if (lseek(pr->fd, pr->off, SEEK_SET) < 0) + return NULL; + ret_read = read(pr->fd, pr->sbbuf, BLKID_SB_BUFSIZ); + if (ret_read < 0) + ret_read = 0; + pr->sbbuf_len = ret_read; + } + if (off + len > pr->sbbuf_len) + return NULL; + return pr->sbbuf + off; + } else { + unsigned char *newbuf = NULL; + + if (len > pr->buf_max) { + newbuf = realloc(pr->buf, len); + if (!newbuf) + return NULL; + pr->buf = newbuf; + pr->buf_max = len; + pr->buf_off = 0; + pr->buf_len = 0; + } + if (newbuf || off < pr->buf_off || + off + len > pr->buf_off + pr->buf_len) { + + if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0) + return NULL; + + ret_read = read(pr->fd, pr->buf, len); + if (ret_read != (ssize_t) len) + return NULL; + pr->buf_off = off; + pr->buf_len = len; + } + return off ? pr->buf + (off - pr->buf_off) : pr->buf; + } +} + +/* + * Assignes the device to probe control struct, resets internal buffers and + * reads 512 bytes from device to the buffers. + * + * Returns -1 in case of failure, or 0 on success. + */ +int blkid_probe_set_device(blkid_probe pr, int fd, + blkid_loff_t off, blkid_loff_t size) +{ + if (!pr) + return -1; + + blkid_reset_probe(pr); + + pr->fd = fd; + pr->off = off; + pr->size = 0; + pr->idx = 0; + + if (size) + pr->size = size; + else { + struct stat sb; + + if (fstat(fd, &sb)) + return -1; + + if (S_ISBLK(sb.st_mode)) + blkdev_get_size(fd, (unsigned long long *) &pr->size); + else + pr->size = sb.st_size; + } + if (!pr->size) + return -1; + + /* read SB to test if the device is readable */ + if (!blkid_probe_get_buffer(pr, 0, 0x200)) { + DBG(DEBUG_LOWPROBE, + printf("failed to prepare a device for low-probing\n")); + return -1; + } + + DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%zd, size=%zd\n", + pr->off, pr->size)); + return 0; +} + +int blkid_probe_set_request(blkid_probe pr, int flags) +{ + if (!pr) + return -1; + pr->probreq = flags; + return 0; +} + +int blkid_probe_reset_filter(blkid_probe pr) +{ + if (!pr) + return -1; + if (pr->fltr) + memset(pr->fltr, 0, BLKID_FLTR_SIZE * sizeof(unsigned long)); + pr->idx = 0; + return 0; +} + +/* + * flag: + * + * BLKID_FLTR_NOTIN - probe all filesystems which are NOT IN names[] + * + * BLKID_FLTR_ONLYIN - probe filesystem which are IN names[] + */ +int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) +{ + int i; + + if (!pr || !names) + return -1; + if (!pr->fltr) + pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long)); + else + blkid_probe_reset_filter(pr); + + if (!pr->fltr) + return -1; + + for (i = 0; i < ARRAY_SIZE(idinfos); i++) { + int has = 0; + const struct blkid_idinfo *id = idinfos[i]; + char **n; + + for (n = names; *n; n++) { + if (!strcmp(id->name, *n)) { + has = 1; + break; + } + } + /* The default is enable all filesystems, + * set relevant bitmap bit means disable the filesystem. + */ + if (flag & BLKID_FLTR_ONLYIN) { + if (!has) + blkid_bmp_set_item(pr->fltr, i); + } else if (flag & BLKID_FLTR_NOTIN) { + if (has) + blkid_bmp_set_item(pr->fltr, i); + } + } + DBG(DEBUG_LOWPROBE, printf("a new probing type-filter initialized\n")); + pr->idx = 0; + return 0; +} + +/* + * flag: + * + * BLKID_FLTR_NOTIN - probe all filesystems which are NOT IN "usage" + * + * BLKID_FLTR_ONLYIN - probe filesystem which are IN "usage" + * + * where the "usage" is a set of filesystem according the usage flag (crypto, + * raid, filesystem, ...) + */ +int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) +{ + int i; + + if (!pr || !usage) + return -1; + if (!pr->fltr) + pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long)); + else + blkid_probe_reset_filter(pr); + + if (!pr->fltr) + return -1; + + for (i = 0; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; + + if (id->usage & usage) { + if (flag & BLKID_FLTR_NOTIN) + blkid_bmp_set_item(pr->fltr, i); + } else if (flag & BLKID_FLTR_ONLYIN) + blkid_bmp_set_item(pr->fltr, i); + } + DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n")); + pr->idx = 0; + return 0; +} + + +int blkid_probe_invert_filter(blkid_probe pr) +{ + int i; + + if (!pr || !pr->fltr) + return -1; + for (i = 0; i < BLKID_FLTR_SIZE; i++) + pr->fltr[i] = ~pr->fltr[i]; + + DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n")); + pr->idx = 0; + 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. + * + * 1/ basic case -- use the first result: + * + * if (blkid_do_probe(pr) == 0) { + * int nvals = blkid_probe_numof_values(pr); + * for (n = 0; n < nvals; n++) { + * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0) + * printf("%s = %s\n", name, data); + * } + * } + * + * 2/ advanced case -- probe for all signatures (don't forget that some + * filesystems can co-exist on one volume (e.g. CD-ROM). + * + * while (blkid_do_probe(pr) == 0) { + * int nvals = blkid_probe_numof_values(pr); + * ... + * } + * + * 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() + * + * in the loop (e.g while()) when you iterate on all signatures. + */ +int blkid_do_probe(blkid_probe pr) +{ + int i = 0; + + if (!pr) + return -1; + + blkid_probe_reset_vals(pr); + + if (pr->idx) + i = pr->idx + 1; + + if (i < 0 && i >= ARRAY_SIZE(idinfos)) + return -1; + + DBG(DEBUG_LOWPROBE, printf("--> starting probing loop\n")); + + for ( ; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id; + const struct blkid_idmag *mag; + int hasmag = 0; + + pr->idx = i; + + if (pr->fltr && blkid_bmp_get_item(pr->fltr, i)) + continue; + + id = idinfos[i]; + mag = id->magics ? &id->magics[0] : NULL; + + /* try to detect by magic string */ + while(mag && mag->magic) { + int idx; + unsigned char *buf; + + idx = mag->kboff + (mag->sboff >> 10); + buf = blkid_probe_get_buffer(pr, idx << 10, 1024); + + 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++; + } + + if (hasmag == 0 && id->magics && id->magics[0].magic) + /* magic string(s) defined, but not found */ + continue; + + /* 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; + } + + /* 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); + + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (type=%s)\n", id->name)); + return 0; + } + DBG(DEBUG_LOWPROBE, printf("<-- leaving probing loop (failed)\n")); + return 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. + */ +int blkid_do_safeprobe(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; + } + if (!(idinfos[pr->idx]->flags & BLKID_IDINFO_TOLERANT)) + intol++; + count++; + } + 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 */ + + /* restore the first result */ + memcpy(pr->vals, first.vals, sizeof(first.vals)); + pr->nvals = first.nvals; + pr->idx = first.idx; + + return 0; +} + +int blkid_probe_numof_values(blkid_probe pr) +{ + if (!pr) + return -1; + return pr->nvals; +} + + +static struct blkid_prval *blkid_probe_assign_value( + blkid_probe pr, const char *name) +{ + struct blkid_prval *v; + + if (!name) + return NULL; + if (pr->nvals >= BLKID_PROBVAL_NVALS) + return NULL; + + v = &pr->vals[pr->nvals]; + v->name = name; + pr->nvals++; + + DBG(DEBUG_LOWPROBE, printf("assigning %s\n", name)); + return v; +} + +int blkid_probe_set_value(blkid_probe pr, const char *name, + unsigned char *data, size_t len) +{ + struct blkid_prval *v; + + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + v = blkid_probe_assign_value(pr, name); + if (!v) + return -1; + + memcpy(v->data, data, len); + v->len = len; + return 0; +} + +int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, + const char *fmt, va_list ap) +{ + struct blkid_prval *v; + size_t len; + + v = blkid_probe_assign_value(pr, name); + if (!v) + return -1; + + len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap); + + if (len <= 0) { + pr->nvals--; /* reset the latest assigned value */ + return -1; + } + v->len = len + 1; + return 0; +} + +int blkid_probe_set_version(blkid_probe pr, const char *version) +{ + if (pr->probreq & BLKID_PROBREQ_VERSION) + return blkid_probe_set_value(pr, "VERSION", + (unsigned char *) version, strlen(version) + 1); + return 0; +} + +int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) +{ + int rc = 0; + + if (pr->probreq & BLKID_PROBREQ_VERSION) { + va_list ap; + + va_start(ap, fmt); + rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap); + va_end(ap); + } + return rc; +} + +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); +} + +int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len) +{ + struct blkid_prval *v; + int i; + + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if ((pr->probreq & BLKID_PROBREQ_LABELRAW) && + blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) + return -1; + if (!(pr->probreq & BLKID_PROBREQ_LABEL)) + return 0; + v = blkid_probe_assign_value(pr, "LABEL"); + if (!v) + return -1; + + memcpy(v->data, label, len); + v->data[len] = '\0'; + + /* remove trailing whitespace */ + i = strnlen((char *) v->data, len); + while (i--) { + if (!isspace(v->data[i])) + break; + } + v->data[++i] = '\0'; + v->len = i + 1; + return 0; +} + +static size_t encode_to_utf8(int enc, unsigned char *dest, size_t len, + unsigned char *src, size_t count) +{ + size_t i, j; + uint16_t c; + + for (j = i = 0; i + 2 <= count; i += 2) { + if (enc == BLKID_ENC_UTF16LE) + c = (src[i+1] << 8) | src[i]; + else /* BLKID_ENC_UTF16BE */ + c = (src[i] << 8) | src[i+1]; + if (c == 0) { + dest[j] = '\0'; + break; + } else if (c < 0x80) { + if (j+1 >= len) + break; + dest[j++] = (uint8_t) c; + } else if (c < 0x800) { + if (j+2 >= len) + break; + dest[j++] = (uint8_t) (0xc0 | (c >> 6)); + dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } else { + if (j+3 >= len) + break; + dest[j++] = (uint8_t) (0xe0 | (c >> 12)); + dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); + dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } + } + dest[j] = '\0'; + return j; +} + +int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, + size_t len, int enc) +{ + struct blkid_prval *v; + + if ((pr->probreq & BLKID_PROBREQ_LABELRAW) && + blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) + return -1; + if (!(pr->probreq & BLKID_PROBREQ_LABEL)) + return 0; + v = blkid_probe_assign_value(pr, "LABEL"); + if (!v) + return -1; + + v->len = encode_to_utf8(enc, v->data, sizeof(v->data), label, len); + return 0; +} + +/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */ +static int uuid_is_empty(const unsigned char *buf, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + if (buf[i]) + return 0; + return 1; +} + +int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, + size_t len, const char *fmt, ...) +{ + int rc = -1; + va_list ap; + + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if (uuid_is_empty(uuid, len)) + return 0; + + if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0) + return -1; + if (!(pr->probreq & BLKID_PROBREQ_UUID)) + return 0; + + va_start(ap, fmt); + rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap); + va_end(ap); + + /* convert to lower case (..be paranoid) */ + if (!rc) { + int i; + struct blkid_prval *v = &pr->vals[pr->nvals]; + + for (i = 0; i < v->len; i++) + if (v->data[i] >= 'A' && v->data[i] <= 'F') + v->data[i] = (v->data[i] - 'A') + 'a'; + } + return rc; +} + +/* function to set UUIDs that are in suberblocks stored as strings */ +int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len) +{ + struct blkid_prval *v; + + if (str == NULL || *str == '\0') + return -1; + if (!len) + len = strlen((char *) str); + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0) + return -1; + if (!(pr->probreq & BLKID_PROBREQ_UUID)) + return 0; + + v = blkid_probe_assign_value(pr, "UUID"); + if (v) { + memcpy((char *) v->data, str, len); + *(v->data + len) = '\0'; + v->len = len; + return 0; + } + return -1; +} + +/* default _set_uuid function to set DCE UUIDs */ +int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name) +{ + struct blkid_prval *v; + + if (uuid_is_empty(uuid, 16)) + return 0; + + if (!name) { + if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0) + return -1; + if (!(pr->probreq & BLKID_PROBREQ_UUID)) + return 0; + + v = blkid_probe_assign_value(pr, "UUID"); + } else + v = blkid_probe_assign_value(pr, name); + +#ifdef HAVE_LIBUUID + { + uuid_unparse(uuid, (char *) v->data); + v->len = 37; + } +#else + v->len = snprintf(v->data, sizeof(v->data), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]); + v->len++; +#endif + return 0; +} + +int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid) +{ + return blkid_probe_set_uuid_as(pr, uuid, NULL); +} + +int blkid_probe_get_value(blkid_probe pr, int num, const char **name, + const char **data, size_t *len) +{ + struct blkid_prval *v; + + if (pr == NULL || num < 0 || num >= pr->nvals) + return -1; + + v = &pr->vals[num]; + if (name) + *name = v->name; + if (data) + *data = (char *) v->data; + if (len) + *len = v->len; + + DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); + return 0; +} + +int blkid_probe_lookup_value(blkid_probe pr, const char *name, + const char **data, size_t *len) +{ + int i; + + if (pr == NULL || pr->nvals == 0 || name == NULL) + return -1; + + for (i = 0; i < pr->nvals; i++) { + struct blkid_prval *v = &pr->vals[i]; + + if (v->name && strcmp(name, v->name) == 0) { + if (data) + *data = (char *) v->data; + if (len) + *len = v->len; + DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); + return 0; + } + } + return -1; +} + +int blkid_probe_has_value(blkid_probe pr, const char *name) +{ + if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0) + return 1; + return 0; +} + -- cgit v1.2.3 From 4ce48a971d322cc1f690dd036f906fc54261c657 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 14 May 2009 18:04:55 +0200 Subject: blkid: fix "hangs forever with partition type mdraid" > #:> blkid /dev/sda7 > /dev/sda7: UUID="c193d159-1fd4-1a4b-4037-f3433e016f3d" TYPE="mdraid" > > The blkid binary build from the util-linux-ng sources just hangs > forever with 100% cpu load with the same command. Reported-by: Juergen Daubert Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index 0e4745ac..b0c0be80 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -160,6 +160,11 @@ static void blkid_probe_reset_vals(blkid_probe pr) pr->nvals = 0; } +static void blkid_probe_reset_idx(blkid_probe pr) +{ + pr->idx = -1; +} + void blkid_reset_probe(blkid_probe pr) { if (!pr) @@ -169,14 +174,13 @@ void blkid_reset_probe(blkid_probe pr) memset(pr->buf, 0, pr->buf_max); pr->buf_off = 0; pr->buf_len = 0; - pr->idx = 0; if (pr->sbbuf) memset(pr->sbbuf, 0, BLKID_SB_BUFSIZ); pr->sbbuf_len = 0; blkid_probe_reset_vals(pr); + blkid_probe_reset_idx(pr); } - /* * Note that we have two offsets: * @@ -263,7 +267,6 @@ int blkid_probe_set_device(blkid_probe pr, int fd, pr->fd = fd; pr->off = off; pr->size = 0; - pr->idx = 0; if (size) pr->size = size; @@ -307,7 +310,7 @@ int blkid_probe_reset_filter(blkid_probe pr) return -1; if (pr->fltr) memset(pr->fltr, 0, BLKID_FLTR_SIZE * sizeof(unsigned long)); - pr->idx = 0; + blkid_probe_reset_idx(pr); return 0; } @@ -324,9 +327,10 @@ int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) if (!pr || !names) return -1; - if (!pr->fltr) + if (!pr->fltr) { pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long)); - else + blkid_probe_reset_idx(pr); + } else blkid_probe_reset_filter(pr); if (!pr->fltr) @@ -355,7 +359,6 @@ int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) } } DBG(DEBUG_LOWPROBE, printf("a new probing type-filter initialized\n")); - pr->idx = 0; return 0; } @@ -375,9 +378,10 @@ int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) if (!pr || !usage) return -1; - if (!pr->fltr) + if (!pr->fltr) { pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long)); - else + blkid_probe_reset_idx(pr); + } else blkid_probe_reset_filter(pr); if (!pr->fltr) @@ -393,7 +397,6 @@ int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) blkid_bmp_set_item(pr->fltr, i); } DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n")); - pr->idx = 0; return 0; } @@ -407,8 +410,8 @@ int blkid_probe_invert_filter(blkid_probe pr) for (i = 0; i < BLKID_FLTR_SIZE; i++) pr->fltr[i] = ~pr->fltr[i]; + blkid_probe_reset_idx(pr); DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n")); - pr->idx = 0; return 0; } @@ -455,8 +458,7 @@ int blkid_do_probe(blkid_probe pr) blkid_probe_reset_vals(pr); - if (pr->idx) - i = pr->idx + 1; + i = pr->idx + 1; if (i < 0 && i >= ARRAY_SIZE(idinfos)) return -1; -- cgit v1.2.3 From 7103157c8bbf37a56c7c385198267120f72b7866 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 14 May 2009 18:29:03 +0200 Subject: blkid: blkid_do_safeprobe() has to be tolerant to RAIDs It's pretty generic that RAID signature is on the same device as FS signature. We have to be tolerant and ignore filesystems signatures on such devices. The RAID signature is always preferred. Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index b0c0be80..af22e34d 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -529,6 +529,10 @@ int blkid_do_probe(blkid_probe pr) * 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. + * + * 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. */ int blkid_do_safeprobe(blkid_probe pr) { @@ -544,9 +548,12 @@ int blkid_do_safeprobe(blkid_probe pr) first.nvals = pr->nvals; first.idx = pr->idx; } + count++; + + if (idinfos[pr->idx]->usage & BLKID_USAGE_RAID) + break; if (!(idinfos[pr->idx]->flags & BLKID_IDINFO_TOLERANT)) intol++; - count++; } if (rc < 0) return rc; /* error */ -- cgit v1.2.3 From 4bf7d60171fb427fac819880c5006d474a2c4871 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 14 May 2009 20:28:11 +0200 Subject: blkid: cleanup debug messages and return codes in blkid_do_probe() Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index af22e34d..38d42762 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -453,17 +453,16 @@ int blkid_do_probe(blkid_probe pr) { int i = 0; - if (!pr) + if (!pr || pr->idx < -1) return -1; blkid_probe_reset_vals(pr); - i = pr->idx + 1; + DBG(DEBUG_LOWPROBE, + printf("--> starting probing loop [idx=%d]\n", + pr->idx)); - if (i < 0 && i >= ARRAY_SIZE(idinfos)) - return -1; - - DBG(DEBUG_LOWPROBE, printf("--> starting probing loop\n")); + i = pr->idx + 1; for ( ; i < ARRAY_SIZE(idinfos); i++) { const struct blkid_idinfo *id; @@ -518,10 +517,13 @@ int blkid_do_probe(blkid_probe pr) blkid_probe_set_usage(pr, id->usage); DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (type=%s)\n", id->name)); + printf("<-- leaving probing loop (type=%s) [idx=%d]\n", + id->name, pr->idx)); return 0; } - DBG(DEBUG_LOWPROBE, printf("<-- leaving probing loop (failed)\n")); + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (failed) [idx=%d]\n", + pr->idx)); return 1; } -- cgit v1.2.3 From 8c0dc0719d4765f50c77b22acf2812b6e0fe74df Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 18 May 2009 15:59:55 +0200 Subject: build-sys: fix headers in mkswap and libblkid Signed-off-by: Karel Zak --- disk-utils/mkswap.c | 6 +++++- shlibs/blkid/src/probe.c | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/disk-utils/mkswap.c b/disk-utils/mkswap.c index 4acc73b2..bb97210e 100644 --- a/disk-utils/mkswap.c +++ b/disk-utils/mkswap.c @@ -57,7 +57,11 @@ #include "wholedisk.h" #ifdef HAVE_LIBUUID -#include +# ifdef HAVE_UUID_UUID_H +# include +#else +# include +# endif #endif static char * program_name = "mkswap"; diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index 38d42762..b2b888d4 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -24,10 +24,15 @@ #include #endif #include +#include + #ifdef HAVE_LIBUUID -#include +# ifdef HAVE_UUID_UUID_H +# include +#else +# include +# endif #endif -#include #include "blkdev.h" #include "blkidP.h" -- cgit v1.2.3 From c8d20dc1971477d3ef684f540a7f878467c0b9cf Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 7 May 2009 19:00:44 +0200 Subject: blkid: add device-mapper snapshot cow device probe The copy-on-write area of device-mapper snapshot has SnAp identifier, disk header is written directly by kernel. [kzak@redhat.com: - rename from "snap_cow" to "DM_snapshot_cow"] Signed-off-by: Milan Broz Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 1 + shlibs/blkid/src/probers/lvm.c | 11 ++++++++++- shlibs/blkid/src/probers/probers.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index b2b888d4..6e73696a 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -55,6 +55,7 @@ static const struct blkid_idinfo *idinfos[] = &jmraid_idinfo, &lvm2_idinfo, &lvm1_idinfo, + &snapcow_idinfo, &luks_idinfo, /* Filesystems */ diff --git a/shlibs/blkid/src/probers/lvm.c b/shlibs/blkid/src/probers/lvm.c index d80d023d..d8edc37a 100644 --- a/shlibs/blkid/src/probers/lvm.c +++ b/shlibs/blkid/src/probers/lvm.c @@ -164,4 +164,13 @@ const struct blkid_idinfo lvm1_idinfo = } }; - +const struct blkid_idinfo snapcow_idinfo = +{ + .name = "DM_snapshot_cow", + .usage = BLKID_USAGE_OTHER, + .magics = + { + { .magic = "SnAp", .len = 4 }, + { NULL } + } +}; diff --git a/shlibs/blkid/src/probers/probers.h b/shlibs/blkid/src/probers/probers.h index c3b22774..78dbd406 100644 --- a/shlibs/blkid/src/probers/probers.h +++ b/shlibs/blkid/src/probers/probers.h @@ -47,6 +47,7 @@ extern const struct blkid_idinfo ufs_idinfo; extern const struct blkid_idinfo hpfs_idinfo; extern const struct blkid_idinfo lvm2_idinfo; extern const struct blkid_idinfo lvm1_idinfo; +extern const struct blkid_idinfo snapcow_idinfo; extern const struct blkid_idinfo luks_idinfo; extern const struct blkid_idinfo highpoint37x_idinfo; extern const struct blkid_idinfo highpoint45x_idinfo; -- cgit v1.2.3 From e512717968ccfc2342b2901b2caba0a4217c4bc1 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 30 Jun 2009 11:26:54 +0200 Subject: libblkid: fix #ifdefs readability Signed-off-by: Karel Zak --- shlibs/blkid/src/probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shlibs/blkid/src/probe.c') diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c index 6e73696a..10fcb003 100644 --- a/shlibs/blkid/src/probe.c +++ b/shlibs/blkid/src/probe.c @@ -29,8 +29,8 @@ #ifdef HAVE_LIBUUID # ifdef HAVE_UUID_UUID_H # include -#else -# include +# else +# include # endif #endif -- cgit v1.2.3