Module: xenomai-forge
Branch: master
Commit: f9e0adfb31c35b0ac93037ea2da23b1a8bd4d096
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=f9e0adfb31c35b0ac93037ea2da23b1a8bd4d096

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Dec 11 22:51:56 2011 +0100

copperplate/registry: introduce support for shared sessions, Cobalt

---

 README                         |   73 ++++++++++++++------------
 include/copperplate/registry.h |   10 ++--
 lib/copperplate/init.c         |   32 +++---------
 lib/copperplate/internal.c     |    1 +
 lib/copperplate/internal.h     |    2 +-
 lib/copperplate/registry.c     |  114 +++++++++++++++++++++++-----------------
 6 files changed, 119 insertions(+), 113 deletions(-)

diff --git a/README b/README
index 5038452..17852e7 100644
--- a/README
+++ b/README
@@ -116,12 +116,11 @@ or Xenomai-specific knobs:
 --enable-assert
 
        A number of debug assertion statements are wired into the
-       Xenomai core, which aim at checking the internal consistency
-       of the emulation system during runtime (see man
-       assert(3)). Passing --disable-assert to the configure script
-       disables built-in assertions unconditionally. By default,
-       assertions are enabled in partial or full debug modes,
-       disabled otherwise.
+       Xenomai core, checking the internal consistency of the runtime
+       system dynamically (see man assert(3)). Passing
+       --disable-assert to the configure script disables built-in
+       assertions unconditionally. By default, assertions are enabled
+       in partial or full debug modes, disabled otherwise.
 
 --enable-pshared
 
@@ -131,7 +130,7 @@ or Xenomai-specific knobs:
 
 --enable-registry
 
-       Some Xenomai APIs can export their internal state through a
+       Xenomai APIs can export their internal state through a
        pseudo-filesystem, which files may be read to obtain
        information about the existing real-time objects, such as
        tasks, semaphores, message queues and so on.  This feature is
@@ -140,30 +139,30 @@ or Xenomai-specific knobs:
        requires the FUSE development libraries to be installed on the
        build system.
 
-       When this option is enabled, the emulator creates a file
-       hierachy under /mnt/xenomai/<pid> (by default), where you can
-       access the internal state of the active real-time
-       objects. E.g. looking at the properties of a VxWorks task
-       could be done as follows:
+       When this option is enabled, the system creates a file
+       hierachy under /mnt/xenomai/<session>.<pid> (by default),
+       where you can access the internal state of the active
+       real-time objects. The session label is obtained from the
+       --session runtime switch. E.g. looking at the properties of a
+       VxWorks task could be done as follows:
 
-       $ cat /mnt/xenomai/12656/vxworks/tasks/windTask 
+       $ cat /mnt/xenomai/anon.12656/vxworks/tasks/windTask 
        name       = windTask
        errno      = 0
        status     = ready
        priority   = 70
        lock_depth = 0
 
-       You may override the default mount point of the registry
-       hierarchy by using the --registry-mountpt runtime option (see
-       below).
+       You may override the default root of the registry hierarchy by
+       using the --registry-root runtime option (see below).
 
        NOTE: the FUSE-based registry support is still in its early
        stage, and only a few objects are currently exported, only by
        the VxWorks API when running over the Mercury core. This is
        work in progress, so don't expect too much yet.
 
-       When running over the Cobalt core however, the /proc/xenomai
-       interface is available for inspecting the core system state
+       When running over the Cobalt core, the /proc/xenomai interface
+       is still available for inspecting the system state
        (i.e. nucleus and RTDM), like with Xenomai 2.x.
 
 --enable-lores-clock
@@ -271,34 +270,40 @@ command line, namely:
        when and how it sees fit, in order to avoid the extra latency
        induced by virtual memory paging.  Otherwise,
        mlockall(MCL_CURRENT | MCL_FUTURE) is automatically invoked by
-       the Xenomai core as part of the emulator initialization
-       duties.
+       the Xenomai core as part of the API initialization duties.
 
        This flag only applies to the Mercury core. Memory must be
        locked when invoking dual kernel services, therefore this
        switch is a nop over Cobalt.
 
---registry-mountpt=<path>
+--registry-root=<path>
 
