]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/filemon/filemon_wrapper.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / filemon / filemon_wrapper.c
1 /*-
2  * Copyright (c) 2011, David E. O'Brien.
3  * Copyright (c) 2009-2011, Juniper Networks, Inc.
4  * 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 JUNIPER NETWORKS AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL JUNIPER NETWORKS 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
21  * OR 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 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/sx.h>
32
33 #include "opt_compat.h"
34
35 #if __FreeBSD_version > 800032
36 #define FILEMON_HAS_LINKAT
37 #endif
38
39 #if __FreeBSD_version < 900044  /* r225617 (2011-09-16) failed to bump
40                                    __FreeBSD_version.  This really should
41                                    be based on "900045".  "900044" is r225469
42                                    (2011-09-10) so this code is broken for
43                                    9-CURRENT September 10th-16th. */
44 #define sys_chdir       chdir
45 #define sys_execve      execve
46 #define sys_fork        fork
47 #define sys_link        link
48 #define sys_open        open
49 #define sys_rename      rename
50 #define sys_stat        stat
51 #define sys_symlink     symlink
52 #define sys_unlink      unlink
53 #define sys_vfork       vfork
54 #define sys_sys_exit    sys_exit
55 #ifdef FILEMON_HAS_LINKAT
56 #define sys_linkat      linkat
57 #endif
58 #endif  /* __FreeBSD_version */
59
60 static void
61 filemon_output(struct filemon *filemon, char *msg, size_t len)
62 {
63         struct uio auio;
64         struct iovec aiov;
65
66         if (filemon->fp == NULL)
67                 return;
68
69         aiov.iov_base = msg;
70         aiov.iov_len = len;
71         auio.uio_iov = &aiov;
72         auio.uio_iovcnt = 1;
73         auio.uio_resid = len;
74         auio.uio_segflg = UIO_SYSSPACE;
75         auio.uio_rw = UIO_WRITE;
76         auio.uio_td = curthread;
77         auio.uio_offset = (off_t) -1;
78
79         bwillwrite();
80
81         fo_write(filemon->fp, &auio, curthread->td_ucred, 0, curthread);
82 }
83
84 static struct filemon *
85 filemon_pid_check(struct proc *p)
86 {
87         struct filemon *filemon;
88
89         sx_slock(&proctree_lock);
90         while (p != initproc) {
91                 TAILQ_FOREACH(filemon, &filemons_inuse, link) {
92                         if (p->p_pid == filemon->pid) {
93                                 sx_sunlock(&proctree_lock);
94                                 return (filemon);
95                         }
96                 }
97                 p = proc_realparent(p);
98         }
99         sx_sunlock(&proctree_lock);
100         return (NULL);
101 }
102
103 static void
104 filemon_comment(struct filemon *filemon)
105 {
106         int len;
107         struct timeval now;
108
109         /* Load timestamp before locking.  Less accurate but less contention. */
110         getmicrotime(&now);
111
112         /* Grab a read lock on the filemon inuse list. */
113         filemon_lock_read();
114
115         /* Lock the found filemon structure. */
116         filemon_filemon_lock(filemon);
117
118         len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr),
119             "# filemon version %d\n# Target pid %d\n# Start %ju.%06ju\nV %d\n",
120             FILEMON_VERSION, curproc->p_pid, (uintmax_t)now.tv_sec,
121             (uintmax_t)now.tv_usec, FILEMON_VERSION);
122
123         filemon_output(filemon, filemon->msgbufr, len);
124
125         /* Unlock the found filemon structure. */
126         filemon_filemon_unlock(filemon);
127
128         /* Release the read lock. */
129         filemon_unlock_read();
130 }
131
132 static int
133 filemon_wrapper_chdir(struct thread *td, struct chdir_args *uap)
134 {
135         int ret;
136         size_t done;
137         size_t len;
138         struct filemon *filemon;
139
140         if ((ret = sys_chdir(td, uap)) == 0) {
141                 /* Grab a read lock on the filemon inuse list. */
142                 filemon_lock_read();
143
144                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
145                         /* Lock the found filemon structure. */
146                         filemon_filemon_lock(filemon);
147
148                         copyinstr(uap->path, filemon->fname1,
149                             sizeof(filemon->fname1), &done);
150
151                         len = snprintf(filemon->msgbufr,
152                             sizeof(filemon->msgbufr), "C %d %s\n",
153                             curproc->p_pid, filemon->fname1);
154
155                         filemon_output(filemon, filemon->msgbufr, len);
156
157                         /* Unlock the found filemon structure. */
158                         filemon_filemon_unlock(filemon);
159                 }
160
161                 /* Release the read lock. */
162                 filemon_unlock_read();
163         }
164
165         return (ret);
166 }
167
168 static int
169 filemon_wrapper_execve(struct thread *td, struct execve_args *uap)
170 {
171         char fname[MAXPATHLEN];
172         int ret;
173         size_t done;
174         size_t len;
175         struct filemon *filemon;
176
177         copyinstr(uap->fname, fname, sizeof(fname), &done);
178
179         if ((ret = sys_execve(td, uap)) == 0) {
180                 /* Grab a read lock on the filemon inuse list. */
181                 filemon_lock_read();
182
183                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
184                         /* Lock the found filemon structure. */
185                         filemon_filemon_lock(filemon);
186
187                         len = snprintf(filemon->msgbufr,
188                             sizeof(filemon->msgbufr), "E %d %s\n",
189                             curproc->p_pid, fname);
190
191                         filemon_output(filemon, filemon->msgbufr, len);
192
193                         /* Unlock the found filemon structure. */
194                         filemon_filemon_unlock(filemon);
195                 }
196
197                 /* Release the read lock. */
198                 filemon_unlock_read();
199         }
200
201         return (ret);
202 }
203
204 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
205 static int
206 filemon_wrapper_freebsd32_execve(struct thread *td,
207     struct freebsd32_execve_args *uap)
208 {
209         char fname[MAXPATHLEN];
210         int ret;
211         size_t done;
212         size_t len;
213         struct filemon *filemon;
214
215         copyinstr(uap->fname, fname, sizeof(fname), &done);
216
217         if ((ret = freebsd32_execve(td, uap)) == 0) {
218                 /* Grab a read lock on the filemon inuse list. */
219                 filemon_lock_read();
220
221                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
222                         /* Lock the found filemon structure. */
223                         filemon_filemon_lock(filemon);
224
225                         len = snprintf(filemon->msgbufr,
226                             sizeof(filemon->msgbufr), "E %d %s\n",
227                             curproc->p_pid, fname);
228
229                         filemon_output(filemon, filemon->msgbufr, len);
230
231                         /* Unlock the found filemon structure. */
232                         filemon_filemon_unlock(filemon);
233                 }
234
235                 /* Release the read lock. */
236                 filemon_unlock_read();
237         }
238
239         return (ret);
240 }
241 #endif
242
243 static int
244 filemon_wrapper_fork(struct thread *td, struct fork_args *uap)
245 {
246         int ret;
247         size_t len;
248         struct filemon *filemon;
249
250         if ((ret = sys_fork(td, uap)) == 0) {
251                 /* Grab a read lock on the filemon inuse list. */
252                 filemon_lock_read();
253
254                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
255                         /* Lock the found filemon structure. */
256                         filemon_filemon_lock(filemon);
257
258                         len = snprintf(filemon->msgbufr,
259                             sizeof(filemon->msgbufr), "F %d %ld\n",
260                             curproc->p_pid, (long)curthread->td_retval[0]);
261
262                         filemon_output(filemon, filemon->msgbufr, len);
263
264                         /* Unlock the found filemon structure. */
265                         filemon_filemon_unlock(filemon);
266                 }
267
268                 /* Release the read lock. */
269                 filemon_unlock_read();
270         }
271
272         return (ret);
273 }
274
275 static int
276 filemon_wrapper_open(struct thread *td, struct open_args *uap)
277 {
278         int ret;
279         size_t done;
280         size_t len;
281         struct filemon *filemon;
282
283         if ((ret = sys_open(td, uap)) == 0) {
284                 /* Grab a read lock on the filemon inuse list. */
285                 filemon_lock_read();
286
287                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
288                         /* Lock the found filemon structure. */
289                         filemon_filemon_lock(filemon);
290
291                         copyinstr(uap->path, filemon->fname1,
292                             sizeof(filemon->fname1), &done);
293
294                         if (uap->flags & O_RDWR) {
295                                 /*
296                                  * We'll get the W record below, but need
297                                  * to also output an R to distingish from
298                                  * O_WRONLY.
299                                  */
300                                 len = snprintf(filemon->msgbufr,
301                                     sizeof(filemon->msgbufr), "R %d %s\n",
302                                     curproc->p_pid, filemon->fname1);
303                                 filemon_output(filemon, filemon->msgbufr, len);
304                         }
305
306
307                         len = snprintf(filemon->msgbufr,
308                             sizeof(filemon->msgbufr), "%c %d %s\n",
309                             (uap->flags & O_ACCMODE) ? 'W':'R',
310                             curproc->p_pid, filemon->fname1);
311                         filemon_output(filemon, filemon->msgbufr, len);
312
313                         /* Unlock the found filemon structure. */
314                         filemon_filemon_unlock(filemon);
315                 }
316
317                 /* Release the read lock. */
318                 filemon_unlock_read();
319         }
320
321         return (ret);
322 }
323
324 static int
325 filemon_wrapper_openat(struct thread *td, struct openat_args *uap)
326 {
327         int ret;
328         size_t done;
329         size_t len;
330         struct filemon *filemon;
331
332         if ((ret = sys_openat(td, uap)) == 0) {
333                 /* Grab a read lock on the filemon inuse list. */
334                 filemon_lock_read();
335
336                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
337                         /* Lock the found filemon structure. */
338                         filemon_filemon_lock(filemon);
339
340                         copyinstr(uap->path, filemon->fname1,
341                             sizeof(filemon->fname1), &done);
342
343                         filemon->fname2[0] = '\0';
344                         if (filemon->fname1[0] != '/' && uap->fd != AT_FDCWD) {
345                                 /*
346                                  * rats - we cannot do too much about this.
347                                  * the trace should show a dir we read
348                                  * recently.. output an A record as a clue
349                                  * until we can do better.
350                                  */
351                                 len = snprintf(filemon->msgbufr,
352                                     sizeof(filemon->msgbufr), "A %d %s\n",
353                                     curproc->p_pid, filemon->fname1);
354                                 filemon_output(filemon, filemon->msgbufr, len);
355                         }
356                         if (uap->flag & O_RDWR) {
357                                 /*
358                                  * We'll get the W record below, but need
359                                  * to also output an R to distingish from
360                                  * O_WRONLY.
361                                  */
362                                 len = snprintf(filemon->msgbufr,
363                                     sizeof(filemon->msgbufr), "R %d %s%s\n",
364                                     curproc->p_pid, filemon->fname2, filemon->fname1);
365                                 filemon_output(filemon, filemon->msgbufr, len);
366                         }
367
368
369                         len = snprintf(filemon->msgbufr,
370                             sizeof(filemon->msgbufr), "%c %d %s%s\n",
371                             (uap->flag & O_ACCMODE) ? 'W':'R',
372                             curproc->p_pid, filemon->fname2, filemon->fname1);
373                         filemon_output(filemon, filemon->msgbufr, len);
374
375                         /* Unlock the found filemon structure. */
376                         filemon_filemon_unlock(filemon);
377                 }
378
379                 /* Release the read lock. */
380                 filemon_unlock_read();
381         }
382
383         return (ret);
384 }
385
386 static int
387 filemon_wrapper_rename(struct thread *td, struct rename_args *uap)
388 {
389         int ret;
390         size_t done;
391         size_t len;
392         struct filemon *filemon;
393
394         if ((ret = sys_rename(td, uap)) == 0) {
395                 /* Grab a read lock on the filemon inuse list. */
396                 filemon_lock_read();
397
398                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
399                         /* Lock the found filemon structure. */
400                         filemon_filemon_lock(filemon);
401
402                         copyinstr(uap->from, filemon->fname1,
403                             sizeof(filemon->fname1), &done);
404                         copyinstr(uap->to, filemon->fname2,
405                             sizeof(filemon->fname2), &done);
406
407                         len = snprintf(filemon->msgbufr,
408                             sizeof(filemon->msgbufr), "M %d '%s' '%s'\n",
409                             curproc->p_pid, filemon->fname1, filemon->fname2);
410
411                         filemon_output(filemon, filemon->msgbufr, len);
412
413                         /* Unlock the found filemon structure. */
414                         filemon_filemon_unlock(filemon);
415                 }
416
417                 /* Release the read lock. */
418                 filemon_unlock_read();
419         }
420
421         return (ret);
422 }
423
424 static int
425 filemon_wrapper_link(struct thread *td, struct link_args *uap)
426 {
427         int ret;
428         size_t done;
429         size_t len;
430         struct filemon *filemon;
431
432         if ((ret = sys_link(td, uap)) == 0) {
433                 /* Grab a read lock on the filemon inuse list. */
434                 filemon_lock_read();
435
436                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
437                         /* Lock the found filemon structure. */
438                         filemon_filemon_lock(filemon);
439
440                         copyinstr(uap->path, filemon->fname1,
441                             sizeof(filemon->fname1), &done);
442                         copyinstr(uap->link, filemon->fname2,
443                             sizeof(filemon->fname2), &done);
444
445                         len = snprintf(filemon->msgbufr,
446                             sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
447                             curproc->p_pid, filemon->fname1, filemon->fname2);
448
449                         filemon_output(filemon, filemon->msgbufr, len);
450
451                         /* Unlock the found filemon structure. */
452                         filemon_filemon_unlock(filemon);
453                 }
454
455                 /* Release the read lock. */
456                 filemon_unlock_read();
457         }
458
459         return (ret);
460 }
461
462 static int
463 filemon_wrapper_symlink(struct thread *td, struct symlink_args *uap)
464 {
465         int ret;
466         size_t done;
467         size_t len;
468         struct filemon *filemon;
469
470         if ((ret = sys_symlink(td, uap)) == 0) {
471                 /* Grab a read lock on the filemon inuse list. */
472                 filemon_lock_read();
473
474                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
475                         /* Lock the found filemon structure. */
476                         filemon_filemon_lock(filemon);
477
478                         copyinstr(uap->path, filemon->fname1,
479                             sizeof(filemon->fname1), &done);
480                         copyinstr(uap->link, filemon->fname2,
481                             sizeof(filemon->fname2), &done);
482
483                         len = snprintf(filemon->msgbufr,
484                             sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
485                             curproc->p_pid, filemon->fname1, filemon->fname2);
486
487                         filemon_output(filemon, filemon->msgbufr, len);
488
489                         /* Unlock the found filemon structure. */
490                         filemon_filemon_unlock(filemon);
491                 }
492
493                 /* Release the read lock. */
494                 filemon_unlock_read();
495         }
496
497         return (ret);
498 }
499
500 #ifdef FILEMON_HAS_LINKAT
501 static int
502 filemon_wrapper_linkat(struct thread *td, struct linkat_args *uap)
503 {
504         int ret;
505         size_t done;
506         size_t len;
507         struct filemon *filemon;
508
509         if ((ret = sys_linkat(td, uap)) == 0) {
510                 /* Grab a read lock on the filemon inuse list. */
511                 filemon_lock_read();
512
513                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
514                         /* Lock the found filemon structure. */
515                         filemon_filemon_lock(filemon);
516
517                         copyinstr(uap->path1, filemon->fname1,
518                             sizeof(filemon->fname1), &done);
519                         copyinstr(uap->path2, filemon->fname2,
520                             sizeof(filemon->fname2), &done);
521
522                         len = snprintf(filemon->msgbufr,
523                             sizeof(filemon->msgbufr), "L %d '%s' '%s'\n",
524                             curproc->p_pid, filemon->fname1, filemon->fname2);
525
526                         filemon_output(filemon, filemon->msgbufr, len);
527
528                         /* Unlock the found filemon structure. */
529                         filemon_filemon_unlock(filemon);
530                 }
531
532                 /* Release the read lock. */
533                 filemon_unlock_read();
534         }
535
536         return (ret);
537 }
538 #endif
539
540 static int
541 filemon_wrapper_stat(struct thread *td, struct stat_args *uap)
542 {
543         int ret;
544         size_t done;
545         size_t len;
546         struct filemon *filemon;
547
548         if ((ret = sys_stat(td, uap)) == 0) {
549                 /* Grab a read lock on the filemon inuse list. */
550                 filemon_lock_read();
551
552                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
553                         /* Lock the found filemon structure. */
554                         filemon_filemon_lock(filemon);
555
556                         copyinstr(uap->path, filemon->fname1,
557                             sizeof(filemon->fname1), &done);
558
559                         len = snprintf(filemon->msgbufr,
560                             sizeof(filemon->msgbufr), "S %d %s\n",
561                             curproc->p_pid, filemon->fname1);
562
563                         filemon_output(filemon, filemon->msgbufr, len);
564
565                         /* Unlock the found filemon structure. */
566                         filemon_filemon_unlock(filemon);
567                 }
568
569                 /* Release the read lock. */
570                 filemon_unlock_read();
571         }
572
573         return (ret);
574 }
575
576 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
577 static int
578 filemon_wrapper_freebsd32_stat(struct thread *td,
579     struct freebsd32_stat_args *uap)
580 {
581         int ret;
582         size_t done;
583         size_t len;
584         struct filemon *filemon;
585
586         if ((ret = freebsd32_stat(td, uap)) == 0) {
587                 /* Grab a read lock on the filemon inuse list. */
588                 filemon_lock_read();
589
590                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
591                         /* Lock the found filemon structure. */
592                         filemon_filemon_lock(filemon);
593
594                         copyinstr(uap->path, filemon->fname1,
595                             sizeof(filemon->fname1), &done);
596
597                         len = snprintf(filemon->msgbufr,
598                             sizeof(filemon->msgbufr), "S %d %s\n",
599                             curproc->p_pid, filemon->fname1);
600
601                         filemon_output(filemon, filemon->msgbufr, len);
602
603                         /* Unlock the found filemon structure. */
604                         filemon_filemon_unlock(filemon);
605                 }
606
607                 /* Release the read lock. */
608                 filemon_unlock_read();
609         }
610
611         return (ret);
612 }
613 #endif
614
615 static void
616 filemon_wrapper_sys_exit(struct thread *td, struct sys_exit_args *uap)
617 {
618         size_t len;
619         struct filemon *filemon;
620         struct timeval now;
621
622         /* Get timestamp before locking. */
623         getmicrotime(&now);
624
625         /* Grab a read lock on the filemon inuse list. */
626         filemon_lock_read();
627
628         if ((filemon = filemon_pid_check(curproc)) != NULL) {
629                 /* Lock the found filemon structure. */
630                 filemon_filemon_lock(filemon);
631
632                 len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr),
633                     "X %d %d\n", curproc->p_pid, uap->rval);
634
635                 filemon_output(filemon, filemon->msgbufr, len);
636
637                 /* Check if the monitored process is about to exit. */
638                 if (filemon->pid == curproc->p_pid) {
639                         len = snprintf(filemon->msgbufr,
640                             sizeof(filemon->msgbufr),
641                             "# Stop %ju.%06ju\n# Bye bye\n",
642                             (uintmax_t)now.tv_sec, (uintmax_t)now.tv_usec);
643
644                         filemon_output(filemon, filemon->msgbufr, len);
645                         filemon->pid = -1;
646                 }
647
648                 /* Unlock the found filemon structure. */
649                 filemon_filemon_unlock(filemon);
650         }
651
652         /* Release the read lock. */
653         filemon_unlock_read();
654
655         sys_sys_exit(td, uap);
656 }
657
658 static int
659 filemon_wrapper_unlink(struct thread *td, struct unlink_args *uap)
660 {
661         int ret;
662         size_t done;
663         size_t len;
664         struct filemon *filemon;
665
666         if ((ret = sys_unlink(td, uap)) == 0) {
667                 /* Grab a read lock on the filemon inuse list. */
668                 filemon_lock_read();
669
670                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
671                         /* Lock the found filemon structure. */
672                         filemon_filemon_lock(filemon);
673
674                         copyinstr(uap->path, filemon->fname1,
675                             sizeof(filemon->fname1), &done);
676
677                         len = snprintf(filemon->msgbufr,
678                             sizeof(filemon->msgbufr), "D %d %s\n",
679                             curproc->p_pid, filemon->fname1);
680
681                         filemon_output(filemon, filemon->msgbufr, len);
682
683                         /* Unlock the found filemon structure. */
684                         filemon_filemon_unlock(filemon);
685                 }
686
687                 /* Release the read lock. */
688                 filemon_unlock_read();
689         }
690
691         return (ret);
692 }
693
694 static int
695 filemon_wrapper_vfork(struct thread *td, struct vfork_args *uap)
696 {
697         int ret;
698         size_t len;
699         struct filemon *filemon;
700
701         if ((ret = sys_vfork(td, uap)) == 0) {
702                 /* Grab a read lock on the filemon inuse list. */
703                 filemon_lock_read();
704
705                 if ((filemon = filemon_pid_check(curproc)) != NULL) {
706                         /* Lock the found filemon structure. */
707                         filemon_filemon_lock(filemon);
708
709                         len = snprintf(filemon->msgbufr,
710                             sizeof(filemon->msgbufr), "F %d %ld\n",
711                             curproc->p_pid, (long)curthread->td_retval[0]);
712
713                         filemon_output(filemon, filemon->msgbufr, len);
714
715                         /* Unlock the found filemon structure. */
716                         filemon_filemon_unlock(filemon);
717                 }
718
719                 /* Release the read lock. */
720                 filemon_unlock_read();
721         }
722
723         return (ret);
724 }
725
726 static void
727 filemon_wrapper_install(void)
728 {
729 #if defined(__LP64__)
730         struct sysent *sv_table = elf64_freebsd_sysvec.sv_table;
731 #else
732         struct sysent *sv_table = elf32_freebsd_sysvec.sv_table;
733 #endif
734
735         sv_table[SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir;
736         sv_table[SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit;
737         sv_table[SYS_execve].sy_call = (sy_call_t *) filemon_wrapper_execve;
738         sv_table[SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
739         sv_table[SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
740         sv_table[SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat;
741         sv_table[SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
742         sv_table[SYS_stat].sy_call = (sy_call_t *) filemon_wrapper_stat;
743         sv_table[SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
744         sv_table[SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork;
745         sv_table[SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link;
746         sv_table[SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink;
747 #ifdef FILEMON_HAS_LINKAT
748         sv_table[SYS_linkat].sy_call = (sy_call_t *) filemon_wrapper_linkat;
749 #endif
750
751 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
752         sv_table = ia32_freebsd_sysvec.sv_table;
753
754         sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir;
755         sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit;
756         sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_execve;
757         sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork;
758         sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open;
759         sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat;
760         sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename;
761         sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_stat;
762         sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink;
763         sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork;
764         sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link;
765         sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink;
766 #ifdef FILEMON_HAS_LINKAT
767         sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *) filemon_wrapper_linkat;
768 #endif
769 #endif  /* COMPAT_ARCH32 */
770 }
771
772 static void
773 filemon_wrapper_deinstall(void)
774 {
775 #if defined(__LP64__)
776         struct sysent *sv_table = elf64_freebsd_sysvec.sv_table;
777 #else
778         struct sysent *sv_table = elf32_freebsd_sysvec.sv_table;
779 #endif
780
781         sv_table[SYS_chdir].sy_call = (sy_call_t *)sys_chdir;
782         sv_table[SYS_exit].sy_call = (sy_call_t *)sys_sys_exit;
783         sv_table[SYS_execve].sy_call = (sy_call_t *)sys_execve;
784         sv_table[SYS_fork].sy_call = (sy_call_t *)sys_fork;
785         sv_table[SYS_open].sy_call = (sy_call_t *)sys_open;
786         sv_table[SYS_openat].sy_call = (sy_call_t *)sys_openat;
787         sv_table[SYS_rename].sy_call = (sy_call_t *)sys_rename;
788         sv_table[SYS_stat].sy_call = (sy_call_t *)sys_stat;
789         sv_table[SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
790         sv_table[SYS_vfork].sy_call = (sy_call_t *)sys_vfork;
791         sv_table[SYS_link].sy_call = (sy_call_t *)sys_link;
792         sv_table[SYS_symlink].sy_call = (sy_call_t *)sys_symlink;
793 #ifdef FILEMON_HAS_LINKAT
794         sv_table[SYS_linkat].sy_call = (sy_call_t *)sys_linkat;
795 #endif
796
797 #if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32)
798         sv_table = ia32_freebsd_sysvec.sv_table;
799
800         sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *)sys_chdir;
801         sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *)sys_sys_exit;
802         sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *)freebsd32_execve;
803         sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *)sys_fork;
804         sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *)sys_open;
805         sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *)sys_openat;
806         sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *)sys_rename;
807         sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *)freebsd32_stat;
808         sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *)sys_unlink;
809         sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *)sys_vfork;
810         sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *)sys_link;
811         sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *)sys_symlink;
812 #ifdef FILEMON_HAS_LINKAT
813         sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *)sys_linkat;
814 #endif
815 #endif  /* COMPAT_ARCH32 */
816 }