svn commit: trunk/busybox: editors libbb util-linux/volume_id

vda at busybox.net vda at busybox.net
Sun Oct 19 19:36:30 UTC 2008


Author: vda
Date: 2008-10-19 12:36:30 -0700 (Sun, 19 Oct 2008)
New Revision: 23723

Log:
volume identification: abolish /proc/partitions and /proc/cdroms
scanning. It does not catch volume managers and such.
Adding even more cruft is bad, so I decided to simply
scan /dev/* for any block devices. See how much better
it finds devices now:

# ./busybox_old blkid
/dev/sda1: LABEL="/boot" UUID="7931e231-dcb4-4b6d-9301-f7354ae24061"
/dev/dm-0: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a"
/dev/dm-1: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267"
/dev/sdb1: UUID="6F84-ED0F"

# ./busybox blkid
/dev/sdb1: UUID="6F84-ED0F"
/dev/root: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a"
/dev/dm-1: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267"
/dev/dm-0: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a"
/dev/sda1: LABEL="/boot" UUID="7931e231-dcb4-4b6d-9301-f7354ae24061"
/dev/mapper/VolGroup00-LogVol01: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267"
/dev/mapper/VolGroup00-LogVol00: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a"

function                                             old     new   delta
static.drive_name_string                              12       -     -12
append_mount_options                                 205     190     -15
volume_id_open_node                                   37      18     -19
uuidcache_check_device                               485     257    -228
uuidcache_init                                       637      36    -601
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-875)           Total: -875 bytes
   text    data     bss     dec     hex filename
 792218     592    6648  799458   c32e2 busybox_old
 791260     592    6648  798500   c2f24 busybox_unstripped



Modified:
   trunk/busybox/editors/diff.c
   trunk/busybox/libbb/make_directory.c
   trunk/busybox/util-linux/volume_id/get_devname.c
   trunk/busybox/util-linux/volume_id/volume_id.c
   trunk/busybox/util-linux/volume_id/volume_id_internal.h


Changeset:
Modified: trunk/busybox/editors/diff.c
===================================================================
--- trunk/busybox/editors/diff.c	2008-10-19 17:47:31 UTC (rev 23722)
+++ trunk/busybox/editors/diff.c	2008-10-19 19:36:30 UTC (rev 23723)
@@ -1189,7 +1189,7 @@
 		recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS,
 					add_to_dirlist, /* file_action */
 					NULL, /* dir_action */
