Fri, Oct 05, 2001 at 14:19:58, eddy+public+spam (E.B. Dreger) wrote about "AIO 
issues... or not?": 

> When using aio_* calls, I received ENOSYS.  I grepped LINT, and
> found that I'd forgotten to "OPTIONS VFS_AIO".  Simple enough.
> 
> However, there's a rather ominous and non-descriptive warning
> present:  "There are numerous stability issues in the current aio
> code that make it unsuitable for inclusion on shell boxes."  Can
> anyone please elaborate?  Is this admonition outdated?

At least, privilege to use AIO can be simply bound to some group ID.
I use it on our http proxy server together with patch for squid to use
kernel AIO in aufs code.

--- vfs_aio.c.0 Sat Sep  1 13:33:37 2001
+++ vfs_aio.c   Sat Sep  8 23:03:58 2001
@@ -97,7 +97,12 @@
 static int max_aio_procs = MAX_AIO_PROCS;
 static int num_aio_procs = 0;
 static int target_aio_procs = TARGET_AIO_PROCS;
+/* VFS_AIO_DISABLE_AT_STARTUP is kernel compiling option */
+#ifdef VFS_AIO_DISABLE_AT_STARTUP
+static int max_queue_count = 0;
+#else
 static int max_queue_count = MAX_AIO_QUEUE;
+#endif
 static int num_queue_count = 0;
 static int num_buf_aio = 0;
 static int num_aio_resv_start = 0;
@@ -108,6 +113,16 @@
 static int max_aio_queue_per_proc = MAX_AIO_QUEUE_PER_PROC;
 static int max_buf_aio = MAX_BUF_AIO;
 
+/*
+ * aio_group sets group which is allowed to use AIO.
+ * Two special values:
+ * -1 - don't check group, allow for all
+ * -2 - no group is allowed
+ * Root's process are allowed always to use AIO in this checking.
+ * But they may fail if any limit above is set to 0.
+ */
+static long aio_group = 0; /* allow only for group wheel by default */
+
 SYSCTL_NODE(_vfs, OID_AUTO, aio, CTLFLAG_RW, 0, "AIO mgmt");
 
 SYSCTL_INT(_vfs_aio, OID_AUTO, max_aio_per_proc,
@@ -143,6 +158,12 @@
 SYSCTL_INT(_vfs_aio, OID_AUTO, aiod_timeout,
        CTLFLAG_RW, &aiod_timeout, 0, "");
 
+SYSCTL_LONG(_vfs_aio, OID_AUTO, aio_group,
+       CTLFLAG_RW, &aio_group, 0, "");
+
+SYSCTL_LONG(_vfs_aio, OID_AUTO, jobrefid,
+       CTLFLAG_RD, &jobrefid, 0, "");
+
 /*
  * AIO process info
  */
@@ -1453,19 +1465,55 @@
 }
 
 /*
+ * Check permissions, global and process, to use AIO
+ * Called from aio_aqueue() and lio_listio()
+ */
+static int
+aio_allowed(struct proc *p)
+{
+       /* Hard bounce if aio is disabled in sysctl. */
+       if (max_queue_count <= 0 || max_aio_procs <= 0 ||
+           max_aio_per_proc <= 0)
+               return EPROCLIM;
+       if (num_queue_count >= max_queue_count)
+               return EAGAIN;
+
+       /* Check permissions. Allow only root or specified group member. */
+       /* XXX lock/unlock process? (for FreeBSD5) */
+       if (suser_xxx(0, p, PRISON_ROOT) && aio_group != -1) {
+               int ig;
+               if (aio_group == -2)
+                       return EPERM;
+               for (ig = 0; ig < p->p_ucred->cr_ngroups; ig++) {
+                       if (p->p_ucred->cr_groups[ig] == (gid_t)aio_group)
+                               return 0;
+               }
+               return EPERM;
+       }
+       return 0;
+}
+
+/*
  * This routine queues an AIO request, checking for quotas.
  */
 static int
 aio_aqueue(struct proc *p, struct aiocb *job, int type)
 {
        struct kaioinfo *ki;
+       int error;
+
+       /*
+        * Forward this global check before aio_init_aioinfo().
+        * Don't waste resources if it is not allowed.
+        * max_queue_count is sysctl vfs.aio.max_aio_queue.
+        */
+       error = aio_allowed(p);
+       if (error)
+               return error;
 
        if (p->p_aioinfo == NULL)
                aio_init_aioinfo(p);
 
-       if (num_queue_count >= max_queue_count)
-               return EAGAIN;
-
        ki = p->p_aioinfo;
        if (ki->kaio_queue_count >= ki->kaio_qallowed_count)
                return EAGAIN;
@@ -1921,6 +1978,11 @@
        if (nent > AIO_LISTIO_MAX)
                return EINVAL;
 
+       /* Check permissions. */
+       error = aio_allowed(p);
+       if (error)
+               return error;
+
        if (p->p_aioinfo == NULL)
                aio_init_aioinfo(p);
 


/netch

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to