1200483Srwatson/*
2200483Srwatson * Copyright (c) 2009 Mark Heily <mark@heily.com>
3200483Srwatson *
4200483Srwatson * Permission to use, copy, modify, and distribute this software for any
5200483Srwatson * purpose with or without fee is hereby granted, provided that the above
6200483Srwatson * copyright notice and this permission notice appear in all copies.
7200483Srwatson *
8200483Srwatson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9200483Srwatson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10200483Srwatson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11200483Srwatson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12200483Srwatson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13200483Srwatson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14200483Srwatson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15200483Srwatson *
16200483Srwatson * $FreeBSD: stable/11/tests/sys/kqueue/libkqueue/vnode.c 359754 2020-04-09 20:38:36Z kevans $
17200483Srwatson */
18200483Srwatson
19200483Srwatson#include "common.h"
20200483Srwatson
21200483Srwatsonint vnode_fd;
22200483Srwatson
23200483Srwatsonvoid
24200483Srwatsontest_kevent_vnode_add(void)
25200483Srwatson{
26200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, EV_ADD)";
27304797Sjmmv    const char *testfile = "./kqueue-test.tmp";
28200483Srwatson    struct kevent kev;
29200483Srwatson
30200483Srwatson    test_begin(test_id);
31200483Srwatson
32304797Sjmmv    system("touch ./kqueue-test.tmp");
33200483Srwatson    vnode_fd = open(testfile, O_RDONLY);
34200483Srwatson    if (vnode_fd < 0)
35200483Srwatson        err(1, "open of %s", testfile);
36200483Srwatson    else
37200483Srwatson        printf("vnode_fd = %d\n", vnode_fd);
38200483Srwatson
39200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD,
40200483Srwatson            NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME | NOTE_DELETE, 0, NULL);
41200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
42200483Srwatson        err(1, "%s", test_id);
43200483Srwatson
44200483Srwatson    success();
45200483Srwatson}
46200483Srwatson
47200483Srwatsonvoid
48200483Srwatsontest_kevent_vnode_note_delete(void)
49200483Srwatson{
50200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, NOTE_DELETE)";
51200483Srwatson    struct kevent kev;
52200483Srwatson
53200483Srwatson    test_begin(test_id);
54200483Srwatson
55200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_DELETE, 0, NULL);
56200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
57200483Srwatson        err(1, "%s", test_id);
58200483Srwatson
59304797Sjmmv    if (unlink("./kqueue-test.tmp") < 0)
60200483Srwatson        err(1, "unlink");
61200483Srwatson
62200483Srwatson    kevent_cmp(&kev, kevent_get(kqfd));
63200483Srwatson
64200483Srwatson    success();
65200483Srwatson}
66200483Srwatson
67200483Srwatsonvoid
68200483Srwatsontest_kevent_vnode_note_write(void)
69200483Srwatson{
70200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, NOTE_WRITE)";
71200483Srwatson    struct kevent kev;
72200483Srwatson
73200483Srwatson    test_begin(test_id);
74200483Srwatson
75200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_WRITE, 0, NULL);
76200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
77200483Srwatson        err(1, "%s", test_id);
78200483Srwatson
79304797Sjmmv    if (system("echo hello >> ./kqueue-test.tmp") < 0)
80200483Srwatson        err(1, "system");
81200483Srwatson
82200483Srwatson    /* BSD kqueue adds NOTE_EXTEND even though it was not requested */
83200483Srwatson    /* BSD kqueue removes EV_ENABLE */
84200483Srwatson    kev.flags &= ~EV_ENABLE; // XXX-FIXME compatibility issue
85200483Srwatson    kev.fflags |= NOTE_EXTEND; // XXX-FIXME compatibility issue
86200483Srwatson    kevent_cmp(&kev, kevent_get(kqfd));
87200483Srwatson
88200483Srwatson    success();
89200483Srwatson}
90200483Srwatson
91200483Srwatsonvoid
92200483Srwatsontest_kevent_vnode_note_attrib(void)
93200483Srwatson{
94200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, NOTE_ATTRIB)";
95200483Srwatson    struct kevent kev;
96200483Srwatson    int nfds;
97200483Srwatson
98200483Srwatson    test_begin(test_id);
99200483Srwatson
100200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
101200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
102200483Srwatson        err(1, "%s", test_id);
103200483Srwatson
104304797Sjmmv    if (system("touch ./kqueue-test.tmp") < 0)
105200483Srwatson        err(1, "system");
106200483Srwatson
107200483Srwatson    nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
108200483Srwatson    if (nfds < 1)
109200483Srwatson        err(1, "%s", test_id);
110200483Srwatson    if (kev.ident != vnode_fd ||
111200483Srwatson            kev.filter != EVFILT_VNODE ||
112200483Srwatson            kev.fflags != NOTE_ATTRIB)
113200483Srwatson        err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
114200483Srwatson                test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
115200483Srwatson
116200483Srwatson    success();
117200483Srwatson}
118200483Srwatson
119200483Srwatsonvoid
120200483Srwatsontest_kevent_vnode_note_rename(void)
121200483Srwatson{
122200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, NOTE_RENAME)";
123200483Srwatson    struct kevent kev;
124200483Srwatson    int nfds;
125200483Srwatson
126200483Srwatson    test_begin(test_id);
127200483Srwatson
128200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_RENAME, 0, NULL);
129200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
130200483Srwatson        err(1, "%s", test_id);
131200483Srwatson
132304797Sjmmv    if (system("mv ./kqueue-test.tmp ./kqueue-test2.tmp") < 0)
133200483Srwatson        err(1, "system");
134200483Srwatson
135200483Srwatson    nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
136200483Srwatson    if (nfds < 1)
137200483Srwatson        err(1, "%s", test_id);
138200483Srwatson    if (kev.ident != vnode_fd ||
139200483Srwatson            kev.filter != EVFILT_VNODE ||
140200483Srwatson            kev.fflags != NOTE_RENAME)
141200483Srwatson        err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
142200483Srwatson                test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
143200483Srwatson
144304797Sjmmv    if (system("mv ./kqueue-test2.tmp ./kqueue-test.tmp") < 0)
145200483Srwatson        err(1, "system");
146200483Srwatson
147200483Srwatson    success();
148200483Srwatson}
149200483Srwatson
150200483Srwatsonvoid
151200483Srwatsontest_kevent_vnode_del(void)
152200483Srwatson{
153200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, EV_DELETE)";
154200483Srwatson    struct kevent kev;
155200483Srwatson
156200483Srwatson    test_begin(test_id);
157200483Srwatson
158200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
159200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
160200483Srwatson        err(1, "%s", test_id);
161200483Srwatson
162200483Srwatson    success();
163200483Srwatson}
164200483Srwatson
165200483Srwatsonvoid
166200483Srwatsontest_kevent_vnode_disable_and_enable(void)
167200483Srwatson{
168200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, EV_DISABLE and EV_ENABLE)";
169200483Srwatson    struct kevent kev;
170200483Srwatson    int nfds;
171200483Srwatson
172200483Srwatson    test_begin(test_id);
173200483Srwatson
174200483Srwatson    test_no_kevents();
175200483Srwatson
176200483Srwatson    /* Add the watch and immediately disable it */
177200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, NOTE_ATTRIB, 0, NULL);
178200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
179200483Srwatson        err(1, "%s", test_id);
180200483Srwatson    kev.flags = EV_DISABLE;
181200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
182200483Srwatson        err(1, "%s", test_id);
183200483Srwatson
184200483Srwatson    /* Confirm that the watch is disabled */
185304797Sjmmv    if (system("touch ./kqueue-test.tmp") < 0)
186200483Srwatson        err(1, "system");
187200483Srwatson    test_no_kevents();
188200483Srwatson
189200483Srwatson    /* Re-enable and check again */
190200483Srwatson    kev.flags = EV_ENABLE;
191200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
192200483Srwatson        err(1, "%s", test_id);
193304797Sjmmv    if (system("touch ./kqueue-test.tmp") < 0)
194200483Srwatson        err(1, "system");
195200483Srwatson    nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
196200483Srwatson    if (nfds < 1)
197200483Srwatson        err(1, "%s", test_id);
198200483Srwatson    if (kev.ident != vnode_fd ||
199200483Srwatson            kev.filter != EVFILT_VNODE ||
200200483Srwatson            kev.fflags != NOTE_ATTRIB)
201200483Srwatson        err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
202200483Srwatson                test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
203200483Srwatson
204200483Srwatson    success();
205200483Srwatson}
206200483Srwatson
207200483Srwatson#if HAVE_EV_DISPATCH
208200483Srwatsonvoid
209200483Srwatsontest_kevent_vnode_dispatch(void)
210200483Srwatson{
211200483Srwatson    const char *test_id = "kevent(EVFILT_VNODE, EV_DISPATCH)";
212200483Srwatson    struct kevent kev;
213200483Srwatson    int nfds;
214200483Srwatson
215200483Srwatson    test_begin(test_id);
216200483Srwatson
217200483Srwatson    test_no_kevents();
218200483Srwatson
219200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_ADD | EV_DISPATCH, NOTE_ATTRIB, 0, NULL);
220200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
221200483Srwatson        err(1, "%s", test_id);
222200483Srwatson
223304797Sjmmv    if (system("touch ./kqueue-test.tmp") < 0)
224200483Srwatson        err(1, "system");
225200483Srwatson
226200483Srwatson    nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
227200483Srwatson    if (nfds < 1)
228200483Srwatson        err(1, "%s", test_id);
229200483Srwatson    if (kev.ident != vnode_fd ||
230200483Srwatson            kev.filter != EVFILT_VNODE ||
231200483Srwatson            kev.fflags != NOTE_ATTRIB)
232200483Srwatson        err(1, "%s - incorrect event (sig=%u; filt=%d; flags=%d)",
233200483Srwatson                test_id, (unsigned int)kev.ident, kev.filter, kev.flags);
234200483Srwatson
235200483Srwatson    /* Confirm that the watch is disabled automatically */
236200483Srwatson    puts("-- checking that watch is disabled");
237304797Sjmmv    if (system("touch ./kqueue-test.tmp") < 0)
238200483Srwatson        err(1, "system");
239200483Srwatson    test_no_kevents();
240200483Srwatson
241200483Srwatson    /* Delete the watch */
242200483Srwatson    EV_SET(&kev, vnode_fd, EVFILT_VNODE, EV_DELETE, NOTE_ATTRIB, 0, NULL);
243200483Srwatson    if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0)
244200483Srwatson        err(1, "remove watch failed: %s", test_id);
245200483Srwatson
246200483Srwatson    success();
247200483Srwatson}
248200483Srwatson#endif 	/* HAVE_EV_DISPATCH */
249200483Srwatson
250200483Srwatsonvoid
251200483Srwatsontest_evfilt_vnode()
252200483Srwatson{
253341275Sdab    kqfd = kqueue();
254341275Sdab    test_kevent_vnode_add();
255341275Sdab    test_kevent_vnode_del();
256341275Sdab    test_kevent_vnode_disable_and_enable();
257200483Srwatson#if HAVE_EV_DISPATCH
258341275Sdab    test_kevent_vnode_dispatch();
259200483Srwatson#endif
260341275Sdab    test_kevent_vnode_note_write();
261341275Sdab    test_kevent_vnode_note_attrib();
262341275Sdab    test_kevent_vnode_note_rename();
263341275Sdab    test_kevent_vnode_note_delete();
264341275Sdab    close(kqfd);
265200483Srwatson}
266