diff --git a/sys/kern/kern_devctl.c b/sys/kern/kern_devctl.c --- a/sys/kern/kern_devctl.c +++ b/sys/kern/kern_devctl.c @@ -134,6 +134,10 @@ static struct cdev *devctl_dev; static void devaddq(const char *type, const char *what, device_t dev); +static struct devctlbridge { + send_event_f *send_f; +} devctl_notify_hook = { .send_f = NULL }; + static void devctl_init(void) { @@ -435,6 +439,8 @@ if (system == NULL || subsystem == NULL || type == NULL) return; + if (devctl_notify_hook.send_f != NULL) + devctl_notify_hook.send_f(system, subsystem, type, data); dei = devctl_alloc_dei_sb(&sb); if (dei == NULL) return; @@ -478,6 +484,7 @@ struct dev_event_info *dei; const char *parstr; struct sbuf sb; + size_t beginlen; dei = devctl_alloc_dei_sb(&sb); if (dei == NULL) @@ -485,6 +492,7 @@ sbuf_cpy(&sb, type); sbuf_cat(&sb, what); sbuf_cat(&sb, " at "); + beginlen = sbuf_len(&sb); /* Add in the location */ bus_child_location(dev, &sb); @@ -503,6 +511,23 @@ sbuf_putc(&sb, '\n'); if (sbuf_finish(&sb) != 0) goto bad; + if (devctl_notify_hook.send_f != NULL) { + const char *t; + + switch (*type) { + case '+': + t = "ATTACH"; + break; + case '-': + t = "DETACH"; + break; + default: + t = "NOMATCH"; + break; + } + devctl_notify_hook.send_f("device", + what, t, sbuf_data(&sb) + beginlen); + } devctl_queue(dei); return; bad: @@ -568,3 +593,16 @@ sbuf_putc(sb, *src++); } } + +void +devctl_set_notify_hook(send_event_f *hook) +{ + devctl_notify_hook.send_f = hook; +} + +void +devctl_unset_notify_hook(void) +{ + devctl_notify_hook.send_f = NULL; +} + diff --git a/sys/sys/devctl.h b/sys/sys/devctl.h --- a/sys/sys/devctl.h +++ b/sys/sys/devctl.h @@ -12,11 +12,39 @@ * devctl hooks. Typically one should use the devctl_notify * hook to send the message. */ + +static const char *devctl_systems[] = { + "ACPI", + "AEON", + "CAM", + "CARP", + "coretemp", + "DEVFS", + "device", + "ETHERNET", + "GEOM", + "HYPERV_NIC_VF", + "IFNET", + "INFINIBAND", + "KERNEL", + "nvme", + "PMU", + "RCTL", + "USB", + "VFS", + "VT", + "ZFS", +}; + bool devctl_process_running(void); void devctl_notify(const char *__system, const char *__subsystem, const char *__type, const char *__data); struct sbuf; void devctl_safe_quote_sb(struct sbuf *__sb, const char *__src); +typedef void send_event_f(const char *system, const char *subsystem, + const char *type, const char *data); +void devctl_set_notify_hook(send_event_f *hook); +void devctl_unset_notify_hook(void); #endif #endif /* _SYS_DEVCTL_H_ */