summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Gerum <rpm@xenomai.org>2015-09-11 18:47:24 +0200
committerPhilippe Gerum <rpm@xenomai.org>2015-09-14 11:35:37 +0200
commitcf21e806295981a9d0e342f683bfef419b6e3c68 (patch)
treea131978946db4b54d3342850e6206d2eb2678885
parent48d54b272b0d8053200418659a6691d47c278265 (diff)
downloadxenomai-3-cf21e806295981a9d0e342f683bfef419b6e3c68.tar.bz2
copperplate: enable group-based access to sessions
Passing --session foo/<group> will allow the members of the designated UNIX group to attach the shared heap and use the Copperplate services within a particular session. <group> may be a valid GID or group name from /etc/group. With Cobalt, such group would typically match the xenomai.allowed_group parameter passed to the kernel. To set up a shared session involving non-privileged users, all of them must be members of a dedicated UNIX group, and the following operations should be carried out: 1. if using Cobalt, pass xenomai.gid=<group-id> on the kernel command line accordingly 2. set udev rules to chown+chmod /dev/rtdm/* files with proper group permissions (e.g. for user group "xenomai" => SUBSYSTEM=="rtdm", MODE="0660", GROUP="xenomai") 3. create the registry root manually with proper permissions, 1777 is recommended if non-privileged processes will belong to the session 4. if --shared-registry is required from a non-privileged session initiator (i.e. the first process establishing the session), set user_allow_other in /etc/fuse.conf 5. to start a session with group-based access control, suffix the session name with the allowed group name or id separated with a slash ('/') when starting the session initiator, i.e. --session name/<group-id|group-name>. For instance, with {user} a member of the "xenomai" group: /* The initiator of session 'foo' is [root] */ [root] ./program --session foo/xenomai /* Bind a non-privileged process from {user} to session 'foo' */ {user} ./program --session foo Or, with {user1} and {user2} both members of the "xenomai" group: /* The initiator of session 'foo' is {user1} */ {user1} ./program --session foo/xenomai /* Bind a process from {user2} to session 'foo' */ {user2} ./program --session foo
-rw-r--r--include/copperplate/heapobj.h8
-rw-r--r--include/copperplate/threadobj.h3
-rw-r--r--include/copperplate/tunables.h11
-rw-r--r--lib/copperplate/cluster.c5
-rw-r--r--lib/copperplate/heapobj-pshared.c55
-rw-r--r--lib/copperplate/init.c47
-rw-r--r--lib/copperplate/internal.c10
-rw-r--r--lib/copperplate/internal.h2
-rw-r--r--lib/copperplate/registry.c5
-rw-r--r--lib/copperplate/threadobj.c50
10 files changed, 150 insertions, 46 deletions
diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h
index c61cf3e..4cf947e 100644
--- a/include/copperplate/heapobj.h
+++ b/include/copperplate/heapobj.h
@@ -192,11 +192,6 @@ struct sysgroup_memspec {
192 struct holder next; 192 struct holder next;
193}; 193};
194 194
195struct agent_memspec {
196 /** Agent pid in owner process. */
197 pid_t pid;
198};
199
200static inline void *mainheap_ptr(memoff_t off) 195static inline void *mainheap_ptr(memoff_t off)
201{ 196{
202 return off ? (void *)__memptr(__main_heap, off) : NULL; 197 return off ? (void *)__memptr(__main_heap, off) : NULL;
@@ -326,9 +321,6 @@ char *xnstrdup(const char *ptr);
326struct sysgroup_memspec { 321struct sysgroup_memspec {
327}; 322};
328 323
329struct agent_memspec {
330};
331
332/* 324/*
333 * Whether an object is laid in some shared heap. Never if pshared 325 * Whether an object is laid in some shared heap. Never if pshared
334 * mode is disabled. 326 * mode is disabled.
diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index 1d01709..f27c111 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -212,7 +212,6 @@ struct threadobj {
212 struct traceobj *tracer; 212 struct traceobj *tracer;
213 sem_t *cancel_sem; 213 sem_t *cancel_sem;
214 struct sysgroup_memspec memspec; 214 struct sysgroup_memspec memspec;
215 struct agent_memspec agent;
216 struct backtrace_data btd; 215 struct backtrace_data btd;
217}; 216};
218 217
@@ -392,7 +391,7 @@ static inline int threadobj_local_p(struct threadobj *thobj)
392 391
393void threadobj_init_key(void); 392void threadobj_init_key(void);
394 393
395int threadobj_pkg_init(void); 394int threadobj_pkg_init(int anon_session);
396 395
397#ifdef __cplusplus 396#ifdef __cplusplus
398} 397}
diff --git a/include/copperplate/tunables.h b/include/copperplate/tunables.h
index 8428716..640b8b4 100644
--- a/include/copperplate/tunables.h
+++ b/include/copperplate/tunables.h
@@ -27,6 +27,7 @@ struct copperplate_setup_data {
27 int no_registry; 27 int no_registry;
28 int shared_registry; 28 int shared_registry;
29 size_t mem_pool; 29 size_t mem_pool;
30 gid_t session_gid;
30}; 31};
31 32
32#ifdef __cplusplus 33#ifdef __cplusplus
@@ -85,6 +86,16 @@ static inline read_config_tunable(mem_pool_size, size_t)
85 return __copperplate_setup_data.mem_pool; 86 return __copperplate_setup_data.mem_pool;
86} 87}
87 88
89static inline define_config_tunable(session_gid, gid_t, gid)
90{
91 __copperplate_setup_data.session_gid = gid;
92}
93
94static inline read_config_tunable(session_gid, gid_t)
95{
96 return __copperplate_setup_data.session_gid;
97}
98
88#ifdef __cplusplus 99#ifdef __cplusplus
89} 100}
90#endif 101#endif
diff --git a/lib/copperplate/cluster.c b/lib/copperplate/cluster.c
index eac0afe..f0552f0 100644
--- a/lib/copperplate/cluster.c
+++ b/lib/copperplate/cluster.c
@@ -174,8 +174,11 @@ static int cluster_probe(struct hashobj *hobj)
174 * we can send the latter a signal, the node is deemed active. 174 * we can send the latter a signal, the node is deemed active.
175 * Over Cobalt, the main thread is always shadowed, therefore 175 * Over Cobalt, the main thread is always shadowed, therefore
176 * we may use Cobalt's kill() service to probe for it. 176 * we may use Cobalt's kill() service to probe for it.
177 * Receiving EPERM does mean that we found an active node,
178 * just that we don't have the credentials to actually send it
179 * a signal.
177 */ 180 */
178 return __RT(kill(cobj->cnode, 0)) == 0; 181 return copperplate_probe_tid(cobj->cnode) == 0;
179} 182}
180 183
181int cluster_addobj(struct cluster *c, const char *name, 184int cluster_addobj(struct cluster *c, const char *name,
diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c
index c1631e5..38b4bca 100644
--- a/lib/copperplate/heapobj-pshared.c
+++ b/lib/copperplate/heapobj-pshared.c
@@ -620,6 +620,7 @@ out:
620static int create_main_heap(pid_t *cnode_r) 620static int create_main_heap(pid_t *cnode_r)
621{ 621{
622 const char *session = __copperplate_setup_data.session_label; 622 const char *session = __copperplate_setup_data.session_label;
623 gid_t gid =__copperplate_setup_data.session_gid;
623 size_t size = __copperplate_setup_data.mem_pool; 624 size_t size = __copperplate_setup_data.mem_pool;
624 struct heapobj *hobj = &main_pool; 625 struct heapobj *hobj = &main_pool;
625 struct session_heap *m_heap; 626 struct session_heap *m_heap;
@@ -666,21 +667,26 @@ static int create_main_heap(pid_t *cnode_r)
666 return __bt(-errno); 667 return __bt(-errno);
667 668
668 ret = flock(fd, LOCK_EX); 669 ret = flock(fd, LOCK_EX);
669 if (ret) 670 if (__bterrno(ret))
670 goto errno_fail; 671 goto errno_fail;
671 672
672 ret = fstat(fd, &sbuf); 673 ret = fstat(fd, &sbuf);
673 if (ret) 674 if (__bterrno(ret))
674 goto errno_fail; 675 goto errno_fail;
675 676
676 if (sbuf.st_size == 0) 677 if (sbuf.st_size == 0)
677 goto init; 678 goto init;
678 679
679 m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); 680 m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0));
680 if (m_heap == MAP_FAILED) 681 if (m_heap == MAP_FAILED) {
681 goto errno_fail; 682 ret = __bt(-errno);
683 goto close_fail;
684 }
682 685
683 if (m_heap->cpid && kill(m_heap->cpid, 0) == 0) { 686 if (m_heap->cpid == 0)
687 goto reset;
688
689 if (copperplate_probe_tid(m_heap->cpid) == 0) {
684 if (m_heap->maplen == len) { 690 if (m_heap->maplen == len) {
685 /* CAUTION: __moff() depends on __main_heap. */ 691 /* CAUTION: __moff() depends on __main_heap. */
686 __main_heap = m_heap; 692 __main_heap = m_heap;
@@ -693,25 +699,47 @@ static int create_main_heap(pid_t *cnode_r)
693 __STD(close(fd)); 699 __STD(close(fd));
694 return __bt(-EEXIST); 700 return __bt(-EEXIST);
695 } 701 }
696 702reset:
697 munmap(m_heap, len); 703 munmap(m_heap, len);
704 /*
705 * Reset shared memory ownership to revoke permissions from a
706 * former session with more permissive access rules, such as
707 * group-controlled access.
708 */
709 fchown(fd, geteuid(), getegid());
698init: 710init:
699 ret = ftruncate(fd, 0); /* Clear all previous contents if any. */ 711 ret = ftruncate(fd, 0); /* Clear all previous contents if any. */
700 if (ret) 712 if (__bterrno(ret))
701 goto unlink_fail; 713 goto unlink_fail;
702 714
703 ret = ftruncate(fd, len); 715 ret = ftruncate(fd, len);
704 if (ret) 716 if (__bterrno(ret))
705 goto unlink_fail; 717 goto unlink_fail;
706 718
719 /*
720 * If we need to share the heap between members of a group,
721 * give the group RW access to the shared memory file backing
722 * the heap.
723 */
724 if (gid != USHRT_MAX) {
725 ret = fchown(fd, geteuid(), gid);
726 if (__bterrno(ret) < 0)
727 goto unlink_fail;
728 ret = fchmod(fd, 0660);
729 if (__bterrno(ret) < 0)
730 goto unlink_fail;
731 }
732
707 m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); 733 m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0));
708 if (m_heap == MAP_FAILED) 734 if (m_heap == MAP_FAILED) {
735 ret = __bt(-errno);
709 goto unlink_fail; 736 goto unlink_fail;
737 }
710 738
711 m_heap->maplen = len; 739 m_heap->maplen = len;
712 /* CAUTION: init_main_heap() depends on hobj->pool_ref. */ 740 /* CAUTION: init_main_heap() depends on hobj->pool_ref. */
713 hobj->pool_ref = __moff(&m_heap->heap); 741 hobj->pool_ref = __moff(&m_heap->heap);
714 ret = init_main_heap(m_heap, size); 742 ret = __bt(init_main_heap(m_heap, size));
715 if (ret) { 743 if (ret) {
716 errno = -ret; 744 errno = -ret;
717 goto unmap_fail; 745 goto unmap_fail;
@@ -731,7 +759,7 @@ done:
731unmap_fail: 759unmap_fail:
732 munmap(m_heap, len); 760 munmap(m_heap, len);
733unlink_fail: 761unlink_fail:
734 ret = __bt(-errno); 762 ret = -errno;
735 shm_unlink(hobj->fsname); 763 shm_unlink(hobj->fsname);
736 goto close_fail; 764 goto close_fail;
737errno_fail: 765errno_fail:
@@ -781,7 +809,7 @@ static int bind_main_heap(const char *session)
781 cpid = m_heap->cpid; 809 cpid = m_heap->cpid;
782 __STD(close(fd)); 810 __STD(close(fd));
783 811
784 if (cpid == 0 || kill(cpid, 0)) { 812 if (cpid == 0 || copperplate_probe_tid(cpid)) {
785 munmap(m_heap, len); 813 munmap(m_heap, len);
786 return -ENOENT; 814 return -ENOENT;
787 } 815 }
@@ -905,7 +933,8 @@ void heapobj_destroy(struct heapobj *hobj)
905 } 933 }
906 934
907 cpid = main_heap.cpid; 935 cpid = main_heap.cpid;
908 if (cpid != get_thread_pid() && kill(cpid, 0) == 0) { 936 if (cpid != 0 && cpid != get_thread_pid() &&
937 copperplate_probe_tid(cpid) == 0) {
909 munmap(&main_heap, main_heap.maplen); 938 munmap(&main_heap, main_heap.maplen);
910 return; 939 return;
911 } 940 }
diff --git a/lib/copperplate/init.c b/lib/copperplate/init.c
index d24673d..a9b4efd 100644
--- a/lib/copperplate/init.c
+++ b/lib/copperplate/init.c
@@ -25,6 +25,7 @@
25#include <pwd.h> 25#include <pwd.h>
26#include <errno.h> 26#include <errno.h>
27#include <getopt.h> 27#include <getopt.h>
28#include <grp.h>
28#include "copperplate/threadobj.h" 29#include "copperplate/threadobj.h"
29#include "copperplate/heapobj.h" 30#include "copperplate/heapobj.h"
30#include "copperplate/clockobj.h" 31#include "copperplate/clockobj.h"
@@ -39,6 +40,7 @@ struct copperplate_setup_data __copperplate_setup_data = {
39 .registry_root = DEFAULT_REGISTRY_ROOT, 40 .registry_root = DEFAULT_REGISTRY_ROOT,
40 .session_label = NULL, 41 .session_label = NULL,
41 .session_root = NULL, 42 .session_root = NULL,
43 .session_gid = USHRT_MAX,
42}; 44};
43 45
44#ifdef CONFIG_XENO_COBALT 46#ifdef CONFIG_XENO_COBALT
@@ -145,6 +147,42 @@ static int get_session_root(int *regflags_r)
145 return 0; 147 return 0;
146} 148}
147 149
150static int get_session_label(const char *optarg)
151{
152 char *session, *grpname, *p;
153 struct group *grp;
154 gid_t gid;
155
156 session = strdup(optarg);
157 grpname = strrchr(session, '/');
158 if (grpname == NULL)
159 goto no_group;
160
161 *grpname++ = '\0';
162
163 if (isdigit(*grpname)) {
164 gid = (gid_t)strtol(grpname, &p, 10);
165 if (*p)
166 return -EINVAL;
167 errno = 0;
168 grp = getgrgid(gid);
169 } else {
170 errno = 0;
171 grp = getgrnam(grpname);
172 }
173
174 if (grp == NULL) {
175 warning("invalid group %s", grpname);
176 return errno ? -errno : -EINVAL;
177 }
178
179 __copperplate_setup_data.session_gid = grp->gr_gid;
180no_group:
181 __copperplate_setup_data.session_label = session;
182
183 return 0;
184}
185
148static int copperplate_init(void) 186static int copperplate_init(void)
149{ 187{
150 int ret, regflags = 0; 188 int ret, regflags = 0;
@@ -177,7 +215,7 @@ static int copperplate_init(void)
177 return ret; 215 return ret;
178 } 216 }
179 217
180 ret = threadobj_pkg_init(); 218 ret = threadobj_pkg_init((regflags & REGISTRY_ANON) != 0);
181 if (ret) { 219 if (ret) {
182 warning("failed to initialize multi-threading package"); 220 warning("failed to initialize multi-threading package");
183 return ret; 221 return ret;
@@ -195,6 +233,7 @@ static int copperplate_init(void)
195static int copperplate_parse_option(int optnum, const char *optarg) 233static int copperplate_parse_option(int optnum, const char *optarg)
196{ 234{
197 size_t memsz; 235 size_t memsz;
236 int ret;
198 237
199 switch (optnum) { 238 switch (optnum) {
200 case mempool_opt: 239 case mempool_opt:
@@ -214,7 +253,9 @@ static int copperplate_parse_option(int optnum, const char *optarg)
214 __copperplate_setup_data.mem_pool = memsz; 253 __copperplate_setup_data.mem_pool = memsz;
215 break; 254 break;
216 case session_opt: 255 case session_opt:
217 __copperplate_setup_data.session_label = strdup(optarg); 256 ret = get_session_label(optarg);
257 if (ret)
258 return ret;
218 break; 259 break;
219 case regroot_opt: 260 case regroot_opt:
220 __copperplate_setup_data.registry_root = strdup(optarg); 261 __copperplate_setup_data.registry_root = strdup(optarg);
@@ -236,7 +277,7 @@ static void copperplate_help(void)
236 fprintf(stderr, "--no-registry suppress object registration\n"); 277 fprintf(stderr, "--no-registry suppress object registration\n");
237 fprintf(stderr, "--shared-registry enable public access to registry\n"); 278 fprintf(stderr, "--shared-registry enable public access to registry\n");
238 fprintf(stderr, "--registry-root=<path> root path of registry\n"); 279 fprintf(stderr, "--registry-root=<path> root path of registry\n");
239 fprintf(stderr, "--session=<label> label of shared multi-processing session\n"); 280 fprintf(stderr, "--session=<label>[/<group>] enable shared session\n");
240} 281}
241 282
242static struct setup_descriptor copperplate_interface = { 283static struct setup_descriptor copperplate_interface = {
diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c
index b9751e4..eeb40e1 100644
--- a/lib/copperplate/internal.c
+++ b/lib/copperplate/internal.c
@@ -91,6 +91,11 @@ int copperplate_kill_tid(pid_t tid, int sig)
91 return __RT(kill(tid, sig)) ? -errno : 0; 91 return __RT(kill(tid, sig)) ? -errno : 0;
92} 92}
93 93
94int copperplate_probe_tid(pid_t tid)
95{
96 return copperplate_kill_tid(tid, 0);
97}
98
94void copperplate_set_current_name(const char *name) 99void copperplate_set_current_name(const char *name)
95{ 100{
96 __RT(pthread_setname_np(pthread_self(), name)); 101 __RT(pthread_setname_np(pthread_self(), name));
@@ -103,6 +108,11 @@ int copperplate_kill_tid(pid_t tid, int sig)
103 return syscall(__NR_tkill, tid, sig) ? -errno : 0; 108 return syscall(__NR_tkill, tid, sig) ? -errno : 0;
104} 109}
105 110
111int copperplate_probe_tid(pid_t tid)
112{
113 return copperplate_kill_tid(tid, 0) && errno != EPERM ? -errno : 0;
114}
115
106void copperplate_set_current_name(const char *name) 116void copperplate_set_current_name(const char *name)
107{ 117{
108 prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0); 118 prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
diff --git a/lib/copperplate/internal.h b/lib/copperplate/internal.h
index 6369694..23047b4 100644
--- a/lib/copperplate/internal.h
+++ b/lib/copperplate/internal.h
@@ -85,6 +85,8 @@ int copperplate_get_current_name(char *name, size_t maxlen);
85 85
86int copperplate_kill_tid(pid_t tid, int sig); 86int copperplate_kill_tid(pid_t tid, int sig);
87 87
88int copperplate_probe_tid(pid_t tid);
89
88int copperplate_create_thread(struct corethread_attributes *cta, 90int copperplate_create_thread(struct corethread_attributes *cta,
89 pthread_t *ptid); 91 pthread_t *ptid);
90 92
diff --git a/lib/copperplate/registry.c b/lib/copperplate/registry.c
index 52c0f64..1df7d6e 100644
--- a/lib/copperplate/registry.c
+++ b/lib/copperplate/registry.c
@@ -821,9 +821,10 @@ int registry_pkg_init(const char *arg0, int flags)
821 char *mountpt; 821 char *mountpt;
822 int ret; 822 int ret;
823 823
824 ret = connect_regd(__copperplate_setup_data.session_root, &mountpt, flags); 824 ret = connect_regd(__copperplate_setup_data.session_root,
825 &mountpt, flags);
825 if (ret) 826 if (ret)
826 return ret; 827 return __bt(ret);
827 828
828 return __bt(__registry_pkg_init(arg0, mountpt, flags)); 829 return __bt(__registry_pkg_init(arg0, mountpt, flags));
829} 830}
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index 961d8c4..2f25992 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -168,6 +168,13 @@ static inline int send_agent(struct threadobj *thobj,
168 struct remote_request *rq) 168 struct remote_request *rq)
169{ 169{
170 union sigval val = { .sival_ptr = rq }; 170 union sigval val = { .sival_ptr = rq };
171
172 /*
173 * We are not supposed to issue remote requests when nobody
174 * else may share our session.
175 */
176 assert(agent_pid != 0);
177
171 /* 178 /*
172 * XXX: No backtracing, may legitimately fail if the remote 179 * XXX: No backtracing, may legitimately fail if the remote
173 * process goes away (hopefully cleanly). However, the request 180 * process goes away (hopefully cleanly). However, the request
@@ -176,7 +183,7 @@ static inline int send_agent(struct threadobj *thobj,
176 * creating user threads are unlikely to ungracefully leave 183 * creating user threads are unlikely to ungracefully leave
177 * the session they belong to intentionally. 184 * the session they belong to intentionally.
178 */ 185 */
179 return __RT(sigqueue(thobj->agent.pid, SIGAGENT, val)); 186 return __RT(sigqueue(agent_pid, SIGAGENT, val));
180} 187}
181 188
182static void start_agent(void) 189static void start_agent(void)
@@ -197,7 +204,7 @@ static void start_agent(void)
197 sigaddset(&set, SIGAGENT); 204 sigaddset(&set, SIGAGENT);
198 pthread_sigmask(SIG_BLOCK, &set, NULL); 205 pthread_sigmask(SIG_BLOCK, &set, NULL);
199 206
200 cta.policy = SCHED_CORE; 207 cta.policy = threadobj_agent_prio ? SCHED_CORE : SCHED_OTHER;
201 cta.param_ex.sched_priority = threadobj_agent_prio; 208 cta.param_ex.sched_priority = threadobj_agent_prio;
202 cta.prologue = agent_prologue; 209 cta.prologue = agent_prologue;
203 cta.run = agent_loop; 210 cta.run = agent_loop;
@@ -210,11 +217,6 @@ static void start_agent(void)
210 panic("failed to start agent thread, %s", symerror(ret)); 217 panic("failed to start agent thread, %s", symerror(ret));
211} 218}
212 219
213static void threadobj_set_agent(struct threadobj *thobj)
214{
215 thobj->agent.pid = agent_pid;
216}
217
218#else /* !CONFIG_XENO_PSHARED */ 220#else /* !CONFIG_XENO_PSHARED */
219 221
220static inline void start_agent(void) 222static inline void start_agent(void)
@@ -222,11 +224,6 @@ static inline void start_agent(void)
222 /* No agent in private (process-local) session. */ 224 /* No agent in private (process-local) session. */
223} 225}
224 226
225static inline void threadobj_set_agent(struct threadobj *thobj)
226{
227 /* nop */
228}
229
230#endif /* !CONFIG_XENO_PSHARED */ 227#endif /* !CONFIG_XENO_PSHARED */
231 228
232#ifdef CONFIG_XENO_COBALT 229#ifdef CONFIG_XENO_COBALT
@@ -235,8 +232,15 @@ static inline void threadobj_set_agent(struct threadobj *thobj)
235 232
236static inline void pkg_init_corespec(void) 233static inline void pkg_init_corespec(void)
237{ 234{
235 /*
236 * We must have CAP_SYS_NICE since we reached this code either
237 * as root or as a member of the allowed group, as a result of
238 * binding the current process to the Cobalt core earlier in
239 * libcobalt's setup code.
240 */
238 threadobj_irq_prio = sched_get_priority_max_ex(SCHED_CORE); 241 threadobj_irq_prio = sched_get_priority_max_ex(SCHED_CORE);
239 threadobj_high_prio = sched_get_priority_max_ex(SCHED_FIFO); 242 threadobj_high_prio = sched_get_priority_max_ex(SCHED_FIFO);
243 threadobj_agent_prio = threadobj_high_prio;
240} 244}
241 245
242static inline int threadobj_init_corespec(struct threadobj *thobj) 246static inline int threadobj_init_corespec(struct threadobj *thobj)
@@ -556,6 +560,18 @@ static inline void pkg_init_corespec(void)
556 threadobj_irq_prio = sched_get_priority_max(SCHED_FIFO); 560 threadobj_irq_prio = sched_get_priority_max(SCHED_FIFO);
557 threadobj_lock_prio = threadobj_irq_prio - 1; 561 threadobj_lock_prio = threadobj_irq_prio - 1;
558 threadobj_high_prio = threadobj_irq_prio - 2; 562 threadobj_high_prio = threadobj_irq_prio - 2;
563 threadobj_agent_prio = threadobj_high_prio;
564 /*
565 * We allow a non-privileged process to start a low priority
566 * agent thread only, on the assumption that it lacks
567 * CAP_SYS_NICE, but this is pretty much the maximum extent of
568 * our abilities for such processes. Other internal threads
569 * requiring SCHED_CORE/FIFO scheduling such as the timer
570 * manager won't start properly, therefore the corresponding
571 * services won't be available.
572 */
573 if (geteuid())
574 threadobj_agent_prio = 0;
559 575
560 memset(&sa, 0, sizeof(sa)); 576 memset(&sa, 0, sizeof(sa));
561 sa.sa_handler = unblock_sighandler; 577 sa.sa_handler = unblock_sighandler;
@@ -1322,7 +1338,6 @@ int threadobj_prologue(struct threadobj *thobj, const char *name)
1322 thobj->ptid = pthread_self(); 1338 thobj->ptid = pthread_self();
1323 thobj->pid = get_thread_pid(); 1339 thobj->pid = get_thread_pid();
1324 thobj->errno_pointer = &errno; 1340 thobj->errno_pointer = &errno;
1325 threadobj_set_agent(thobj);
1326 backtrace_init_context(&thobj->btd, name); 1341 backtrace_init_context(&thobj->btd, name);
1327 ret = threadobj_setup_corespec(thobj); 1342 ret = threadobj_setup_corespec(thobj);
1328 if (ret) { 1343 if (ret) {
@@ -1569,7 +1584,7 @@ int threadobj_sleep(const struct timespec *ts)
1569 */ 1584 */
1570 if (ts->tv_sec == 0 && ts->tv_nsec == 0) { 1585 if (ts->tv_sec == 0 && ts->tv_nsec == 0) {
1571 sigemptyset(&set); 1586 sigemptyset(&set);
1572 ret = __RT(sigwaitinfo(&set, NULL)) ? errno : 0; 1587 ret = __RT(sigwaitinfo(&set, NULL)) ? -errno : 0;
1573 } else 1588 } else
1574 ret = __RT(clock_nanosleep(CLOCK_COPPERPLATE, 1589 ret = __RT(clock_nanosleep(CLOCK_COPPERPLATE,
1575 TIMER_ABSTIME, ts, NULL)); 1590 TIMER_ABSTIME, ts, NULL));
@@ -1751,12 +1766,13 @@ static inline int main_overlay(void)
1751 return 0; 1766 return 0;
1752} 1767}
1753 1768
1754int threadobj_pkg_init(void) 1769int threadobj_pkg_init(int anon_session)
1755{ 1770{
1756 sigaddset(&sigperiod_set, SIGPERIOD); 1771 sigaddset(&sigperiod_set, SIGPERIOD);
1757 pkg_init_corespec(); 1772 pkg_init_corespec();
1758 threadobj_agent_prio = threadobj_high_prio; 1773
1759 start_agent(); 1774 if (!anon_session)
1775 start_agent();
1760 1776
1761 return main_overlay(); 1777 return main_overlay();
1762} 1778}
Mirror
http://xenomai.org/mirroring-xenomai-git-repositories-with-grokmirror/