[klibc] hotplug for klibc utils

Arnd Bergmann arnd at arndb.de
Fri Feb 27 14:02:06 PST 2004


Several people have run into problems when attaching large disk arrays to
a mainframe because of running /sbin/hotplug as a bash script takes far
longer than the interval between hotplug events.

Attaching more than 300 devices at once will cause an out-of-memory
condition and the kernel starts killing random processes.

Running only udev instead of hotplug from the kernel is fast enough.

Christian Bornträger was so kind to reimplement the Gregs hotplug 
shell script in C and verify that this solves the problem.

The shell version currently does:
> DIR="/etc/hotplug.d"
> for I in "${DIR}/$1/"*.hotplug "${DIR}/"default/*.hotplug ; do
>         if [ -f $I ]; then test -x $I && $I $1 ; fi
> done
> exit 1;

	Arnd <><

diff -urN klibc-0.115/utils/Makefile klibc-0.115-hotplug/utils/Makefile
--- klibc-0.115/utils/Makefile	2004-02-22 01:57:32.000000000 +0100
+++ klibc-0.115-hotplug/utils/Makefile	2004-02-27 11:00:40.000000000 +0100
@@ -6,7 +6,7 @@
 CFLAGS       = $(MAKEDEPS) $(OPTFLAGS) $(REQFLAGS) -W -Wall
 LIBS         = $(KLIBC) $(LIBGCC)
 PROGS       := chroot dd fstype mkdir mkfifo mount pivot_root umount \
-	       true false sleep ln
+	       true false sleep ln hotplug
 STATICPROGS := $(patsubst %,static/%,$(PROGS))
 SHAREDPROGS := $(patsubst %,shared/%,$(PROGS))
 LIBOBJS	     = file_mode.o
diff -urN klibc-0.115/utils/hotplug.c klibc-0.115-hotplug/utils/hotplug.c
--- klibc-0.115/utils/hotplug.c	1970-01-01 01:00:00.000000000 +0100
+++ klibc-0.115-hotplug/utils/hotplug.c	2004-02-27 11:00:28.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * Hotplug Multiplexer
+ * Author(s) Christian Borntraeger <cborntra at de.ibm.com>
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define HOTPLUGDIR "/etc/hotplug.d"
+#define SUFFIX ".hotplug"
+
+static inline void run_agent(char *name, char *parm)
+{
+	pid_t pid;
+
+	if (strlen(name) < sizeof (SUFFIX))
+		return;
+
+	if (strcmp(name + strlen(name) - sizeof (".hotplug") + 1, ".hotplug") != 0)
+		return;
+
+	pid = fork();
+
+	if (pid < 0) {
+		perror("fork");
+		return;
+	} 
+	
+	if (pid > 0){
+		wait(NULL);
+		return;
+	}
+
+	execlp(name, name, parm, NULL);
+	exit(1);
+}
+
+/*
+ * enters the given directory and execute the *.hotplug files
+ */
+static void execute_dir (char *dirname, char *parm)
+{
+	DIR *directory;
+	struct dirent *entry;
+	char filename[256];
+
+	directory = opendir(dirname);
+	if (!directory)
+		return;
+
+	while ((entry = readdir(directory))) {
+		snprintf(filename, sizeof (filename),
+			 "%s%s", dirname, entry->d_name);
+		filename[sizeof (filename)-1] = '\0';
+		run_agent(filename, parm);
+	}
+
+	closedir(directory);
+}
+
+int main (int argc, char **argv)
+{
+	char dirname[256];
+
+	if (argc == 1)
+		return 0;
+
+	snprintf(dirname, sizeof (dirname), HOTPLUGDIR "/%s/", argv[1]);
+	dirname[sizeof (dirname)-1] = '\0';
+	execute_dir(dirname, argv[1]);
+
+	strcpy(dirname, HOTPLUGDIR "/default/");
+	execute_dir(dirname, argv[1]);
+	return 0;
+}




More information about the klibc mailing list