version 1.4, 1993/03/27 00:37:11 |
version 1.21, 1994/05/17 04:10:29 |
|
|
/* |
/* |
|
* Copyright (c) 1992 The Regents of the University of California |
* Copyright (c) 1990, 1992 Jan-Simon Pendry |
* Copyright (c) 1990, 1992 Jan-Simon Pendry |
* All rights reserved. |
* All rights reserved. |
* |
* |
* This code is derived from software contributed to Berkeley by |
* This code is derived from software donated to Berkeley by |
* Jan-Simon Pendry. |
* Jan-Simon Pendry. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* without specific prior written permission. |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
* |
* |
* $Id$ |
* From: |
|
* Id: kernfs_vnops.c,v 4.1 1994/01/02 14:41:30 jsp Exp |
|
* |
|
* $Id$ |
*/ |
*/ |
|
|
/* |
/* |
* Kernel parameter filesystem |
* Kernel parameter filesystem |
*/ |
*/ |
|
|
#include "param.h" |
#include <sys/param.h> |
#include "systm.h" |
#include <sys/systm.h> |
#include "kernel.h" |
#include <sys/kernel.h> |
#include "types.h" |
#include <sys/types.h> |
#include "time.h" |
#include <sys/time.h> |
#include "proc.h" |
#include <sys/proc.h> |
#include "file.h" |
#include <sys/file.h> |
#include "vnode.h" |
#include <sys/vnode.h> |
#include "stat.h" |
#include <sys/stat.h> |
#include "mount.h" |
#include <sys/mount.h> |
#include "namei.h" |
#include <sys/namei.h> |
#include "buf.h" |
#include <sys/buf.h> |
#include "miscfs/kernfs/kernfs.h" |
#include <miscfs/kernfs/kernfs.h> |
|
|
#include "../ufs/dir.h" /* For readdir() XXX */ |
#include <ufs/dir.h> /* For readdir() XXX */ |
|
|
#define KSTRING 256 /* Largest I/O available via this filesystem */ |
#define KSTRING 256 /* Largest I/O available via this filesystem */ |
#define UIO_MX 32 |
#define UIO_MX 32 |
Line 70 struct kern_target { |
|
Line 74 struct kern_target { |
|
#define KTT_AVENRUN 53 |
#define KTT_AVENRUN 53 |
int kt_tag; |
int kt_tag; |
#define KTM_RO 0 |
#define KTM_RO 0 |
#define KTM_RO_MODE (S_IRUSR|S_IRGRP|S_IROTH) |
#define KTM_RO_MODE \ |
|
((VREAD) | (VREAD >> 3) | (VREAD >> 6)) |
#define KTM_RW 43 |
#define KTM_RW 43 |
#define KTM_RW_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) |
#define KTM_RW_MODE \ |
#define KTM_DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) |
((VWRITE) | KTM_RO_MODE) |
|
#define KTM_DIR_MODE \ |
|
((VREAD|VEXEC) | ((VREAD|VEXEC) >> 3) | ((VREAD|VEXEC) >> 6)) |
int kt_rw; |
int kt_rw; |
int kt_vtype; |
enum vtype kt_vtype; |
} kern_targets[] = { |
} kern_targets[] = { |
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
/* name data tag ro/rw */ |
/* name data tag ro/rw */ |
Line 86 struct kern_target { |
|
Line 93 struct kern_target { |
|
{ "hz", &hz, KTT_INT, KTM_RO, VREG }, |
{ "hz", &hz, KTT_INT, KTM_RO, VREG }, |
{ "loadavg", 0, KTT_AVENRUN, KTM_RO, VREG }, |
{ "loadavg", 0, KTT_AVENRUN, KTM_RO, VREG }, |
{ "physmem", &physmem, KTT_INT, KTM_RO, VREG }, |
{ "physmem", &physmem, KTT_INT, KTM_RO, VREG }, |
|
#if 0 |
{ "root", 0, KTT_NULL, KTM_RO, VDIR }, |
{ "root", 0, KTT_NULL, KTM_RO, VDIR }, |
|
#endif |
{ "rootdev", 0, KTT_NULL, KTM_RO, VBLK }, |
{ "rootdev", 0, KTT_NULL, KTM_RO, VBLK }, |
|
#ifdef notdef |
{ "rrootdev", 0, KTT_NULL, KTM_RO, VCHR }, |
{ "rrootdev", 0, KTT_NULL, KTM_RO, VCHR }, |
|
#endif |
{ "time", 0, KTT_TIME, KTM_RO, VREG }, |
{ "time", 0, KTT_TIME, KTM_RO, VREG }, |
{ "version", version, KTT_STRING, KTM_RO, VREG }, |
{ "version", version, KTT_STRING, KTM_RO, VREG }, |
}; |
}; |
Line 133 kernfs_xread(kt, buf, len, lenp) |
|
Line 144 kernfs_xread(kt, buf, len, lenp) |
|
char *cp = hostname; |
char *cp = hostname; |
int xlen = hostnamelen; |
int xlen = hostnamelen; |
|
|
if (xlen >= len) |
if (xlen >= (len-2)) |
return (EINVAL); |
return (EINVAL); |
|
|
sprintf(buf, "%s\n", cp); |
bcopy(cp, buf, xlen); |
|
buf[xlen] = '\n'; |
|
buf[xlen+1] = '\0'; |
break; |
break; |
} |
} |
|
|
case KTT_AVENRUN: |
case KTT_AVENRUN: |
sprintf(buf, "%d %d %d %d\n", |
sprintf(buf, "%d %d %d %d\n", |
averunnable[0], |
averunnable.ldavg[0], |
averunnable[1], |
averunnable.ldavg[1], |
averunnable[2], |
averunnable.ldavg[2], |
FSCALE); |
averunnable.fscale); |
break; |
break; |
|
|
default: |
default: |
Line 167 kernfs_xwrite(kt, buf, len) |
|
Line 180 kernfs_xwrite(kt, buf, len) |
|
if (buf[len-1] == '\n') |
if (buf[len-1] == '\n') |
--len; |
--len; |
bcopy(buf, hostname, len); |
bcopy(buf, hostname, len); |
hostnamelen = len - 1; |
hostname[len] = '\0'; |
|
hostnamelen = len; |
return (0); |
return (0); |
} |
} |
|
|
Line 177 kernfs_xwrite(kt, buf, len) |
|
Line 191 kernfs_xwrite(kt, buf, len) |
|
} |
} |
|
|
/* |
/* |
|
* implement access checking. |
|
* |
|
* something very similar to this code is duplicated |
|
* throughout the 4bsd kernel and should be moved |
|
* into kern/vfs_subr.c sometime. |
|
* |
|
* actually, the check for super-user is slightly |
|
* broken since it will allow read access to write-only |
|
* objects. this doesn't cause any particular trouble |
|
* but does mean that the i/o entry points need to check |
|
* that the operation really does make sense. |
|
*/ |
|
kernfs_access(vp, mode, cred, p) |
|
struct vnode *vp; |
|
int mode; |
|
struct ucred *cred; |
|
struct proc *p; |
|
{ |
|
struct vattr *vap; |
|
struct vattr vattr; |
|
int error; |
|
|
|
/* |
|
* If you're the super-user, |
|
* you always get access. |
|
*/ |
|
if (cred->cr_uid == (uid_t) 0) |
|
return (0); |
|
vap = &vattr; |
|
if (error = VOP_GETATTR(vp, vap, cred, p)) |
|
return (error); |
|
|
|
/* |
|
* Access check is based on only one of owner, group, public. |
|
* If not owner, then check group. If not a member of the |
|
* group, then check public access. |
|
*/ |
|
if (cred->cr_uid != vap->va_uid) { |
|
gid_t *gp; |
|
int i; |
|
|
|
mode >>= 3; |
|
gp = cred->cr_groups; |
|
for (i = 0; i < cred->cr_ngroups; i++, gp++) |
|
if (vap->va_gid == *gp) |
|
goto found; |
|
mode >>= 3; |
|
found: |
|
; |
|
} |
|
|
|
if ((vap->va_mode & mode) == mode) |
|
return (0); |
|
|
|
return (EACCES); |
|
} |
|
|
|
/* |
* vp is the current namei directory |
* vp is the current namei directory |
* ndp is the name to locate in that directory... |
* ndp is the name to locate in that directory... |
*/ |
*/ |
Line 200 kernfs_lookup(dvp, ndp, p) |
|
Line 272 kernfs_lookup(dvp, ndp, p) |
|
/*VOP_LOCK(dvp);*/ |
/*VOP_LOCK(dvp);*/ |
return (0); |
return (0); |
} |
} |
|
|
|
#if 0 |
if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) { |
if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) { |
ndp->ni_dvp = dvp; |
ndp->ni_dvp = rootdir; |
ndp->ni_vp = rootdir; |
ndp->ni_vp = rootdir; |
VREF(rootdir); |
VREF(rootdir); |
|
VREF(rootdir); |
VOP_LOCK(rootdir); |
VOP_LOCK(rootdir); |
return (0); |
return (0); |
} |
} |
|
#endif |
|
|
/* |
/* |
* /kern/rootdev is the root device |
* /kern/rootdev is the root device |
Line 222 kernfs_lookup(dvp, ndp, p) |
|
Line 297 kernfs_lookup(dvp, ndp, p) |
|
return (0); |
return (0); |
} |
} |
|
|
/* |
|
* /kern/rrootdev is the root device |
|
*/ |
|
if (ndp->ni_namelen == 8 && bcmp(pname, "rrootdev", 7) == 0) { |
|
ndp->ni_dvp = dvp; |
|
ndp->ni_vp = rrootdevvp; |
|
VREF(rrootdevvp); |
|
VOP_LOCK(rrootdevvp); |
|
return (0); |
|
} |
|
|
|
for (i = 0; i < nkern_targets; i++) { |
for (i = 0; i < nkern_targets; i++) { |
struct kern_target *kt = &kern_targets[i]; |
struct kern_target *kt = &kern_targets[i]; |
if (ndp->ni_namelen == strlen(kt->kt_name) && |
if (ndp->ni_namelen == strlen(kt->kt_name) && |
Line 252 kernfs_lookup(dvp, ndp, p) |
|
Line 316 kernfs_lookup(dvp, ndp, p) |
|
#ifdef KERNFS_DIAGNOSTIC |
#ifdef KERNFS_DIAGNOSTIC |
printf("kernfs_lookup: allocate new vnode\n"); |
printf("kernfs_lookup: allocate new vnode\n"); |
#endif |
#endif |
error = getnewvnode(VT_UFS, dvp->v_mount, &kernfs_vnodeops, &fvp); |
error = getnewvnode(VT_KERNFS, dvp->v_mount, &kernfs_vnodeops, &fvp); |
if (error) |
if (error) |
goto bad; |
goto bad; |
VTOKERN(fvp)->kf_kt = &kern_targets[i]; |
VTOKERN(fvp)->kf_kt = &kern_targets[i]; |
Line 301 kernfs_open(vp, mode, cred, p) |
|
Line 365 kernfs_open(vp, mode, cred, p) |
|
#endif |
#endif |
|
|
if ((mode & FWRITE) && VTOKERN(vp)->kf_kt->kt_rw != KTM_RW) |
if ((mode & FWRITE) && VTOKERN(vp)->kf_kt->kt_rw != KTM_RW) |
return (EBADF); |
return (EACCES); |
|
|
return (0); |
return (0); |
} |
} |
Line 321 kernfs_getattr(vp, vap, cred, p) |
|
Line 385 kernfs_getattr(vp, vap, cred, p) |
|
vap->va_uid = 0; |
vap->va_uid = 0; |
vap->va_gid = 0; |
vap->va_gid = 0; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; |
/* vap->va_qsize = 0; */ |
vap->va_size = 0; |
vap->va_blocksize = DEV_BSIZE; |
vap->va_blocksize = DEV_BSIZE; |
microtime(&vap->va_atime); |
microtime(&vap->va_atime); |
vap->va_mtime = vap->va_atime; |
vap->va_mtime = vap->va_atime; |
Line 329 kernfs_getattr(vp, vap, cred, p) |
|
Line 393 kernfs_getattr(vp, vap, cred, p) |
|
vap->va_gen = 0; |
vap->va_gen = 0; |
vap->va_flags = 0; |
vap->va_flags = 0; |
vap->va_rdev = 0; |
vap->va_rdev = 0; |
/* vap->va_qbytes = 0; */ |
|
vap->va_bytes = 0; |
vap->va_bytes = 0; |
|
|
if (vp->v_flag & VROOT) { |
if (vp->v_flag & VROOT) { |
Line 392 kernfs_read(vp, uio, ioflag, cred) |
|
Line 455 kernfs_read(vp, uio, ioflag, cred) |
|
printf("kern_read %s\n", kt->kt_name); |
printf("kern_read %s\n", kt->kt_name); |
#endif |
#endif |
|
|
|
if (vp->v_flag & VROOT) |
|
return (EOPNOTSUPP); |
|
|
error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len); |
error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len); |
if (error) |
if (error) |
return (error); |
return (error); |
Line 426 kernfs_write(vp, uio, ioflag, cred) |
|
Line 492 kernfs_write(vp, uio, ioflag, cred) |
|
return (EIO); |
return (EIO); |
|
|
strbuf[xlen] = '\0'; |
strbuf[xlen] = '\0'; |
|
xlen = strlen(strbuf); |
return (kernfs_xwrite(kt, strbuf, xlen)); |
return (kernfs_xwrite(kt, strbuf, xlen)); |
} |
} |
|
|
|
|
int fflag, \ |
int fflag, \ |
struct ucred *cred, \ |
struct ucred *cred, \ |
struct proc *p))) nullop) |
struct proc *p))) nullop) |
#define kernfs_access ((int (*) __P(( \ |
|
struct vnode *vp, \ |
|
int mode, \ |
|
struct ucred *cred, \ |
|
struct proc *p))) nullop) |
|
#define kernfs_ioctl ((int (*) __P(( \ |
#define kernfs_ioctl ((int (*) __P(( \ |
struct vnode *vp, \ |
struct vnode *vp, \ |
int command, \ |
int command, \ |