linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] dev_d.c file sorting and cleanup
@ 2004-03-25 13:43 Kay Sievers
  2004-03-27  1:08 ` Greg KH
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kay Sievers @ 2004-03-25 13:43 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 529 bytes --]

On Thu, Mar 25, 2004 at 02:52:13AM +0100, Kay Sievers wrote:
> Please have look if it still works for you, I only did a very quick
> test.

Here is a unified version, with all the functions moved to udev_lib.c.
We have a generic function now, to call a given fnct(char *) for every
file ending with a specific suffix, sorted in lexical order. We use it
to execute the dev.d/ files and read our rules.d/ files. The binary
should be a bit smaller now.

I've also changed it, to not do the dev.d/ exec for net devices.

thanks,
Kay

[-- Attachment #2: 02-dev.d.patch --]
[-- Type: text/plain, Size: 11847 bytes --]

===== dev_d.c 1.2 vs edited =====
--- 1.2/dev_d.c	Thu Mar 25 00:31:03 2004
+++ edited/dev_d.c	Thu Mar 25 14:38:22 2004
@@ -1,30 +1,23 @@
 /*
- * dev.d multipleer
+ * dev_d.c - dev.d/ multiplexer
  * 
  * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
  *
  *	This program is free software; you can redistribute it and/or modify it
  *	under the terms of the GNU General Public License as published by the
  *	Free Software Foundation version 2 of the License.
- * 
- * Based on the klibc version of hotplug written by:
- *	Author(s) Christian Borntraeger <cborntra@de.ibm.com>
- * which was based on the shell script written by:
- *	Greg Kroah-Hartman <greg@kroah.com>
- *
  */
 
-/* 
+/*
  * This essentially emulates the following shell script logic in C:
-	DIR="/etc/dev.d"
-	export DEVNODE="whatever_dev_name_udev_just_gave"
-	for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do
-		if [ -f $I ]; then $I $1 ; fi
-	done
-	exit 1;
+ *	DIR="/etc/dev.d"
+ *	export DEVNODE="whatever_dev_name_udev_just_gave"
+ *	for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do
+ *		if [ -f $I ]; then $I $1 ; fi
+ *	done
+ *	exit 1;
  */
 
-#include <dirent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -35,73 +28,38 @@
 #include "udev_lib.h"
 #include "logging.h"
 
-#define HOTPLUGDIR	"/etc/dev.d"
-#define SUFFIX		".dev" 
-#define COMMENT_PREFIX	'#'
+#define DEVD_DIR			"/etc/dev.d/"
+#define DEVD_SUFFIX			".dev"
 
-static void run_program(char *name)
+static int run_program(char *name)
 {
 	pid_t pid;
 
 	dbg("running %s", name);
 
 	pid = fork();
-
-	if (pid < 0) {
-		perror("fork");
-		return;
-	} 
-	
-	if (pid > 0) {
+	switch (pid) {
+	case 0:
+		/* child */
+		execv(name, main_argv);
+		dbg("exec of child failed");
+		exit(1);
+	case -1:
+		dbg("fork of child failed");
+		break;
+		return -1;
+	default:
 		wait(NULL);
-		return;
-	}
-
-	execv(name, main_argv);
-	exit(1);
-}
-
-static void execute_dir (char *dirname)
-{
-	DIR *directory;
-	struct dirent *entry;
-	char filename[NAME_SIZE];
-	int name_len;
-
-	dbg("opening %s", dirname);
-	directory = opendir(dirname);
-	if (!directory)
-		return;
-
-	while ((entry = readdir(directory))) {
-		if (entry->d_name[0] == '\0')
-			break;
-		/* Don't run the files '.', '..', or hidden files, 
-		 * or files that start with a '#' */
-		if ((entry->d_name[0] == '.') ||
-		    (entry->d_name[0] == COMMENT_PREFIX))
-			continue;
-
-		/* Nor do we run files that do not end in ".dev" */
-		name_len = strlen(entry->d_name);
-		if (name_len < strlen(SUFFIX))
-			continue;
-		if (strcmp(&entry->d_name[name_len - sizeof (SUFFIX) + 1], SUFFIX) != 0)
-			continue;
-
-		/* FIXME - need to use file_list_insert() here to run these in sorted order... */
-		snprintf(filename, sizeof(filename), "%s%s", dirname, entry->d_name);
-		filename[sizeof(filename)-1] = '\0';
-		run_program(filename);
 	}
 
-	closedir(directory);
+	return 0;
 }
 
-/* runs files in these directories in order:
- * 	name given by udev
- * 	subsystem
- * 	default
+/* 
+ * runs files in these directories in order:
+ * 	<node name given by udev>/
+ * 	subsystem/
+ * 	default/
  */
 void dev_d_send(struct udevice *dev, char *subsystem)
 {
@@ -112,15 +70,15 @@
 	strfieldcat(devnode, dev->name);
 	setenv("DEVNODE", devnode, 1);
 
-	snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", dev->name);
-	dirname[sizeof(dirname)-1] = '\0';
-	execute_dir(dirname);
-
-	snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", subsystem);
-	dirname[sizeof(dirname)-1] = '\0';
-	execute_dir(dirname);
+	strcpy(dirname, DEVD_DIR);
+	strfieldcat(dirname, dev->name);
+	call_foreach_file(run_program, dirname, DEVD_SUFFIX);
+
+	strcpy(dirname, DEVD_DIR);
+	strfieldcat(dirname, subsystem);
+	call_foreach_file(run_program, dirname, DEVD_SUFFIX);
 
-	strcpy(dirname, HOTPLUGDIR "/default/");
-	execute_dir(dirname);
+	strcpy(dirname, DEVD_DIR "default");
+	call_foreach_file(run_program, dirname, DEVD_SUFFIX);
 }
 
===== namedev.h 1.29 vs edited =====
--- 1.29/namedev.h	Wed Mar 10 23:00:15 2004
+++ edited/namedev.h	Thu Mar 25 12:48:30 2004
@@ -53,8 +53,8 @@
 
 #define MAX_SYSFS_PAIRS		5
 
-#define RULEFILE_EXT		".rules"
-#define PERMFILE_EXT		".permissions"
+#define RULEFILE_SUFFIX		".rules"
+#define PERMFILE_SUFFIX		".permissions"
 
 #define set_empty_perms(dev, m, o, g)		\
 	if (dev->mode == 0)			\
===== namedev_parse.c 1.33 vs edited =====
--- 1.33/namedev_parse.c	Wed Mar 17 23:40:12 2004
+++ edited/namedev_parse.c	Thu Mar 25 13:10:52 2004
@@ -33,7 +33,6 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <sys/stat.h>
-#include <dirent.h>
 #include <errno.h>
 
 #include "udev.h"
@@ -41,8 +40,6 @@
 #include "logging.h"
 #include "namedev.h"
 
-LIST_HEAD(file_list);
-
 
 static int add_config_dev(struct config_device *new_dev)
 {
@@ -416,88 +413,26 @@
 	return retval;
 }
 
-struct files {
-	struct list_head list;
-	char name[NAME_SIZE];
-};
-
-/* sort files in lexical order */
-static int file_list_insert(char *filename)
-{
-	struct files *loop_file;
-	struct files *new_file;
-
-	list_for_each_entry(loop_file, &file_list, list) {
-		if (strcmp(loop_file->name, filename) > 0) {
-			break;
-		}
-	}
-
-	new_file = malloc(sizeof(struct files));
-	if (new_file == NULL) {
-		dbg("error malloc");
-		return -ENOMEM;
-	}
-
-	strfieldcpy(new_file->name, filename);
-	list_add_tail(&new_file->list, &loop_file->list);
-	return 0;
-}
-
-/* calls function for file or every file found in directory */
-static int call_foreach_file(int parser (char *f) , char *filename, char *extension)
+int namedev_init_rules()
 {
-	struct dirent *ent;
-	DIR *dir;
-	char *ext;
-	char file[NAME_SIZE];
 	struct stat stats;
-	struct files *loop_file;
-	struct files *tmp_file;
 
-	/* look if we have a plain file or a directory to scan */
-	stat(filename, &stats);
+	stat(udev_rules_filename, &stats);
 	if ((stats.st_mode & S_IFMT) != S_IFDIR)
-		return parser(filename);
-
-	/* sort matching filename into list */
-	dbg("open config as directory '%s'", filename);
-	dir = opendir(filename);
-	while (1) {
-		ent = readdir(dir);
-		if (ent == NULL || ent->d_name[0] == '\0')
-			break;
-
-		dbg("found file '%s'", ent->d_name);
-		ext = strrchr(ent->d_name, '.');
-		if (ext == NULL)
-			continue;
-
-		if (strcmp(ext, extension) == 0) {
-			dbg("put file in list '%s'", ent->d_name);
-			file_list_insert(ent->d_name);
-		}
-	}
-
-	/* parse every file in the list */
-	list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
-		strfieldcpy(file, filename);
-		strfieldcat(file, loop_file->name);
-		parser(file);
-		list_del(&loop_file->list);
-		free(loop_file);
-	}
-
-	closedir(dir);
-	return 0;
-}
-
-int namedev_init_rules()
-{
-	return call_foreach_file(namedev_parse_rules, udev_rules_filename, RULEFILE_EXT);
+		return namedev_parse_rules(udev_rules_filename);
+	else
+		return call_foreach_file(namedev_parse_rules,
+					 udev_rules_filename, RULEFILE_SUFFIX);
 }
 
 int namedev_init_permissions()
 {
-	return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, PERMFILE_EXT);
+	struct stat stats;
+
+	stat(udev_permissions_filename, &stats);
+	if ((stats.st_mode & S_IFMT) != S_IFDIR)
+		return namedev_parse_permissions(udev_permissions_filename);
+	else
+		return call_foreach_file(namedev_parse_permissions,
+					 udev_permissions_filename, PERMFILE_SUFFIX);
 }
===== udev-add.c 1.66 vs edited =====
--- 1.66/udev-add.c	Thu Mar 25 00:14:16 2004
+++ edited/udev-add.c	Thu Mar 25 13:25:50 2004
@@ -393,6 +393,7 @@
 	retval = ioctl(sk, SIOCSIFNAME, &ifr);
 	if (retval != 0)
 		dbg("error changing net interface name");
+	close(sk);
 
 	return retval;
 }
@@ -453,6 +454,8 @@
 	case 'b':
 	case 'c':
 		retval = create_node(&dev, fake);
+		if ((retval == 0) && (!fake))
+			dev_d_send(&dev, subsystem);
 		break;
 
 	case 'n':
@@ -461,9 +464,6 @@
 			dbg("net device naming failed");
 		break;
 	}
-
-	if ((retval == 0) && (!fake))
-		dev_d_send(&dev, subsystem);
 
 exit:
 	if (class_dev)
===== udev_lib.c 1.3 vs edited =====
--- 1.3/udev_lib.c	Thu Mar 25 00:50:34 2004
+++ edited/udev_lib.c	Thu Mar 25 13:29:50 2004
@@ -21,14 +21,19 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stddef.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 
 #include "libsysfs/sysfs/libsysfs.h"
 #include "udev.h"
+#include "logging.h"
 #include "udev_lib.h"
+#include "list.h"
 
 
 char *get_action(void)
@@ -136,3 +141,84 @@
 	return count - cur;
 }
 
+struct files {
+	struct list_head list;
+	char name[NAME_SIZE];
+};
+
+/* sort files in lexical order */
+static int file_list_insert(char *filename, struct list_head *file_list)
+{
+	struct files *loop_file;
+	struct files *new_file;
+
+	list_for_each_entry(loop_file, file_list, list) {
+		if (strcmp(loop_file->name, filename) > 0) {
+			break;
+		}
+	}
+
+	new_file = malloc(sizeof(struct files));
+	if (new_file == NULL) {
+		dbg("error malloc");
+		return -ENOMEM;
+	}
+
+	strfieldcpy(new_file->name, filename);
+	list_add_tail(&new_file->list, &loop_file->list);
+	return 0;
+}
+
+/* calls function for file or every file found in directory */
+int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix)
+{
+	struct dirent *ent;
+	DIR *dir;
+	char *ext;
+	char file[NAME_SIZE];
+	struct files *loop_file;
+	struct files *tmp_file;
+	LIST_HEAD(file_list);
+
+	dbg("open directory '%s'", dirname);
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		dbg("unable to open '%s'", dirname);
+		return -1;
+	}
+
+	while (1) {
+		ent = readdir(dir);
+		if (ent == NULL || ent->d_name[0] == '\0')
+			break;
+
+		if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER))
+			continue;
+
+		/* look for file with specified suffix */
+		ext = strrchr(ent->d_name, '.');
+		if (ext == NULL)
+			continue;
+
+		if (strcmp(ext, suffix) != 0)
+			continue;
+
+		dbg("put file '%s/%s' in list", dirname, ent->d_name);
+		file_list_insert(ent->d_name, &file_list);
+	}
+
+	/* call function for every file in the list */
+	list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
+		strfieldcpy(file, dirname);
+		strfieldcat(file, "/");
+		strfieldcat(file, loop_file->name);
+
+		fnct(file);
+
+		list_del(&loop_file->list);
+		free(loop_file);
+	}
+
+	closedir(dir);
+	return 0;
+}
===== udev_lib.h 1.3 vs edited =====
--- 1.3/udev_lib.h	Thu Mar 25 00:14:20 2004
+++ edited/udev_lib.h	Thu Mar 25 12:38:24 2004
@@ -75,6 +75,7 @@
 extern int file_map(const char *filename, char **buf, size_t *bufsize);
 extern void file_unmap(char *buf, size_t bufsize);
 extern size_t buf_get_line(char *buf, size_t buflen, size_t cur);
+extern int  call_foreach_file(int fnct(char *f) , char *filename, char *extension);
 
 
 #endif
===== udevd.c 1.24 vs edited =====
--- 1.24/udevd.c	Wed Mar 17 23:40:12 2004
+++ edited/udevd.c	Thu Mar 25 12:43:05 2004
@@ -45,9 +45,9 @@
 volatile static int children_waiting;
 volatile static int msg_q_timeout;
 
-LIST_HEAD(msg_list);
-LIST_HEAD(exec_list);
-LIST_HEAD(running_list);
+static LIST_HEAD(msg_list);
+static LIST_HEAD(exec_list);
+static LIST_HEAD(running_list);
 
 static void exec_queue_manager(void);
 static void msg_queue_manager(void);
===== udevruler.c 1.1 vs edited =====
--- 1.1/udevruler.c	Thu Mar 18 04:23:51 2004
+++ edited/udevruler.c	Thu Mar 25 12:45:16 2004
@@ -81,8 +81,8 @@
 	int added;
 };
 
-LIST_HEAD(device_list);
-int device_count;
+static LIST_HEAD(device_list);
+static int device_count;
 
 /* callback for database dump */
 static int add_record(char *path, struct udevice *udev)
@@ -149,8 +149,8 @@
 	char key[NAME_SIZE];
 };
 
-LIST_HEAD(attribute_list);
-int attribute_count;
+static LIST_HEAD(attribute_list);
+static int attribute_count;
 
 static int add_attribute(const char *key, int level)
 {

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] dev_d.c file sorting and cleanup
  2004-03-25 13:43 [PATCH] dev_d.c file sorting and cleanup Kay Sievers
@ 2004-03-27  1:08 ` Greg KH
  2004-03-27  1:13 ` Kay Sievers
  2004-03-27  1:21 ` Greg KH
  2 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2004-03-27  1:08 UTC (permalink / raw)
  To: linux-hotplug

