NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/38694: module dependencies do not work as expected



How does this look?


Index: subr_kobj.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_kobj.c,v
retrieving revision 1.18
diff -u -r1.18 subr_kobj.c
--- subr_kobj.c 20 May 2008 13:34:44 -0000      1.18
+++ subr_kobj.c 20 May 2008 14:11:04 -0000
@@ -150,9 +150,10 @@
 static void    kobj_free(kobj_t, void *, size_t);
 static void    kobj_close(kobj_t);
 static int     kobj_load(kobj_t);
+static int     kobj_find_module(const char *, struct nameidata *);
 
 extern struct vm_map *lkm_map;
-static const char      *kobj_path = "/modules";        /* XXX ??? */
+static const char      *kobj_path = "/kernel/modules"; /* XXX ??? */
 
 /*
  * kobj_load_file:
@@ -164,9 +165,8 @@
 {
        struct nameidata nd;
        kauth_cred_t cred;
-       char *path;
-       int error;
        kobj_t ko;
+       int error;
 
        cred = kauth_cred_get();
 
@@ -175,31 +175,8 @@
                return ENOMEM;
        }
 
-       /* XXX where to look? */
-       NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename);
-       error = vn_open(&nd, FREAD, 0);
+       error = kobj_find_module(filename, &nd);
        if (error != 0) {
-               if (error != ENOENT) {
-                       goto out;
-               }
-               path = PNBUF_GET();
-               snprintf(path, MAXPATHLEN - 1, "%s/%s", kobj_path,
-                   filename);
-               NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
-               error = vn_open(&nd, FREAD, 0);
-               if (error != 0) {
-                       strlcat(path, ".o", MAXPATHLEN);
-                       NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
-                       error = vn_open(&nd, FREAD, 0);
-               }
-               PNBUF_PUT(path);
-               if (error != 0) {
-                       goto out;
-               }
-       }
-
- out:
-       if (error != 0) {
                kmem_free(ko, sizeof(*ko));
                return error;
        }
@@ -1102,6 +1079,63 @@
                kmem_free(base, size);
 }
 
+/*
+ * kobj_find_module:
+ *
+ *     Utility function: find kobj for module name in the file system.
+ */
+static int
+kobj_find_module(const char *name, struct nameidata *pnd)
+{
+       char *path;
+       int error;
+
+       if (name == NULL)
+               return EINVAL;
+
+       /* Try absolute pathname first */
+       NDINIT(pnd, LOOKUP, FOLLOW, UIO_SYSSPACE, name);
+       error = vn_open(pnd, FREAD, 0);
+       if (!error)
+               return 0;
+       if (error != ENOENT)
+               return error;
+
+       /* Search will probably fail if this is an absolute path */
+       if (*name == '/')
+               return error;
+
+       /* Next try kobj_path/name/name.kmod */
+       path = PNBUF_GET();
+       snprintf(path, MAXPATHLEN - 1, "%s/%s/%s.kmod", kobj_path, name, name);
+       NDINIT(pnd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
+       error = vn_open(pnd, FREAD, 0);
+       PNBUF_PUT(path);
+       if (!error)
+               return 0;
+
+       /* Now try kobj_path/name */
+       path = PNBUF_GET();
+       snprintf(path, MAXPATHLEN - 1, "%s/%s", kobj_path, name);
+       NDINIT(pnd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
+       error = vn_open(pnd, FREAD, 0);
+       PNBUF_PUT(path);
+       if (!error)
+               return 0;
+
+       /* Finally try kobj_path/name.kmod */
+       path = PNBUF_GET();
+       snprintf(path, MAXPATHLEN - 1, "%s/%s.kmod", kobj_path, name);
+       NDINIT(pnd, LOOKUP, FOLLOW, UIO_SYSSPACE, path);
+       error = vn_open(pnd, FREAD, 0);
+       PNBUF_PUT(path);
+       if (!error)
+               return 0;
+
+       /* Not found */
+       return ENOENT;
+}
+
 #else  /* MODULAR */
 
 int


Home | Main Index | Thread Index | Old Index