Page MenuHomeFreeBSD

D34504.id155018.diff
No OneTemporary

D34504.id155018.diff

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1028,6 +1028,7 @@
MLINKS+=dev_clone.9 drain_dev_clone_events.9
MLINKS+=dev_refthread.9 devvn_refthread.9 \
dev_refthread.9 dev_relthread.9
+MLINKS+=devctl_notify.9 devctl_notifyf.9
MLINKS+=devfs_set_cdevpriv.9 devfs_clear_cdevpriv.9 \
devfs_set_cdevpriv.9 devfs_get_cdevpriv.9 \
devfs_set_cdevpriv.9 devfs_foreach_cdevpriv.9
diff --git a/share/man/man9/devctl_notify.9 b/share/man/man9/devctl_notify.9
--- a/share/man/man9/devctl_notify.9
+++ b/share/man/man9/devctl_notify.9
@@ -21,16 +21,19 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd September 22, 2020
+.Dd April 21, 2025
.Dt DEVCTL_NOTIFY 9
.Os
.Sh NAME
-.Nm devctl_notify
+.Nm devctl_notify ,
+.Nm devctl_notifyf
.Nd Send a message, via devctl, to userland
.Sh SYNOPSIS
.In sys/devctl.h
.Ft void
.Fn devctl_notify "const char *system" "const char *subsystem" "const char *type" "const char *data"
+.Ft void
+.Fn devctl_notifyf "const char *system" "const char *subsystem" "const char *type" "const char *datafmt" "..."
.Sh DESCRIPTION
Send a notification to user land via
.Xr devctl 4 .
@@ -64,11 +67,22 @@
discover itself and sending all the data userland will want to use to
decide what to do with the message.
.Pp
+The
+.Fn devctl_notifyf
+function is identical to
+.Fn devctl_notify ,
+except it takes a format string to populate
+.Fa data
+and formats it as
+.Xr printf 9
+would print it.
+.Pp
The current total message length limit is just under 1kb.
Senders should try to remain well below this limit.
.Sh SEE ALSO
.Xr devctl 4 ,
-.Xr devd 8
+.Xr devd 8 ,
+.Xr printf 9
.Sh AUTHORS
This manual page was written by
.An M. Warner Losh
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
@@ -430,19 +430,20 @@
}
/**
- * @brief Send a 'notification' to userland, using standard ways
+ * @brief Send a 'notification' to userland, using standard ways. This version
+ * takes a format string and varargs, which fits a number of consumers' slightly
+ * less trivial needs.
*/
void
-devctl_notify(const char *system, const char *subsystem, const char *type,
- const char *data)
+devctl_notifyf(const char *system, const char *subsystem, const char *type,
+ const char *datafmt, ...)
{
struct dev_event_info *dei;
struct sbuf sb;
+ ssize_t metasz;
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;
@@ -452,15 +453,77 @@
sbuf_cat(&sb, subsystem);
sbuf_cat(&sb, " type=");
sbuf_cat(&sb, type);
- if (data != NULL) {
+
+ metasz = sbuf_len(&sb);
+ if (datafmt != NULL && *datafmt != '\0') {
+ va_list ap;
+
+ va_start(ap, datafmt);
sbuf_putc(&sb, ' ');
- sbuf_cat(&sb, data);
+ sbuf_vprintf(&sb, datafmt, ap);
+ va_end(ap);
}
+
sbuf_putc(&sb, '\n');
- if (sbuf_finish(&sb) != 0)
+ if (sbuf_finish(&sb) != 0) {
devctl_free_dei(dei); /* overflow -> drop it */
- else
- devctl_queue(dei);
+ return;
+ }
+
+ if (devctl_notify_hook.send_f != NULL) {
+ ssize_t datasz;
+ char *hdata, *nlpos;
+
+ MPASS(metasz > 0); /* Implies we overflowed */
+
+ nlpos = NULL;
+ if (datafmt == NULL) {
+ hdata = NULL;
+ } else {
+ /*
+ * Chop off the newline while we send it to the hook,
+ * we'll restore it after.
+ */
+ hdata = sbuf_data(&sb);
+ datasz = sbuf_len(&sb);
+ nlpos = &hdata[datasz - 1];
+
+ MPASS(hdata[metasz] == ' ');
+ MPASS(*nlpos == '\n');
+ *nlpos = '\0';
+
+
+ /*
+ * The sbuf was laid out like: [metadata] data,
+ * so we advance here past the space.
+ */
+ hdata += metasz + 1;
+ }
+
+ devctl_notify_hook.send_f(system, subsystem, type, hdata);
+
+ /* Fix the devctl formatted string before we enqueue. */
+ if (nlpos != NULL) {
+ *nlpos = '\n';
+ }
+ }
+
+ devctl_queue(dei);
+}
+
+/**
+ * @brief Send a 'notification' to userland, using standard ways
+ */
+void
+devctl_notify(const char *system, const char *subsystem, const char *type,
+ const char *data)
+{
+
+ if (data != NULL) {
+ devctl_notifyf(system, subsystem, type, "%s", data);
+ } else {
+ devctl_notifyf(system, subsystem, type, NULL);
+ }
}
/*
diff --git a/sys/sys/devctl.h b/sys/sys/devctl.h
--- a/sys/sys/devctl.h
+++ b/sys/sys/devctl.h
@@ -14,6 +14,8 @@
*/
bool devctl_process_running(void);
+void devctl_notifyf(const char *__system, const char *__subsystem,
+ const char *__type, const char *__datafmt, ...) __printflike(4, 5);
void devctl_notify(const char *__system, const char *__subsystem,
const char *__type, const char *__data);
struct sbuf;

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 3:14 PM (45 m, 32 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31917422
Default Alt Text
D34504.id155018.diff (4 KB)

Event Timeline