[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Linux-cluster] [PATCH] iddev - convert to general purpose device identifier



Updated patch.

Changes:
- Use mmap.
- Add the device size to the exported information.

Bastian

-- 
A princess should not be afraid -- not with a brave knight to protect her.
		-- McCoy, "Shore Leave", stardate 3025.3
=== lib/iddev.h
==================================================================
--- lib/iddev.h   (/iddev/trunk)   (revision 29)
+++ lib/iddev.h   (/iddev/local/branches/refactor)   (revision 29)
@@ -16,19 +16,65 @@
 
 
 /**
+ * device_info - 
+ */
+
+enum device_info_family
+{
+	DEVICE_INFO_UNDEFINED_FAMILY = 0,
+	DEVICE_INFO_CONTAINER,
+	DEVICE_INFO_FILESYSTEM,
+	DEVICE_INFO_SWAP,
+};
+
+enum device_info_type
+{
+	DEVICE_INFO_UNDEFINED_TYPE = 0,
+	DEVICE_INFO_CONTAINER_CCA,
+	DEVICE_INFO_CONTAINER_CIDEV,
+	DEVICE_INFO_CONTAINER_LVM1,
+	DEVICE_INFO_CONTAINER_LVM2,
+	DEVICE_INFO_CONTAINER_PARTITION,
+	DEVICE_INFO_CONTAINER_POOL,
+	DEVICE_INFO_FILESYSTEM_EXT23,
+	DEVICE_INFO_FILESYSTEM_GFS,
+	DEVICE_INFO_FILESYSTEM_REISERFS,
+	DEVICE_INFO_FILESYSTEM_XFS,
+};
+
+enum device_info_subtype
+{
+	DEVICE_INFO_UNDEFINED_SUBTYPE = 0,
+	DEVICE_INFO_CONTAINER_PARTITION_MSDOS,
+	DEVICE_INFO_FILESYSTEM_EXT2,
+	DEVICE_INFO_FILESYSTEM_EXT3,
+};
+
+struct device_info
+{
+	enum device_info_family family;
+	enum device_info_type type;
+	enum device_info_subtype subtype;
+
+	char display[128];
+	unsigned char uuid[16];
+	uint64_t device_size;
+	uint32_t block_size;
+};
+
+/**
  * indentify_device - figure out what's on a device
  * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
+ * @info: a buffer
  *
  * The offset of @fd will be changed by the function.
  * This routine will not write to this device.
  *
  * Returns: -1 on error (with errno set), 1 if unabled to identify,
- *          0 if device identified (with @type set)
+ *          0 if device identified (with @info set)
  */
 
-int identify_device(int fd, char *type, unsigned type_len);
+int identify_device(int fd, struct device_info *info);
 
 
 /**
@@ -39,7 +85,7 @@
  * Returns: -1 on error (with errno set), 0 on success (with @bytes set)
  */
 
-int device_size(int fd, uint64 *bytes);
+int device_size(int fd, uint64_t *bytes);
 
 
 #endif /* __IDDEV_DOT_H__ */
=== lib/identify_device.c
==================================================================
--- lib/identify_device.c   (/iddev/trunk)   (revision 29)
+++ lib/identify_device.c   (/iddev/local/branches/refactor)   (revision 29)
@@ -50,8 +50,8 @@
 int main(int argc, char *argv[])
 {
   int fd;
-  char buf[BUFSIZE];
-  uint64 bytes;
+  struct device_info info;
+  const char *display;
   int error;
 
   prog_name = argv[0];
@@ -63,18 +63,16 @@
   if (fd < 0)
     die("can't open %s: %s\n", argv[1], strerror(errno));
 
-  error = identify_device(fd, buf, BUFSIZE);
+  error = identify_device(fd, &info);
   if (error < 0)
     die("error identifying the contents of %s: %s\n", argv[1], strerror(errno));
   else if (error)
-    strcpy(buf, "unknown");
+    display = "unknown";
+  else
+    display = info.display;
 
-  error = device_size(fd, &bytes);
-  if (error < 0)
-    die("error determining the size of %s: %s\n", argv[1], strerror(errno));
-
   printf("%s:\n%-15s%s\n%-15s%"PRIu64"\n",
-	 argv[1], "  contents:", buf, "  bytes:", bytes);
+	 argv[1], "  contents:", display, "  bytes:", info.device_size);
 
   close(fd);
 
