[klibc] klibc insmod for recent kernels
H. Peter Anvin
hpa@zytor.com
Fri, 03 Jan 2003 23:02:47 -0800
Rusty Russell wrote:
>>
>>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.
Sure, but why spawn /bin/sh to do it? It seems doing it internally
would be both cleaner and faster.
> 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.
Probably not, in this application. The kind of things you have below is
more like it. (klibc doesn't use syscall(nr, ...) -- you just name the
syscall; if it conflicts with a C library function with different
semantics add __ in front.)
-hpa
> /* 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.