]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_devctl.c
Merge bmake-20230909
[FreeBSD/FreeBSD.git] / sys / kern / kern_devctl.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2002-2020 M. Warner Losh <imp@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #include <sys/cdefs.h>
29 #include "opt_bus.h"
30 #include "opt_ddb.h"
31
32 #include <sys/param.h>
33 #include <sys/conf.h>
34 #include <sys/eventhandler.h>
35 #include <sys/filio.h>
36 #include <sys/lock.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/mutex.h>
40 #include <sys/poll.h>
41 #include <sys/priv.h>
42 #include <sys/proc.h>
43 #include <sys/condvar.h>
44 #include <sys/queue.h>
45 #include <machine/bus.h>
46 #include <sys/sbuf.h>
47 #include <sys/selinfo.h>
48 #include <sys/smp.h>
49 #include <sys/sysctl.h>
50 #include <sys/systm.h>
51 #include <sys/uio.h>
52 #include <sys/bus.h>
53
54 #include <machine/cpu.h>
55 #include <machine/stdarg.h>
56
57 #include <vm/uma.h>
58 #include <vm/vm.h>
59
60 #include <ddb/ddb.h>
61
62 STAILQ_HEAD(devq, dev_event_info);
63
64 static struct dev_softc {
65         int             inuse;
66         int             nonblock;
67         int             queued;
68         int             async;
69         struct mtx      mtx;
70         struct cv       cv;
71         struct selinfo  sel;
72         struct devq     devq;
73         struct sigio    *sigio;
74         uma_zone_t      zone;
75 } devsoftc;
76
77 /*
78  * This design allows only one reader for /dev/devctl.  This is not desirable
79  * in the long run, but will get a lot of hair out of this implementation.
80  * Maybe we should make this device a clonable device.
81  *
82  * Also note: we specifically do not attach a device to the device_t tree
83  * to avoid potential chicken and egg problems.  One could argue that all
84  * of this belongs to the root node.
85  */
86
87 #define DEVCTL_DEFAULT_QUEUE_LEN 1000
88 static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS);
89 static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN;
90 SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RWTUN |
91     CTLFLAG_MPSAFE, NULL, 0, sysctl_devctl_queue, "I", "devctl queue length");
92
93 static void devctl_attach_handler(void *arg __unused, device_t dev);
94 static void devctl_detach_handler(void *arg __unused, device_t dev,
95     enum evhdev_detach state);
96 static void devctl_nomatch_handler(void *arg __unused, device_t dev);
97
98 static d_open_t         devopen;
99 static d_close_t        devclose;
100 static d_read_t         devread;
101 static d_ioctl_t        devioctl;
102 static d_poll_t         devpoll;
103 static d_kqfilter_t     devkqfilter;
104
105 #define DEVCTL_BUFFER (1024 - sizeof(void *))
106 struct dev_event_info {
107         STAILQ_ENTRY(dev_event_info) dei_link;
108         char dei_data[DEVCTL_BUFFER];
109 };
110
111
112 static struct cdevsw dev_cdevsw = {
113         .d_version =    D_VERSION,
114         .d_open =       devopen,
115         .d_close =      devclose,
116         .d_read =       devread,
117         .d_ioctl =      devioctl,
118         .d_poll =       devpoll,
119         .d_kqfilter =   devkqfilter,
120         .d_name =       "devctl",
121 };
122
123 static void     filt_devctl_detach(struct knote *kn);
124 static int      filt_devctl_read(struct knote *kn, long hint);
125
126 static struct filterops devctl_rfiltops = {
127         .f_isfd = 1,
128         .f_detach = filt_devctl_detach,
129         .f_event = filt_devctl_read,
130 };
131
132 static struct cdev *devctl_dev;
133 static void devaddq(const char *type, const char *what, device_t dev);
134
135 static struct devctlbridge {
136         send_event_f *send_f;
137 } devctl_notify_hook = { .send_f = NULL };
138
139 static void
140 devctl_init(void)
141 {
142         int reserve;
143         uma_zone_t z;
144
145         devctl_dev = make_dev_credf(MAKEDEV_ETERNAL, &dev_cdevsw, 0, NULL,
146             UID_ROOT, GID_WHEEL, 0600, "devctl");
147         mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF);
148         cv_init(&devsoftc.cv, "dev cv");
149         STAILQ_INIT(&devsoftc.devq);
150         knlist_init_mtx(&devsoftc.sel.si_note, &devsoftc.mtx);
151         if (devctl_queue_length > 0) {
152                 /*
153                  * Allocate a zone for the messages. Preallocate 2% of these for
154                  * a reserve. Allow only devctl_queue_length slabs to cap memory
155                  * usage.  The reserve usually allows coverage of surges of
156                  * events during memory shortages. Normally we won't have to
157                  * re-use events from the queue, but will in extreme shortages.
158                  */
159                 z = devsoftc.zone = uma_zcreate("DEVCTL",
160                     sizeof(struct dev_event_info), NULL, NULL, NULL, NULL,
161                     UMA_ALIGN_PTR, 0);
162                 reserve = max(devctl_queue_length / 50, 100);   /* 2% reserve */
163                 uma_zone_set_max(z, devctl_queue_length);
164                 uma_zone_set_maxcache(z, 0);
165                 uma_zone_reserve(z, reserve);
166                 uma_prealloc(z, reserve);
167         }
168         EVENTHANDLER_REGISTER(device_attach, devctl_attach_handler,
169             NULL, EVENTHANDLER_PRI_LAST);
170         EVENTHANDLER_REGISTER(device_detach, devctl_detach_handler,
171             NULL, EVENTHANDLER_PRI_LAST);
172         EVENTHANDLER_REGISTER(device_nomatch, devctl_nomatch_handler,
173             NULL, EVENTHANDLER_PRI_LAST);
174 }
175 SYSINIT(devctl_init, SI_SUB_DRIVERS, SI_ORDER_SECOND, devctl_init, NULL);
176
177 /*
178  * A device was added to the tree.  We are called just after it successfully
179  * attaches (that is, probe and attach success for this device).  No call
180  * is made if a device is merely parented into the tree.  See devnomatch
181  * if probe fails.  If attach fails, no notification is sent (but maybe
182  * we should have a different message for this).
183  */
184 static void
185 devctl_attach_handler(void *arg __unused, device_t dev)
186 {
187         devaddq("+", device_get_nameunit(dev), dev);
188 }
189
190 /*
191  * A device was removed from the tree.  We are called just before this
192  * happens.
193  */
194 static void
195 devctl_detach_handler(void *arg __unused, device_t dev, enum evhdev_detach state)
196 {
197         if (state == EVHDEV_DETACH_COMPLETE)
198                 devaddq("-", device_get_nameunit(dev), dev);
199 }
200
201 /*
202  * Called when there's no match for this device.  This is only called
203  * the first time that no match happens, so we don't keep getting this
204  * message.  Should that prove to be undesirable, we can change it.
205  * This is called when all drivers that can attach to a given bus
206  * decline to accept this device.  Other errors may not be detected.
207  */
208 static void
209 devctl_nomatch_handler(void *arg __unused, device_t dev)
210 {
211         devaddq("?", "", dev);
212 }
213
214 static int
215 devopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
216 {
217         mtx_lock(&devsoftc.mtx);
218         if (devsoftc.inuse) {
219                 mtx_unlock(&devsoftc.mtx);
220                 return (EBUSY);
221         }
222         /* move to init */
223         devsoftc.inuse = 1;
224         mtx_unlock(&devsoftc.mtx);
225         return (0);
226 }
227
228 static int
229 devclose(struct cdev *dev, int fflag, int devtype, struct thread *td)
230 {
231         mtx_lock(&devsoftc.mtx);
232         devsoftc.inuse = 0;
233         devsoftc.nonblock = 0;
234         devsoftc.async = 0;
235         cv_broadcast(&devsoftc.cv);
236         funsetown(&devsoftc.sigio);
237         mtx_unlock(&devsoftc.mtx);
238         return (0);
239 }
240
241 /*
242  * The read channel for this device is used to report changes to
243  * userland in realtime.  We are required to free the data as well as
244  * the n1 object because we allocate them separately.  Also note that
245  * we return one record at a time.  If you try to read this device a
246  * character at a time, you will lose the rest of the data.  Listening
247  * programs are expected to cope.
248  */
249 static int
250 devread(struct cdev *dev, struct uio *uio, int ioflag)
251 {
252         struct dev_event_info *n1;
253         int rv;
254
255         mtx_lock(&devsoftc.mtx);
256         while (STAILQ_EMPTY(&devsoftc.devq)) {
257                 if (devsoftc.nonblock) {
258                         mtx_unlock(&devsoftc.mtx);
259                         return (EAGAIN);
260                 }
261                 rv = cv_wait_sig(&devsoftc.cv, &devsoftc.mtx);
262                 if (rv) {
263                         /*
264                          * Need to translate ERESTART to EINTR here? -- jake
265                          */
266                         mtx_unlock(&devsoftc.mtx);
267                         return (rv);
268                 }
269         }
270         n1 = STAILQ_FIRST(&devsoftc.devq);
271         STAILQ_REMOVE_HEAD(&devsoftc.devq, dei_link);
272         devsoftc.queued--;
273         mtx_unlock(&devsoftc.mtx);
274         rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio);
275         uma_zfree(devsoftc.zone, n1);
276         return (rv);
277 }
278
279 static  int
280 devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
281 {
282         switch (cmd) {
283         case FIONBIO:
284                 if (*(int*)data)
285                         devsoftc.nonblock = 1;
286                 else
287                         devsoftc.nonblock = 0;
288                 return (0);
289         case FIOASYNC:
290                 if (*(int*)data)
291                         devsoftc.async = 1;
292                 else
293                         devsoftc.async = 0;
294                 return (0);
295         case FIOSETOWN:
296                 return fsetown(*(int *)data, &devsoftc.sigio);
297         case FIOGETOWN:
298                 *(int *)data = fgetown(&devsoftc.sigio);
299                 return (0);
300
301                 /* (un)Support for other fcntl() calls. */
302         case FIOCLEX:
303         case FIONCLEX:
304         case FIONREAD:
305         default:
306                 break;
307         }
308         return (ENOTTY);
309 }
310
311 static  int
312 devpoll(struct cdev *dev, int events, struct thread *td)
313 {
314         int     revents = 0;
315
316         mtx_lock(&devsoftc.mtx);
317         if (events & (POLLIN | POLLRDNORM)) {
318                 if (!STAILQ_EMPTY(&devsoftc.devq))
319                         revents = events & (POLLIN | POLLRDNORM);
320                 else
321                         selrecord(td, &devsoftc.sel);
322         }
323         mtx_unlock(&devsoftc.mtx);
324
325         return (revents);
326 }
327
328 static int
329 devkqfilter(struct cdev *dev, struct knote *kn)
330 {
331         int error;
332
333         if (kn->kn_filter == EVFILT_READ) {
334                 kn->kn_fop = &devctl_rfiltops;
335                 knlist_add(&devsoftc.sel.si_note, kn, 0);
336                 error = 0;
337         } else
338                 error = EINVAL;
339         return (error);
340 }
341
342 static void
343 filt_devctl_detach(struct knote *kn)
344 {
345         knlist_remove(&devsoftc.sel.si_note, kn, 0);
346 }
347
348 static int
349 filt_devctl_read(struct knote *kn, long hint)
350 {
351         kn->kn_data = devsoftc.queued;
352         return (kn->kn_data != 0);
353 }
354
355 /**
356  * @brief Return whether the userland process is running
357  */
358 bool
359 devctl_process_running(void)
360 {
361         return (devsoftc.inuse == 1);
362 }
363
364 static struct dev_event_info *
365 devctl_alloc_dei(void)
366 {
367         struct dev_event_info *dei = NULL;
368
369         mtx_lock(&devsoftc.mtx);
370         if (devctl_queue_length == 0)
371                 goto out;
372         dei = uma_zalloc(devsoftc.zone, M_NOWAIT);
373         if (dei == NULL)
374                 dei = uma_zalloc(devsoftc.zone, M_NOWAIT | M_USE_RESERVE);
375         if (dei == NULL) {
376                 /*
377                  * Guard against no items in the queue. Normally, this won't
378                  * happen, but if lots of events happen all at once and there's
379                  * a chance we're out of allocated space but none have yet been
380                  * queued when we get here, leaving nothing to steal. This can
381                  * also happen with error injection. Fail safe by returning
382                  * NULL in that case..
383                  */
384                 if (devsoftc.queued == 0)
385                         goto out;
386                 dei = STAILQ_FIRST(&devsoftc.devq);
387                 STAILQ_REMOVE_HEAD(&devsoftc.devq, dei_link);
388                 devsoftc.queued--;
389         }
390         MPASS(dei != NULL);
391         *dei->dei_data = '\0';
392 out:
393         mtx_unlock(&devsoftc.mtx);
394         return (dei);
395 }
396
397 static struct dev_event_info *
398 devctl_alloc_dei_sb(struct sbuf *sb)
399 {
400         struct dev_event_info *dei;
401
402         dei = devctl_alloc_dei();
403         if (dei != NULL)
404                 sbuf_new(sb, dei->dei_data, sizeof(dei->dei_data), SBUF_FIXEDLEN);
405         return (dei);
406 }
407
408 static void
409 devctl_free_dei(struct dev_event_info *dei)
410 {
411         uma_zfree(devsoftc.zone, dei);
412 }
413
414 static void
415 devctl_queue(struct dev_event_info *dei)
416 {
417         mtx_lock(&devsoftc.mtx);
418         STAILQ_INSERT_TAIL(&devsoftc.devq, dei, dei_link);
419         devsoftc.queued++;
420         cv_broadcast(&devsoftc.cv);
421         KNOTE_LOCKED(&devsoftc.sel.si_note, 0);
422         mtx_unlock(&devsoftc.mtx);
423         selwakeup(&devsoftc.sel);
424         if (devsoftc.async && devsoftc.sigio != NULL)
425                 pgsigio(&devsoftc.sigio, SIGIO, 0);
426 }
427
428 /**
429  * @brief Send a 'notification' to userland, using standard ways
430  */
431 void
432 devctl_notify(const char *system, const char *subsystem, const char *type,
433     const char *data)
434 {
435         struct dev_event_info *dei;
436         struct sbuf sb;
437
438         if (system == NULL || subsystem == NULL || type == NULL)
439                 return;
440         if (devctl_notify_hook.send_f != NULL)
441                 devctl_notify_hook.send_f(system, subsystem, type, data);
442         dei = devctl_alloc_dei_sb(&sb);
443         if (dei == NULL)
444                 return;
445         sbuf_cpy(&sb, "!system=");
446         sbuf_cat(&sb, system);
447         sbuf_cat(&sb, " subsystem=");
448         sbuf_cat(&sb, subsystem);
449         sbuf_cat(&sb, " type=");
450         sbuf_cat(&sb, type);
451         if (data != NULL) {
452                 sbuf_putc(&sb, ' ');
453                 sbuf_cat(&sb, data);
454         }
455         sbuf_putc(&sb, '\n');
456         if (sbuf_finish(&sb) != 0)
457                 devctl_free_dei(dei);   /* overflow -> drop it */
458         else
459                 devctl_queue(dei);
460 }
461
462 /*
463  * Common routine that tries to make sending messages as easy as possible.
464  * We allocate memory for the data, copy strings into that, but do not
465  * free it unless there's an error.  The dequeue part of the driver should
466  * free the data.  We don't send data when the device is disabled.  We do
467  * send data, even when we have no listeners, because we wish to avoid
468  * races relating to startup and restart of listening applications.
469  *
470  * devaddq is designed to string together the type of event, with the
471  * object of that event, plus the plug and play info and location info
472  * for that event.  This is likely most useful for devices, but less
473  * useful for other consumers of this interface.  Those should use
474  * the devctl_notify() interface instead.
475  *
476  * Output:
477  *      ${type}${what} at $(location dev) $(pnp-info dev) on $(parent dev)
478  */
479 static void
480 devaddq(const char *type, const char *what, device_t dev)
481 {
482         struct dev_event_info *dei;
483         const char *parstr;
484         struct sbuf sb;
485         size_t beginlen;
486
487         dei = devctl_alloc_dei_sb(&sb);
488         if (dei == NULL)
489                 return;
490         sbuf_cpy(&sb, type);
491         sbuf_cat(&sb, what);
492         sbuf_cat(&sb, " at ");
493         beginlen = sbuf_len(&sb);
494
495         /* Add in the location */
496         bus_child_location(dev, &sb);
497         sbuf_putc(&sb, ' ');
498
499         /* Add in pnpinfo */
500         bus_child_pnpinfo(dev, &sb);
501
502         /* Get the parent of this device, or / if high enough in the tree. */
503         if (device_get_parent(dev) == NULL)
504                 parstr = ".";   /* Or '/' ? */
505         else
506                 parstr = device_get_nameunit(device_get_parent(dev));
507         sbuf_cat(&sb, " on ");
508         sbuf_cat(&sb, parstr);
509         sbuf_putc(&sb, '\n');
510         if (sbuf_finish(&sb) != 0)
511                 goto bad;
512         if (devctl_notify_hook.send_f != NULL) {
513                 const char *t;
514
515                 switch (*type) {
516                 case '+':
517                         t = "ATTACH";
518                         break;
519                 case '-':
520                         t = "DETACH";
521                         break;
522                 default:
523                         t = "NOMATCH";
524                         break;
525                 }
526                 devctl_notify_hook.send_f("device",
527                     what, t, sbuf_data(&sb) + beginlen);
528         }
529         devctl_queue(dei);
530         return;
531 bad:
532         devctl_free_dei(dei);
533 }
534
535 static int
536 sysctl_devctl_queue(SYSCTL_HANDLER_ARGS)
537 {
538         int q, error;
539
540         q = devctl_queue_length;
541         error = sysctl_handle_int(oidp, &q, 0, req);
542         if (error || !req->newptr)
543                 return (error);
544         if (q < 0)
545                 return (EINVAL);
546
547         /*
548          * When set as a tunable, we've not yet initialized the mutex.
549          * It is safe to just assign to devctl_queue_length and return
550          * as we're racing no one. We'll use whatever value set in
551          * devinit.
552          */
553         if (!mtx_initialized(&devsoftc.mtx)) {
554                 devctl_queue_length = q;
555                 return (0);
556         }
557
558         /*
559          * XXX It's hard to grow or shrink the UMA zone. Only allow
560          * disabling the queue size for the moment until underlying
561          * UMA issues can be sorted out.
562          */
563         if (q != 0)
564                 return (EINVAL);
565         if (q == devctl_queue_length)
566                 return (0);
567         mtx_lock(&devsoftc.mtx);
568         devctl_queue_length = 0;
569         uma_zdestroy(devsoftc.zone);
570         devsoftc.zone = 0;
571         mtx_unlock(&devsoftc.mtx);
572         return (0);
573 }
574
575 /**
576  * @brief safely quotes strings that might have double quotes in them.
577  *
578  * The devctl protocol relies on quoted strings having matching quotes.
579  * This routine quotes any internal quotes so the resulting string
580  * is safe to pass to snprintf to construct, for example pnp info strings.
581  *
582  * @param sb    sbuf to place the characters into
583  * @param src   Original buffer.
584  */
585 void
586 devctl_safe_quote_sb(struct sbuf *sb, const char *src)
587 {
588         while (*src != '\0') {
589                 if (*src == '"' || *src == '\\')
590                         sbuf_putc(sb, '\\');
591                 sbuf_putc(sb, *src++);
592         }
593 }
594
595 void
596 devctl_set_notify_hook(send_event_f *hook)
597 {
598         devctl_notify_hook.send_f = hook;
599 }
600
601 void
602 devctl_unset_notify_hook(void)
603 {
604         devctl_notify_hook.send_f = NULL;
605 }
606