=== lib/iddev.c
==================================================================
--- lib/iddev.c   (/iddev/trunk)   (revision 29)
+++ lib/iddev.c   (/iddev/local/branches/refactor)   (revision 29)
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -25,48 +26,53 @@
 
 #include "iddev.h"
 
+static void info_set_display(struct device_info *info, const char *display)
+{
+  snprintf(info->display, sizeof (info->display), display);
+}
 
+static inline void info_set(struct device_info *info, const enum device_info_family family, const enum device_info_type type, const enum device_info_subtype subtype, const char *display)
+{
+  info->family = family;
+  info->type = type;
+  info->subtype = subtype;
+  info_set_display(info, display);
+}
 
+static inline void info_set_container(struct device_info *info, const enum device_info_type type, const enum device_info_subtype subtype, const char *display)
+{
+  info_set(info, DEVICE_INFO_CONTAINER, type, subtype, display);
+}
 
+static inline void info_set_filesystem(struct device_info *info, const enum device_info_type type, const enum device_info_subtype subtype, const char *display)
+{
+  info_set(info, DEVICE_INFO_FILESYSTEM, type, subtype, display);
+}
 
+typedef int check(const void *mem, size_t len, struct device_info *info);
+
 /**
  * check_for_gfs - check to see if GFS is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * An EINVAL returned from lseek means that the device was too
- * small -- at least on Linux.
- *
- * Returns: -1 on error (with errno set), 1 if not GFS,
- *          0 if GFS found (with type set)
  */
 
-static int check_for_gfs(int fd, char *type, unsigned type_len)
+enum
 {
-  unsigned char buf[512];
-  uint32 *p = (uint32 *)buf;
-  int error;
+  GFS_OFFSET = 64*1024,
+  GFS_SB_SIZE = 512,
+};
 
-  error = lseek(fd, 65536, SEEK_SET);
-  if (error < 0)
-    return (errno == EINVAL) ? 1 : error;
-  else if (error != 65536)
-  {
-    errno = EINVAL;
-    return -1;
-  }
+static check check_for_gfs;
+static int check_for_gfs(const void *mem, size_t len, struct device_info *info)
+{
+  const uint32_t *p = (const uint32_t *)((const unsigned char *)mem + GFS_OFFSET);
 
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 8)
+  if (len < GFS_OFFSET + GFS_SB_SIZE)
     return 1;
 
   if (osi_be32_to_cpu(*p) != 0x01161970 || osi_be32_to_cpu(*(p + 1)) != 1)
     return 1;
 
-  snprintf(type, type_len, "GFS filesystem");
+  info_set_filesystem(info, DEVICE_INFO_FILESYSTEM_GFS, 0, "GFS filesystem");
 
   return 0;
 }
@@ -74,199 +80,186 @@
 
 /**
  * check_for_pool - check to see if Pool is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not Pool,
- *          0 if Pool found (with type set)
  */
 
-static int check_for_pool(int fd, char *type, unsigned type_len)
+enum
 {
-  unsigned char buf[512];
-  uint64 *p = (uint64 *)buf;
-  int error;
+  POOL_SB_SIZE = 512,
+};
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
+static check check_for_pool;
+static int check_for_pool(const void *mem, size_t len, struct device_info *info)
+{
+  const uint64_t *p = mem;
 
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 8)
+  if (len < POOL_SB_SIZE)
     return 1;
 
   if (osi_be64_to_cpu(*p) != 0x11670)
     return 1;
 
