1 diff -urN -x.svn hotplug2-0.9/AUTHORS hotplug2/AUTHORS
2 --- hotplug2-0.9/AUTHORS 2006-10-08 18:13:50.000000000 +0200
3 +++ hotplug2/AUTHORS 2007-06-30 12:59:20.459674000 +0200
7 iSteve <isteve@bofh.cz>
8 -Tomas Janousek <tomi@nomi.cz>
12 +nbd (rules override patch, various fixes, suggestions, testing etc.)
13 +Tomas Janousek <tomi@nomi.cz> (Makefiles, SVN hosting)
18 Randy Dunlap (help with isapnpmap)
19 Igor2 (provided testing machines)
20 yanek (provided testing machines)
21 +Zdenek Styblik (provided testing OpenWRT device)
22 +OpenWRT team (for trusting this project)
23 +mtu (debugging, testing, ideas)
24 +mnemoc (trivial sanity changes on makefiles, linux24 compat patches)
26 -...anyone taking more than a short peek at the software.
27 \ No newline at end of file
28 +...anyone taking more than a short peek at the software.
29 diff -urN -x.svn hotplug2-0.9/Changelog hotplug2/Changelog
30 --- hotplug2-0.9/Changelog 2006-10-08 15:32:31.000000000 +0200
31 +++ hotplug2/Changelog 2007-06-28 14:51:00.009934640 +0200
34 +* Add --set-rules-file.
36 +* Add 'printdebug' rule.
37 +* Fix chmod, chown, chgrp.
38 +* Use octal for chmod and makedev.
41 * Use signals to handle children.
42 * Separate info and debugging output.
45 * Significant cleanup of rules handling.
46 * Better error reporting.
48 \ No newline at end of file
50 diff -urN -x.svn hotplug2-0.9/common.mak hotplug2/common.mak
51 --- hotplug2-0.9/common.mak 2006-09-26 01:03:08.000000000 +0200
52 +++ hotplug2/common.mak 2007-06-28 14:54:56.013056712 +0200
54 .PHONY: all clean dep install install-recursive clean-recursive \
55 dep-recursive all-recursive
57 -MAKEDEP=-gcc $(CFLAGS) -MM $(wildcard *.c *.cc) > .depend
58 +MAKEDEP=-$(CC) $(CFLAGS) -MM $(wildcard *.c *.cc) > .depend
62 diff -urN -x.svn hotplug2-0.9/docs/hotplug2.8 hotplug2/docs/hotplug2.8
63 --- hotplug2-0.9/docs/hotplug2.8 2006-09-26 09:23:36.000000000 +0200
64 +++ hotplug2/docs/hotplug2.8 2007-06-28 14:50:59.874955160 +0200
67 \fB\-\-dumb\fR, \fB\-\-no\-dumb\fR
68 Run or do not run hotplug2 in dumb mode. Dumb mode means that rules are being ignored, the only action taken is mload modules to all devices whose uevent exports MODALIAS. Only available if compiled with HAVE_RULES.
69 +\fB\-\-override\fR, \fB\-\-no\-override\fR
70 +Allows hotplug2 behavior overriding for different rules, using various flags. See hotplug2 rules documentation for details. The default is not to allow overriding, the flags are therefore ignored.
72 \fB\-\-max\-children <value>\fR
73 Set the value of maximum children hotplug2 may have running simultaneously. Default is 20.
76 \fB\-\-set\-modprobe\-cmd <cmd>\fR
77 Sets the application used to perform modprobe. It only gets used in dumb mode. Default is to autodetect: if '/bin/modprobe' is from module\-init\-tools, use '/sbin/modprobe', otherwise use '/sbin/hotplug2\-modwrap'.
78 +\fB\-\-set\-rules\-file <file>\fR
79 +Sets the path to the file containing hotplug2 rules.
83 diff -urN -x.svn hotplug2-0.9/docs/hotplug2.rules.doc hotplug2/docs/hotplug2.rules.doc
84 --- hotplug2-0.9/docs/hotplug2.rules.doc 2006-09-26 10:19:46.000000000 +0200
85 +++ hotplug2/docs/hotplug2.rules.doc 2007-06-28 14:50:59.872955464 +0200
90 -Comments are allowed, they are prefixed with '#', treating the whole rest of the
91 -line as comment. Please note that comments in place of action parameters are not
93 +Comments are allowed, they are prefixed with '#', treating the whole rest of
94 +the line as comment. Please note that comments in place of action parameters
97 -The <key> is one of the environmental variables that have been obtained by the
99 +The <key> is one of the environmental variables that have been obtained by
108 - Execute an application using system();, takes one parameter. Note that
109 - the application has set all environmental variables read by uevent
111 + Execute an application using system();, takes one parameter. Note
112 + that the application has set all environmental variables read by
116 Break the processing of the current block of actions.
119 * exec <application [parameter [parameter [...]]]> ;
120 Execute an application. Takes variable number of parameters, but the
121 - last parameter must be terminated with semicolon. Again, all variables
122 - are set as environmental.
123 + last parameter must be terminated with semicolon. Again, all
124 + variables are set as environmental.
126 - If you need to escape the ';', use '\\;'. Only applies for actions with
127 - variable number of parameters.
128 + If you need to escape the ';', use '\\;'. Only applies for actions
129 + with variable number of parameters.
131 * makedev <path> <mode>
132 - Create a device with given mode. The mode is not in octal unless it
133 - starts with '0', eg. "0644" != "644".
134 + Create a device with given mode. Mode is interpreted as octal.
136 Major, minor and devpath must be set for makedev to be able to work.
137 Tests for these variables are also performed internally in makedev
140 * symlink <target> <linkname>
141 - Create a symbolic link (symlink, also known as soft link) pointing at
142 - target with name linkname.
143 + Create a symbolic link (symlink, also known as soft link) pointing
144 + at target with name linkname.
146 * chown <path> <owner name>
147 Change owner of path to owner name.
148 @@ -111,12 +110,32 @@
149 Change group of path to group name.
151 * chmod <path> <mode>
152 - Change mode of path to given mode. Like with makedev, heading '0' is
153 - necessary for the mode to be interpreted as octal.
154 + Change mode of path to given mode. Mode is interpreted as octal.
156 * setenv <key> <value>
157 Sets environmental variable key to the given value. If an env var
158 of the given name already exists, it gets overwritten.
161 + Prints all variables read from kernel.
166 +Flags are, syntactically, just like actions; their semantical value is different however.
167 +Instead of doing something, they instead change the general behavior of the processing
170 +Note that for flags to work, you also have to invoke it with --override.
172 +Currently, only one flag is implemented:
175 + Forcibly overrides hotplug2 throttling mechanism. If _all_ rules that match
176 + the given kernel event have 'nothrottle' set, hotplug2 will not wait for
177 + children count to get under max-children limit. That allows to throttle
178 + eg. helper application execution or modprobes, but yet keep node devices
187 -Below is a sample hotplug2.rules file. It loads modules to all available devices
188 -quietly and creates device nodes for block devices.
189 +Below is a sample hotplug2.rules file. It loads modules to all available
190 +devices quietly and creates device nodes for block devices. Note that this
191 +sample is not very viable for real life usage.
192 ---------------------------------------------------------------------------------
194 exec modprobe -q %MODALIAS% ;
196 SUBSYSTEM == block, DEVPATH is set, MAJOR is set, MINOR is set {
197 makedev /dev/%DEVICENAME% 0644
201 +Please find also the more complex set of rules, dedicated to handling most
203 +---------------------------------------------------------------------------------
209 +# Load modules (what old hotplug did)
211 + exec modprobe -q %MODALIAS% ;
214 +# Create device nodes
215 +DEVPATH is set, MAJOR is set, MINOR is set {
216 + makedev /dev/%DEVICENAME% 0644
219 +# Mount a USB flashdisk
220 +ACTION == add, PHYSDEVPATH ~~ "/usb[0-9]*/", DEVICENAME ~~ "^sd[a-z][0-9]+$", DEVPATH is set, MAJOR is set, MINOR is set {
221 + makedev /dev/%DEVICENAME% 0644
222 + exec mount /dev/%DEVICENAME% /mnt/%DEVICENAME%
225 +# Unmount a USB flashdisk
226 +ACTION == remove, PHYSDEVPATH ~~ "/usb[0-9]*/", DEVICENAME ~~ "^sd[a-z][0-9]+$", MAJOR is set, MINOR is set {
227 + exec umount /mnt/%DEVICENAME%
229 diff -urN -x.svn hotplug2-0.9/docs/Makefile hotplug2/docs/Makefile
230 --- hotplug2-0.9/docs/Makefile 2006-09-26 00:27:02.000000000 +0200
231 +++ hotplug2/docs/Makefile 2007-06-28 14:50:59.875955008 +0200
238 +MANDIR=/usr/share/man
243 - $(INSTALL) $(wildcard *.8) /usr/share/man/man8/
244 + $(INSTALL) $(wildcard *.8) $(DESTDIR)$(MANDIR)/man8/
247 include ../common.mak
248 diff -urN -x.svn hotplug2-0.9/examples/Makefile hotplug2/examples/Makefile
249 --- hotplug2-0.9/examples/Makefile 2006-09-26 01:03:08.000000000 +0200
250 +++ hotplug2/examples/Makefile 2007-06-28 14:50:59.991937376 +0200
256 +KERNELVER=`uname -r`
262 - case "`uname -r`" in \
264 - $(INSTALL) hotplug2.rules-2.6kernel /etc/hotplug2.rules \
267 - $(INSTALL) hotplug2.rules-2.4kernel /etc/hotplug2.rules \
270 + if ! [ -e "/etc/hotplug2.rules" ]; then \
271 + case "$(KERNELVER)" in \
273 + $(INSTALL) hotplug2.rules-2.6kernel $(DESTDIR)/etc/hotplug2.rules \
276 + $(INSTALL) hotplug2.rules-2.4kernel $(DESTDIR)/etc/hotplug2.rules \
282 include ../common.mak
283 diff -urN -x.svn hotplug2-0.9/hotplug2.c hotplug2/hotplug2.c
284 --- hotplug2-0.9/hotplug2.c 2006-10-08 15:18:23.000000000 +0200
285 +++ hotplug2/hotplug2.c 2007-06-30 12:59:20.459674000 +0200
291 int max_child_c = 20;
296 free_hotplug2_event(event);
299 +int flags_eval(struct hotplug2_event_t *event, struct rules_t *rules) {
300 + int flags = FLAG_ALL;
304 + for (i = 0; i < rules->rules_c; i++) {
307 + for (j = 0; j < rules->rules[i].conditions_c; j++) {
308 + if (rule_condition_eval(event, &rules->rules[i].conditions[j]) != EVAL_MATCH) {
315 + * Logical AND between flags we've got already and
316 + * those we're adding.
319 + rule_flags(event, &rules->rules[i]);
320 + flags &= rules->rules[i].flags;
325 + * A little trick; if no rule matched, we return FLAG_ALL
326 + * and have it skipped completely.
332 +#define perform_action(event, rules)
335 void perform_dumb_action(struct hotplug2_event_t *event, char *modalias) {
341 char *coldplug_command = NULL;
342 + char *rules_file = HOTPLUG2_RULE_PATH;
345 struct rules_t *rules = NULL;
347 {"persistent", &persistent},
348 {"coldplug", &coldplug},
349 {"udevtrigger", &coldplug}, /* compatibility */
350 + {"override", &override},
354 @@ -435,15 +474,31 @@
357 modprobe_command = *argv;
358 + } else if (!strcmp(*argv, "--set-rules-file")) {
364 + rules_file = *argv;
373 + * We don't use rules, so we use dumb mode only.
378 + * We're not in dumb mode, parse the rules. If we fail,
379 + * faillback to dumb mode.
382 filemap = MAP_FAILED;
383 - rule_fd = open(HOTPLUG2_RULE_PATH, O_RDONLY | O_NOATIME);
384 + rule_fd = open(rules_file, O_RDONLY | O_NOATIME);
387 ERROR("rules parse","Unable to open rules file: %s.", strerror(errno));
388 @@ -477,10 +532,12 @@
391 ERROR("rules parse","Parsing rules failed, switching to dumb mode.");
392 - } else if (!modprobe_command)
394 - if (dumb && !modprobe_command)
398 + * No modprobe command specified, let's autodetect it.
400 + if (!modprobe_command)
402 if (get_modprobe_command()) {
403 ERROR("modprobe_command","Unable to autodetect modprobe command.");
406 modalias = get_hotplug2_value_by_key(tmpevent, "MODALIAS");
407 seqnum = get_hotplug2_value_by_key(tmpevent, "SEQNUM");
410 if (seqnum == NULL) {
411 free_hotplug2_event(tmpevent);
412 ERROR("reading events", "Malformed event read (missing SEQNUM).");
413 @@ -547,13 +604,35 @@
414 if (cur_seqnum > highest_seqnum)
415 highest_seqnum = cur_seqnum;
417 - if (tmpevent->action == ACTION_ADD && (!dumb || modalias != NULL)) {
418 + if ((dumb && tmpevent->action == ACTION_ADD && modalias != NULL) || (!dumb)) {
422 + if (!dumb && override) {
423 + flags = flags_eval(tmpevent, rules);
425 + DBG("flags", "flag returned: %8x", flags);
427 + if (flags == FLAG_ALL)
430 + flags = FLAG_UNSET;
434 * We have more children than we want. Wait until SIGCHLD handler reduces
437 + * Unless, of course, we've specified otherwise and no rules that match
440 - while (child_c >= max_child_c) {
441 - usleep(HOTPLUG2_THROTTLE_INTERVAL);
442 + if (!flags & FLAG_NOTHROTTLE) {
444 + * Okay, throttle away!
446 + while (child_c >= max_child_c) {
447 + usleep(HOTPLUG2_THROTTLE_INTERVAL);
451 sigemptyset(&block_mask);
452 @@ -562,17 +641,15 @@
456 - ERROR("event","fork failed: %s.", strerror(errno));
457 + ERROR("event", "fork failed: %s.", strerror(errno));
460 sigprocmask(SIG_UNBLOCK, &block_mask, 0);
461 signal(SIGCHLD, SIG_DFL);
462 signal(SIGUSR1, SIG_DFL);
465 perform_action(dup_hotplug2_event(tmpevent), rules);
468 perform_dumb_action(dup_hotplug2_event(tmpevent), modalias);
471 @@ -593,12 +670,10 @@
472 signal(SIGINT, SIG_DFL);
473 signal(SIGCHLD, SIG_DFL);
484 diff -urN -x.svn hotplug2-0.9/linux24_compat/hotplug2-modwrap.c hotplug2/linux24_compat/hotplug2-modwrap.c
485 --- hotplug2-0.9/linux24_compat/hotplug2-modwrap.c 2006-09-25 22:23:07.000000000 +0200
486 +++ hotplug2/linux24_compat/hotplug2-modwrap.c 2007-06-28 14:50:59.926947256 +0200
492 + if (strcmp(argv[argc - 1], match_alias) == 0) {
493 + if (execute(argv)) {
494 + ERROR("execute", "Unable to execute: `%s'.", argv[0]);
500 diff -urN -x.svn hotplug2-0.9/linux24_compat/Makefile hotplug2/linux24_compat/Makefile
501 --- hotplug2-0.9/linux24_compat/Makefile 2006-09-26 00:26:46.000000000 +0200
502 +++ hotplug2/linux24_compat/Makefile 2007-06-28 14:50:59.926947256 +0200
505 BINS=generate_alias hotplug2-coldplug-2.4 hotplug2-modwrap
513 - $(INSTALL_BIN) hotplug2-coldplug-2.4 hotplug2-modwrap /sbin/
514 - $(INSTALL_BIN) generate_alias /usr/sbin/
515 + $(INSTALL_BIN) hotplug2-coldplug-2.4 hotplug2-modwrap $(DESTDIR)/sbin/
516 + $(INSTALL_BIN) generate_alias $(DESTDIR)/usr/sbin/
519 hotplug2-coldplug-2.4: hotplug2-coldplug-2.4.o ../parser_utils.o ../filemap_utils.o ../mem_utils.o
520 diff -urN -x.svn hotplug2-0.9/Makefile hotplug2/Makefile
521 --- hotplug2-0.9/Makefile 2006-09-26 01:03:08.000000000 +0200
522 +++ hotplug2/Makefile 2007-06-28 14:51:00.014933880 +0200
525 BINS=hotplug2 hotplug2-dnode
526 SUBDIRS=linux24_compat docs examples
533 - $(INSTALL_BIN) $(BINS) /sbin/
534 + $(INSTALL_BIN) $(BINS) $(DESTDIR)/sbin/
537 hotplug2: hotplug2.o childlist.o mem_utils.o rules.o
538 diff -urN -x.svn hotplug2-0.9/rules.c hotplug2/rules.c
539 --- hotplug2-0.9/rules.c 2006-09-29 22:19:31.000000000 +0200
540 +++ hotplug2/rules.c 2007-06-30 12:44:52.501430000 +0200
545 +static void rmdir_p(char *path) {
548 + path = strdup(path);
550 + while (ptr != NULL) {
551 + ptr = strrchr(path, '/');
563 static char *replace_str(char *hay, char *needle, char *replacement) {
564 char *ptr, *start, *bptr, *buf;
570 -inline int isescaped(char *hay, char *ptr) {
571 +static inline int isescaped(char *hay, char *ptr) {
575 @@ -250,11 +268,30 @@
579 -static int chown_chgrp(int action, char *file, char *param) {
580 +static int chmod_file(struct hotplug2_event_t *event, char *file, char *value) {
583 + file = replace_key_by_value(strdup(file), event);
584 + value = replace_key_by_value(strdup(value), event);
586 + rv = chmod(file, strtoul(value, 0, 8));
594 +static int chown_chgrp(struct hotplug2_event_t *event, int action, char *file, char *param) {
600 + file = replace_key_by_value(strdup(file), event);
601 + param = replace_key_by_value(strdup(param), event);
607 pwd = getpwnam(param);
608 @@ -265,11 +302,23 @@
609 rv = chown(file, -1, grp->gr_gid);
620 +static int print_debug(struct hotplug2_event_t *event) {
623 + for (i = 0; i < event->env_vars_c; i++)
624 + printf("%s=%s\n", event->env_vars[i].key, event->env_vars[i].value);
629 -static int rule_condition_eval(struct hotplug2_event_t *event, struct condition_t *condition) {
630 +int rule_condition_eval(struct hotplug2_event_t *event, struct condition_t *condition) {
632 char *event_value = NULL;
634 @@ -347,11 +396,11 @@
635 last_rv = make_dev_from_event(event, rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
638 - last_rv = chmod(rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
639 + last_rv = chmod_file(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
643 - last_rv = chown_chgrp(rule->actions[i].type, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
644 + last_rv = chown_chgrp(event, rule->actions[i].type, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
647 last_rv = make_symlink(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
650 last_rv = setenv(rule->actions[i].parameter[0], rule->actions[i].parameter[1], 1);
653 + last_rv = unlink(rule->actions[i].parameter[0]);
654 + rmdir_p(rule->actions[i].parameter[0]);
657 + last_rv = print_debug(event);
665 +int rule_flags(struct hotplug2_event_t *event, struct rule_t *rule) {
668 + for (i = 0; i < rule->actions_c; i++) {
669 + switch (rule->actions[i].type) {
670 + case ACT_FLAG_NOTHROTTLE:
671 + rule->flags |= FLAG_NOTHROTTLE;
677 {"chmod", 2, ACT_CHMOD},
678 {"chgrp", 2, ACT_CHGRP},
679 {"setenv", 2, ACT_SETENV},
680 + {"remove", 1, ACT_REMOVE},
681 + {"nothrottle", 0, ACT_FLAG_NOTHROTTLE},
682 + {"printdebug", 0, ACT_DEBUG},
684 {"symlink", 2, ACT_SYMLINK},
685 {"softlink", 2, ACT_SYMLINK},
686 diff -urN -x.svn hotplug2-0.9/rules.h hotplug2/rules.h
687 --- hotplug2-0.9/rules.h 2006-09-25 13:42:22.000000000 +0200
688 +++ hotplug2/rules.h 2007-06-30 12:44:52.501430000 +0200
690 #define ACT_CHGRP 6 /* chgrp <...> */
691 #define ACT_CHOWN 7 /* chown <...> */
692 #define ACT_SYMLINK 8 /* symlink <...> */
693 -#define ACT_NEXT_EVENT 9 /* next */
694 +#define ACT_NEXT_EVENT 9 /* next */
695 #define ACT_NEXT_IF_FAILED 10 /* next_if_failed */
696 #define ACT_SETENV 11 /* setenv <...> */
697 +#define ACT_REMOVE 12 /* remove <...> */
698 +#define ACT_DEBUG 13 /* debug */
699 +#define ACT_FLAG_NOTHROTTLE 14 /* sets 'nothrottle' flag */
702 #define EVAL_NOT_MATCH 0
704 #define STATUS_INITIATOR 3 /* ',' for next cond, '{' for block*/
705 #define STATUS_ACTION 4 /* viz ACT_* and '}' for end of block */
707 +#define FLAG_UNSET 0
708 +#define FLAG_ALL 0xffffffff
709 +#define FLAG_NOTHROTTLE 1 /* We want this rule to ignore max_children limit */
717 struct action_t *actions;
728 +int rule_condition_eval(struct hotplug2_event_t *, struct condition_t *);
729 int rule_execute(struct hotplug2_event_t *, struct rule_t *);
730 +int rule_flags(struct hotplug2_event_t *, struct rule_t *);
731 void rules_free(struct rules_t *);
732 struct rules_t *rules_from_config(char *);
734 diff -urN -x.svn hotplug2-0.9/TODO hotplug2/TODO
735 --- hotplug2-0.9/TODO 1970-01-01 01:00:00.000000000 +0100
736 +++ hotplug2/TODO 2007-06-28 14:51:00.012934184 +0200
738 + - live rules update (via inotify)