From owner-freebsd-hackers Sun Oct 14 1:58: 7 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from segfault.kiev.ua (segfault.kiev.ua [193.193.193.4]) by hub.freebsd.org (Postfix) with ESMTP id 518FC37B401 for ; Sun, 14 Oct 2001 01:57:57 -0700 (PDT) Received: (from uucp@localhost) by segfault.kiev.ua (8) with UUCP id LWF24436; Sun, 14 Oct 2001 11:57:43 +0300 (EEST) (envelope-from netch@iv.nn.kiev.ua) Received: (from netch@localhost) by iv.nn.kiev.ua (8.11.6/8.11.6) id f9E8kvi06796; Sun, 14 Oct 2001 11:46:57 +0300 (EEST) (envelope-from netch) Date: Sun, 14 Oct 2001 11:46:57 +0300 From: Valentin Nechayev To: "E.B. Dreger" Cc: hackers@FreeBSD.ORG Subject: Re: AIO issues... or not? Message-ID: <20011014114657.C3718@iv.nn.kiev.ua> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: ; from eddy+public+spam@noc.everquick.net on Fri, Oct 05, 2001 at 02:19:58PM +0000 X-42: On Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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