Source-Changes-HG archive

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

[src/trunk]: src/sys/rump/librump/rumpvfs Autogenerate /dev nodes. Use (recr...



details:   https://anonhg.NetBSD.org/src/rev/55ca4bb9dbb9
branches:  trunk
changeset: 754453:55ca4bb9dbb9
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Apr 30 21:02:36 2010 +0000

description:
Autogenerate /dev nodes.  Use (recreate) the naming policy in
MAKEDEV. -- Not the famous irrational file system devfs, but an
incredible simulation.

diffstat:

 sys/rump/librump/rumpvfs/devnodes.c         |  151 +++++++++++++++++++++++++++-
 sys/rump/librump/rumpvfs/rump_vfs.c         |    9 +-
 sys/rump/librump/rumpvfs/rump_vfs_private.h |    4 +-
 3 files changed, 156 insertions(+), 8 deletions(-)

diffs (259 lines):

diff -r c642bba2b1d3 -r 55ca4bb9dbb9 sys/rump/librump/rumpvfs/devnodes.c
--- a/sys/rump/librump/rumpvfs/devnodes.c       Fri Apr 30 20:54:17 2010 +0000
+++ b/sys/rump/librump/rumpvfs/devnodes.c       Fri Apr 30 21:02:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: devnodes.c,v 1.4 2009/12/17 00:29:46 pooka Exp $       */
+/*     $NetBSD: devnodes.c,v 1.5 2010/04/30 21:02:36 pooka Exp $       */
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -26,13 +26,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: devnodes.c,v 1.4 2009/12/17 00:29:46 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: devnodes.c,v 1.5 2010/04/30 21:02:36 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/filedesc.h>
 #include <sys/kmem.h>
 #include <sys/lwp.h>
+#include <sys/namei.h>
 #include <sys/stat.h>
 #include <sys/vfs_syscalls.h>
 
@@ -44,9 +45,14 @@
        devmajor_t majnum, devminor_t minnum)
 {
        register_t retval;
+       int error;
 
-       return do_sys_mknod(curlwp, devname, 0666 | devtype,
+       error = do_sys_mknod(curlwp, devname, 0666 | devtype,
            makedev(majnum, minnum), &retval, UIO_SYSSPACE);
+       if (error == EEXIST) /* XXX: should check it's actually the same */
+               error = 0;
+
+       return 0;
 }
 
 int
@@ -68,11 +74,146 @@
                *p = minchar;
 
                if ((error = do_sys_mknod(curlwp, devname, 0666 | devtype,
-                   makedev(maj, minnum), &retval, UIO_SYSSPACE)))
-                       goto out;
+                   makedev(maj, minnum), &retval, UIO_SYSSPACE))) {
+                       if (error == EEXIST)
+                               error = 0;
+                       else
+                               goto out;
+               }
        }
 
  out:
        kmem_free(devname, devlen);
        return error;
 }
