The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/port/pgrp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "../port/error.h"
    7 
    8 enum {
    9         Whinesecs = 10,         /* frequency of out-of-resources printing */
   10 };
   11 
   12 static Ref pgrpid;
   13 static Ref mountid;
   14 
   15 void
   16 pgrpnote(ulong noteid, char *a, long n, int flag)
   17 {
   18         Proc *p, *ep;
   19         char buf[ERRMAX];
   20 
   21         if(n >= ERRMAX-1)
   22                 error(Etoobig);
   23 
   24         memmove(buf, a, n);
   25         buf[n] = 0;
   26         p = proctab(0);
   27         ep = p+conf.nproc;
   28         for(; p < ep; p++) {
   29                 if(p->state == Dead)
   30                         continue;
   31                 if(up != p && p->noteid == noteid && p->kp == 0) {
   32                         qlock(&p->debug);
   33                         if(p->pid == 0 || p->noteid != noteid){
   34                                 qunlock(&p->debug);
   35                                 continue;
   36                         }
   37                         if(!waserror()) {
   38                                 postnote(p, 0, buf, flag);
   39                                 poperror();
   40                         }
   41                         qunlock(&p->debug);
   42                 }
   43         }
   44 }
   45 
   46 Pgrp*
   47 newpgrp(void)
   48 {
   49         Pgrp *p;
   50 
   51         p = smalloc(sizeof(Pgrp));
   52         p->ref = 1;
   53         p->pgrpid = incref(&pgrpid);
   54         return p;
   55 }
   56 
   57 Rgrp*
   58 newrgrp(void)
   59 {
   60         Rgrp *r;
   61 
   62         r = smalloc(sizeof(Rgrp));
   63         r->ref = 1;
   64         return r;
   65 }
   66 
   67 void
   68 closergrp(Rgrp *r)
   69 {
   70         if(decref(r) == 0)
   71                 free(r);
   72 }
   73 
   74 void
   75 closepgrp(Pgrp *p)
   76 {
   77         Mhead **h, **e, *f, *next;
   78 
   79         if(decref(p) != 0)
   80                 return;
   81 
   82         qlock(&p->debug);
   83         wlock(&p->ns);
   84         p->pgrpid = -1;
   85 
   86         e = &p->mnthash[MNTHASH];
   87         for(h = p->mnthash; h < e; h++) {
   88                 for(f = *h; f; f = next) {
   89                         wlock(&f->lock);
   90                         cclose(f->from);
   91                         mountfree(f->mount);
   92                         f->mount = nil;
   93                         next = f->hash;
   94                         wunlock(&f->lock);
   95                         putmhead(f);
   96                 }
   97         }
   98         wunlock(&p->ns);
   99         qunlock(&p->debug);
  100         free(p);
  101 }
  102 
  103 void
  104 pgrpinsert(Mount **order, Mount *m)
  105 {
  106         Mount *f;
  107 
  108         m->order = 0;
  109         if(*order == 0) {
  110                 *order = m;
  111                 return;
  112         }
  113         for(f = *order; f; f = f->order) {
  114                 if(m->mountid < f->mountid) {
  115                         m->order = f;
  116                         *order = m;
  117                         return;
  118                 }
  119                 order = &f->order;
  120         }
  121         *order = m;
  122 }
  123 
  124 /*
  125  * pgrpcpy MUST preserve the mountid allocation order of the parent group
  126  */
  127 void
  128 pgrpcpy(Pgrp *to, Pgrp *from)
  129 {
  130         int i;
  131         Mount *n, *m, **link, *order;
  132         Mhead *f, **tom, **l, *mh;
  133 
  134         wlock(&from->ns);
  135         order = 0;
  136         tom = to->mnthash;
  137         for(i = 0; i < MNTHASH; i++) {
  138                 l = tom++;
  139                 for(f = from->mnthash[i]; f; f = f->hash) {
  140                         rlock(&f->lock);
  141                         mh = newmhead(f->from);
  142                         *l = mh;
  143                         l = &mh->hash;
  144                         link = &mh->mount;
  145                         for(m = f->mount; m; m = m->next) {
  146                                 n = newmount(mh, m->to, m->mflag, m->spec);
  147                                 m->copy = n;
  148                                 pgrpinsert(&order, m);
  149                                 *link = n;
  150                                 link = &n->next;
  151                         }
  152                         runlock(&f->lock);
  153                 }
  154         }
  155         /*
  156          * Allocate mount ids in the same sequence as the parent group
  157          */
  158         lock(&mountid);
  159         for(m = order; m; m = m->order)
  160                 m->copy->mountid = mountid.ref++;
  161         unlock(&mountid);
  162         wunlock(&from->ns);
  163 }
  164 
  165 Fgrp*
  166 dupfgrp(Fgrp *f)
  167 {
  168         Fgrp *new;
  169         Chan *c;
  170         int i;
  171 
  172         new = smalloc(sizeof(Fgrp));
  173         if(f == nil){
  174                 new->fd = smalloc(DELTAFD*sizeof(Chan*));
  175                 new->nfd = DELTAFD;
  176                 new->ref = 1;
  177                 return new;
  178         }
  179 
  180         lock(f);
  181         /* Make new fd list shorter if possible, preserving quantization */
  182         new->nfd = f->maxfd+1;
  183         i = new->nfd%DELTAFD;
  184         if(i != 0)
  185                 new->nfd += DELTAFD - i;
  186         new->fd = malloc(new->nfd*sizeof(Chan*));
  187         if(new->fd == nil){
  188                 unlock(f);
  189                 free(new);
  190                 error("no memory for fgrp");
  191         }
  192         new->ref = 1;
  193 
  194         new->maxfd = f->maxfd;
  195         for(i = 0; i <= f->maxfd; i++) {
  196                 if(c = f->fd[i]){
  197                         incref(c);
  198                         new->fd[i] = c;
  199                 }
  200         }
  201         unlock(f);
  202 
  203         return new;
  204 }
  205 
  206 void
  207 closefgrp(Fgrp *f)
  208 {
  209         int i;
  210         Chan *c;
  211 
  212         if(f == 0)
  213                 return;
  214 
  215         if(decref(f) != 0)
  216                 return;
  217 
  218         /*
  219          * If we get into trouble, forceclosefgrp
  220          * will bail us out.
  221          */
  222         up->closingfgrp = f;
  223         for(i = 0; i <= f->maxfd; i++)
  224                 if(c = f->fd[i]){
  225                         f->fd[i] = nil;
  226                         cclose(c);
  227                 }
  228         up->closingfgrp = nil;
  229 
  230         free(f->fd);
  231         free(f);
  232 }
  233 
  234 /*
  235  * Called from sleep because up is in the middle
  236  * of closefgrp and just got a kill ctl message.
  237  * This usually means that up has wedged because
  238  * of some kind of deadly embrace with mntclose
  239  * trying to talk to itself.  To break free, hand the
  240  * unclosed channels to the close queue.  Once they
  241  * are finished, the blocked cclose that we've 
  242  * interrupted will finish by itself.
  243  */
  244 void
  245 forceclosefgrp(void)
  246 {
  247         int i;
  248         Chan *c;
  249         Fgrp *f;
  250 
  251         if(up->procctl != Proc_exitme || up->closingfgrp == nil){
  252                 print("bad forceclosefgrp call");
  253                 return;
  254         }
  255 
  256         f = up->closingfgrp;
  257         for(i = 0; i <= f->maxfd; i++)
  258                 if(c = f->fd[i]){
  259                         f->fd[i] = nil;
  260                         ccloseq(c);
  261                 }
  262 }
  263 
  264 
  265 Mount*
  266 newmount(Mhead *mh, Chan *to, int flag, char *spec)
  267 {
  268         Mount *m;
  269 
  270         m = smalloc(sizeof(Mount));
  271         m->to = to;
  272         m->head = mh;
  273         incref(to);
  274         m->mountid = incref(&mountid);
  275         m->mflag = flag;
  276         if(spec != 0)
  277                 kstrdup(&m->spec, spec);
  278 
  279         return m;
  280 }
  281 
  282 void
  283 mountfree(Mount *m)
  284 {
  285         Mount *f;
  286 
  287         while(m) {
  288                 f = m->next;
  289                 cclose(m->to);
  290                 m->mountid = 0;
  291                 free(m->spec);
  292                 free(m);
  293                 m = f;
  294         }
  295 }
  296 
  297 void
  298 resrcwait(char *reason)
  299 {
  300         ulong now;
  301         char *p;
  302         static ulong lastwhine;
  303 
  304         if(up == 0)
  305                 panic("resrcwait");
  306 
  307         p = up->psstate;
  308         if(reason) {
  309                 up->psstate = reason;
  310                 now = seconds();
  311                 /* don't tie up the console with complaints */
  312                 if(now - lastwhine > Whinesecs) {
  313                         lastwhine = now;
  314                         print("%s\n", reason);
  315                 }
  316         }
  317 
  318         tsleep(&up->sleep, return0, 0, 300);
  319         up->psstate = p;
  320 }

Cache object: 0847af4591aec7c3e7716976e10b4484


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.