[klibc] klibc insmod for recent kernels

Rusty Russell rusty@rustcorp.com.au
Sat, 04 Jan 2003 17:01:06 +1100


In message <3E15E927.4060007@zytor.com> you write:
> Arnd Bergmann wrote:
> > On Wednesday 25 December 2002 22:29, H. Peter Anvin wrote:
> > 
> > 
> >>That's not necessarily true.  Remember that an initramfs can be
> >>synthetically constructed, and it should be possible to inject a new
> >>driver at boot time, which may need to have dependencies resolved.
> > 
> > 
> > Right. So we actually need the full set of module-init-tools (or a fork
> > of them) to compile against klibc.
> > 
> > The attached patch against module-init-tools-0.9.7 gets us somewhat closer 
> > there. It removes the need for the 'index' and 'syscall' functions,
> > replacing them with 'strchr' and '_syscall#', which are part of 
> > klibc.
> > I also added another Makefile because klibc's MCONFIG does not
> > work well with automake.
> > 
> > The other patch adds the functions system, strerror, fgetc and fgets
> > to klibc. This might not be a good idea, since the fgets implementation
> > is about as slow as it gets and someone might be tempted to use it,
> > but it does the job for module-init-tools.
> > 
> 
> Not a good idea is probably a good way to sum it up, especially for 
> system().  Why on earth does module-init-tools need system()?  Requiring 
> a shell to install modules seems, ahem, daft?

No.  You can insert arbitary commands in the /etc/modprobe.conf (as
you could in /etc/modules.conf), which it executes in place of
inserting the module.

Do you want a config file at all for this?  Probably not.  Something
simple like the following (untested, but you get the idea) is probably
what you want.  Adjust to suit... this would be easier in a scripting
language, of course.

/* Dumb as dust modprobe.  Usage: modprobe modulename modules.dep */
static void *read_in(const char *filename, unsigned long *len)
{
	void *ret;
	unsigned long done = 0;
	int r, fd;
	struct stat statbuf;

	fd = open(filename, O_RDONLY);
	if (fstat(fd, &statbuf) < 0)
		exit(1);
	*len = statbuf.st_size;
	ret = malloc(*len + 1);
	
	while (done < *len) {
		r = read(fd, ret + done, *len - done);
		if (r <= 0)
			exit(1);
		done += r;
	}
	ret[*len] = '\0';
	return ret;
}

/* Insert in reverse order. */
static void insmod(const char *files)
{
	char *sep, *module;
	unsigned long len;

	if (!files)
		return;

	/* Swallow leading spaces */
	while (files[0] == ' ')
		files++;
	
	sep = strchr(files, ' ');
	insmod(sep);
	*sep = '\0';

	module = read_in(files, &len);
	if (syscall(__NR_init_module, module, len, "") != 0)
		exit(1);
	free(module);
}

int main(int argc, char *argv[])
{
	char *deps, *ptr;
	unsigned long len;
	
	deps = read_in(argv[2], &len);

	for (ptr = strstr(deps, argv[1]); ptr; ptr = strstr(ptr+1, argv[1])) {
		if (ptr != deps && ptr[-1] != '/' && ptr[-1] != '\n')
			continue;
		if (ptr[strlen(argv[1])] != ':')
			continue;
		break;
	}
	if (!ptr)
		exit(1);

	/* Turn into one-line list of modules. */
	*strchr(ptr, ':') = ' ';
	deps = ptr;
	ptr = strchr(deps, '\n');
	if (ptr)
		*ptr = '\0';
	insmod(deps);
}
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.