-  snprintf(type, type_len, "Pool subdevice");
+  info_set_container(info, DEVICE_INFO_CONTAINER_POOL, 0, "Pool subdevice");
 
   return 0;
 }
 
 
 /**
- * check_for_paritition - check to see if Partition is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not Partition,
- *          0 if Partition found (with type set)
+ * check_for_partition_msdos - check to see if Partition is on this device
  */
 
-static int check_for_partition(int fd, char *type, unsigned type_len)
+enum
 {
-  unsigned char buf[512];
-  int error;
+  PARTITION_MSDOS_SB_SIZE = 512,
+};
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
+static check check_for_partition_msdos;
+static int check_for_partition_msdos(const void *mem, size_t len, struct device_info *info)
+{
+  const unsigned char *buf = mem;
 
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 512)
+  if (len < PARTITION_MSDOS_SB_SIZE)
     return 1;
 
   if (buf[510] != 0x55 || buf[511] != 0xAA)
     return 1;
 
-  snprintf(type, type_len, "partition information");
+  info_set_container(info, DEVICE_INFO_CONTAINER_PARTITION, DEVICE_INFO_CONTAINER_PARTITION_MSDOS, "MSDOS partition information");
 
   return 0;
 }
 
+enum
+{
+  EXT23_OFFSET = 1024,
+  EXT23_SB_SIZE = 512,
+  EXT23_BLOCK_SIZE_BITS = 10,
+  EXT23_BLOCK_SIZE = (1 << EXT23_BLOCK_SIZE_BITS),
+  EXT23_SUPER_MAGIC = 0xEF53,
+  EXT23_FEATURE_COMPAT_HAS_JOURNAL = 0x4,
+};
 
+struct ext23_superblock
+{
+  uint32_t _r1[6];                      /**< 0x00 - 0x14 */
+  uint32_t s_log_block_size;            /**< 0x18 */
+  uint32_t _r2[7];                      /**< 0x1c - 0x34 */
+  uint16_t s_magic;                     /**< 0x38 */
+  uint16_t s_state;                     /**< 0x3a */
+  uint32_t _r3[8];                      /**< 0x3c - 0x58 */
+  uint32_t s_feature_compat;            /**< 0x5c */
+  uint32_t s_feature_incompat;          /**< 0x60 */
+  uint32_t s_feature_ro_compat;         /**< 0x64 */
+  uint8_t s_uuid[16];                   /**< 0x68 - 0x77 */
+};
+
 /**
  * check_for_ext23 - check to see if EXT23 is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * An EINVAL returned from lseek means that the device was too
- * small -- at least on Linux.
- *
- * Returns: -1 on error (with errno set), 1 if not EXT23,
- *          0 if EXT23 found (with type set)
  */
 
-static int check_for_ext23(int fd, char *type, unsigned type_len)
+static check check_for_ext23;
+static int check_for_ext23(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[512];
-  uint16 *p = (uint16 *)buf;
-  int error;
+  const struct ext23_superblock *p = (const struct ext23_superblock *)((const unsigned char *)mem + EXT23_OFFSET);
 
-  error = lseek(fd, 1024, SEEK_SET);
-  if (error < 0)
-    return (errno == EINVAL) ? 1 : error;
-  else if (error != 1024)
-  {
-    errno = EINVAL;
-    return -1;
-  }
+  if (len < EXT23_OFFSET + EXT23_SB_SIZE)
+    return 1;
 
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 58)
+  if (osi_le16_to_cpu(p->s_magic) != EXT23_SUPER_MAGIC)
     return 1;
 
