hal/hald/linux2/probing probe-volume.c, 1.31, 1.32 probe-storage.c, 1.23, 1.24 Makefile.am, 1.12, 1.13

Kay Sievers kay at kemper.freedesktop.org
Mon Jul 10 16:47:44 PDT 2006


Update of /cvs/hal/hal/hald/linux2/probing
In directory kemper:/tmp/cvs-serv4908/hald/linux2/probing

Modified Files:
	probe-volume.c probe-storage.c Makefile.am 
Log Message:
2006-07-11  Kay Sievers  <kay.sievers at vrfy.org>

        * configure.in:
        * hald/linux2/probing/Makefile.am:
        * hald/linux2/probing/probe-storage.c: (vid_log), (main):
        * hald/linux2/probing/probe-volume.c: (vid_log),
        (probe_msdos_part_table), (set_volume_id_values), (main):
        Depend on external shared version of libvolume_id.


Index: probe-volume.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/probe-volume.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- probe-volume.c	10 Jul 2006 18:20:14 -0000	1.31
+++ probe-volume.c	10 Jul 2006 23:47:42 -0000	1.32
@@ -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 @@
 	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 @@
 	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 @@
 	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;
 
@@ -558,51 +692,45 @@
 			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);
 		}
 	}

Index: probe-storage.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/probe-storage.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- probe-storage.c	9 May 2006 20:34:38 -0000	1.23
+++ probe-storage.c	10 Jul 2006 23:47:42 -0000	1.24
@@ -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 @@
 
 	fd = -1;
 
+	/* hook in our debug into libvolume_id */
+	volume_id_log_fn = vid_log;
+
 	/* assume failure */
 	ret = 1;
 

Index: Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/probing/Makefile.am,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- Makefile.am	23 Jan 2006 12:15:50 -0000	1.12
+++ Makefile.am	10 Jul 2006 23:47:42 -0000	1.13
@@ -30,10 +30,10 @@
 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@
 




More information about the hal-commit mailing list