Author: dchagin
Date: Sun Apr 10 07:11:29 2016
New Revision: 297781
URL: https://svnweb.freebsd.org/changeset/base/297781

Log:
  More complete implementation of /proc/self/limits.
  Fix the way the code accesses process limits struct - pointed out by mjg@.
  
  PR:           207386
  Reviewed by:  no objection form des@
  MFC after:    3 weeks

Modified:
  head/sys/compat/linprocfs/linprocfs.c
  head/sys/compat/linux/linux_misc.h

Modified: head/sys/compat/linprocfs/linprocfs.c
==============================================================================
--- head/sys/compat/linprocfs/linprocfs.c       Sun Apr 10 06:36:58 2016        
(r297780)
+++ head/sys/compat/linprocfs/linprocfs.c       Sun Apr 10 07:11:29 2016        
(r297781)
@@ -1370,65 +1370,92 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
 /*
  * Filler function for proc/pid/limits
  */
-
-#define RLIM_NONE -1
-
-static const struct limit_info {
+static const struct linux_rlimit_ident {
        const char      *desc;
        const char      *unit;
-       unsigned long long      rlim_id;
-} limits_info[] = {
-       { "Max cpu time",               "seconds",      RLIMIT_CPU },
-       { "Max file size",              "bytes",        RLIMIT_FSIZE },
-       { "Max data size",              "bytes",        RLIMIT_DATA },
-       { "Max stack size",             "bytes",        RLIMIT_STACK },
-       { "Max core file size",         "bytes",        RLIMIT_CORE },
-       { "Max resident set",           "bytes",        RLIMIT_RSS },
-       { "Max processes",              "processes",    RLIMIT_NPROC },
-       { "Max open files",             "files",        RLIMIT_NOFILE },
-       { "Max locked memory",          "bytes",        RLIMIT_MEMLOCK },
-       { "Max address space",          "bytes",        RLIMIT_AS },
-       { "Max file locks",             "locks",        RLIM_INFINITY },
-       { "Max pending signals",        "signals",      RLIM_INFINITY },
-       { "Max msgqueue size",          "bytes",        RLIM_NONE },
-       { "Max nice priority",          "",             RLIM_NONE },
-       { "Max realtime priority",      "",             RLIM_NONE },
-       { "Max realtime timeout",       "us",           RLIM_INFINITY },
+       unsigned int    rlim_id;
+} linux_rlimits_ident[] = {
+       { "Max cpu time",       "seconds",      RLIMIT_CPU },
+       { "Max file size",      "bytes",        RLIMIT_FSIZE },
+       { "Max data size",      "bytes",        RLIMIT_DATA },
+       { "Max stack size",     "bytes",        RLIMIT_STACK },
+       { "Max core file size",  "bytes",       RLIMIT_CORE },
+       { "Max resident set",   "bytes",        RLIMIT_RSS },
+       { "Max processes",      "processes",    RLIMIT_NPROC },
+       { "Max open files",     "files",        RLIMIT_NOFILE },
+       { "Max locked memory",  "bytes",        RLIMIT_MEMLOCK },
+       { "Max address space",  "bytes",        RLIMIT_AS },
+       { "Max file locks",     "locks",        LINUX_RLIMIT_LOCKS },
+       { "Max pending signals", "signals",     LINUX_RLIMIT_SIGPENDING },
+       { "Max msgqueue size",  "bytes",        LINUX_RLIMIT_MSGQUEUE },
+       { "Max nice priority",          "",     LINUX_RLIMIT_NICE },
+       { "Max realtime priority",      "",     LINUX_RLIMIT_RTPRIO },
+       { "Max realtime timeout",       "us",   LINUX_RLIMIT_RTTIME },
        { 0, 0, 0 }
 };
 
 static int
 linprocfs_doproclimits(PFS_FILL_ARGS)
 {
-       const struct limit_info *li;
-       struct rlimit li_rlimits;
-       struct plimit *cur_proc_lim;
-
-       cur_proc_lim = lim_alloc();
-       lim_copy(cur_proc_lim, p->p_limit);
-       sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n", "Limit", "Soft Limit",
+       const struct linux_rlimit_ident *li;
+       struct plimit *limp;
+       struct rlimit rl;
+       ssize_t size;
+       int res, error;
+
+       PROC_LOCK(p);
+       limp = lim_hold(p->p_limit);
+       PROC_UNLOCK(p);
+       size = sizeof(res);
+       sbuf_printf(sb, "%-26s%-21s%-21s%-21s\n", "Limit", "Soft Limit",
                        "Hard Limit", "Units");
-       for (li = limits_info; li->desc != NULL; ++li) {
-               if (li->rlim_id != RLIM_INFINITY && li->rlim_id != RLIM_NONE)
-                       li_rlimits = cur_proc_lim->pl_rlimit[li->rlim_id];
-               else {
-                       li_rlimits.rlim_cur = 0;
-                       li_rlimits.rlim_max = 0;
+       for (li = linux_rlimits_ident; li->desc != NULL; ++li) {
+               switch (li->rlim_id)
+               {
+               case LINUX_RLIMIT_LOCKS:
+                       /* FALLTHROUGH */
+               case LINUX_RLIMIT_RTTIME:
+                       rl.rlim_cur = RLIM_INFINITY;
+                       break;
+               case LINUX_RLIMIT_SIGPENDING:
+                       error = kernel_sysctlbyname(td,
+                           "kern.sigqueue.max_pending_per_proc",
+                           &res, &size, 0, 0, 0, 0);
+                       if (error != 0)
+                               break;
+                       rl.rlim_cur = res;
+                       rl.rlim_max = res;
+                       break;
+               case LINUX_RLIMIT_MSGQUEUE:
+                       error = kernel_sysctlbyname(td,
+                           "kern.ipc.msgmnb", &res, &size, 0, 0, 0, 0);
+                       if (error != 0)
+                               break;
+                       rl.rlim_cur = res;
+                       rl.rlim_max = res;
+                       break;
+               case LINUX_RLIMIT_NICE:
+                       /* FALLTHROUGH */
+               case LINUX_RLIMIT_RTPRIO:
+                       rl.rlim_cur = 0;
+                       rl.rlim_max = 0;
+                       break;
+               default:
+                       rl = limp->pl_rlimit[li->rlim_id];
+                       break;
                }
-               if (li->rlim_id == RLIM_INFINITY ||
-                   li_rlimits.rlim_cur == RLIM_INFINITY)
+               if (rl.rlim_cur == RLIM_INFINITY)
                        sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n",
                            li->desc, "unlimited", "unlimited", li->unit);
                else
-                       sbuf_printf(sb, "%-26s%-21ld%-21ld%-10s\n",
-                           li->desc, (long)li_rlimits.rlim_cur,
-                           (long)li_rlimits.rlim_max, li->unit);
+                       sbuf_printf(sb, "%-26s%-21llu%-21llu%-10s\n",
+                           li->desc, (unsigned long long)rl.rlim_cur,
+                           (unsigned long long)rl.rlim_max, li->unit);
        }
-       lim_free(cur_proc_lim);
-       return (0);
+       lim_free(limp);
+       return (error);
 }
 
-
 /*
  * Filler function for proc/sys/kernel/random/uuid
  */

Modified: head/sys/compat/linux/linux_misc.h
==============================================================================
--- head/sys/compat/linux/linux_misc.h  Sun Apr 10 06:36:58 2016        
(r297780)
+++ head/sys/compat/linux/linux_misc.h  Sun Apr 10 07:11:29 2016        
(r297781)
@@ -143,6 +143,13 @@ extern int stclohz;
 #define        LINUX_P_PID             1
 #define        LINUX_P_PGID            2
 
+#define        LINUX_RLIMIT_LOCKS      RLIM_NLIMITS + 1
+#define        LINUX_RLIMIT_SIGPENDING RLIM_NLIMITS + 2
+#define        LINUX_RLIMIT_MSGQUEUE   RLIM_NLIMITS + 3
+#define        LINUX_RLIMIT_NICE       RLIM_NLIMITS + 4
+#define        LINUX_RLIMIT_RTPRIO     RLIM_NLIMITS + 5
+#define        LINUX_RLIMIT_RTTIME     RLIM_NLIMITS + 6
+
 #define        LINUX_RLIM_INFINITY     (~0UL)
 
 int linux_common_wait(struct thread *td, int pid, int *status,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to