-  if (osi_le16_to_cpu(p[28]) != 0xEF53)
+  info->block_size = (EXT23_BLOCK_SIZE << osi_le32_to_cpu(p->s_log_block_size));
+
+  if (osi_le16_to_cpu(p->s_feature_compat) & EXT23_FEATURE_COMPAT_HAS_JOURNAL)
+    info_set_filesystem(info, DEVICE_INFO_FILESYSTEM_EXT23, DEVICE_INFO_FILESYSTEM_EXT3, "EXT3 filesystem");
+  else
+    info_set_filesystem(info, DEVICE_INFO_FILESYSTEM_EXT23, DEVICE_INFO_FILESYSTEM_EXT2, "EXT2 filesystem");
+
+  return 0;
+}
+
+
+enum
+{
+  XFS_SB_SIZE = 512,
+  XFS_SB_MAGIC = 0x58465342,
+};
+
+struct xfs_superblock
+{
+  uint32_t sb_magicnum;
+  uint32_t sb_blocksize;
+  uint64_t sb_dblocks;
+  uint64_t sb_rblocks;
+  uint64_t sb_rextents;
+  uint8_t sb_uuid[16];
+};
+
+/**
+ * check_for_xfs - check to see if XFS is on this device
+ */
+
+static check check_for_xfs;
+static int check_for_xfs(const void *mem, size_t len, struct device_info *info)
+{
+  const struct xfs_superblock *p = mem;
+
+  if (len < XFS_SB_SIZE)
     return 1;
 
-  snprintf(type, type_len, "EXT2/3 filesystem");
+  if (osi_be32_to_cpu(p->sb_magicnum) != XFS_SB_MAGIC)
+    return 1;
 
+  info->block_size = osi_be32_to_cpu(p->sb_blocksize);
+
+  info_set_filesystem(info, DEVICE_INFO_FILESYSTEM_XFS, 0, "XFS filesystem");
+
   return 0;
 }
 
 
 /**
  * check_for_swap - check to see if SWAP is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not SWAP,
- *          0 if SWAP found (with type set)
  */
 
-static int check_for_swap(int fd, char *type, unsigned type_len)
+static check check_for_swap;
+static int check_for_swap(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[8192];
-  int error;
+  const unsigned char *buf = mem;
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
-
-  error = read(fd, buf, 8192);
-  if (error < 0)
-    return error;
-  else if (error < 4096)
+  if (len < 8192)
     return 1;
 
   if (memcmp(buf + 4086, "SWAP-SPACE", 10) && memcmp(buf + 4086, "SWAPSPACE2", 10))
     return 1;
 
-  snprintf(type, type_len, "swap device");
+  info_set(info, DEVICE_INFO_SWAP, 0, 0, "swap device");
 
   return 0;
 }
 
 
+enum
+{
+  LVM1_SB_SIZE = 512,
+};
+
 /**
  * check_for_lvm1 - check to see if LVM1 is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not LVM1,
- *          0 if LVM1 found (with type set)
  */
 
-static int check_for_lvm1(int fd, char *type, unsigned type_len)
+static check check_for_lvm1;
+static int check_for_lvm1(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[512];
-  int error;
+  const unsigned char *buf = mem;
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
-
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 2)
+  if (len < LVM1_SB_SIZE)
     return 1;
 
   if (buf[0] != 'H' || buf[1] != 'M')
     return 1;
 
-  snprintf(type, type_len, "lvm1 subdevice");
+  info_set_container(info, DEVICE_INFO_CONTAINER_LVM1, 0, "LVM1 subdevice");
 
   return 0;
 }
@@ -274,39 +267,22 @@
 
 /**
  * check_for_lvm2 - check to see if LVM2 is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not LVM2,
- *          0 if LVM1 found (with type set)
  */
 
