Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Mar 2001 09:45:05 -0500 (EST)
From:      Robert Watson <rwatson@FreeBSD.ORG>
To:        Gurpratap Virdi <gvirdi@gvirdi.com>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: Writing to a file in the kernel
Message-ID:  <Pine.NEB.3.96L.1010330093326.96088h-100000@fledge.watson.org>
In-Reply-To: <001501c0b923$51754e10$8d7d1f26@dhgfhcpps5nhe1>

next in thread | previous in thread | raw e-mail | index | archive | help

On Fri, 30 Mar 2001, Gurpratap Virdi wrote:

> I am trying to debug some modifications I made to the kernel. I would
> like to write some debug messages to a log file however fopen(),
> fprint() don't work. It gives me a linking error when I try to use them.
> How can I do this?  Thanks in advance! 

There are two techniques normally used for customized logging in the
kernel.

(1) The first is to create a /dev/myfavoritelogdevice, and queue messages
there for a userland daemon to pick up, possibly filter or process, and
spit into a file.  This is much what syslog does with kernel messages, as
well as various incarnations of auditing support, pccardd, and other
kernel event-driven daemons.  In this scenario, you borrow a major device
number, and implement a queueing facility in kernel for the device.
Depending on the properties you want, the queue might be bounded or
un-bounded.  When reads occur on the device, you spit one line out at a
time to the userland process.  Take a look at src/sys/kern/subr_log.c for
an example of such a device.

(2) The second is for the kernel to write directly to a file.  In such
situations, the file to log to is generally indicated by a userland
process, and pathnames are generally only meaningful in the context of a
particular process (in fact, namei() requires a process to function, as
that's where it gets its notion of "root" and "working" directories). 
There are a number of examples of this process, including support for
accounting, quotas, UFS extended attributes, and even core dumps.  Some
process-driven event (often a syscall) indicates to the kernel which file
to send things to, the kernel performs a vn_open()  (or appropriate
VOP_OPEN() and other activities) on the passed name, and on success,
returns success on the syscall but keeps the file open.  Writes are then
made using vn_rw() or VOP_WRITE().

Most examples of this are relatively complex, but this may be the closest
match to what you are looking for -- this is a lot simpler if you just
open, write, close based on a single userland-initiated event, than if you
want a persisting open file.  Take a look at the implementation of
quotactl(), and ufs_quotactl(), as well as extattrctl() and
ufs_extattrctl(), both of which open a file based on a userland
administration syscall, and then keep the file open for later reading and
writing.  Both preserve the credential of the process at the time of
open() for use during writing (remember to crhold() the credential
reference, or it might get garbage-collected out from under you).  In
order to write to a vnode, you also need to have a current struct proc for
scheduling in the event that sleeping is required.  This means that you
can't do VOP's from interrupt context, except in -CURRENT where, due to
SMPng, interrupt threads have enough context to sleep (yay!).  When you're
done with the log file, remember to close it and release the right number
of vnode references.  If you fail to close it, it is possible that changes
written to the file might not be appropriately flushed on some file
systems.  For example, AFS and Coda both have a "flush on close" semantic,
so a failure to close means a failure to flush :-).  If you're just using
UFS, you're probably OK.

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1010330093326.96088h-100000>