home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: alt.sources
- From: auspex!guy@uunet.uu.net (Guy Harris)
- Subject: [sun-spots] Device that gives you access to the running kernel file
- Message-ID: <1990Aug6.040912.25098@math.lsa.umich.edu>
- Date: Mon, 6 Aug 90 04:09:12 GMT
-
- Archive-name: dev-vmunix/05-Aug-90
- Original-posting-by: auspex!guy@uunet.uu.net (Guy Harris)
- Original-subject: Device that gives you access to the running kernel file
- Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
-
- [Reposted from comp.sys.sun.
- Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
-
- The following may be useful, or it may just be an entertaining toy. It's
- a device driver for "/dev/vmunix", an idea I came up with a while ago, to
- deal with the problem of programs such as "ps" that need to get at the
- kernel file that was booted, to find the kernel's symbol table.
-
- Normally, this isn't a headache, but those of you who have installed new
- kernels, calling them something other than "/vmunix", and then tried to
- run "ps" or whatever and didn't provide whatever magic argument (if any)
- tells it to look elsewhere than "/vmunix", know that it can be a nuisance
- on occasion.
-
- With this driver, you open "/dev/vmunix", and you have a file descriptor
- that lets you read from the kernel file that was booted, even if it's not
- named "/vmunix", even if it was renamed since the system was booted (as
- long as you open it once before it gets renamed), or even if it was
- unlinked since the system was booted - the driver holds onto the vnode, so
- it doesn't go away (well, modulo the usual NFSisms; if it's unlinked on
- the client, the system should rename it rather than removing it, but if
- it's unlinked on the server, you lose).
-
- It's quite tiny, only 48 lines of code (counting blank lines and comments
- :-)).
-
- It has an "open()" routine which, the first time it's called, grabs the
- name handed to the boot PROM (and if it's a null string, defaults to
- "vmunix"), and opens the file in the current directory with that name.
-
- (This first open must be done in the root directory; the best way to do
- this would be with a toy program run from one of the "/etc/rc*" files.
- Ideally, this wouldn't be necessary; SunOS does permit a pseudo-device
- driver, such as this one, to have an "init" routine, but it appears to be
- called quite early in the boot process, before the system is ready to let
- you play around with the root file system.)
-
- It also has a "read" routine that, if the kernel file was successfully
- opened, calls the "read" method for the vnode for that file.
-
- You need to modify "sun/conf.c" to have an entry for this device. You
- should be able to just open it and read from it, and get the same data
- you'd have gotten had you opened the running kernel file.
-
- NOTE: this is, of course, maximally useful *only* if you can coerce all
- kmem-groveling programs to use it. This means whacking on various
- commands and "libkvm"; either you need source, or you need to patch the
- binaries to look elsewhere than "/vmunix". I make no claim that this
- driver can drop in and make this problem magically vanish....
-
- Tested under 4.0.3, on a Sun-3E (well, on an NS5000, but "the difference
- that makes no difference is no difference"...). I was able to do "cp
- /dev/vmunix /tmp/vmunix" (from the root directory, so that the first
- "open" could find the file), and get the currently-running kernel file.
- The test was under UFS; I've not tried it under NFS, nor under 4.1. No
- more rigorous testing has been done. If you find bugs - or, even better,
- find bugs *and* the fixes for same - or have any other comments, send 'em
- to me.
-
- NOTE: this does not constitute a commitment by Auspex to provide this as
- part of SunOS on our systems.
-
- #include <sys/errno.h>
- #include <sys/param.h>
- #include <sys/file.h>
- #include <sys/user.h>
- #include <sys/uio.h>
- #include <sys/time.h>
- #include <sys/vnode.h>
-
- #include <mon/sunromvec.h>
-
- static struct vnode *vmunixvp;
-
- /*ARGSUSED*/
- int
- vmunixopen(dev, flags)
- dev_t dev;
- int flags;
- {
- register struct bootparam *bp;
- register char *vmunix_name;
-
- if (vmunixvp == NULL) {
- bp = (*romp->v_bootparam);
- vmunix_name = bp->bp_name;
- if (vmunix_name[0] == '\0') {
- /*
- * No name given when booting; assume it was
- * "vmunix".
- */
- vmunix_name = "vmunix";
- }
- return (vn_open(vmunix_name, UIO_SYSSPACE, FREAD, 0,
- &vmunixvp));
- } else
- return (0);
- }
-
- /*ARGSUSED*/
- int
- vmunixread(dev, uio)
- dev_t dev;
- register struct uio *uio;
- {
- if (vmunixvp == NULL)
- return (ENOENT);
-
- return (VOP_RDWR(vmunixvp, uio, UIO_READ, 0, u.u_cred));
- }
-