-static int check_for_lvm2(int fd, char *type, unsigned type_len)
+static check check_for_lvm2;
+static int check_for_lvm2(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[512];
-  int error;
   int i;
 
+  if (len < 6 * 512)
+    return 1;
+
   /* LVM 2 labels can start in sectors 1-4 */
 
   for (i = 1; i < 5; i++)
   {
-    error = lseek(fd, 512 * i, SEEK_SET);
-    if (error < 0)
-      return (errno == EINVAL) ? 1 : error;
-    else if (error != 512 * i)
-    {
-      errno = EINVAL;
-      return -1;
-    }
+    const unsigned char *buf = (const unsigned char *)mem + 512 * i;
 
-    error = read(fd, buf, 512);
-    if (error < 0)
-      return error;
-    else if (error < 32)
-      return 1;
-
     if (strncmp(buf, "LABELONE", 8) != 0)
       continue;
     if (((uint64_t *)buf)[1] != i)
@@ -315,7 +291,7 @@
     if (strncmp(&buf[24], "LVM2 001", 8) != 0)
       continue;
 
-    snprintf(type, type_len, "lvm2 subdevice");
+    info_set_container(info, DEVICE_INFO_CONTAINER_LVM2, 0, "LVM2 subdevice");
 
     return 0;
   }
@@ -324,127 +300,85 @@
 }
 
 
+enum
+{
+  CIDEV_SB_SIZE = 512,
+};
+
 /**
  * check_for_cidev - check to see if CIDEV is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not CIDEV,
- *          0 if CIDEV found (with type set)
  */
 
-static int check_for_cidev(int fd, char *type, unsigned type_len)
+static check check_for_cidev;
+static int check_for_cidev(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[512];
-  uint32 *p = (uint32 *)buf;
-  int error;
+  const uint32_t *p = mem;
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
-
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 4)
+  if (len < CIDEV_SB_SIZE)
     return 1;
 
   if (osi_be32_to_cpu(*p) != 0x47465341)
     return 1;
 
-  snprintf(type, type_len, "CIDEV");
+  info_set_container(info, DEVICE_INFO_CONTAINER_CIDEV, 0, "CIDEV");
 
   return 0;
 }
 
 
+enum
+{
+  CCA_SB_SIZE = 512,
+};
+
 /**
  * check_for_cca - check to see if CCA is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not CCA,
- *          0 if CCA found (with type set)
  */
 
-static int check_for_cca(int fd, char *type, unsigned type_len)
+static check check_for_cca;
+static int check_for_cca(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned char buf[512];
-  uint32 *p = (uint32 *)buf;
-  int error;
+  const uint32_t *p = mem;
 
-  error = lseek(fd, 0, SEEK_SET);
-  if (error < 0)
-    return error;
-  else if (error != 0)
-  {
-    errno = EINVAL;
-    return -1;
-  }
-
-  error = read(fd, buf, 512);
-  if (error < 0)
-    return error;
-  else if (error < 4)
+  if (len < CCA_SB_SIZE)
     return 1;
 
   if (osi_be32_to_cpu(*p) != 0x122473)
     return 1;
 
-  snprintf(type, type_len, "CCA device");
+  info_set_container(info, DEVICE_INFO_CONTAINER_CCA, 0, "CCA device");
 
   return 0;
 }
 
 
+enum
+{
+  REISERFS_SB_SIZE = 65 * 1024,
+};
+
 /**
  * check_for_reiserfs - check to see if reisterfs is on this device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * Returns: -1 on error (with errno set), 1 if not reiserfs,
- *          0 if CCA found (with type set)
  */
 
