Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Oct 2001 11:46:57 +0300
From:      Valentin Nechayev <netch@iv.nn.kiev.ua>
To:        "E.B. Dreger" <eddy+public+spam@noc.everquick.net>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: AIO issues... or not?
Message-ID:  <20011014114657.C3718@iv.nn.kiev.ua>
In-Reply-To: <Pine.LNX.4.20.0110051355580.28641-100000@www.everquick.net>; from eddy%2Bpublic%2Bspam@noc.everquick.net on Fri, Oct 05, 2001 at 02:19:58PM %2B0000
References:  <Pine.LNX.4.20.0110051355580.28641-100000@www.everquick.net>

next in thread | previous in thread | raw e-mail | index | archive | help
 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 majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011014114657.C3718>