1/*
2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (c) 1989, 1993
25 *	The Regents of the University of California.  All rights reserved.
26 *
27 * This code is derived from software contributed to Berkeley by
28 * Rick Macklem at The University of Guelph.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 *    notice, this list of conditions and the following disclaimer in the
37 *    documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 *    must display the following acknowledgement:
40 *	This product includes software developed by the University of
41 *	California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 *    may be used to endorse or promote products derived from this software
44 *    without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59#include <sys/param.h>
60#include <sys/ioctl.h>
61#include <sys/syslog.h>
62#include <sys/ucred.h>
63#include <sys/wait.h>
64#include <sys/types.h>
65#include <sys/sysctl.h>
66
67#include <err.h>
68#include <errno.h>
69#include <fcntl.h>
70#include <signal.h>
71#include <stdio.h>
72#include <stdlib.h>
73#include <unistd.h>
74#include <string.h>
75
76#define	NFS_DEFASYNCTHREAD 	16	/* Def. # nfsiod threads */
77#define	NFS_MAXASYNCTHREAD 	128	/* max # nfsiod threads */
78
79void
80usage(void)
81{
82	fprintf(stderr, "usage: nfsiod [-n num_servers]\n");
83	exit(1);
84}
85
86/*
87 * nfsiod does asynchronous buffered I/O on behalf of the NFS client.
88 * It does not have to be running for correct operation, but will
89 * improve throughput.
90 */
91int
92main(int argc, char *argv[])
93{
94	int ch, rv, num_servers, old_servers;
95	size_t num_size, old_size;
96
97	num_servers = old_servers = -1;
98	num_size = sizeof(num_servers);
99	old_size = sizeof(old_servers);
100
101	while ((ch = getopt(argc, argv, "n:")) != EOF)
102		switch (ch) {
103		case 'n':
104			num_servers = atoi(optarg);
105			if (num_servers < 0)
106				errx(1, "invalid count: %d", num_servers);
107			break;
108		case '?':
109		default:
110			usage();
111		}
112	argc -= optind;
113	argv += optind;
114
115	/*
116	 * XXX
117	 * Backward compatibility, trailing number is the count of threads.
118	 */
119	if (argc > 1)
120		usage();
121	if (argc == 1) {
122		num_servers = atoi(argv[0]);
123		if (num_servers < 0)
124			errx(1, "invalid count: %d", num_servers);
125	}
126
127	if (num_servers > NFS_MAXASYNCTHREAD) {
128		warnx("nfsiod count %d; clamped to %d", num_servers, NFS_MAXASYNCTHREAD);
129		num_servers = NFS_MAXASYNCTHREAD;
130	}
131
132	if (num_servers == -1)
133		rv = sysctlbyname("vfs.generic.nfs.client.nfsiod_thread_max", &old_servers, &old_size, NULL, 0);
134	else
135		rv = sysctlbyname("vfs.generic.nfs.client.nfsiod_thread_max", &old_servers, &old_size, &num_servers, num_size);
136	if (rv < 0)
137		err(1, "sysctl(vfs.generic.nfs.client.nfsiod_thread_max)");
138
139	printf("nfs.client.nfsiod_thread_max: ");
140	printf("%d", old_servers);
141	if (num_servers != -1)
142		printf(" -> %d", num_servers);
143	printf("\n");
144
145	exit (0);
146}
147