-       Tells the emulator to mount the object registry over the given
-       path, instead of /mnt/xenomai/<pid> by default (see the
-       --enable-registry switch from the build time options).
+       Tells Xenomai to root the object registry at the given path,
+       instead of /mnt/xenomai by default (see the --enable-registry
+       switch from the build time options).
 
 --no-registry
 
        This switch disables registry support at runtime. No real-time
-       objects will be exported to /mnt/xenomai/<pid>, despite the
-       registry code has been compiled in.
+       objects will be exported to /mnt/xenomai/<session>.<pid>,
+       despite the registry code has been compiled in.
 
---session=<name>
+--session=<label>
 
        Name of the session the new process will be part of (or create
-       if not present). This is only useful when --enable-pshared was
-       passed at build time, to allow multiple processes to operate
-       on remote objects. e.g. allowing a process to post a semaphore
-       created by another process within the same session. This is
-       done using a common heap area, shared by all processes within
-       the same session.
+       if not present). When --enable-pshared was passed at build
+       time, this label allows multiple processes giving the same
+       label at startup to operate on the same set of
+       objects. e.g. allowing a process to post a semaphore created
+       by another process within the same session. This is done using
+       a common heap area, shared by all processes within the same
+       session.
+
+       This label is also used to form the registry mount point for
+       each process, e.g. /mnt/xenomai/<session>.<pid>. See
+       --enable-registry from the build options.
+
+       By default, "anon" is used as the session label.
 
 --reset
 
@@ -335,5 +340,5 @@ Alchemy             This is a re-implementation of 
Xenomai's former "native"
                API, fully rebased on the new RTOS emulation core.
                This is work in progress.
 
-Wed Sep 21 11:54:54 CEST 2011
+Mon Dec 12 11:47:44 CET 2011
 by <r...@xenomai.org>
diff --git a/include/copperplate/registry.h b/include/copperplate/registry.h
index f1eddab..f314e98 100644
--- a/include/copperplate/registry.h
+++ b/include/copperplate/registry.h
@@ -46,7 +46,7 @@ struct fsobj {
        struct regfs_dir *dir;
        struct timespec ctime;
        struct timespec mtime;
-       struct registry_operations *ops;
+       const struct registry_operations *ops;
        struct pvholder link;
        struct pvhashobj hobj;
 };
@@ -58,7 +58,7 @@ extern "C" {
 int registry_add_dir(const char *fmt, ...);
 
 void registry_init_file(struct fsobj *fsobj,
-                       struct registry_operations *ops);
+                       const struct registry_operations *ops);
 
 int registry_add_file(struct fsobj *fsobj,
                      int mode,
@@ -68,7 +68,7 @@ void registry_destroy_file(struct fsobj *fsobj);
 
 void registry_touch_file(struct fsobj *fsobj);
 
-int registry_pkg_init(char *arg0, char *mntpt, int do_mkdir);
+int registry_pkg_init(char *arg0);
 
 void registry_pkg_destroy(void);
 
@@ -92,7 +92,7 @@ int registry_add_dir(const char *fmt, ...)
 
 static inline
 int registry_init_file(struct fsobj *fsobj,
-                      struct registry_operations *ops)
+                      const struct registry_operations *ops)
 {
        return 0;
 }
@@ -116,7 +116,7 @@ void registry_touch_file(struct fsobj *fsobj)
 }
 
 static inline
-int registry_pkg_init(char *arg0, char *mntpt, int do_mkdir)
+int registry_pkg_init(char *arg0)
 {
        return 0;
 }
diff --git a/lib/copperplate/init.c b/lib/copperplate/init.c
index 81e103e..de21cee 100644
--- a/lib/copperplate/init.c
+++ b/lib/copperplate/init.c
@@ -43,8 +43,6 @@ struct timespec __init_date;
 
 static DEFINE_PRIVATE_LIST(skins);
 
