]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / fs / puffs / h_dtfs / dtfs.c
1 /*      $NetBSD: dtfs.c,v 1.2 2010/07/21 06:58:25 pooka Exp $   */
2
3 /*
4  * Copyright (c) 2006  Antti Kantee.  All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 /*
29  * Delectable Test File System: a simple in-memory file system which
30  * demonstrates the use of puffs.
31  * (a.k.a. Detrempe FS ...)
32  */
33
34 #include <sys/types.h>
35
36 #include <err.h>
37 #include <mntopts.h>
38 #include <paths.h>
39 #include <puffs.h>
40 #include <signal.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45
46 #include "dtfs.h"
47
48 #ifdef DEEP_ROOTED_CLUE
49 #define FSNAME "detrempe"
50 #else
51 #define FSNAME "dt"
52 #endif
53 #define MAXREQMAGIC -37
54
55 static struct puffs_usermount *gpu;
56 static struct dtfs_mount gdtm;
57 int dynamicfh;
58 int straightflush;
59
60 static void usage(void);
61
62 static void
63 usage()
64 {
65
66         fprintf(stderr, "usage: %s [-bsdftl] [-c hashbuckets] [-m maxreqsize] "
67             "[-n typename]\n       [-o mntopt] [-o puffsopt] [-p prot] "
68             "[-r rootnodetype]\n       detrempe /mountpoint\n", getprogname());
69         exit(1);
70 }
71
72 static void
73 wipe_the_sleep_out_of_my_eyes(int v)
74 {
75
76         gdtm.dtm_needwakeup++;
77 }
78
79 static void
80 loopfun(struct puffs_usermount *pu)
81 {
82         struct dtfs_mount *dtm = puffs_getspecific(pu);
83         struct dtfs_poll *dp;
84
85         while (dtm->dtm_needwakeup) {
86                 dtm->dtm_needwakeup--;
87                 dp = LIST_FIRST(&dtm->dtm_pollent);
88                 if (dp == NULL)
89                         return;
90
91                 LIST_REMOVE(dp, dp_entries);
92                 puffs_cc_continue(dp->dp_pcc);
93         }
94 }
95
96 int
97 main(int argc, char *argv[])
98 {
99         extern char *optarg;
100         extern int optind;
101         struct puffs_usermount *pu;
102         struct puffs_pathobj *po_root;
103         struct puffs_ops *pops;
104         struct timespec ts;
105         const char *typename;
106         char *rtstr;
107         mntoptparse_t mp;
108         int pflags, detach, mntflags;
109         int ch;
110         int khashbuckets;
111         int maxreqsize;
112
113         setprogname(argv[0]);
114
115         rtstr = NULL;
116         detach = 1;
117         mntflags = 0;
118         khashbuckets = 256;
119         pflags = PUFFS_KFLAG_IAONDEMAND;
120         typename = FSNAME;
121         maxreqsize = MAXREQMAGIC;
122         gdtm.dtm_allowprot = VM_PROT_ALL;
123         while ((ch = getopt(argc, argv, "bc:dfilm:n:o:p:r:st")) != -1) {
124                 switch (ch) {
125                 case 'b': /* build paths, for debugging the feature */
126                         pflags |= PUFFS_FLAG_BUILDPATH;
127                         break;
128                 case 'c':
129                         khashbuckets = atoi(optarg);
130                         break;
131                 case 'd':
132                         dynamicfh = 1;
133                         break;
134                 case 'f':
135                         pflags |= PUFFS_KFLAG_LOOKUP_FULLPNBUF;
136                         break;
137                 case 'i':
138                         pflags &= ~PUFFS_KFLAG_IAONDEMAND;
139                         break;
140                 case 'l':
141                         straightflush = 1;
142                         break;
143                 case 'm':
144                         maxreqsize = atoi(optarg);
145                         break;
146                 case 'n':
147                         typename = optarg;
148                         break;
149                 case 'o':
150                         mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
151                         if (mp == NULL)
152                                 err(1, "getmntopts");
153                         freemntopts(mp);
154                         break;
155                 case 'p':
156                         gdtm.dtm_allowprot = atoi(optarg);
157                         if ((gdtm.dtm_allowprot | VM_PROT_ALL) != VM_PROT_ALL)
158                                 usage();
159                         break;
160                 case 'r':
161                         rtstr = optarg;
162                         break;
163                 case 's': /* stay on top */
164                         detach = 0;
165                         break;
166                 case 't':
167                         pflags |= PUFFS_KFLAG_WTCACHE;
168                         break;
169                 default:
170                         usage();
171                         /*NOTREACHED*/
172                 }
173         }
174         if (pflags & PUFFS_FLAG_OPDUMP)
175                 detach = 0;
176         argc -= optind;
177         argv += optind;
178
179         if (argc != 2)
180                 usage();
181
182         PUFFSOP_INIT(pops);
183
184         PUFFSOP_SET(pops, dtfs, fs, statvfs);
185         PUFFSOP_SET(pops, dtfs, fs, unmount);
186         PUFFSOP_SETFSNOP(pops, sync);
187         PUFFSOP_SET(pops, dtfs, fs, fhtonode);
188         PUFFSOP_SET(pops, dtfs, fs, nodetofh);
189
190         PUFFSOP_SET(pops, dtfs, node, lookup);
191         PUFFSOP_SET(pops, dtfs, node, access);
192         PUFFSOP_SET(pops, puffs_genfs, node, getattr);
193         PUFFSOP_SET(pops, dtfs, node, setattr);
194         PUFFSOP_SET(pops, dtfs, node, create);
195         PUFFSOP_SET(pops, dtfs, node, remove);
196         PUFFSOP_SET(pops, dtfs, node, readdir);
197         PUFFSOP_SET(pops, dtfs, node, poll);
198         PUFFSOP_SET(pops, dtfs, node, mmap);
199         PUFFSOP_SET(pops, dtfs, node, mkdir);
200         PUFFSOP_SET(pops, dtfs, node, rmdir);
201         PUFFSOP_SET(pops, dtfs, node, rename);
202         PUFFSOP_SET(pops, dtfs, node, read);
203         PUFFSOP_SET(pops, dtfs, node, write);
204         PUFFSOP_SET(pops, dtfs, node, link);
205         PUFFSOP_SET(pops, dtfs, node, symlink);
206         PUFFSOP_SET(pops, dtfs, node, readlink);
207         PUFFSOP_SET(pops, dtfs, node, mknod);
208         PUFFSOP_SET(pops, dtfs, node, inactive);
209         PUFFSOP_SET(pops, dtfs, node, pathconf);
210         PUFFSOP_SET(pops, dtfs, node, reclaim);
211
212         srandom(time(NULL)); /* for random generation numbers */
213
214         pu = puffs_init(pops, _PATH_PUFFS, typename, &gdtm, pflags);
215         if (pu == NULL)
216                 err(1, "init");
217         gpu = pu;
218
219         puffs_setfhsize(pu, sizeof(struct dtfs_fid),
220             PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3
221             | (dynamicfh ? PUFFS_FHFLAG_DYNAMIC : 0));
222         puffs_setncookiehash(pu, khashbuckets);
223
224         if (signal(SIGALRM, wipe_the_sleep_out_of_my_eyes) == SIG_ERR)
225                 warn("cannot set alarm sighandler");
226
227         /* init */
228         if (dtfs_domount(pu, rtstr) != 0)
229                 errx(1, "dtfs_domount failed");
230
231         po_root = puffs_getrootpathobj(pu);
232         po_root->po_path = argv[0];
233         po_root->po_len = strlen(argv[0]);
234
235         /* often enough for testing poll */
236         ts.tv_sec = 1;
237         ts.tv_nsec = 0;
238         puffs_ml_setloopfn(pu, loopfun);
239         puffs_ml_settimeout(pu, &ts);
240
241         if (maxreqsize != MAXREQMAGIC)
242                 puffs_setmaxreqlen(pu, maxreqsize);
243
244         puffs_set_errnotify(pu, puffs_kernerr_abort);
245         if (detach)
246                 if (puffs_daemon(pu, 1, 1) == -1)
247                         err(1, "puffs_daemon");
248
249         if (puffs_mount(pu,  argv[1], mntflags, puffs_getroot(pu)) == -1)
250                 err(1, "mount");
251         if (puffs_mainloop(pu) == -1)
252                 err(1, "mainloop");
253
254         return 0;
255 }