/dev/kmsg
検証
[root@localhost ~]# echo babakaka1 > /dev/kmsg [root@localhost ~]# echo babakaka2 > /dev/kmsg [root@localhost ~]# dmesg : [ 3107.092587] pcnet32 0000:02:01.0: eth0: link down [ 3117.073758] pcnet32 0000:02:01.0: eth0: link up [ 3340.842392] pcnet32 0000:02:01.0: eth0: link down [ 3350.768666] pcnet32 0000:02:01.0: eth0: link up [ 5455.068601] babakaka1 [ 5461.321331] babakaka2 [root@localhost ~]# cat /dev/kmsg cat: /dev/kmsg: 無効な引数です
実装
static const struct file_operations kmsg_fops = { .aio_write = kmsg_writev, .llseek = noop_llseek, }; loff_t noop_llseek(struct file *file, loff_t offset, int origin) { return file->f_pos; } static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv, unsigned long count, loff_t pos) { char *line, *p; int i; ssize_t ret = -EFAULT; size_t len = iov_length(iv, count); line = kmalloc(len + 1, GFP_KERNEL); if (line == NULL) return -ENOMEM; p = line; for (i = 0; i < count; i++) { if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len)) goto out; p += iv[i].iov_len; } p[0] = '\0'; ret = printk("%s", line); if (ret > len) ret = len; out: kfree(line); return ret; }
備考
noop_llseek()は、read/writeでfile->f_posに依存しないファイルの.llseekコールバックで使用され、lseek()をコールしてもfile->f_posが更新されず、返り値はfile->f_posの初期値の0となり、従ってlseek()はエラーとなりません。他にfifo等にも適用されています。ファイル参照をlseekして行う場合、lseek()のエラーチェックにおいて、file->f_posに依存しないこのようなファイルの考慮する必要がありません。
read/writeはfile->f_posに依存しながらも、lseekできないファイルには、.llseekコールバックにno_llseek()が設定され、pipe等に適用されています。
loff_t no_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; }