svn commit: trunk/busybox/networking

vda at busybox.net vda at busybox.net
Wed May 2 21:38:45 UTC 2007


Author: vda
Date: 2007-05-02 14:38:44 -0700 (Wed, 02 May 2007)
New Revision: 18541

Log:
ifupdown: reread state file before rewriting it.
Fixes "ifup started another ifup" state corruption bug.
Patch by Natanael Copa <natanael.copa at gmail.com>.



Modified:
   trunk/busybox/networking/ifupdown.c


Changeset:
Modified: trunk/busybox/networking/ifupdown.c
===================================================================
--- trunk/busybox/networking/ifupdown.c	2007-05-02 18:20:58 UTC (rev 18540)
+++ trunk/busybox/networking/ifupdown.c	2007-05-02 21:38:44 UTC (rev 18541)
@@ -1083,15 +1083,33 @@
 	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 = 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 +1136,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 +1165,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 +1181,7 @@
 					continue;
 				}
 			}
+			llist_free(state_list, free);
 		}
 
 #if ENABLE_FEATURE_IFUPDOWN_MAPPING
@@ -1239,6 +1236,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 +1253,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;




More information about the busybox-cvs mailing list