link storage prober against external libvolume_id
Kay Sievers
kay.sievers at vrfy.org
Fri Jul 7 17:13:27 PDT 2006
Here we get rid of the private copy of libvolume_id and depend on the
shared library, provided by the udev package.
The copy in the tree should be removed as it is no longer maintained
and already a bit behind the udev version.
Thanks,
Kay
-------------- next part --------------
Index: configure.in
===================================================================
RCS file: /cvs/hal/hal/configure.in,v
retrieving revision 1.134
diff -u -p -r1.134 configure.in
--- configure.in 15 Jun 2006 01:47:09 -0000 1.134
+++ configure.in 8 Jul 2006 00:04:37 -0000
@@ -180,7 +180,8 @@ AM_CONDITIONAL(GCOV, test x$enable_gcov
glib_module="glib-2.0 >= 2.6.0"
dbus_module="dbus-1 >= 0.33"
polkit_module="polkit >= 0.2"
-pkg_modules="$glib_module, gobject-2.0 >= 2.6.0, dbus-glib-1 >= 0.33, $dbus_module, $polkit_module"
+volume_id_module="libvolume_id >= 0.66"
+pkg_modules="$glib_module, gobject-2.0 >= 2.6.0, dbus-glib-1 >= 0.33, $dbus_module, $polkit_module, $volume_id_module"
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
EXPAT_LIB=""
@@ -263,6 +264,11 @@ PKG_CHECK_MODULES(POLKIT, [$polkit_modul
AC_SUBST(POLKIT_CFLAGS)
AC_SUBST(POLKIT_LIBS)
+# volume_id
+PKG_CHECK_MODULES(VOLUME_ID, [$volume_id_module])
+AC_SUBST(VOLUME_ID_CFLAGS)
+AC_SUBST(VOLUME_ID_LIBS)
+
# Check for BLKGETSIZE64
AC_CHECK_TYPE(pgoff_t, ,
[AC_DEFINE(pgoff_t, unsigned long, [Index into the pagecache])],
Index: hald/linux2/probing/Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/Makefile.am,v
retrieving revision 1.12
diff -u -p -r1.12 Makefile.am
--- hald/linux2/probing/Makefile.am 23 Jan 2006 12:15:50 -0000 1.12
+++ hald/linux2/probing/Makefile.am 8 Jul 2006 00:04:38 -0000
@@ -30,10 +30,10 @@ hald_probe_serial_SOURCES = probe-serial
hald_probe_serial_LDADD = $(top_builddir)/libhal/libhal.la
hald_probe_storage_SOURCES = probe-storage.c linux_dvd_rw_utils.c linux_dvd_rw_utils.h shared.h
-hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/volume_id/libvolume_id.la @PACKAGE_LIBS@
+hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la @PACKAGE_LIBS@
hald_probe_pc_floppy_SOURCES = probe-pc-floppy.c
hald_probe_volume_SOURCES = probe-volume.c linux_dvd_rw_utils.c linux_dvd_rw_utils.h shared.h
-hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/volume_id/libvolume_id.la @PACKAGE_LIBS@
+hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la @PACKAGE_LIBS@
Index: hald/linux2/probing/probe-storage.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/probe-storage.c,v
retrieving revision 1.23
diff -u -p -r1.23 probe-storage.c
--- hald/linux2/probing/probe-storage.c 9 May 2006 20:34:38 -0000 1.23
+++ hald/linux2/probing/probe-storage.c 8 Jul 2006 00:04:38 -0000
@@ -44,20 +44,21 @@
#include <mntent.h>
#include <glib.h>
+#include <libvolume_id.h>
#include "libhal/libhal.h"
-
-#include "volume_id/volume_id.h"
#include "linux_dvd_rw_utils.h"
-
#include "shared.h"
-void
-volume_id_log (const char *format, ...)
+static void vid_log(int priority, const char *file, int line, const char *format, ...)
{
+ char log_str[1024];
va_list args;
- va_start (args, format);
- _do_dbg (format, args);
+
+ va_start(args, format);
+ vsnprintf(log_str, sizeof(log_str), format, args);
+ dbg("%s:%i %s", file, line, log_str);
+ va_end(args);
}
static char *
@@ -132,6 +133,9 @@ main (int argc, char *argv[])
fd = -1;
+ /* hook in our debug into libvolume_id */
+ volume_id_log_fn = vid_log;
+
/* assume failure */
ret = 1;
Index: hald/linux2/probing/probe-volume.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/probe-volume.c,v
retrieving revision 1.30
diff -u -p -r1.30 probe-volume.c
--- hald/linux2/probing/probe-volume.c 12 May 2006 16:43:44 -0000 1.30
+++ hald/linux2/probing/probe-volume.c 8 Jul 2006 00:04:38 -0000
@@ -46,19 +46,21 @@
#include <sys/time.h>
#include <glib.h>
+#include <libvolume_id.h>
#include "libhal/libhal.h"
-#include "volume_id/volume_id.h"
#include "linux_dvd_rw_utils.h"
-
#include "shared.h"
-void
-volume_id_log (const char *format, ...)
+static void vid_log(int priority, const char *file, int line, const char *format, ...)
{
+ char log_str[1024];
va_list args;
- va_start (args, format);
- _do_dbg (format, args);
+
+ va_start(args, format);
+ vsnprintf(log_str, sizeof(log_str), format, args);
+ dbg("%s:%i %s", file, line, log_str);
+ va_end(args);
}
static gchar *
@@ -88,6 +90,138 @@ strdup_valid_utf8 (const char *str)
return newstr;
}
+/* probe_msdos_part_table: return array of partiton type numbers */
+#define BSIZE 0x200
+#define MSDOS_MAGIC "\x55\xaa"
+#define MSDOS_PARTTABLE_OFFSET 0x1be
+#define MSDOS_SIG_OFF 0x1fe
+#define DOS_EXTENDED_PARTITION 0x05
+#define LINUX_EXTENDED_PARTITION 0x85
+#define WIN98_EXTENDED_PARTITION 0x0f
+#define is_extended(type) \
+ (type == DOS_EXTENDED_PARTITION || \
+ type == WIN98_EXTENDED_PARTITION || \
+ type == LINUX_EXTENDED_PARTITION)
+
+static unsigned char *probe_msdos_part_table(int fd)
+{
+ static unsigned char partition_id_index[256];
+ unsigned int partition_count;
+ const uint8_t buf[BSIZE];
+ int i;
+ uint64_t poff;
+ uint64_t plen;
+ uint64_t extended = 0;
+ uint64_t next;
+ int limit;
+ int empty = 1;
+ struct msdos_partition_entry {
+ uint8_t boot_ind;
+ uint8_t head;
+ uint8_t sector;
+ uint8_t cyl;
+ uint8_t sys_ind;
+ uint8_t end_head;
+ uint8_t end_sector;
+ uint8_t end_cyl;
+ uint32_t start_sect;
+ uint32_t nr_sects;
+ } __attribute__((packed)) *part;
+
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ dbg("lseek failed (%s)", strerror(errno));
+ return NULL;
+ }
+ if (read(fd, &buf, BSIZE) < BSIZE) {
+ dbg("read failed (%s)", strerror(errno));
+ return NULL;
+ }
+ if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
+ return NULL;
+
+ part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
+ /* check flags on all entries for a valid partition table */
+ for (i = 0; i < 4; i++) {
+ if (part[i].boot_ind != 0 &&
+ part[i].boot_ind != 0x80)
+ return NULL;
+
+ if (GINT32_FROM_LE(part[i].nr_sects) != 0)
+ empty = 0;
+ }
+ if (empty == 1)
+ return NULL;
+
+ memset(partition_id_index, 0x00, sizeof(partition_id_index));
+
+ for (i = 0; i < 4; i++) {
+ poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE;
+ plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE;
+
+ if (plen == 0)
+ continue;
+
+ partition_id_index[i] = part[i].sys_ind;
+
+ if (is_extended(part[i].sys_ind)) {
+ dbg("found extended partition at 0x%llx", (unsigned long long) poff);
+ if (extended == 0)
+ extended = poff;
+ } else {
+ dbg("found 0x%x primary data partition at 0x%llx, len 0x%llx",
+ part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
+ }
+ }
+
+ /* follow extended partition chain and add data partitions */
+ partition_count = 4;
+ limit = 255;
+ next = extended;
+ while (next != 0) {
+ if (limit-- == 0) {
+ dbg("extended chain limit reached");
+ break;
+ }
+
+ dbg("read 0x%llx (%llu)", next, next);
+ if (lseek(fd, next, SEEK_SET) < 0) {
+ dbg("lseek failed (%s)", strerror(errno));
+ return NULL;
+ }
+ if (read(fd, &buf, BSIZE) < BSIZE) {
+ dbg("read failed (%s)", strerror(errno));
+ return NULL;
+ }
+ if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
+ break;
+
+ next = 0;
+
+ part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
+ for (i = 0; i < 4; i++) {
+ poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE;
+ plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE;
+
+ if (plen == 0)
+ continue;
+
+ if (is_extended(part[i].sys_ind)) {
+ dbg("found extended partition (chain) at 0x%llx", (unsigned long long) poff);
+ if (next == 0)
+ next = extended + poff;
+ } else {
+ dbg("found 0x%x logical data partition at 0x%llx, len 0x%llx",
+ part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
+
+ partition_id_index[partition_count] = part[i].sys_ind;
+ partition_count++;
+ }
+ }
+ }
+
+ return partition_id_index;
+}
+
static void
set_volume_id_values (LibHalContext *ctx, const char *udi, struct volume_id *vid)
{
@@ -102,9 +236,6 @@ set_volume_id_values (LibHalContext *ctx
case VOLUME_ID_FILESYSTEM:
usage = "filesystem";
break;
- case VOLUME_ID_PARTITIONTABLE:
- usage = "partitiontable";
- break;
case VOLUME_ID_OTHER:
usage = "other";
break;
@@ -312,6 +443,9 @@ main (int argc, char *argv[])
dbus_uint64_t vol_probe_offset = 0;
fd = -1;
+ /* hook in our debug into libvolume_id */
+ volume_id_log_fn = vid_log;
+
/* assume failure */
ret = 1;
@@ -556,51 +690,45 @@ main (int argc, char *argv[])
volume_id_close(vid);
}
- /* get partition type (if we are from partitioned media)
- *
- * (presently we only support PC style partition tables)
- */
+ /* get partition type number, if we find a msdos partition table */
if (partition_number_str != NULL) {
+ unsigned char *idx;
+ int fd;
+
if ((stordev_dev_file = libhal_device_get_property_string (
- ctx, parent_udi, "block.device", &error)) == NULL) {
+ ctx, parent_udi, "block.device", &error)) == NULL) {
goto out;
}
- vid = volume_id_open_node (stordev_dev_file);
- if (vid != NULL) {
- if (volume_id_probe_msdos_part_table (vid, 0) == 0) {
- dbg ("Number of partitions = %d", vid->partition_count);
-
- if (partition_number > 0 && partition_number <= vid->partition_count) {
- struct volume_id_partition *p;
- p = &vid->partitions[partition_number-1];
-
+ fd = open(stordev_dev_file, O_RDONLY);
+ if (fd >= 0) {
+ idx = probe_msdos_part_table(fd);
+ if (idx != NULL) {
+ unsigned char type;
+
+ type = idx[partition_number - 1];
+ if (type > 0) {
libhal_device_set_property_int (
ctx, udi, "volume.partition.msdos_part_table_type",
- p->partition_type_raw, &error);
-
+ type, &error);
+
/* NOTE: We trust the type from the partition table
* if it explicitly got correct entries for RAID and
* LVM partitions.
*
- * Btw, in general it's not a good idea to trust the
+ * But in general it's not a good idea to trust the
* partition table type as many geek^Wexpert users use
* FAT filesystems on type 0x83 which is Linux.
*
* Linux RAID autodetect is 0xfd and Linux LVM is 0x8e
*/
- if (p->partition_type_raw == 0xfd ||
- p->partition_type_raw == 0x8e ) {
+ if (type == 0xfd || type == 0x8e ) {
libhal_device_set_property_string (
ctx, udi, "volume.fsusage", "raid", &error);
}
-
- } else {
- dbg ("warning: partition_number=%d not in [0;%d[",
- partition_number, vid->partition_count);
}
}
- volume_id_close(vid);
- }
+ close (fd);
+ }
libhal_free_string (stordev_dev_file);
}
}
More information about the hal
mailing list