Reputation: 1328
I want to write to /dev/kmsg
so I can compare user space logging in an application to things that are happening in the kernel.
I wrote a simple application that should log a message similar to how you can do this from the command line with echo "foo" > /dev/kmsg
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fdKmsg = -1;
fdKmsg = open("/dev/kmsg", O_WRONLY);
if (fdKmsg != -1)
{
dprintf(fdKmsg, "-- Hello World --\n");
close(fd);
}
else
{
printf("Unable to get file descriptor\n");
}
return 0;
}
However, when I run this even as root, I don't see anything either in dmesg
or in /proc/kmsg
. What am I missing? Even with a call to fsync()
, it doesn't appear to write to dmesg
.
Upvotes: 2
Views: 4364
Reputation: 58518
It looks like this was a bug in glibc on Ubuntu 22.04 and presumably other systems of that vintage. Apparently dprintf
(indirectly, via libio) calls lseek
on the file; it's prepared for it to fail with ESPIPE
for a non-seekable file such as a pipe, but in the case of /dev/kmsg
, it fails with EINVAL
instead. This is unexpected so dprintf
returns failure. (Checking the return value could have been useful.)
In December 2022, dprintf
was refactored and doesn't call that code anymore, so no seek is attempted. Indeed, on Ubuntu 24.04 your program works as expected.
Upvotes: 0
Reputation: 1328
It appears that dprintf()
will not work in this case. However, calling write()
will work. I'm not sure why this is, but I would guess that the printf()
functions don't call the write
method for the exposed /dev
interface.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{
int fdKmsg = -1;
fdKmsg = open("/dev/kmsg", O_WRONLY);
char *buf = "Hello World\n";
if (fdKmsg != -1)
{
//dprintf(fdKmsg, "-- Hello World --\n");
write(fdKmsg, buf, strlen(buf) + 1);
close(fd);
}
else
{
printf("Unable to get file descriptor\n");
}
return 0;
}
Upvotes: 2