diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index f2479871068..0aa13f66bdd 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -42,14 +42,15 @@ */ #include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include @@ -62,7 +63,10 @@ #include #include -struct proc; +#include + +#define T2J(x) (((x) * 100) / stathz) +#define T2S(x) ((x) / stathz) int linprocfs_domeminfo(curp, p, pfs, uio) @@ -73,7 +77,6 @@ linprocfs_domeminfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ unsigned long memtotal; /* total memory in bytes */ unsigned long memused; /* used memory in bytes */ @@ -148,11 +151,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int @@ -164,7 +163,6 @@ linprocfs_docpuinfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ char *class; #if 0 @@ -208,9 +206,89 @@ linprocfs_docpuinfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } + +int +linprocfs_dostat(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + char psbuf[512]; + int xlen; + + ps = psbuf; + ps += sprintf(ps, + "cpu %ld %ld %ld %ld\n" + "disk 0 0 0 0\n" + "page %u %u\n" + "swap %u %u\n" + "intr %u\n" + "ctxt %u\n" + "btime %ld\n", + T2J(cp_time[CP_USER]), + T2J(cp_time[CP_NICE]), + T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), + T2J(cp_time[CP_IDLE]), + cnt.v_vnodepgsin, + cnt.v_vnodepgsout, + cnt.v_swappgsin, + cnt.v_swappgsout, + cnt.v_intr, + cnt.v_swtch, + boottime.tv_sec); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_douptime(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + char psbuf[64]; + struct timeval tv; + long ip, fp; + + getmicrouptime(&tv); + ps = psbuf; + ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", + tv.tv_sec, tv.tv_usec / 10000, + T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_doversion(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + + ps = version; /* XXX not entirely correct */ + for (xlen = 0; ps[xlen] != '\n'; ++xlen) + /* nothing */ ; + ++xlen; + xlen -= uio->uio_offset; + ps += uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + diff --git a/sys/compat/linprocfs/linprocfs.h b/sys/compat/linprocfs/linprocfs.h index 3ab9a28ec28..2e25fb32296 100644 --- a/sys/compat/linprocfs/linprocfs.h +++ b/sys/compat/linprocfs/linprocfs.h @@ -50,8 +50,11 @@ typedef enum { Pproc, /* a process-specific sub-directory */ Pexe, /* the executable file */ Pmem, /* the process's memory image */ - Pmeminfo, - Pcpuinfo + Pmeminfo, /* memory system statistics */ + Pcpuinfo, /* CPU model, speed and features */ + Pstat, /* kernel/system statistics */ + Puptime, /* system uptime */ + Pversion, /* system version */ } pfstype; /* @@ -122,6 +125,9 @@ int linprocfs_write_dbregs __P((struct proc *, struct dbreg *)); #endif int linprocfs_domeminfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int linprocfs_docpuinfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_dostat __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_douptime __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_doversion __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); /* functions to check whether or not files should be displayed */ int linprocfs_validfile __P((struct proc *)); diff --git a/sys/compat/linprocfs/linprocfs_misc.c b/sys/compat/linprocfs/linprocfs_misc.c index f2479871068..0aa13f66bdd 100644 --- a/sys/compat/linprocfs/linprocfs_misc.c +++ b/sys/compat/linprocfs/linprocfs_misc.c @@ -42,14 +42,15 @@ */ #include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include @@ -62,7 +63,10 @@ #include #include -struct proc; +#include + +#define T2J(x) (((x) * 100) / stathz) +#define T2S(x) ((x) / stathz) int linprocfs_domeminfo(curp, p, pfs, uio) @@ -73,7 +77,6 @@ linprocfs_domeminfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ unsigned long memtotal; /* total memory in bytes */ unsigned long memused; /* used memory in bytes */ @@ -148,11 +151,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int @@ -164,7 +163,6 @@ linprocfs_docpuinfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ char *class; #if 0 @@ -208,9 +206,89 @@ linprocfs_docpuinfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } + +int +linprocfs_dostat(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + char psbuf[512]; + int xlen; + + ps = psbuf; + ps += sprintf(ps, + "cpu %ld %ld %ld %ld\n" + "disk 0 0 0 0\n" + "page %u %u\n" + "swap %u %u\n" + "intr %u\n" + "ctxt %u\n" + "btime %ld\n", + T2J(cp_time[CP_USER]), + T2J(cp_time[CP_NICE]), + T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), + T2J(cp_time[CP_IDLE]), + cnt.v_vnodepgsin, + cnt.v_vnodepgsout, + cnt.v_swappgsin, + cnt.v_swappgsout, + cnt.v_intr, + cnt.v_swtch, + boottime.tv_sec); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_douptime(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + char psbuf[64]; + struct timeval tv; + long ip, fp; + + getmicrouptime(&tv); + ps = psbuf; + ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", + tv.tv_sec, tv.tv_usec / 10000, + T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_doversion(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + + ps = version; /* XXX not entirely correct */ + for (xlen = 0; ps[xlen] != '\n'; ++xlen) + /* nothing */ ; + ++xlen; + xlen -= uio->uio_offset; + ps += uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + diff --git a/sys/compat/linprocfs/linprocfs_subr.c b/sys/compat/linprocfs/linprocfs_subr.c index 8e724084c46..d3613b2f581 100644 --- a/sys/compat/linprocfs/linprocfs_subr.c +++ b/sys/compat/linprocfs/linprocfs_subr.c @@ -177,6 +177,9 @@ loop: case Pmeminfo: case Pcpuinfo: + case Pstat: + case Puptime: + case Pversion: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); @@ -254,6 +257,15 @@ linprocfs_rw(ap) case Pcpuinfo: rtval = linprocfs_docpuinfo(curp, p, pfs, uio); break; + case Pstat: + rtval = linprocfs_dostat(curp, p, pfs, uio); + break; + case Puptime: + rtval = linprocfs_douptime(curp, p, pfs, uio); + break; + case Pversion: + rtval = linprocfs_doversion(curp, p, pfs, uio); + break; default: rtval = EOPNOTSUPP; break; diff --git a/sys/compat/linprocfs/linprocfs_vnops.c b/sys/compat/linprocfs/linprocfs_vnops.c index e8ae910e48e..4aff2a89e9b 100644 --- a/sys/compat/linprocfs/linprocfs_vnops.c +++ b/sys/compat/linprocfs/linprocfs_vnops.c @@ -526,8 +526,14 @@ linprocfs_getattr(ap) case Pmeminfo: case Pcpuinfo: + case Pstat: + case Puptime: + case Pversion: + vap->va_bytes = vap->va_size = 0; + vap->va_uid = 0; + vap->va_gid = 0; break; - + case Pmem: /* * If we denied owner access earlier, then we have to @@ -674,6 +680,12 @@ linprocfs_lookup(ap) return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmeminfo)); if (CNEQ(cnp, "cpuinfo", 7)) return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo)); + if (CNEQ(cnp, "stat", 4)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pstat)); + if (CNEQ(cnp, "uptime", 6)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Puptime)); + if (CNEQ(cnp, "version", 7)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pversion)); pid = atopid(pname, cnp->cn_namelen); if (pid == NO_PID) @@ -852,6 +864,27 @@ linprocfs_readdir(ap) dp->d_type = DT_REG; break; + case 5: + dp->d_fileno = PROCFS_FILENO(0, Puptime); + dp->d_namlen = 4; + bcopy("stat", dp->d_name, 5); + dp->d_type = DT_REG; + break; + + case 6: + dp->d_fileno = PROCFS_FILENO(0, Puptime); + dp->d_namlen = 6; + bcopy("uptime", dp->d_name, 7); + dp->d_type = DT_REG; + break; + + case 7: + dp->d_fileno = PROCFS_FILENO(0, Pversion); + dp->d_namlen = 7; + bcopy("version", dp->d_name, 8); + dp->d_type = DT_REG; + break; + default: while (pcnt < i) { p = p->p_list.le_next; diff --git a/sys/i386/linux/linprocfs/linprocfs.h b/sys/i386/linux/linprocfs/linprocfs.h index 3ab9a28ec28..2e25fb32296 100644 --- a/sys/i386/linux/linprocfs/linprocfs.h +++ b/sys/i386/linux/linprocfs/linprocfs.h @@ -50,8 +50,11 @@ typedef enum { Pproc, /* a process-specific sub-directory */ Pexe, /* the executable file */ Pmem, /* the process's memory image */ - Pmeminfo, - Pcpuinfo + Pmeminfo, /* memory system statistics */ + Pcpuinfo, /* CPU model, speed and features */ + Pstat, /* kernel/system statistics */ + Puptime, /* system uptime */ + Pversion, /* system version */ } pfstype; /* @@ -122,6 +125,9 @@ int linprocfs_write_dbregs __P((struct proc *, struct dbreg *)); #endif int linprocfs_domeminfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int linprocfs_docpuinfo __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_dostat __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_douptime __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int linprocfs_doversion __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); /* functions to check whether or not files should be displayed */ int linprocfs_validfile __P((struct proc *)); diff --git a/sys/i386/linux/linprocfs/linprocfs_misc.c b/sys/i386/linux/linprocfs/linprocfs_misc.c index f2479871068..0aa13f66bdd 100644 --- a/sys/i386/linux/linprocfs/linprocfs_misc.c +++ b/sys/i386/linux/linprocfs/linprocfs_misc.c @@ -42,14 +42,15 @@ */ #include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include @@ -62,7 +63,10 @@ #include #include -struct proc; +#include + +#define T2J(x) (((x) * 100) / stathz) +#define T2S(x) ((x) / stathz) int linprocfs_domeminfo(curp, p, pfs, uio) @@ -73,7 +77,6 @@ linprocfs_domeminfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ unsigned long memtotal; /* total memory in bytes */ unsigned long memused; /* used memory in bytes */ @@ -148,11 +151,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int @@ -164,7 +163,6 @@ linprocfs_docpuinfo(curp, p, pfs, uio) { char *ps; int xlen; - int error; char psbuf[512]; /* XXX - conservative */ char *class; #if 0 @@ -208,9 +206,89 @@ linprocfs_docpuinfo(curp, p, pfs, uio) xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - return (error); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } + +int +linprocfs_dostat(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + char psbuf[512]; + int xlen; + + ps = psbuf; + ps += sprintf(ps, + "cpu %ld %ld %ld %ld\n" + "disk 0 0 0 0\n" + "page %u %u\n" + "swap %u %u\n" + "intr %u\n" + "ctxt %u\n" + "btime %ld\n", + T2J(cp_time[CP_USER]), + T2J(cp_time[CP_NICE]), + T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), + T2J(cp_time[CP_IDLE]), + cnt.v_vnodepgsin, + cnt.v_vnodepgsout, + cnt.v_swappgsin, + cnt.v_swappgsout, + cnt.v_intr, + cnt.v_swtch, + boottime.tv_sec); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_douptime(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + char psbuf[64]; + struct timeval tv; + long ip, fp; + + getmicrouptime(&tv); + ps = psbuf; + ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", + tv.tv_sec, tv.tv_usec / 10000, + T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + +int +linprocfs_doversion(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int xlen; + + ps = version; /* XXX not entirely correct */ + for (xlen = 0; ps[xlen] != '\n'; ++xlen) + /* nothing */ ; + ++xlen; + xlen -= uio->uio_offset; + ps += uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); +} + diff --git a/sys/i386/linux/linprocfs/linprocfs_subr.c b/sys/i386/linux/linprocfs/linprocfs_subr.c index 8e724084c46..d3613b2f581 100644 --- a/sys/i386/linux/linprocfs/linprocfs_subr.c +++ b/sys/i386/linux/linprocfs/linprocfs_subr.c @@ -177,6 +177,9 @@ loop: case Pmeminfo: case Pcpuinfo: + case Pstat: + case Puptime: + case Pversion: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); @@ -254,6 +257,15 @@ linprocfs_rw(ap) case Pcpuinfo: rtval = linprocfs_docpuinfo(curp, p, pfs, uio); break; + case Pstat: + rtval = linprocfs_dostat(curp, p, pfs, uio); + break; + case Puptime: + rtval = linprocfs_douptime(curp, p, pfs, uio); + break; + case Pversion: + rtval = linprocfs_doversion(curp, p, pfs, uio); + break; default: rtval = EOPNOTSUPP; break; diff --git a/sys/i386/linux/linprocfs/linprocfs_vnops.c b/sys/i386/linux/linprocfs/linprocfs_vnops.c index e8ae910e48e..4aff2a89e9b 100644 --- a/sys/i386/linux/linprocfs/linprocfs_vnops.c +++ b/sys/i386/linux/linprocfs/linprocfs_vnops.c @@ -526,8 +526,14 @@ linprocfs_getattr(ap) case Pmeminfo: case Pcpuinfo: + case Pstat: + case Puptime: + case Pversion: + vap->va_bytes = vap->va_size = 0; + vap->va_uid = 0; + vap->va_gid = 0; break; - + case Pmem: /* * If we denied owner access earlier, then we have to @@ -674,6 +680,12 @@ linprocfs_lookup(ap) return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmeminfo)); if (CNEQ(cnp, "cpuinfo", 7)) return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo)); + if (CNEQ(cnp, "stat", 4)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pstat)); + if (CNEQ(cnp, "uptime", 6)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Puptime)); + if (CNEQ(cnp, "version", 7)) + return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pversion)); pid = atopid(pname, cnp->cn_namelen); if (pid == NO_PID) @@ -852,6 +864,27 @@ linprocfs_readdir(ap) dp->d_type = DT_REG; break; + case 5: + dp->d_fileno = PROCFS_FILENO(0, Puptime); + dp->d_namlen = 4; + bcopy("stat", dp->d_name, 5); + dp->d_type = DT_REG; + break; + + case 6: + dp->d_fileno = PROCFS_FILENO(0, Puptime); + dp->d_namlen = 6; + bcopy("uptime", dp->d_name, 7); + dp->d_type = DT_REG; + break; + + case 7: + dp->d_fileno = PROCFS_FILENO(0, Pversion); + dp->d_namlen = 7; + bcopy("version", dp->d_name, 8); + dp->d_type = DT_REG; + break; + default: while (pcnt < i) { p = p->p_list.le_next;