-static int check_for_reiserfs(int fd, char *type, unsigned type_len)
+static check check_for_reiserfs;
+static int check_for_reiserfs(const void *mem, size_t len, struct device_info *info)
 {
-  unsigned int pass;
-  uint64 offset;
-  unsigned char buf[512];
-  int error;
+  int pass;
 
+  if (len < REISERFS_SB_SIZE)
+    return 1;
+
   for (pass = 0; pass < 2; pass++)
   {
-    offset = (pass) ? 65536 : 8192;
+    unsigned int offset = (pass) ? 65536 : 8192;
+    const unsigned char *p = (const unsigned char *)mem + offset;
 
-    error = lseek(fd, offset, SEEK_SET);
-    if (error < 0)
-      return (errno == EINVAL) ? 1 : error;
-    else if (error != offset)
+    if (strncmp(p + 52, "ReIsErFs", 8) == 0 ||
+	strncmp(p + 52, "ReIsEr2Fs", 9) == 0 ||
+	strncmp(p + 52, "ReIsEr3Fs", 9) == 0)
     {
-      errno = EINVAL;
-      return -1;
-    }
-
-    error = read(fd, buf, 512);
-    if (error < 0)
-      return error;
-    else if (error < 62)
-      return 1;
-
-    if (strncmp(buf + 52, "ReIsErFs", 8) == 0 ||
-	strncmp(buf + 52, "ReIsEr2Fs", 9) == 0 ||
-	strncmp(buf + 52, "ReIsEr3Fs", 9) == 0)
-    {
-      snprintf(type, type_len, "Reiserfs filesystem");
+      info_set_filesystem(info, DEVICE_INFO_FILESYSTEM_REISERFS, 0, "ReiserFS filesystem");
       return 0;
     }
   }
@@ -453,69 +387,49 @@
 }
 
 
-/**
- * identify_device - figure out what's on a device
- * @fd: a file descriptor open on a device open for (at least) reading
- * @type: a buffer that contains the type of filesystem
- * @type_len: the amount of space pointed to by @type
- *
- * The offset of @fd will be changed by this function.
- * This routine will not write to the device.
- *
- * Returns: -1 on error (with errno set), 1 if unabled to identify,
- *          0 if device identified (with type set)
- */
+static check *checks[] =
+{
+  check_for_partition_msdos,
+  check_for_pool,
+  check_for_lvm1,
+  check_for_lvm2,
+  check_for_cidev,
+  check_for_cca,
+  check_for_ext23,
+  check_for_gfs,
+  check_for_reiserfs,
+  check_for_xfs,
+  check_for_swap,
+};
 
-int identify_device(int fd, char *type, unsigned type_len)
+int identify_device(int fd, struct device_info *info)
 {
-  int error;
+  int i;
+  const void *mem;
+  size_t len;
 
-  if (!type || !type_len)
+  if (!info)
   {
     errno = EINVAL;
     return -1;
   }
 
-  error = check_for_pool(fd, type, type_len);
-  if (error <= 0)
-    return error;
+  memset(info, sizeof (struct device_info), 0);
 
-  error = check_for_lvm1(fd, type, type_len);
-  if (error <= 0)
-    return error;
+  if (device_size(fd, &info->device_size) < 0)
+    return -1;
 
-  error = check_for_lvm2(fd, type, type_len);
-  if(error <= 0)
-    return error;
+  len = info->device_size <= 256*1024 ? info->device_size : 256*1024;
 
-  error = check_for_cidev(fd, type, type_len);
-  if (error <= 0)
-    return error;
+  mem = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
 
-  error = check_for_cca(fd, type, type_len);
-  if (error <= 0)
-    return error;
+  for (i = 0; i < sizeof (checks) / sizeof (*checks); ++i)
+  {
+    int error = checks[i](mem, len, info);
+    if (error <= 0)
+      return error;
+  }
 
-  error = check_for_gfs(fd, type, type_len);
-  if (error <= 0)
-    return error;
-
-  error = check_for_ext23(fd, type, type_len);
-  if (error <= 0)
-    return error;
-
-  error = check_for_reiserfs(fd, type, type_len);
-  if (error <= 0)
-    return error;
-
-  error = check_for_swap(fd, type, type_len);
-  if (error <= 0)
-    return error;
-
-  error = check_for_partition(fd, type, type_len);
-  if (error <= 0)
-    return error;
-
   return 1;
 }
 

Attachment: signature.asc
Description: Digital signature


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]