+
+enum { NOTEXIST, SAME, DIFFERENT };
+static int
+doesitexist(const char *path, bool isblk, devmajor_t dmaj, devminor_t dmin)
+{
+       struct stat sb;
+       int error;
+
+       error = do_sys_stat(path, 0, &sb);
+       /* even if not ENOENT, we might be able to create it */
+       if (error)
+               return NOTEXIST;
+
+       if (major(sb.st_rdev) != dmaj || minor(sb.st_rdev) != dmin)
+               return DIFFERENT;
+       if (isblk && !S_ISBLK(sb.st_mode))
+               return DIFFERENT;
+       if (!isblk && !S_ISCHR(sb.st_mode))
+               return DIFFERENT;
+
+       return SAME;
+}
+
+static void
+makeonenode(char *buf, devmajor_t blk, devmajor_t chr, devminor_t dmin,
+       const char *base, int c1, int c2)
+{
+       char cstr1[2] = {0,0}, cstr2[2] = {0,0};
+       register_t rv;
+       int error;
+
+       if (c1 != -1) {
+               cstr1[0] = '0' + c1;
+               cstr1[1] = '\0';
+       }
+
+       if (c2 != -1) {
+               cstr2[0] = 'a' + c2;
+               cstr2[1] = '\0';
+
+       }
+
+       /* block device */
+       snprintf(buf, MAXPATHLEN, "/dev/%s%s%s", base, cstr1, cstr2);
+       if (blk != NODEV) {
+               switch (doesitexist(buf, true, blk, dmin)) {
+               case DIFFERENT:
+                       aprint_verbose("mkdevnodes: block device %s "
+                           "already exists\n", buf);
+                       break;
+               case NOTEXIST:
+                       if ((error = do_sys_mknod(curlwp, buf, 0600 | S_IFBLK,
+                           makedev(blk, dmin), &rv, UIO_SYSSPACE)) != 0)
+                               aprint_verbose("mkdevnodes: failed to "
+                                   "create %s: %d\n", buf, error);
+                       break;
+               case SAME:
+                       /* done */
+                       break;
+               }
+               sprintf(buf, "/dev/r%s%s%s", base, cstr1, cstr2);
+       }
+
+       switch (doesitexist(buf, true, chr, dmin)) {
+       case DIFFERENT:
+               aprint_verbose("mkdevnodes: character device %s "
+                   "already exists\n", buf);
+               break;
+       case NOTEXIST:
+               if ((error = do_sys_mknod(curlwp, buf, 0600 | S_IFCHR,
+                   makedev(chr, dmin), &rv, UIO_SYSSPACE)) != 0)
+                       aprint_verbose("mkdevnodes: failed to "
+                           "create %s: %d\n", buf, error);
+               break;
+       case SAME:
+               /* yeehaa */
+               break;
+       }
+}
+
+void
+rump_vfs_builddevs(struct devsw_conv *dcvec, size_t dcvecsize)
+{
+       char *pnbuf = PNBUF_GET();
+       struct devsw_conv *dc;
+       size_t i;
+       int v1, v2;
+
+       for (i = 0; i < dcvecsize; i++) {
+               dc = &dcvec[i];
+
+               switch (dc->d_class) {
+               case DEVNODE_DONTBOTHER:
+                       break;
+               case DEVNODE_SINGLE:
+                       makeonenode(pnbuf,
+                           dc->d_bmajor, dc->d_cmajor, 0, dc->d_name, -1, -1);
+                       break;
+               case DEVNODE_VECTOR:
+                       for (v1 = 0; v1 < dc->d_vectdim[0]; v1++) {
+                               if (dc->d_vectdim[1] == 0) {
+                                       makeonenode(pnbuf,
+                                           dc->d_bmajor, dc->d_cmajor,
+                                           v1, dc->d_name, v1, -1);
+                               } else {
+                                       for (v2 = 0;
+                                           v2 < dc->d_vectdim[1]; v2++) {
+                                               makeonenode(pnbuf,
+                                                   dc->d_bmajor, dc->d_cmajor,
+                                                   v1 * dc->d_vectdim[1] + v2,
+                                                   dc->d_name, v1, v2);
+                                       }
+                               }
+                       }
+
+                       /* add some extra sanity checks here */
+                       if (dc->d_flags & DEVNODE_FLAG_LINKZERO) {
+                               /*
+                                * ok, so we cheat a bit since
+                                * symlink isn't supported on rumpfs ...
+                                */
+                               makeonenode(pnbuf, -1, dc->d_cmajor, 0,
+                                   dc->d_name, -1, -1);
+                                   
+                       }
+                       break;
+               }
+       }
+
+       PNBUF_PUT(pnbuf);
+}
diff -r c642bba2b1d3 -r 55ca4bb9dbb9 sys/rump/librump/rumpvfs/rump_vfs.c
--- a/sys/rump/librump/rumpvfs/rump_vfs.c       Fri Apr 30 20:54:17 2010 +0000
+++ b/sys/rump/librump/rumpvfs/rump_vfs.c       Fri Apr 30 21:02:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rump_vfs.c,v 1.47 2010/04/26 23:43:36 pooka Exp $      */
+/*     $NetBSD: rump_vfs.c,v 1.48 2010/04/30 21:02:36 pooka Exp $      */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.47 2010/04/26 23:43:36 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.48 2010/04/30 21:02:36 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -42,6 +42,7 @@
 #include <sys/module.h>
 #include <sys/namei.h>
 #include <sys/queue.h>
+#include <sys/stat.h>
 #include <sys/vfs_syscalls.h>
 #include <sys/vnode.h>
 #include <sys/wapbl.h>
@@ -77,6 +78,8 @@
 void
 rump_vfs_init(void)
 {
+       extern struct devsw_conv devsw_conv0[];
+       extern int max_devsw_convs;
        extern struct vfsops rumpfs_vfsops;
        char buf[64];
        int error;
@@ -145,6 +148,8 @@
 #endif
 
        module_init_class(MODULE_CLASS_VFS);
+
+       rump_vfs_builddevs(devsw_conv0, max_devsw_convs);
 }
 
 void
diff -r c642bba2b1d3 -r 55ca4bb9dbb9 sys/rump/librump/rumpvfs/rump_vfs_private.h
--- a/sys/rump/librump/rumpvfs/rump_vfs_private.h       Fri Apr 30 20:54:17 2010 +0000
+++ b/sys/rump/librump/rumpvfs/rump_vfs_private.h       Fri Apr 30 21:02:36 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rump_vfs_private.h,v 1.11 2010/04/14 16:05:53 pooka Exp $      */
+/*     $NetBSD: rump_vfs_private.h,v 1.12 2010/04/30 21:02:36 pooka Exp $      */
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -29,6 +29,7 @@
 #define _SYS_RUMP_VFS_PRIVATE_H_
 
 #include <sys/types.h>
+#include <sys/conf.h>
 
 void           rump_vfs_init(void);
 void           rump_vfs_fini(void);
@@ -47,6 +48,7 @@
 int     rump_vfs_makeonedevnode(dev_t, const char *, devmajor_t, devminor_t);
 int     rump_vfs_makedevnodes(dev_t, const char *, char,
                              devmajor_t, devminor_t, int);
+void   rump_vfs_builddevs(struct devsw_conv *, size_t numelem);
 
 #include <sys/mount.h>
 #include <sys/vnode.h>



Home | Main Index | Thread Index | Old Index