-static int mkdir_mountpt = 1;
-
 static const struct option base_options[] = {
        {
 #define help_opt       0
@@ -68,8 +66,8 @@ static const struct option base_options[] = {
                .val = 1
        },
        {
-#define mountpt_opt    3
-               .name = "registry-mountpt",
+#define regroot_opt    3
+               .name = "registry-root",
                .has_arg = 1,
                .flag = NULL,
                .val = 0
@@ -124,7 +122,7 @@ static void usage(void)
         fprintf(stderr, "usage: program <options>, where options may be:\n");
         fprintf(stderr, "--mem-pool-size=<sizeK>          size of the main 
heap (kbytes)\n");
         fprintf(stderr, "--no-mlock                       do not lock memory 
at init (Mercury only)\n");
-        fprintf(stderr, "--registry-mountpt=<path>        mount point of 
registry\n");
+        fprintf(stderr, "--registry-root=<path>           root path of 
registry\n");
         fprintf(stderr, "--no-registry                    suppress object 
registration\n");
         fprintf(stderr, "--session=<label>                label of shared 
multi-processing session\n");
         fprintf(stderr, "--reset                          remove any older 
session\n");
@@ -320,18 +318,11 @@ static int parse_base_options(int *argcp, char *const 
**argvp,
                case mempool_opt:
                        __node_info.mem_pool = atoi(optarg) * 1024;
                        break;
-               case mountpt_opt:
-                       __node_info.registry_mountpt = strdup(optarg);
-                       mkdir_mountpt = 0;
-#ifndef CONFIG_XENO_REGISTRY
-                       warning("Xenomai compiled without registry support");
-#endif
-                       break;
                case session_opt:
                        __node_info.session_label = strdup(optarg);
-#ifndef CONFIG_XENO_PSHARED
-                       warning("Xenomai compiled without shared 
multi-processing support");
-#endif
+                       break;
+               case regroot_opt:
+                       __node_info.registry_root = strdup(optarg);
                        break;
                case affinity_opt:
                        ret = collect_cpu_affinity(optarg);
@@ -438,14 +429,6 @@ void copperplate_init(int *argcp, char *const **argvp)
                goto fail;
        }
 
-       /* Set a reasonable default value for the registry mount point. */
-       ret = asprintf(&__node_info.registry_mountpt,
-                      "/mnt/xenomai/%d", getpid());
-       if (ret < 0) {
-               ret = -ENOMEM;
-               goto fail;
-       }
-
        /* Define default CPU affinity, i.e. no particular affinity. */
        CPU_ZERO(&__node_info.cpu_affinity);
 
@@ -487,8 +470,7 @@ void copperplate_init(int *argcp, char *const **argvp)
        }
 
        if (__node_info.no_registry == 0) {
-               ret = registry_pkg_init(uargv[0], __node_info.registry_mountpt,
-                                       mkdir_mountpt);
+               ret = registry_pkg_init(uargv[0]);
                if (ret)
                        goto fail;
        }
diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c
index 04bcb93..1265f3d 100644
--- a/lib/copperplate/internal.c
+++ b/lib/copperplate/internal.c
@@ -33,6 +33,7 @@
 struct coppernode __node_info = {
        .mem_pool = 1024 * 1024, /* Default, 1Mb. */
        .session_label = "anon",
+       .registry_root = "/mnt/xenomai",
        .no_mlock = 0,
        .no_registry = 0,
        .reset_session = 0,
diff --git a/lib/copperplate/internal.h b/lib/copperplate/internal.h
index 960c8f9..4c5b1a6 100644
--- a/lib/copperplate/internal.h
+++ b/lib/copperplate/internal.h
@@ -28,8 +28,8 @@
 
 struct coppernode {
        unsigned int mem_pool;
-       char *registry_mountpt;
        const char *session_label;
+       const char *registry_root;
        cpu_set_t cpu_affinity;
        /* No bitfield below, we have to take address of thoses. */
        int no_mlock;
diff --git a/lib/copperplate/registry.c b/lib/copperplate/registry.c
index 488d6a9..e878aed 100644
--- a/lib/copperplate/registry.c
+++ b/lib/copperplate/registry.c
@@ -17,6 +17,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/mount.h>
 #include <sys/wait.h>
 #include <limits.h>
 #include <stdarg.h>
@@ -38,7 +39,10 @@
 #include "copperplate/debug.h"
 #include "internal.h"
 
-#define REGISTRY_ROOT "/mnt/xenomai"
+/* We allow use of oldish umount2(). */
+#ifndef MNT_DETACH
+#define MNT_DETACH 0
+#endif
 
 static struct pvhash_table regfs_objtable;
 
@@ -123,7 +127,8 @@ done:
        return __bt(ret);
 }
 
-void registry_init_file(struct fsobj *fsobj,  struct registry_operations *ops)
+void registry_init_file(struct fsobj *fsobj, 
+                       const struct registry_operations *ops)
 {
        pthread_mutexattr_t mattr;
 
@@ -260,13 +265,13 @@ static int regfs_getattr(const char *path, struct stat 
*sbuf)
                sbuf->st_mode = S_IFREG;
                switch (fsobj->mode) {
                case O_RDONLY:
-                       sbuf->st_mode |= 0440;
+                       sbuf->st_mode |= 0444;
                        break;
                case O_WRONLY:
-                       sbuf->st_mode |= 0220;
+                       sbuf->st_mode |= 0222;
                        break;
                case O_RDWR:
-                       sbuf->st_mode |= 0660;
+                       sbuf->st_mode |= 0666;
                        break;
                }
                sbuf->st_nlink = 1;
@@ -279,7 +284,7 @@ static int regfs_getattr(const char *path, struct stat 
*sbuf)
 done:
        read_unlock(&regfs_lock);
 
-       return __bt(ret);
+       return ret;
 }
 
 static int regfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
@@ -303,9 +308,13 @@ static int regfs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
        d = container_of(hobj, struct regfs_dir, hobj);
 
        if (!pvlist_empty(&d->dir_list)) {
-               pvlist_for_each_entry(subd, &d->dir_list, link)
+               pvlist_for_each_entry(subd, &d->dir_list, link) {
+                       /* We don't output empty directories. */
+                       if (subd->ndirs + subd->nfiles == 0)
+                               continue;
                        if (filler(buf, subd->basename, NULL, 0))
                                break;
+               }
        }
 
        if (!pvlist_empty(&d->file_list)) {
@@ -363,10 +372,12 @@ static int regfs_read(const char *path, char *buf, size_t 
size, off_t offset,
                return __bt(-ENOSYS);
        }
 
-       read_lock_nocancel(&fsobj->lock);
+       push_cleanup_lock(&fsobj->lock);
+       read_lock(&fsobj->lock);
        read_unlock(&regfs_lock);
        ret = fsobj->ops->read(fsobj, buf, size, offset);
        read_unlock(&fsobj->lock);
+       pop_cleanup_lock(&fsobj->lock);
 
        return __bt(ret);
 }
@@ -392,10 +403,12 @@ static int regfs_write(const char *path, const char *buf, 
size_t size, off_t off
                return __bt(-ENOSYS);
        }
 
-       read_lock_nocancel(&fsobj->lock);
+       push_cleanup_lock(&fsobj->lock);
+       read_lock(&fsobj->lock);
        read_unlock(&regfs_lock);
        ret = fsobj->ops->write(fsobj, buf, size, offset);
-       read_unlock(&regfs_lock);
+       read_unlock(&fsobj->lock);
+       pop_cleanup_lock(&fsobj->lock);
 
        return __bt(ret);
 }
@@ -456,30 +469,15 @@ static struct fuse_operations regfs_opts = {
 
 struct regfs_init_struct {
        char *arg0;
-       char *mntpt;
-       int do_rmdir;
+       char *mountpt;
 };
 
 static void regfs_cleanup(void *arg)
 {
        struct regfs_init_struct *s = arg;
-       pid_t pid;
-
-       if (s->do_rmdir) {
-               /* FIXME: Oh dear... Ahem, sorry... */
-               if ((pid = vfork()) == 0) {
-                       close(0);
-                       close(1);
-                       close(2);
-                       execl("/bin/fusermount", "fusermount", "-z", "-u", 
"-q", s->mntpt, NULL);
-               } else
-                       waitpid(pid, NULL, WUNTRACED);
-
-               if (rmdir(s->mntpt) < 0) {
-                       warning("failed to remove registry mount point %s (%s)",
-                               s->mntpt, symerror(-errno));
-               }
-       }
+
+       umount2(s->mountpt, MNT_DETACH);
+       rmdir(s->mountpt);
 
        if (__fs_killed)
                _exit(99);
@@ -488,7 +486,7 @@ static void regfs_cleanup(void *arg)
 static void *registry_thread(void *arg)
 {
        struct regfs_init_struct *s = arg;
-       char *av[5];
+       char *av[7];
        int ret;
 
        pthread_cleanup_push(regfs_cleanup, arg);
@@ -496,34 +494,47 @@ static void *registry_thread(void *arg)
        av[0] = s->arg0;
        av[1] = "-s";
        av[2] = "-f";
-       av[3] = s->mntpt;
-       av[4] = NULL;
-       ret = fuse_main(4, av, &regfs_opts, NULL);
+       av[3] = s->mountpt;
+       av[4] = "-o";
+       av[5] = "allow_other,default_permissions";
+       av[6] = NULL;
+       ret = fuse_main(6, av, &regfs_opts, NULL);
 
        pthread_cleanup_pop(0);
 
        if (ret) {
-               warning("failed to mount registry fs on %s", s->mntpt);
+               warning("can't mount registry onto %s", s->mountpt);
                return (void *)(long)ret;
        }
 
        return NULL;
 }
 
-int registry_pkg_init(char *arg0, char *mntpt, int do_mkdir)
+int registry_pkg_init(char *arg0)
 {
        static struct regfs_init_struct s;
        pthread_mutexattr_t mattr;
        pthread_attr_t thattr;
+       char *mountpt;
+       int ret;
 
-       if (do_mkdir) {
-               if (access(REGISTRY_ROOT, F_OK) < 0)
-                       mkdir(REGISTRY_ROOT, 0755);
-               if (mkdir(mntpt, 0755) < 0 && errno != EEXIST) {
-                       warning("failed to create registry mount point %s 
(%s)\n",
-                               mntpt, symerror(-errno));
-                       return __bt(-errno);
-               }
+       if (__node_info.no_registry)
+               return 0;
+
+       ret = asprintf(&mountpt, "%s/%s.%d",
+                      __node_info.registry_root,
+                      __node_info.session_label, getpid());
+       if (ret < 0)
+               return -ENOMEM;
+
+       if (access(__node_info.registry_root, F_OK) < 0)
+               mkdir(__node_info.registry_root, 0755);
+
+       if (mkdir(mountpt, 0755) < 0) {
+               ret = -errno;
+               warning("can't create registry mount point at %s (%s)\n",
+                       mountpt, symerror(ret));
+               return ret;
        }
 
        __RT(pthread_mutexattr_init(&mattr));
@@ -537,6 +548,7 @@ int registry_pkg_init(char *arg0, char *mntpt, int do_mkdir)
 
        registry_add_dir("/");  /* Create the fs root. */
 
+       /* We want a SCHED_OTHER thread, use defaults. */
        pthread_attr_init(&thattr);
        /*
         * Memory is locked as the process data grows, so we set a
@@ -546,15 +558,21 @@ int registry_pkg_init(char *arg0, char *mntpt, int 
do_mkdir)
        pthread_attr_setstacksize(&thattr, PTHREAD_STACK_MIN * 4);
        pthread_attr_setscope(&thattr, PTHREAD_SCOPE_PROCESS);
        s.arg0 = arg0;
-       s.mntpt = mntpt;
-       s.do_rmdir = do_mkdir;
+       s.mountpt = mountpt;
 
-       /* Start the FUSE server thread. */
-       return __bt(-__STD(pthread_create(&regfs_thid, &thattr, 
registry_thread, &s)));
+       /*
+        * Start the FUSE filesystem daemon. Over Cobalt, it runs as a
+        * non real-time Xenomai shadow, so that it may synchronize on
+        * real-time objects.
+        */
+       return __bt(-__RT(pthread_create(&regfs_thid, &thattr, registry_thread, 
&s)));
 }
 
 void registry_pkg_destroy(void)
 {
+       if (__node_info.no_registry)
+               return;
+
        pthread_cancel(regfs_thid);
-       __STD(pthread_join(regfs_thid, NULL));
+       pthread_join(regfs_thid, NULL);
 }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to