Author: trasz
Date: Mon Oct  3 16:23:20 2011
New Revision: 225940
URL: http://svn.freebsd.org/changeset/base/225940

Log:
  Fix another bug introduced in r225641, which caused rctl to access certain
  fields in 'struct proc' before they got initialized in do_fork().
  
  MFC after:    3 days

Modified:
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_racct.c
  head/sys/kern/kern_rctl.c
  head/sys/sys/racct.h

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c   Mon Oct  3 16:02:55 2011        (r225939)
+++ head/sys/kern/kern_fork.c   Mon Oct  3 16:23:20 2011        (r225940)
@@ -939,6 +939,7 @@ fork1(struct thread *td, int flags, int 
                if (flags & RFPROCDESC)
                        procdesc_finit(newproc->p_procdesc, fp_procdesc);
 #endif
+               racct_proc_fork_done(newproc);
                return (0);
        }
 

Modified: head/sys/kern/kern_racct.c
==============================================================================
--- head/sys/kern/kern_racct.c  Mon Oct  3 16:02:55 2011        (r225939)
+++ head/sys/kern/kern_racct.c  Mon Oct  3 16:23:20 2011        (r225940)
@@ -585,6 +585,24 @@ out:
        return (error);
 }
 
+/*
+ * Called at the end of fork1(), to handle rules that require the process
+ * to be fully initialized.
+ */
+void
+racct_proc_fork_done(struct proc *child)
+{
+
+#ifdef RCTL
+       PROC_LOCK(child);
+       mtx_lock(&racct_lock);
+       rctl_enforce(child, RACCT_NPROC, 0);
+       rctl_enforce(child, RACCT_NTHR, 0);
+       mtx_unlock(&racct_lock);
+       PROC_UNLOCK(child);
+#endif
+}
+
 void
 racct_proc_exit(struct proc *p)
 {
@@ -810,6 +828,11 @@ racct_proc_fork(struct proc *parent, str
 }
 
 void
+racct_proc_fork_done(struct proc *child)
+{
+}
+
+void
 racct_proc_exit(struct proc *p)
 {
 }

Modified: head/sys/kern/kern_rctl.c
==============================================================================
--- head/sys/kern/kern_rctl.c   Mon Oct  3 16:02:55 2011        (r225939)
+++ head/sys/kern/kern_rctl.c   Mon Oct  3 16:23:20 2011        (r225940)
@@ -312,6 +312,16 @@ rctl_enforce(struct proc *p, int resourc
                        if (link->rrl_exceeded != 0)
                                continue;
 
+                       /*
+                        * If the process state is not fully initialized yet,
+                        * we can't access most of the required fields, e.g.
+                        * p->p_comm.  This happens when called from fork1().
+                        * Ignore this rule for now; it will be processed just
+                        * after fork, when called from racct_proc_fork_done().
+                        */
+                       if (p->p_state != PRS_NORMAL)
+                               continue;
+
                        if (!ppsratecheck(&lasttime, &curtime, 10))
                                continue;
 
@@ -335,6 +345,9 @@ rctl_enforce(struct proc *p, int resourc
                        if (link->rrl_exceeded != 0)
                                continue;
 
+                       if (p->p_state != PRS_NORMAL)
+                               continue;
+       
                        buf = malloc(RCTL_LOG_BUFSIZE, M_RCTL, M_NOWAIT);
                        if (buf == NULL) {
                                printf("rctl_enforce: out of memory\n");
@@ -357,23 +370,15 @@ rctl_enforce(struct proc *p, int resourc
                        if (link->rrl_exceeded != 0)
                                continue;
 
+                       if (p->p_state != PRS_NORMAL)
+                               continue;
+
                        KASSERT(rule->rr_action > 0 &&
                            rule->rr_action <= RCTL_ACTION_SIGNAL_MAX,
                            ("rctl_enforce: unknown action %d",
                             rule->rr_action));
 
                        /*
-                        * We're supposed to send a signal, but the process
-                        * is not fully initialized yet, probably because we
-                        * got called from fork1().  For now just deny the
-                        * allocation instead.
-                        */
-                       if (p->p_state != PRS_NORMAL) {
-                               should_deny = 1;
-                               continue;
-                       }
-
-                       /*
                         * We're using the fact that RCTL_ACTION_SIG* values
                         * are equal to their counterparts from sys/signal.h.
                         */

Modified: head/sys/sys/racct.h
==============================================================================
--- head/sys/sys/racct.h        Mon Oct  3 16:02:55 2011        (r225939)
+++ head/sys/sys/racct.h        Mon Oct  3 16:23:20 2011        (r225940)
@@ -137,6 +137,7 @@ void        racct_create(struct racct **racctp)
 void   racct_destroy(struct racct **racctp);
 
 int    racct_proc_fork(struct proc *parent, struct proc *child);
+void   racct_proc_fork_done(struct proc *child);
 void   racct_proc_exit(struct proc *p);
 
 void   racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to