devctl: allow to register a hook to receive the events

In preparation for netlink sysvent add a function that allow
registering a function to hook the events and also send it via
another kernel module (nlsysvent will be that module).

Prepare a static list of known existing events in the kernel that
will be used to prepopulate nlsysvent multicast group (one per event)

Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D37573
This commit is contained in:
Baptiste Daroussin 2023-06-01 23:01:40 +02:00
parent fe06db1817
commit afbb26b58b
2 changed files with 66 additions and 0 deletions

View File

@ -134,6 +134,10 @@ static struct filterops devctl_rfiltops = {
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 @@ devctl_notify(const char *system, const char *subsystem, const char *type,
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 @@ devaddq(const char *type, const char *what, device_t dev)
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 @@ devaddq(const char *type, const char *what, device_t dev)
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 @@ devaddq(const char *type, const char *what, device_t dev)
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 @@ devctl_safe_quote_sb(struct sbuf *sb, const char *src)
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;
}

View File

@ -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_ */