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