-					(void*)(strlen(path) + 1),
+					(void*)(ptrdiff_t)(strlen(path) + 1),
 					0);
 	} else {
 		DIR *dp;

Modified: trunk/busybox/libbb/make_directory.c
===================================================================
--- trunk/busybox/libbb/make_directory.c	2008-10-19 17:47:31 UTC (rev 23722)
+++ trunk/busybox/libbb/make_directory.c	2008-10-19 19:36:30 UTC (rev 23723)
@@ -71,7 +71,7 @@
 			}
 			/* Since the directory exists, don't attempt to change
 			 * permissions if it was the full target.  Note that
-			 * this is not an error conditon. */
+			 * this is not an error condition. */
 			if (!c) {
 				umask(mask);
 				return 0;

Modified: trunk/busybox/util-linux/volume_id/get_devname.c
===================================================================
--- trunk/busybox/util-linux/volume_id/get_devname.c	2008-10-19 17:47:31 UTC (rev 23722)
+++ trunk/busybox/util-linux/volume_id/get_devname.c	2008-10-19 19:36:30 UTC (rev 23723)
@@ -22,38 +22,23 @@
 
 /* Returns !0 on error.
  * Otherwise, returns malloc'ed strings for label and uuid
- * (and they can't be NULL, although they can be "") */
-#if !ENABLE_FEATURE_VOLUMEID_ISO9660
-#define get_label_uuid(device, label, uuid, iso_only) \
-	get_label_uuid(device, label, uuid)
-#endif
+ * (and they can't be NULL, although they can be "").
+ * NB: closes fd. */
 static int
-get_label_uuid(const char *device, char **label, char **uuid, int iso_only)
+get_label_uuid(int fd, char **label, char **uuid)
 {
 	int rv = 1;
 	uint64_t size;
 	struct volume_id *vid;
 
-	vid = volume_id_open_node(device);
-	if (!vid)
-		return rv;
+	/* fd is owned by vid now */
+	vid = volume_id_open_node(fd);
 
-	if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
+	if (ioctl(/*vid->*/fd, BLKGETSIZE64, &size) != 0)
 		size = 0;
 
-#if ENABLE_FEATURE_VOLUMEID_ISO9660
-	if ((iso_only ?
-	     volume_id_probe_iso9660(vid, 0) :
-	     volume_id_probe_all(vid, 0, size)
-	    ) != 0
-	) {
+	if (volume_id_probe_all(vid, 0, size) != 0)
 		goto ret;
-	}
-#else
-	if (volume_id_probe_all(vid, 0, size) != 0) {
-		goto ret;
-	}
-#endif
 
 	if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
 		*label = xstrndup(vid->label, sizeof(vid->label));
@@ -62,7 +47,7 @@
 		rv = 0;
 	}
  ret:
-	free_volume_id(vid);
+	free_volume_id(vid); /* also closes fd */
 	return rv;
 }
 
@@ -91,214 +76,42 @@
 /* If get_label_uuid() on device_name returns success,
  * add a cache entry for this device.
  * If device node does not exist, it will be temporarily created. */
-#if !ENABLE_FEATURE_VOLUMEID_ISO9660
-#define uuidcache_check_device(device_name, ma, mi, iso_only) \
-	uuidcache_check_device(device_name, ma, mi)
-#endif
-static void
-uuidcache_check_device(const char *device_name, int ma, int mi, int iso_only)
+static int FAST_FUNC
+uuidcache_check_device(const char *device,
+		struct stat *statbuf,
+		void *userData UNUSED_PARAM,
+		int depth UNUSED_PARAM)
 {
-	char *device, *last_slash;
-	char *uuid, *label;
-	char *ptr;
-	int must_remove = 0;
-	int added = 0;
+	char *uuid = uuid; /* for compiler */
+	char *label = label;
+	int fd;
 
-	last_slash = NULL;
-	device = xasprintf("/dev/%s", device_name);
-	if (access(device, F_OK) != 0) {
-		/* device does not exist, temporarily create */
-		int slash_cnt = 0;
+	if (!S_ISBLK(statbuf->st_mode))
+		return TRUE;
 
-		if ((ma | mi) < 0)
-			goto ret; /* we don't know major:minor! */
+	fd = open(device, O_RDONLY);
+	if (fd < 0)
+		return TRUE;
 
-		ptr = device;
-		while (*ptr)
-			if (*ptr++ == '/')
-				slash_cnt++;
-		if (slash_cnt > 2) {
-// BUG: handles only slash_cnt == 3 case
-			last_slash = strrchr(device, '/');
-			*last_slash = '\0';
-			if (mkdir(device, 0644)) {
-				bb_perror_msg("can't create directory %s", device);
-				*last_slash = '/';
-				last_slash = NULL; /* prevents rmdir */
-			} else {
-				*last_slash = '/';
-			}
-		}
-		mknod(device, S_IFBLK | 0600, makedev(ma, mi));
-		must_remove = 1;
+	/* get_label_uuid() closes fd in all cases (success & failure) */
+	if (get_label_uuid(fd, &label, &uuid) == 0) {
+		/* uuidcache_addentry() takes ownership of all three params */
+		uuidcache_addentry(xstrdup(device), /*ma, mi,*/ label, uuid);
 	}
-
-	uuid = NULL;
-	label = NULL;
-	if (get_label_uuid(device, &label, &uuid, iso_only) == 0) {
-		uuidcache_addentry(device, /*ma, mi,*/ label, uuid);
-		/* "device" is owned by cache now, don't free */
-		added = 1;
-	}
-
-	if (must_remove)
-		unlink(device);
-	if (last_slash) {
-		*last_slash = '\0';
-		rmdir(device);
-	}
- ret:
-	if (!added)
-		free(device);
+	return TRUE;
 }
 
-/* Run uuidcache_check_device() for every device mentioned
- * in /proc/partitions */
 static void
-uuidcache_init_partitions(void)
-{
-	char line[100];
-	int ma, mi;
-	unsigned long long sz;
-	FILE *procpt;
-	int firstPass;
-	int handleOnFirst;
-	char *chptr;
-
-	procpt = xfopen_for_read("/proc/partitions");
-/*
-# cat /proc/partitions
-major minor  #blocks  name
-
-   8     0  293036184 sda
-   8     1    6835626 sda1
-   8     2          1 sda2
-   8     5     979933 sda5
-   8     6   15623181 sda6
-   8     7   97659103 sda7
-   8     8  171935631 sda8
-*/
-	for (firstPass = 1; firstPass >= 0; firstPass--) {
-		fseek(procpt, 0, SEEK_SET);
-
-		while (fgets(line, sizeof(line), procpt)) {
-			/* The original version of this code used sscanf, but
-			   diet's sscanf is quite limited */
-			chptr = line;
-			if (*chptr != ' ') continue;
-			chptr = skip_whitespace(chptr);
-
-			ma = bb_strtou(chptr, &chptr, 0);
-			if (ma < 0) continue;
-			chptr = skip_whitespace(chptr);
-
-			mi = bb_strtou(chptr, &chptr, 0);
-			if (mi < 0) continue;
-			chptr = skip_whitespace(chptr);
-
-			sz = bb_strtoull(chptr, &chptr, 0);
-			if ((long long)sz == -1LL) continue;
-			chptr = skip_whitespace(chptr);
-
-			/* skip extended partitions (heuristic: size 1) */
-			if (sz == 1)
-				continue;
-
-			*strchrnul(chptr, '\n') = '\0';
-			/* now chptr => device name */
-			dbg("/proc/partitions: maj:%d min:%d sz:%llu name:'%s'",
-						ma, mi, sz, chptr);
-			if (!chptr[0])
-				continue;
-
-			/* look only at md devices on first pass */
-			handleOnFirst = (chptr[0] == 'm' && chptr[1] == 'd');
-			if (firstPass != handleOnFirst)
-				continue;
-
-			/* heuristic: partition name ends in a digit */
-			if (isdigit(chptr[strlen(chptr) - 1])) {
-				uuidcache_check_device(chptr, ma, mi, 0);
-			}
-		}
-	}
-
-	fclose(procpt);
-}
-
-static void
-dev_get_major_minor(char *device_name, int *major, int *minor)
-{
-	char dev[16];
-	char *dev_path;
-	char *colon;
-	int sz;
-
-	dev_path = xasprintf("/sys/block/%s/dev", device_name);
-	sz = open_read_close(dev_path, dev, sizeof(dev) - 1);
-	if (sz < 0)
-		goto ret;
-	dev[sz] = '\0';
-
-	colon = strchr(dev, ':');
-	if (!colon)
-		goto ret;
-	*major = bb_strtou(dev, NULL, 10);
-	*minor = bb_strtou(colon + 1, NULL, 10);
-
- ret:
-	free(dev_path);
-	return;
-}
-
-static void
-uuidcache_init_cdroms(void)
-{
-#define PROC_CDROMS "/proc/sys/dev/cdrom/info"
-	char line[100];
-	int ma, mi;
-	FILE *proccd;
-
-	proccd = fopen_for_read(PROC_CDROMS);
-	if (!proccd) {
-//		static smallint warn = 0;
-//		if (!warn) {
-//			warn = 1;
-//			bb_error_msg("can't open %s, UUID and LABEL "
-//				"conversion cannot be done for CD-Roms",
-//				PROC_CDROMS);
-//		}
-		return;
-	}
-
-	while (fgets(line, sizeof(line), proccd)) {
-		static const char drive_name_string[] ALIGN1 = "drive name:";
-
-		if (strncmp(line, drive_name_string, sizeof(drive_name_string) - 1) == 0) {
-			char *device_name;
-
-			device_name = strtok(skip_whitespace(line + sizeof(drive_name_string) - 1), " \t\n");
-			while (device_name && device_name[0]) {
-				ma = mi = -1;
-				dev_get_major_minor(device_name, &ma, &mi);
-				uuidcache_check_device(device_name, ma, mi, 1);
-				device_name = strtok(NULL, " \t\n");
-			}
-			break;
-		}
-	}
-
-	fclose(proccd);
-}
-
-static void
 uuidcache_init(void)
 {
 	if (uuidCache)
 		return;
 
-	uuidcache_init_partitions();
-	uuidcache_init_cdroms();
+	recursive_action("/dev", ACTION_RECURSE,
+		uuidcache_check_device, /* file_action */
+		NULL, /* dir_action */
+		NULL, /* userData */
+		0 /* depth */);
 }
 
 #define UUID   1

Modified: trunk/busybox/util-linux/volume_id/volume_id.c
===================================================================
--- trunk/busybox/util-linux/volume_id/volume_id.c	2008-10-19 17:47:31 UTC (rev 23722)
+++ trunk/busybox/util-linux/volume_id/volume_id.c	2008-10-19 19:36:30 UTC (rev 23723)
@@ -190,19 +190,14 @@
 }
 
 /* open volume by device node */
-struct volume_id *volume_id_open_node(const char *path)
+struct volume_id *volume_id_open_node(int fd)
 {
 	struct volume_id *id;
-	int fd;
 
-	fd = open(path, O_RDONLY);
-	if (fd < 0)
-		return NULL;
 	id = xzalloc(sizeof(struct volume_id));
 	id->fd = fd;
 	///* close fd on device close */
 	//id->fd_close = 1;
-
 	return id;
 }
 

Modified: trunk/busybox/util-linux/volume_id/volume_id_internal.h
===================================================================
--- trunk/busybox/util-linux/volume_id/volume_id_internal.h	2008-10-19 17:47:31 UTC (rev 23722)
+++ trunk/busybox/util-linux/volume_id/volume_id_internal.h	2008-10-19 19:36:30 UTC (rev 23723)
@@ -87,7 +87,7 @@
 //	int		fd_close:1;
 };
 
-struct volume_id *volume_id_open_node(const char *path);
+struct volume_id *volume_id_open_node(int fd);
 int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size);
 void free_volume_id(struct volume_id *id);
 




More information about the busybox-cvs mailing list