Looks good except for:

On Thu, Mar 25, 2004 at 02:43:50PM +0100, Kay Sievers wrote:
> +		/* look for file with specified suffix */
> +		ext = strrchr(ent->d_name, '.');
> +		if (ext = NULL)
> +			continue;
> +
> +		if (strcmp(ext, suffix) != 0)
> +			continue;

That would still execute files named "foo.dev.rpmsave" right?  That's
what we want to avoid happening.  We need to make sure we match "*.dev$"
only.

So I'll hold off applying this for now.

thanks,

greg k-h


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id\x1470&alloc_id638&op=click
_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] dev_d.c file sorting and cleanup
  2004-03-25 13:43 [PATCH] dev_d.c file sorting and cleanup Kay Sievers
  2004-03-27  1:08 ` Greg KH
@ 2004-03-27  1:13 ` Kay Sievers
  2004-03-27  1:21 ` Greg KH
  2 siblings, 0 replies; 4+ messages in thread
From: Kay Sievers @ 2004-03-27  1:13 UTC (permalink / raw)
  To: linux-hotplug

On Fri, Mar 26, 2004 at 05:08:02PM -0800, Greg KH wrote:
> Looks good except for:
> 
> On Thu, Mar 25, 2004 at 02:43:50PM +0100, Kay Sievers wrote:
> > +		/* look for file with specified suffix */
> > +		ext = strrchr(ent->d_name, '.');
> > +		if (ext = NULL)
> > +			continue;
> > +
> > +		if (strcmp(ext, suffix) != 0)
> > +			continue;
> 
> That would still execute files named "foo.dev.rpmsave" right?  That's
> what we want to avoid happening.  We need to make sure we match "*.dev$"
> only.
> 

Hey, just read a few lines more :)

+               if (strcmp(ext, suffix) != 0)
+                       continue;
+

Kay


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id\x1470&alloc_id638&op=click
_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] dev_d.c file sorting and cleanup
  2004-03-25 13:43 [PATCH] dev_d.c file sorting and cleanup Kay Sievers
  2004-03-27  1:08 ` Greg KH
  2004-03-27  1:13 ` Kay Sievers
@ 2004-03-27  1:21 ` Greg KH
  2 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2004-03-27  1:21 UTC (permalink / raw)
  To: linux-hotplug

On Thu, Mar 25, 2004 at 02:43:50PM +0100, Kay Sievers wrote:
> On Thu, Mar 25, 2004 at 02:52:13AM +0100, Kay Sievers wrote:
> > Please have look if it still works for you, I only did a very quick
> > test.
> 
> Here is a unified version, with all the functions moved to udev_lib.c.
> We have a generic function now, to call a given fnct(char *) for every
> file ending with a specific suffix, sorted in lexical order. We use it
> to execute the dev.d/ files and read our rules.d/ files. The binary
> should be a bit smaller now.
> 
> I've also changed it, to not do the dev.d/ exec for net devices.

Ok, care to fix it back so we call exec for net devices?

And now that I can read code, I've applied it :)

thanks,

greg k-h


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id\x1470&alloc_id638&op=click
_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-03-27  1:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-25 13:43 [PATCH] dev_d.c file sorting and cleanup Kay Sievers
2004-03-27  1:08 ` Greg KH
2004-03-27  1:13 ` Kay Sievers
2004-03-27  1:21 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).