On Wed, 2007-05-02 at 02:38 +0200, Denis Vlasenko wrote: 
> On Tuesday 01 May 2007 02:27, Nathan Angelacos wrote:
> > Hello,
> > 
> > The ifupdown applet in 1.5.0 appears to have a bug that was not present
> > in 1.4.1.  The bug is that /var/run/ifstate is not updated with all
> > interfaces if an interface stanza calls ifup statement to bring up a
> > second interface.
... 
> You can attempt to go after these solutions:
> 
> (a) provide a patch for ifupdown to read/write
>     /var/run/ifstate AFTER child if done.


Attatched.

The patch also removes this dead code (and memory leak):
-                       /* iface_down */
-                       const llist_t *list = state_list;
-                       while (list) {
-                               llist_add_to_end(&target_list, 
xstrdup(list->data));
-                               list = list->link;
-                       }
-                       target_list = defn->autointerfaces;

(first copy state_list to target_list and next second just reassign
target_list???)

It would be nice if patch could go into 1.5.1.

Thanks!

Natanael Copa
--- 1.5.0.orig/networking/ifupdown.c	2007-04-03 08:05:26 +0000
+++ 1.5.0/networking/ifupdown.c	2007-05-02 12:04:19 +0000
@@ -1083,15 +1083,32 @@
 	return NULL;
 }
 
+/* read the previous state from the state file */
+static llist_t *read_iface_state(void) {
+	llist_t *state_list = NULL;
+	FILE *state_fp;
+	state_fp = fopen("/var/run/ifstate", "r");
+	if (state_fp) {
+		char *start, *end_ptr;
+		while ((start = xmalloc_fgets(state_fp)) != NULL) {
+			/* We should only need to check for a single character */
+			end_ptr = start + strcspn(start, " \t\n");
+			*end_ptr = '\0';
+			llist_add_to(&state_list, start);
+		}
+		fclose(state_fp);
+	}
+	return state_list;
+}
+
+
 int ifupdown_main(int argc, char **argv);
 int ifupdown_main(int argc, char **argv)
 {
 	int (*cmds)(struct interface_defn_t *) = NULL;
 	struct interfaces_file_t *defn;
-	llist_t *state_list = NULL;
 	llist_t *target_list = NULL;
 	const char *interfaces = "/etc/network/interfaces";
-	FILE *state_fp;
 	bool any_failures = 0;
 
 	cmds = iface_down;
@@ -1118,32 +1135,9 @@
 	startup_PATH = getenv("PATH");
 	if (!startup_PATH) startup_PATH = "";
 
-	/* Read the previous state from the state file */
-	state_fp = fopen("/var/run/ifstate", "r");
-	if (state_fp) {
-		char *start, *end_ptr;
-		while ((start = xmalloc_fgets(state_fp)) != NULL) {
-			/* We should only need to check for a single character */
-			end_ptr = start + strcspn(start, " \t\n");
-			*end_ptr = '\0';
-			llist_add_to(&state_list, start);
-		}
-		fclose(state_fp);
-	}
-
 	/* Create a list of interfaces to work on */
 	if (DO_ALL) {
-		if (cmds == iface_up) {
-			target_list = defn->autointerfaces;
-		} else {
-			/* iface_down */
-			const llist_t *list = state_list;
-			while (list) {
-				llist_add_to_end(&target_list, xstrdup(list->data));
-				list = list->link;
-			}
-			target_list = defn->autointerfaces;
-		}
+		target_list = defn->autointerfaces;
 	} else {
 		llist_add_to_end(&target_list, argv[optind]);
 	}
@@ -1170,6 +1164,7 @@
 		}
 
 		if (!FORCE) {
+			llist_t *state_list = read_iface_state();
 			const llist_t *iface_state = find_iface_state(state_list, iface);
 
 			if (cmds == iface_up) {
@@ -1185,6 +1180,7 @@
 					continue;
 				}
 			}
+			llist_free(state_list, free);
 		}
 
 #if ENABLE_FEATURE_IFUPDOWN_MAPPING
@@ -1239,6 +1235,8 @@
 			bb_error_msg("ignoring unknown interface %s", liface);
 			any_failures = 1;
 		} else {
+			/* update the state file */
+			llist_t *state_list = read_iface_state();
 			llist_t *iface_state = find_iface_state(state_list, iface);
 
 			if (cmds == iface_up) {
@@ -1254,19 +1252,21 @@
 				llist_unlink(&state_list, iface_state);
 				free(llist_pop(&iface_state));
 			}
-		}
-	}
 
-	/* Actually write the new state */
-	if (!NO_ACT) {
-		state_fp = xfopen("/var/run/ifstate", "w");
-		while (state_list) {
-			if (state_list->data) {
-				fprintf(state_fp, "%s\n", state_list->data);
+			/* Actually write the new state */
+			if (!NO_ACT) {
+				FILE *state_fp = xfopen("/var/run/ifstate", "w");
+				llist_t *state = state_list;
+				while (state) {
+					if (state->data) {
+						fprintf(state_fp, "%s\n", state->data);
+					}
+					state = state->link;
+				}
+				fclose(state_fp);
 			}
-			state_list = state_list->link;
+			llist_free(state_list, free);
 		}
-		fclose(state_fp);
 	}
 
 	return any_failures;
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to