source: rtems/cpukit/include/sys/event.h @ 57c03363

5
Last change on this file since 57c03363 was 57c03363, checked in by jhb <jhb@…>, on 11/25/17 at 04:49:12

Decode kevent structures logged via ktrace(2) in kdump.

  • Add a new KTR_STRUCT_ARRAY ktrace record type which dumps an array of structures.

The structure name in the record payload is preceded by a size_t
containing the size of the individual structures. Use this to
replace the previous code that dumped the kevent arrays dumped for
kevent(). kdump is now able to decode the kevent structures rather
than dumping their contents via a hexdump.

One change from before is that the 'changes' and 'events' arrays are
not marked with separate 'read' and 'write' annotations in kdump
output. Instead, the first array is the 'changes' array, and the
second array (only present if kevent doesn't fail with an error) is
the 'events' array. For kevent(), empty arrays are denoted by an
entry with an array containing zero entries rather than no record.

  • Move kevent decoding tables from truss to libsysdecode.

This adds three new functions to decode members of struct kevent:
sysdecode_kevent_filter, sysdecode_kevent_flags, and
sysdecode_kevent_fflags.

kdump uses these helper functions to pretty-print kevent fields.

  • Move structure definitions for freebsd11 and freebsd32 kevent structures to <sys/event.h> so that they can be shared with userland. The 32-bit structures are only exposed if _WANT_KEVENT32 is defined. The freebsd11 structures are only exposed if _WANT_FREEBSD11_KEVENT is defined. The 32-bit freebsd11 structure requires both.
  • Decode freebsd11 kevent structures in truss for the compat11.kevent() system call.
  • Log 32-bit kevent structures via ktrace for 32-bit compat kevent() system calls.
  • While here, constify the 'void *data' argument to ktrstruct().

Reviewed by: kib (earlier version)
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D12470

  • Property mode set to 100644
File size: 12.1 KB
Line 
1/*-
2 * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/sys/event.h 313704 2017-02-13 19:00:09Z ed $
27 */
28
29#ifndef _SYS_EVENT_H_
30#define _SYS_EVENT_H_
31
32#include <sys/_types.h>
33#include <sys/queue.h>
34
35#define EVFILT_READ             (-1)
36#define EVFILT_WRITE            (-2)
37#define EVFILT_AIO              (-3)    /* attached to aio requests */
38#define EVFILT_VNODE            (-4)    /* attached to vnodes */
39#define EVFILT_PROC             (-5)    /* attached to struct proc */
40#define EVFILT_SIGNAL           (-6)    /* attached to struct proc */
41#define EVFILT_TIMER            (-7)    /* timers */
42#define EVFILT_PROCDESC         (-8)    /* attached to process descriptors */
43#define EVFILT_FS               (-9)    /* filesystem events */
44#define EVFILT_LIO              (-10)   /* attached to lio requests */
45#define EVFILT_USER             (-11)   /* User events */
46#define EVFILT_SENDFILE         (-12)   /* attached to sendfile requests */
47#define EVFILT_EMPTY            (-13)   /* empty send socket buf */
48#define EVFILT_SYSCOUNT         13
49
50#define EV_SET(kevp_, a, b, c, d, e, f) do {    \
51        struct kevent *kevp = (kevp_);          \
52        (kevp)->ident = (a);                    \
53        (kevp)->filter = (b);                   \
54        (kevp)->flags = (c);                    \
55        (kevp)->fflags = (d);                   \
56        (kevp)->data = (e);                     \
57        (kevp)->udata = (f);                    \
58        (kevp)->ext[0] = 0;                     \
59        (kevp)->ext[1] = 0;                     \
60        (kevp)->ext[2] = 0;                     \
61        (kevp)->ext[3] = 0;                     \
62} while(0)
63
64struct kevent {
65        __uintptr_t     ident;          /* identifier for this event */
66        short           filter;         /* filter for event */
67        unsigned short  flags;
68        unsigned int    fflags;
69        __int64_t       data;
70        void            *udata;         /* opaque user data identifier */
71        __uint64_t      ext[4];
72};
73
74#if defined(_WANT_FREEBSD11_KEVENT)
75/* Older structure used in FreeBSD 11.x and older. */
76struct kevent_freebsd11 {
77        __uintptr_t     ident;          /* identifier for this event */
78        short           filter;         /* filter for event */
79        unsigned short  flags;
80        unsigned int    fflags;
81        __intptr_t      data;
82        void            *udata;         /* opaque user data identifier */
83};
84#endif
85
86#if defined(_WANT_KEVENT32) || (defined(_KERNEL) && defined(__LP64__))
87struct kevent32 {
88        uint32_t        ident;          /* identifier for this event */
89        short           filter;         /* filter for event */
90        u_short         flags;
91        u_int           fflags;
92#ifndef __amd64__
93        uint32_t        pad0;
94#endif
95        int32_t         data1, data2;
96        uint32_t        udata;          /* opaque user data identifier */
97#ifndef __amd64__
98        uint32_t        pad1;
99#endif
100        uint32_t        ext64[8];
101};
102
103#ifdef _WANT_FREEBSD11_KEVENT
104struct kevent32_freebsd11 {
105        u_int32_t       ident;          /* identifier for this event */
106        short           filter;         /* filter for event */
107        u_short         flags;
108        u_int           fflags;
109        int32_t         data;
110        u_int32_t       udata;          /* opaque user data identifier */
111};
112#endif
113#endif
114
115/* actions */
116#define EV_ADD          0x0001          /* add event to kq (implies enable) */
117#define EV_DELETE       0x0002          /* delete event from kq */
118#define EV_ENABLE       0x0004          /* enable event */
119#define EV_DISABLE      0x0008          /* disable event (not reported) */
120#define EV_FORCEONESHOT 0x0100          /* enable _ONESHOT and force trigger */
121
122/* flags */
123#define EV_ONESHOT      0x0010          /* only report one occurrence */
124#define EV_CLEAR        0x0020          /* clear event state after reporting */
125#define EV_RECEIPT      0x0040          /* force EV_ERROR on success, data=0 */
126#define EV_DISPATCH     0x0080          /* disable event after reporting */
127
128#define EV_SYSFLAGS     0xF000          /* reserved by system */
129#define EV_DROP         0x1000          /* note should be dropped */
130#define EV_FLAG1        0x2000          /* filter-specific flag */
131#define EV_FLAG2        0x4000          /* filter-specific flag */
132
133/* returned values */
134#define EV_EOF          0x8000          /* EOF detected */
135#define EV_ERROR        0x4000          /* error, data contains errno */
136
137 /*
138  * data/hint flags/masks for EVFILT_USER, shared with userspace
139  *
140  * On input, the top two bits of fflags specifies how the lower twenty four
141  * bits should be applied to the stored value of fflags.
142  *
143  * On output, the top two bits will always be set to NOTE_FFNOP and the
144  * remaining twenty four bits will contain the stored fflags value.
145  */
146#define NOTE_FFNOP      0x00000000              /* ignore input fflags */
147#define NOTE_FFAND      0x40000000              /* AND fflags */
148#define NOTE_FFOR       0x80000000              /* OR fflags */
149#define NOTE_FFCOPY     0xc0000000              /* copy fflags */
150#define NOTE_FFCTRLMASK 0xc0000000              /* masks for operations */
151#define NOTE_FFLAGSMASK 0x00ffffff
152
153#define NOTE_TRIGGER    0x01000000              /* Cause the event to be
154                                                   triggered for output. */
155
156/*
157 * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
158 */
159#define NOTE_LOWAT      0x0001                  /* low water mark */
160#define NOTE_FILE_POLL  0x0002                  /* behave like poll() */
161
162/*
163 * data/hint flags for EVFILT_VNODE, shared with userspace
164 */
165#define NOTE_DELETE     0x0001                  /* vnode was removed */
166#define NOTE_WRITE      0x0002                  /* data contents changed */
167#define NOTE_EXTEND     0x0004                  /* size increased */
168#define NOTE_ATTRIB     0x0008                  /* attributes changed */
169#define NOTE_LINK       0x0010                  /* link count changed */
170#define NOTE_RENAME     0x0020                  /* vnode was renamed */
171#define NOTE_REVOKE     0x0040                  /* vnode access was revoked */
172#define NOTE_OPEN       0x0080                  /* vnode was opened */
173#define NOTE_CLOSE      0x0100                  /* file closed, fd did not
174                                                   allowed write */
175#define NOTE_CLOSE_WRITE 0x0200                 /* file closed, fd did allowed
176                                                   write */
177#define NOTE_READ       0x0400                  /* file was read */
178
179/*
180 * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
181 */
182#define NOTE_EXIT       0x80000000              /* process exited */
183#define NOTE_FORK       0x40000000              /* process forked */
184#define NOTE_EXEC       0x20000000              /* process exec'd */
185#define NOTE_PCTRLMASK  0xf0000000              /* mask for hint bits */
186#define NOTE_PDATAMASK  0x000fffff              /* mask for pid */
187
188/* additional flags for EVFILT_PROC */
189#define NOTE_TRACK      0x00000001              /* follow across forks */
190#define NOTE_TRACKERR   0x00000002              /* could not track child */
191#define NOTE_CHILD      0x00000004              /* am a child process */
192
193/* additional flags for EVFILT_TIMER */
194#define NOTE_SECONDS            0x00000001      /* data is seconds */
195#define NOTE_MSECONDS           0x00000002      /* data is milliseconds */
196#define NOTE_USECONDS           0x00000004      /* data is microseconds */
197#define NOTE_NSECONDS           0x00000008      /* data is nanoseconds */
198#define NOTE_ABSTIME            0x00000010      /* timeout is absolute */
199
200struct knote;
201SLIST_HEAD(klist, knote);
202struct kqueue;
203TAILQ_HEAD(kqlist, kqueue);
204struct knlist {
205        struct  klist   kl_list;
206        void    (*kl_lock)(void *);     /* lock function */
207        void    (*kl_unlock)(void *);
208        void    (*kl_assert_locked)(void *);
209        void    (*kl_assert_unlocked)(void *);
210        void    *kl_lockarg;            /* argument passed to lock functions */
211        int     kl_autodestroy;
212};
213
214
215#ifdef _KERNEL
216
217/*
218 * Flags for knote call
219 */
220#define KNF_LISTLOCKED  0x0001                  /* knlist is locked */
221#define KNF_NOKQLOCK    0x0002                  /* do not keep KQ_LOCK */
222
223#define KNOTE(list, hint, flags)        knote(list, hint, flags)
224#define KNOTE_LOCKED(list, hint)        knote(list, hint, KNF_LISTLOCKED)
225#define KNOTE_UNLOCKED(list, hint)      knote(list, hint, 0)
226
227#define KNLIST_EMPTY(list)              SLIST_EMPTY(&(list)->kl_list)
228
229/*
230 * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
231 * shared by EVFILT_PROC  (all knotes attached to p->p_klist)
232 */
233#define NOTE_SIGNAL     0x08000000
234
235/*
236 * Hint values for the optional f_touch event filter.  If f_touch is not set
237 * to NULL and f_isfd is zero the f_touch filter will be called with the type
238 * argument set to EVENT_REGISTER during a kevent() system call.  It is also
239 * called under the same conditions with the type argument set to EVENT_PROCESS
240 * when the event has been triggered.
241 */
242#define EVENT_REGISTER  1
243#define EVENT_PROCESS   2
244
245struct filterops {
246        int     f_isfd;         /* true if ident == filedescriptor */
247        int     (*f_attach)(struct knote *kn);
248        void    (*f_detach)(struct knote *kn);
249        int     (*f_event)(struct knote *kn, long hint);
250        void    (*f_touch)(struct knote *kn, struct kevent *kev, u_long type);
251};
252
253/*
254 * An in-flux knote cannot be dropped from its kq while the kq is
255 * unlocked.  If the KN_SCAN flag is not set, a thread can only set
256 * kn_influx when it is exclusive owner of the knote state, and can
257 * modify kn_status as if it had the KQ lock.  KN_SCAN must not be set
258 * on a knote which is already in flux.
259 *
260 * kn_sfflags, kn_sdata, and kn_kevent are protected by the knlist lock.
261 */
262struct knote {
263        SLIST_ENTRY(knote)      kn_link;        /* for kq */
264        SLIST_ENTRY(knote)      kn_selnext;     /* for struct selinfo */
265        struct                  knlist *kn_knlist;      /* f_attach populated */
266        TAILQ_ENTRY(knote)      kn_tqe;
267        struct                  kqueue *kn_kq;  /* which queue we are on */
268        struct                  kevent kn_kevent;
269        void                    *kn_hook;
270        int                     kn_hookid;
271        int                     kn_status;      /* protected by kq lock */
272#define KN_ACTIVE       0x01                    /* event has been triggered */
273#define KN_QUEUED       0x02                    /* event is on queue */
274#define KN_DISABLED     0x04                    /* event is disabled */
275#define KN_DETACHED     0x08                    /* knote is detached */
276#define KN_MARKER       0x20                    /* ignore this knote */
277#define KN_KQUEUE       0x40                    /* this knote belongs to a kq */
278#define KN_HASKQLOCK    0x80                    /* for _inevent */
279#define KN_SCAN         0x100                   /* flux set in kqueue_scan() */
280        int                     kn_influx;
281        int                     kn_sfflags;     /* saved filter flags */
282        int64_t                 kn_sdata;       /* saved data field */
283        union {
284                struct          file *p_fp;     /* file data pointer */
285                struct          proc *p_proc;   /* proc pointer */
286                struct          kaiocb *p_aio;  /* AIO job pointer */
287                struct          aioliojob *p_lio;       /* LIO job pointer */
288                void            *p_v;           /* generic other pointer */
289        } kn_ptr;
290        struct                  filterops *kn_fop;
291
292#define kn_id           kn_kevent.ident
293#define kn_filter       kn_kevent.filter
294#define kn_flags        kn_kevent.flags
295#define kn_fflags       kn_kevent.fflags
296#define kn_data         kn_kevent.data
297#define kn_fp           kn_ptr.p_fp
298};
299struct kevent_copyops {
300        void    *arg;
301        int     (*k_copyout)(void *arg, struct kevent *kevp, int count);
302        int     (*k_copyin)(void *arg, struct kevent *kevp, int count);
303        size_t  kevent_size;
304};
305
306struct thread;
307struct proc;
308struct knlist;
309struct mtx;
310struct rwlock;
311
312void    knote(struct knlist *list, long hint, int lockflags);
313void    knote_fork(struct knlist *list, int pid);
314struct knlist *knlist_alloc(struct mtx *lock);
315void    knlist_detach(struct knlist *knl);
316void    knlist_add(struct knlist *knl, struct knote *kn, int islocked);
317void    knlist_remove(struct knlist *knl, struct knote *kn, int islocked);
318int     knlist_empty(struct knlist *knl);
319void    knlist_init(struct knlist *knl, void *lock, void (*kl_lock)(void *),
320            void (*kl_unlock)(void *), void (*kl_assert_locked)(void *),
321            void (*kl_assert_unlocked)(void *));
322void    knlist_init_mtx(struct knlist *knl, struct mtx *lock);
323void    knlist_init_rw_reader(struct knlist *knl, struct rwlock *lock);
324void    knlist_destroy(struct knlist *knl);
325void    knlist_cleardel(struct knlist *knl, struct thread *td,
326            int islocked, int killkn);
327#define knlist_clear(knl, islocked)                             \
328        knlist_cleardel((knl), NULL, (islocked), 0)
329#define knlist_delete(knl, td, islocked)                        \
330        knlist_cleardel((knl), (td), (islocked), 1)
331void    knote_fdclose(struct thread *p, int fd);
332int     kqfd_register(int fd, struct kevent *kev, struct thread *p,
333            int waitok);
334int     kqueue_add_filteropts(int filt, struct filterops *filtops);
335int     kqueue_del_filteropts(int filt);
336
337#else   /* !_KERNEL */
338
339#include <sys/cdefs.h>
340struct timespec;
341
342__BEGIN_DECLS
343int     kqueue(void);
344int     kevent(int kq, const struct kevent *changelist, int nchanges,
345            struct kevent *eventlist, int nevents,
346            const struct timespec *timeout);
347__END_DECLS
348
349#endif /* !_KERNEL */
350
351#endif /* !_SYS_EVENT_H_ */
Note: See TracBrowser for help on using the repository browser.