Hi,
here is a quite big patch against devfsd v1.3.18.
This enable user to select which modprobe to use,
This also let the user specify arguments to pass to it.
The config options could be put in devfsd.conf or on command line.
Command line options have a higher priority.
Also some Makefile little tweaks
This work perfectly for me (with a patch against modprobe
to make it use syslog(), the patch was sent to the modutils team).
Feel free to use it as is, or make any modification to my code.
--
Yann Droneaud <ydroneaud@xxxxxxxxxxx>
================ patch-devfsd-meuh-modprobe-arguments =========================
diff -ur devfsd-1.3.18/GNUmakefile devfsd-1.3.18-meuh/GNUmakefile
--- devfsd-1.3.18/GNUmakefile Sat Aug 18 19:50:39 2001
+++ devfsd-1.3.18-meuh/GNUmakefile Fri Nov 16 22:12:20 2001
@@ -16,14 +16,16 @@
OBJECTS = devfsd.o expression.o compat_name.o
+CC = gcc
+CFLAGS = -g -O2 -W -Wall
+CFLAGS += -I.
ifdef KERNEL_DIR
-CFLAGS = -O2 -I. -I$(KERNEL_DIR)/include -Wall $(CEXTRAS) $(DEFINES)
-else
-CFLAGS = -O2 -I. -Wall $(CEXTRAS) $(DEFINES)
+CFLAGS += -I$(KERNEL_DIR)/include
endif
+CFLAGS += $(CEXTRAS) $(DEFINES)
devfsd: $(OBJECTS)
- cc -O2 -o devfsd $(OBJECTS) $(LDFLAGS) -export-dynamic -ldl
+ $(CC) $(CFLAGS) -o devfsd $(OBJECTS) $(LDFLAGS) -export-dynamic -ldl
install: devfsd
@if fgrep -q "Generic section: do not change" /etc/modules.conf ; then\
diff -ur devfsd-1.3.18/devfsd.c devfsd-1.3.18-meuh/devfsd.c
--- devfsd-1.3.18/devfsd.c Mon Aug 20 02:12:21 2001
+++ devfsd-1.3.18-meuh/devfsd.c Fri Nov 16 23:36:44 2001
@@ -206,11 +206,13 @@
Updated by Richard Gooch 18-AUG-2001: Dynamically load libnsl at
run-time as needed, rather than linking. Based on patch from Adam J. Richter.
- Last updated by Richard Gooch 19-AUG-2001: Switched to stat(2) in
+ Updated by Richard Gooch 19-AUG-2001: Switched to stat(2) in
<action_permissions> to avoid harmless false positives. Return 0 instead of
exiting if passwd or group entry not found in database. Do not exit in
<action_execute> if fork(2) fails.
+ Last updated by Yann Droneaud <ydroneaud@xxxxxxxxxxx> 16-NOV-2001: support
for
+ modprobe configuration (which modprobe use and with what parameters)
*/
#define _GNU_SOURCE
@@ -247,8 +249,10 @@
# define RTLD_DEFAULT RTLD_NEXT
#endif
+#define MODPROBE "/sbin/modprobe"
#define CONFIG_FILE "/etc/devfsd.conf"
-#define MAX_ARGS (6 + 1)
+#define MAX_ARGS (6 + 1)
+#define MAX_ARGV_ARGS 16 /* number of arguments passed to modprobe */
#define MAX_SUBEXPR 10
/* Update only after changing code to reflect new protocol */
@@ -287,7 +291,7 @@
struct execute_type
{
- char *argv[MAX_ARGS + 1]; /* argv[0] must always be the programme */
+ char *argv[MAX_ARGS + 1]; /* argv[0] must always be the program */
};
struct call_function_type
@@ -343,6 +347,21 @@
struct shared_object *next;
};
+struct modprobe
+{
+ flag verbose_option; /* on command line/devfsd.conf/env */
+ flag verbose_config;
+
+ char path_option[STRING_LENGTH];
+ char path_config[STRING_LENGTH];
+ char path[STRING_LENGTH];
+
+ int argc;
+ char *argv[MAX_ARGV_ARGS + 1];
+ char extra_argv[MAX_ARGV_ARGS + 1][STRING_LENGTH]; /* for extra params in
config file */
+
+ int (*func) (int argc, char **argv);
+};
/* External functions */
EXTERN_FUNCTION (flag st_expr_expand,
@@ -415,6 +434,21 @@
/* Private data */
+static struct modprobe modprobe =
+{
+ verbose_option: -1,
+ verbose_config: -1,
+ path_option: "",
+ path_config: "",
+ path: "",
+
+ argc: 0,
+ argv: { NULL },
+ extra_argv: { "", "" },
+
+ func: NULL,
+};
+
static struct config_entry_struct *first_config = NULL;
static struct config_entry_struct *last_config = NULL;
static struct shared_object *first_so = NULL;
@@ -452,7 +486,7 @@
unsigned long event_mask = 0;
struct sigaction new_action;
struct stat statbuf;
- static char usage[] = "devfsd mntpnt [-v] [-d] [-t num] [-D mask] [-fg]
[-np]";
+ static char usage[] = "devfsd mntpnt [-v] [-d] [-t num] [-D mask] [-fg]
[-np] [-m[nv|v] [modprobe]]";
if (argc < 2)
{
@@ -476,6 +510,22 @@
}
else if (strcmp (argv[count], "-fg") == 0) do_daemon = FALSE;
else if (strcmp (argv[count], "-np") == 0) no_polling = TRUE;
+ else if (strcmp (argv[count], "-mnv") == 0) /* modprobe non verbose */
+ {
+ modprobe.verbose_option = FALSE;
+ if ((count + 1) < argc && argv[count + 1][0] != '-')
+ strncpy(modprobe.path_option, argv[++count], STRING_LENGTH);
+ }
+ else if (strcmp (argv[count], "-mv") == 0) /* modprobe verbose */
+ {
+ modprobe.verbose_option = TRUE;
+ if ((count + 1) < argc && argv[count + 1][0] != '-')
+ strncpy(modprobe.path_option, argv[++count], STRING_LENGTH);
+ }
+ else if ( (strcmp (argv[count], "-m") == 0) && (++count < argc) ) /*
modprobe */
+ {
+ strncpy(modprobe.path_option, argv[count], STRING_LENGTH);
+ }
else
{
fprintf (stderr, "Usage:\t%s\n", usage);
@@ -730,7 +780,7 @@
{
int err, num_args, count;
struct config_entry_struct *new;
- char p[MAX_ARGS][STRING_LENGTH];
+ char p[MAX_ARGS + 1][STRING_LENGTH];
char when[STRING_LENGTH], what[STRING_LENGTH];
char name[STRING_LENGTH], tmp[STRING_LENGTH];
@@ -759,6 +809,40 @@
event_mask);
return;
}
+ if (strcasecmp (when, "MODPROBE") == 0) /* set the modprobe path/and or
option */
+ {
+ if (strcasecmp(name, "DEFAULT") == 0)
+ modprobe.path_config[0] = '\0'; /* get modprobe from
/proc/sys/kernel/modprobe */
+ else if ( (strcasecmp(name, "CURRENT") != 0) && /* if match CURRENT|.*
use the current value, don't set it */
+ (strcasecmp(name, ".*") != 0) )
+ strncpy(modprobe.path_config, name, STRING_LENGTH); /* else take the
argument */
+
+ if (num_args > 2)
+ {
+ if (strcasecmp(what, "VERBOSE") == 0) /* be verbose */
+ modprobe.verbose_config = TRUE;
+ else if (strcasecmp(what, "NORMAL") == 0) /* don't be verbose */
+ modprobe.verbose_config = FALSE;
+ else if ( (strcasecmp(what, "ARGS") == 0) ||
+ (strcasecmp(what, "ARGUMENTS") == 0) )
+ {
+ int i;
+
+ /* read all args and store them in the modprobe structure */
+ for(i = 0; i < num_args - 3; i++)
+ strncpy(modprobe.extra_argv[i], p[i], STRING_LENGTH);
+
+ modprobe.extra_argv[i][0] = '\0';
+ }
+ else
+ {
+ SYSLOG (LOG_ERR, "bad config line: \"%s\"\n", line);
+ SYSLOG (LOG_ERR, "exiting\n");
+ exit (1);
+ }
+ }
+ return;
+ }
if (num_args < 3)
{
SYSLOG (LOG_ERR, "bad config line: \"%s\"\n", line);
@@ -1123,6 +1207,37 @@
}
} /* End Function action_permissions */
+static char * modprobe_find(void)
+{
+ FILE *file;
+ int num;
+
+ /* modprobe path must be configurable at runtime
+ o default /sbin/modprobe
+ o from /proc/sys/kernel/modprobe
+ o parameter on command line
+ o from devfsd.conf
+ */
+
+ if (modprobe.path_option[0] != '\0')
+ return modprobe.path_option; /* use the one provided on the command line */
+
+ if (modprobe.path_config[0] != '\0')
+ return modprobe.path_config; /* use the one found in config file */
+
+ file = fopen("/proc/sys/kernel/modprobe", "r");
+ if (file != NULL)
+ {
+ num = fscanf(file, "%s", modprobe.path);
+ fclose(file);
+
+ if (num == 1)
+ return modprobe.path;
+ }
+
+ return MODPROBE; /* use the default path */
+}
+
static void action_modload (const struct devfsd_notify_struct *info,
const struct config_entry_struct *entry)
/* [SUMMARY] Load a module.
@@ -1131,38 +1246,60 @@
[RETURNS] Nothing.
*/
{
- char *argv[6];
char device[STRING_LENGTH];
- static int (*modprobe) (int argc, char **argv) = NULL;
- static flag first_time = TRUE;
-
- if (first_time)
- {
- void *lib;
+ void *lib;
+ int i;
+
+ /* can't compute args only one time, must be resetup when devfsd.conf is
reread (SIGHUP) */
+
+ modprobe.argc = 0;
+ modprobe.argv[modprobe.argc ++] = NULL; /* place for modprobe path */
+ if ( (modprobe.verbose_option == TRUE) ||
+ (modprobe.verbose_option == -1 && modprobe.verbose_config == TRUE) )
+ {
+ modprobe.argv[modprobe.argc ++] = "-s"; /* use syslog */
+ modprobe.argv[modprobe.argc ++] = "-v"; /* be verbose */
+ }
+
+ /* add extra args */
+ for(i = 0; modprobe.extra_argv[i][0] != '\0' ; i++)
+ modprobe.argv[modprobe.argc ++] = modprobe.extra_argv[i];
+
+ modprobe.argv[modprobe.argc ++] = "-k"; /* Auto unload this module if
unused */
+ modprobe.argv[modprobe.argc ++] = "-C"; /* use this config file : */
+ modprobe.argv[modprobe.argc ++] = "/etc/modules.devfs";
+
+ modprobe.argv[modprobe.argc ++] = NULL; /* place for the device name */
+ modprobe.argv[modprobe.argc] = NULL;
- first_time = FALSE;
- if ( ( lib = dlopen ("/lib/modutils.so", RTLD_NOW) ) != NULL )
- modprobe = dlsym (lib, "modprobe");
- }
- argv[0] = "/sbin/modprobe";
- argv[1] = "-k";
- argv[2] = "-C";
- argv[3] = "/etc/modules.devfs";
- argv[4] = device;
- argv[5] = NULL;
+ /* compute really dynamic parameter (those that don't depend of us
directly) */
+ modprobe.argv[0] = modprobe_find();
snprintf (device, sizeof (device), "/dev/%s", info->devname);
+ modprobe.argv[modprobe.argc - 1] = device;
+
+ /* always try to open this */
+ lib = dlopen ("/lib/modutils.so", RTLD_NOW);
+ if ( lib != NULL )
+ modprobe.func = dlsym (lib, "modprobe");
+ else
+ modprobe.func = NULL;
+
if (trace_level > 1)
fprintf (stderr, "Calling modprobe with name: \"%s\"\n", device);
- if (modprobe != NULL)
+ if (modprobe.func != NULL)
{
- (*modprobe) (5, argv);
+ /* use the function from the library */
+ (*modprobe.func) (modprobe.argc, modprobe.argv);
return;
}
switch ( fork () )
{
case 0:
/* Child */
- break;
+ execvp (modprobe.argv[0], modprobe.argv);
+ SYSLOG (LOG_ERR, "error execing: \"%s\"\t%s\n", modprobe.argv[0],
ERRSTRING);
+ _exit (1);
+ /* break; */
case -1:
/* Error */
SYSLOG (LOG_ERR, "error forking\t%s\n", ERRSTRING);
@@ -1174,15 +1311,12 @@
return;
/*break;*/
}
- execvp (argv[0], argv);
- SYSLOG (LOG_ERR, "error execing: \"%s\"\t%s\n", argv[0], ERRSTRING);
- _exit (1);
} /* End Function action_modload */
static void action_execute (const struct devfsd_notify_struct *info,
const struct config_entry_struct *entry,
const regmatch_t *regexpr, unsigned int numexpr)
-/* [SUMMARY] Execute a programme.
+/* [SUMMARY] Execute a program.
<info> The devfs change.
<entry> The config file entry.
<regexpr> The number of subexpression (start, end) offsets within the
@@ -1222,7 +1356,7 @@
break;
case -1:
/* Error */
- SYSLOG (LOG_ERR, "error forking for programme: %s\t%s\n",
+ SYSLOG (LOG_ERR, "error forking for program: %s\t%s\n",
argv[0], ERRSTRING);
return;
/*break;*/
diff -ur devfsd-1.3.18/devfsd.conf devfsd-1.3.18-meuh/devfsd.conf
--- devfsd-1.3.18/devfsd.conf Thu Mar 29 22:05:37 2001
+++ devfsd-1.3.18-meuh/devfsd.conf Fri Nov 16 23:39:20 2001
@@ -1,6 +1,16 @@
# Sample /etc/devfsd.conf configuration file.
# Richard Gooch <rgooch@xxxxxxxxxxxxx> 3-JUL-2000
#
+# Some configuration tricks for modprobe
+# use this modprobe
+#MODPROBE /sbin/modprobe
+# make modprobe verbose (pass -s -v flags)
+#MODPROBE .* VERBOSE
+# add some flags to the modprobe command line
+#MODPROBE current ARGS -a -d
+# use the default modprobe (from /proc/sys/kernel/modprobe or "/sbin/modprobe")
+#MODPROBE default
+
# Enable full compatibility mode for old device names. You may comment these
# out if you don't use the old device names. Make sure you know what you're
# doing!
========== patch-devfsd-meuh-modprobe-arguments ======================
|