[PATCH] support for modprobe.d

Natanael Copa natanael.copa at gmail.com
Wed Jul 9 15:01:06 UTC 2008


hi,

attatched is a patch from Timo Teräs that adds support for modprobe.d

seems like it increase size on my hardened gcc-3.4.6 uclibc setup but
reduce size on glibc + gcc-4.2.3

includes a compilation fix for mtab

-nc

-------------- next part --------------
Index: modutils/modprobe.c
===================================================================
--- modutils/modprobe.c	(revision 22700)
+++ modutils/modprobe.c	(working copy)
@@ -48,6 +48,10 @@
 	struct mod_list_t * m_next;
 };
 
+struct include_conf_t {
+	struct dep_t *first;
+	struct dep_t *current;
+};
 
 static struct dep_t *depend;
 
@@ -242,21 +246,60 @@
  * This function reads aliases and default module options from a configuration file
  * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
  */
-static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd)
+
+static int FAST_FUNC include_conf_file_act(const char *filename,
+					   struct stat *statbuf UNUSED_PARAM,
+					   void *userdata,
+					   int depth UNUSED_PARAM);
+
+static int FAST_FUNC include_conf_dir_act(const char *filename UNUSED_PARAM,
+					  struct stat *statbuf UNUSED_PARAM,
+					  void *userdata UNUSED_PARAM,
+					  int depth)
 {
+	if (depth > 1)
+		return SKIP;
+
+	return TRUE;
+}
+
+static int inline include_conf_recursive(struct include_conf_t *conf, const char *filename)
+{
+	return recursive_action(filename, ACTION_RECURSE,
+				include_conf_file_act,
+				include_conf_dir_act,
+				conf, 1);
+}
+
+static int FAST_FUNC include_conf_file_act(const char *filename,
+					   struct stat *statbuf UNUSED_PARAM,
+					   void *userdata,
+					   int depth UNUSED_PARAM)
+{
+	struct include_conf_t *conf = (struct include_conf_t *) userdata;
+	struct dep_t **first = &conf->first;
+	struct dep_t **current = &conf->current;
 	int continuation_line = 0;
+	int fd;
 
+	if (bb_basename(filename)[0] == '.')
+		return TRUE;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		return FALSE;
+
 	// alias parsing is not 100% correct (no correct handling of continuation lines within an alias)!
 
-	while (reads(fd, buffer, buflen)) {
+	while (reads(fd, line_buffer, sizeof(line_buffer))) {
 		int l;
 
-		*strchrnul(buffer, '#') = '\0';
+		*strchrnul(line_buffer, '#') = '\0';
 
-		l = strlen(buffer);
+		l = strlen(line_buffer);
 
-		while (l && isspace(buffer[l-1])) {
-			buffer[l-1] = '\0';
+		while (l && isspace(line_buffer[l-1])) {
+			line_buffer[l-1] = '\0';
 			l--;
 		}
 
@@ -268,10 +311,10 @@
 		if (continuation_line)
 			continue;
 
-		if (is_conf_command(buffer, "alias")) {
+		if (is_conf_command(line_buffer, "alias")) {
 			char *alias, *mod;
 
-			if (parse_tag_value(buffer + 6, &alias, &mod)) {
+			if (parse_tag_value(line_buffer + 6, &alias, &mod)) {
 				/* handle alias as a module dependent on the aliased module */
 				if (!*current) {
 					(*first) = (*current) = xzalloc(sizeof(struct dep_t));
@@ -292,11 +335,11 @@
 				}
 				/*(*current)->m_next = NULL; - done by xzalloc */
 			}
-		} else if (is_conf_command(buffer, "options")) {
+		} else if (is_conf_command(line_buffer, "options")) {
 			char *mod, *opt;
 
 			/* split the line in the module/alias name, and options */
-			if (parse_tag_value(buffer + 8, &mod, &opt)) {
+			if (parse_tag_value(line_buffer + 8, &mod, &opt)) {
 				struct dep_t *dt;
 
 				/* find the corresponding module */
@@ -315,22 +358,17 @@
 					}
 				}
 			}
-		} else if (is_conf_command(buffer, "include")) {
-			int fdi;
-			char *filename;
+		} else if (is_conf_command(line_buffer, "include")) {
+			char *includefile;
 
-			filename = skip_whitespace(buffer + 8);
-			fdi = open(filename, O_RDONLY);
-			if (fdi >= 0) {
-				include_conf(first, current, buffer, buflen, fdi);
-				close(fdi);
-			}
+			includefile = skip_whitespace(line_buffer + 8);
+			include_conf_recursive(conf, includefile);
 		} else if (ENABLE_FEATURE_MODPROBE_BLACKLIST &&
-				(is_conf_command(buffer, "blacklist"))) {
+				(is_conf_command(line_buffer, "blacklist"))) {
 			char *mod;
 			struct dep_t *dt;
 
-			mod = skip_whitespace(buffer + 10);
+			mod = skip_whitespace(line_buffer + 10);
 			for (dt = *first; dt; dt = dt->m_next) {
 				if (strcmp(dt->m_name, mod) == 0)
 					break;
@@ -339,8 +377,25 @@
 				dt->m_isblacklisted = 1;
 		}
 	} /* while (reads(...)) */
+
+	close(fd);
+	return TRUE;
 }
 
+static int include_conf_file(struct include_conf_t *conf,
+			     const char *filename)
+{
+	return include_conf_file_act(filename, NULL, conf, 0);
+}
+
+static int include_conf_file2(struct include_conf_t *conf,
+			      const char *filename, const char *oldname)
+{
+	if (include_conf_file(conf, filename) == TRUE)
+		return TRUE;
+	return include_conf_file(conf, oldname);
+}
+
 /*
  * This function builds a list of dependency rules from /lib/modules/`uname -r`/modules.dep.
  * It then fills every modules and aliases with their default options, found by parsing
@@ -350,8 +405,7 @@
 {
 	int fd;
 	struct utsname un;
-	struct dep_t *first = NULL;
-	struct dep_t *current = NULL;
+	struct include_conf_t conf = { NULL, NULL };
 	char *filename;
 	int continuation_line = 0;
 	int k_version;
@@ -421,14 +475,14 @@
 				mod = xstrndup(mods, dot - mods);
 
 				/* enqueue new module */
-				if (!current) {
-					first = current = xzalloc(sizeof(struct dep_t));
+				if (!conf.current) {
+					conf.first = conf.current = xzalloc(sizeof(struct dep_t));
 				} else {
-					current->m_next = xzalloc(sizeof(struct dep_t));
-					current = current->m_next;
+					conf.current->m_next = xzalloc(sizeof(struct dep_t));
+					conf.current = conf.current->m_next;
 				}
-				current->m_name = mod;
-				current->m_path = xstrdup(modpath);
+				conf.current->m_name = mod;
+				conf.current->m_path = xstrdup(modpath);
 				/*current->m_options = NULL; - xzalloc did it*/
 				/*current->m_isalias = 0;*/
 				/*current->m_depcnt = 0;*/
@@ -482,8 +536,8 @@
 				dep = xstrndup(deps, next - deps - ext + 1);
 
 				/* Add the new dependable module name */
-				current->m_deparr = xrealloc_vector(current->m_deparr, 2, current->m_depcnt);
-				current->m_deparr[current->m_depcnt++] = dep;
+				conf.current->m_deparr = xrealloc_vector(conf.current->m_deparr, 2, conf.current->m_depcnt);
+				conf.current->m_deparr[conf.current->m_depcnt++] = dep;
 
 				p = next + 2;
 			} while (next < end);
@@ -500,52 +554,41 @@
 	 * >=2.6: we only care about modprobe.conf
 	 * <=2.4: we care about modules.conf and conf.modules
 	 */
-	if (ENABLE_FEATURE_2_6_MODULES
-	 && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0)
-		if (ENABLE_FEATURE_2_4_MODULES
-		 && (fd = open("/etc/modules.conf", O_RDONLY)) < 0)
-			if (ENABLE_FEATURE_2_4_MODULES)
-				fd = open("/etc/conf.modules", O_RDONLY);
+	{
+		int r = FALSE;
 
-	if (fd >= 0) {
-		include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
-		close(fd);
+		if (ENABLE_FEATURE_2_6_MODULES) {
+			if (include_conf_file(&conf, "/etc/modprobe.conf"))
+				r = TRUE;
+			if (include_conf_recursive(&conf, "/etc/modprobe.d"))
+				r = TRUE;
+		}
+		if (ENABLE_FEATURE_2_4_MODULES && !r)
+			include_conf_file2(&conf,
+					   "/etc/modules.conf",
+					   "/etc/conf.modules");
 	}
 
 	/* Only 2.6 has a modules.alias file */
 	if (ENABLE_FEATURE_2_6_MODULES) {
 		/* Parse kernel-declared module aliases */
 		filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release);
-		fd = open(filename, O_RDONLY);
-		if (fd < 0) {
-			/* Ok, that didn't work.  Fall back to looking in /lib/modules */
-			fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.alias", O_RDONLY);
-		}
+		include_conf_file2(&conf,
+				   filename,
+				   CONFIG_DEFAULT_MODULES_DIR"/modules.alias");
 		if (ENABLE_FEATURE_CLEAN_UP)
 			free(filename);
 
-		if (fd >= 0) {
-			include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
-			close(fd);
-		}
-
 		/* Parse kernel-declared symbol aliases */
 		filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release);
-		fd = open(filename, O_RDONLY);
-		if (fd < 0) {
-			/* Ok, that didn't work.  Fall back to looking in /lib/modules */
-			fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.symbols", O_RDONLY);
-		}
+		include_conf_file2(&conf,
+				   filename,
+				   CONFIG_DEFAULT_MODULES_DIR"/modules.symbols");
 		if (ENABLE_FEATURE_CLEAN_UP)
 			free(filename);
-
-		if (fd >= 0) {
-			include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
-			close(fd);
-		}
 	}
 
-	return first;
+	return conf.first;
 }
 
 /* return 1 = loaded, 0 = not loaded, -1 = can't tell */
Index: modutils/insmod.c
===================================================================
--- modutils/insmod.c	(revision 22700)
+++ modutils/insmod.c	(working copy)
@@ -3082,7 +3082,7 @@
 		if (i == f->header.e_shnum) {
 			struct obj_section *sec;
 
-			f->sections = xrealloc(f->sections, 2, i);
+			f->sections = xrealloc_vector(f->sections, 2, i);
 			f->sections[i] = sec = arch_new_section();
 			f->header.e_shnum = i + 1;
 
Index: coreutils/install.c
===================================================================
--- coreutils/install.c	(revision 22700)
+++ coreutils/install.c	(working copy)
@@ -20,6 +20,7 @@
 	"group\0"               No_argument       "g"
 	"mode\0"                No_argument       "m"
 	"owner\0"               No_argument       "o"
+	"\0"                    No_argument       "D"
 /* autofs build insists of using -b --suffix=.orig */
 /* TODO? (short option for --suffix is -S) */
 #if ENABLE_SELINUX
@@ -63,6 +64,36 @@
 
 #endif
 
+static int create_dirs_with_owner(char *path, int mode, int setowner, int uid, int gid, int skiplast)
+{
+	int ret = 0;
+	char *slash = path;
+	while (1) {
+		slash = strchr(slash + 1, '/');
+		if (slash) {
+			*slash = '\0';
+		} else if (skiplast) {
+			break;
+		}
+		if (mkdir(path, mode | 0111) == -1) {
+			if (errno != EEXIST) {
+				bb_perror_msg("cannot create %s", path);
+				ret = EXIT_FAILURE;
+				break;
+			}
+		} /* dir was created, chown? */
+		else if (setowner && lchown(path, uid, gid) == -1) {
+			bb_perror_msg("cannot change ownership of %s", path);
+			ret = EXIT_FAILURE;
+			break;
+		}
+		if (!slash)
+			break;
+		*slash = '/';
+	}
+	return ret;
+}
+
 int install_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int install_main(int argc, char **argv)
 {
@@ -92,9 +123,10 @@
 		OPT_GROUP         = 1 << 6,
 		OPT_MODE          = 1 << 7,
 		OPT_OWNER         = 1 << 8,
+		OPT_MKDIRDEST	  = 1 << 9,
 #if ENABLE_SELINUX
-		OPT_SET_SECURITY_CONTEXT = 1 << 9,
-		OPT_PRESERVE_SECURITY_CONTEXT = 1 << 10,
+		OPT_SET_SECURITY_CONTEXT = 1 << 10,
+		OPT_PRESERVE_SECURITY_CONTEXT = 1 << 11,
 #endif
 	};
 
@@ -105,7 +137,7 @@
 	/* -c exists for backwards compatibility, it's needed */
 	/* -v is ignored ("print name of each created directory") */
 	/* -b is ignored ("make a backup of each existing destination file") */
-	flags = getopt32(argv, "cvb" "dpsg:m:o:" USE_SELINUX("Z:"),
+	flags = getopt32(argv, "cvb" "dpsg:m:o:D" USE_SELINUX("Z:"),
 			&gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext));
 	argc -= optind;
 	argv += optind;
@@ -142,29 +174,10 @@
 	 */
 	if (flags & OPT_DIRECTORY) {
 		while ((arg = *argv++) != NULL) {
-			char *slash = arg;
-			while (1) {
-				slash = strchr(slash + 1, '/');
-				if (slash)
-					*slash = '\0';
-				if (mkdir(arg, mode | 0111) == -1) {
-					if (errno != EEXIST) {
-						bb_perror_msg("cannot create %s", arg);
-						ret = EXIT_FAILURE;
-						break;
-					}
-				} /* dir was created, chown? */
-				else if ((flags & (OPT_OWNER|OPT_GROUP))
-				 && lchown(arg, uid, gid) == -1
-				) {
-					bb_perror_msg("cannot change ownership of %s", arg);
-					ret = EXIT_FAILURE;
-					break;
-				}
-				if (!slash)
-					break;
-				*slash = '/';
-			}
+			int status = create_dirs_with_owner(arg, mode, 
+				flags & (OPT_OWNER|OPT_GROUP), uid, gid, 0);
+			if (status)
+				ret = status;
 		}
 		return ret;
 	}
@@ -181,6 +194,9 @@
 		char *dest = last;
 		if (isdir)
 			dest = concat_path_file(last, basename(arg));
+		if (flags & OPT_MKDIRDEST)
+			create_dirs_with_owner(dest, mode, 
+				flags & (OPT_OWNER|OPT_GROUP), uid, gid, 1);
 		if (copy_file(arg, dest, copy_flags)) {
 			/* copy is not made */
 			ret = EXIT_FAILURE;
Index: libbb/mtab.c
===================================================================
--- libbb/mtab.c	(revision 22700)
+++ libbb/mtab.c	(working copy)
@@ -27,7 +27,7 @@
 	}
 
 	while ((m = getmntent(mountTable)) != 0) {
-		entries = xrealloc(entries, 3, count);
+		entries = xrealloc_vector(entries, 3, count);
 		entries[count].mnt_fsname = xstrdup(m->mnt_fsname);
 		entries[count].mnt_dir = xstrdup(m->mnt_dir);
 		entries[count].mnt_type = xstrdup(m->mnt_type);


More information about the busybox mailing list