Date: Fri, 15 Sep 2000 08:56:24 -0700 (PDT) From: Jim.Pirzyk@disney.com To: FreeBSD-gnats-submit@freebsd.org Subject: kern/21294: linprocfs:/proc/stat & /proc/<PID>/stat missing, /proc/cpuinfo needs work Message-ID: <200009151556.IAA23154@snoopy.fan.fa.disney.com>
next in thread | raw e-mail | index | archive | help
>Number: 21294
>Category: kern
>Synopsis: linprocfs:/proc/stat & /proc/<PID>/stat does not exist
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Sep 15 09:00:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Jim Pirzyk
>Release: FreeBSD 4.1-RELEASE i386
>Organization:
>Environment:
In the Linux emulation enviroment, the /proc filesystem is incomplete
for LSF to work.
>Description:
We use LSF from Platform, Inc, and they have a linux version of their
software. It uses /proc/stat, /proc/<PID>/stat, /proc/cpuinfo and
/proc/meminfo to gather information about the load on the system.
To make the Linux version of LSF work, we need these files also.
>How-To-Repeat:
Run the LSF daemons on a system with the Linux emulation mode, then
type lshosts <HOSTNAME> and the results would come out like this:
HOST_NAME type model cpuf ncpus maxmem maxswp server RESOURCES
snoopy LINUX DECDS10 15.0 - - - Yes ()
>Fix:
Add these patches and create a sym link in /sys/i386/linux/linprocfs
to /sys/miscfs/procfs/procfs_status.c
*** ./sys/modules/linprocfs/Makefile.orig Tue Sep 12 15:07:49 2000
--- ./sys/modules/linprocfs/Makefile Tue Sep 12 15:38:44 2000
***************
*** 3,9 ****
.PATH: ${.CURDIR}/../../i386/linux/linprocfs
KMOD= linprocfs
SRCS= vnode_if.h linprocfs_misc.c linprocfs_subr.c \
! linprocfs_vfsops.c linprocfs_vnops.c
NOMAN=
CFLAGS+= -DLINPROCFS
--- 3,10 ----
.PATH: ${.CURDIR}/../../i386/linux/linprocfs
KMOD= linprocfs
SRCS= vnode_if.h linprocfs_misc.c linprocfs_subr.c \
! linprocfs_vfsops.c linprocfs_vnops.c \
! procfs_status.c
NOMAN=
CFLAGS+= -DLINPROCFS
*** ./sys/i386/linux/linprocfs/linprocfs.h.orig Mon Sep 11 13:05:51 2000
--- ./sys/i386/linux/linprocfs/linprocfs.h Tue Sep 12 13:58:08 2000
***************
*** 49,57 ****
Pexe, /* the executable file */
Pmem, /* the process's memory image */
Pmeminfo,
! Pcpuinfo
} pfstype;
/*
* control data for the proc file system.
*/
--- 49,61 ----
Pexe, /* the executable file */
Pmem, /* the process's memory image */
Pmeminfo,
! Pcpuinfo,
! Pstat, /* the processes' stats */
! Psstat /* the system's stats */
} pfstype;
+ #define LINUX_NR_IRQS 224
+
/*
* control data for the proc file system.
*/
***************
*** 120,125 ****
--- 124,130 ----
#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_dosstat __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 *));
*** ./sys/i386/linux/linprocfs/linprocfs_misc.c.orig Mon Sep 11 13:13:01 2000
--- ./sys/i386/linux/linprocfs/linprocfs_misc.c Thu Sep 14 09:46:03 2000
***************
*** 60,67 ****
--- 60,76 ----
#include <machine/md_var.h>
#include <machine/cputypes.h>
+ #include <sys/dkstat.h>
+
struct proc;
+ #ifdef SMP
+ extern int mp_ncpus;
+ #endif
+ extern u_int tsc_freq;
+ extern int hw_float;
+ extern char cpu_model[128]; /* use the same variable as the hw.model field */
+
int
linprocfs_domeminfo(curp, p, pfs, uio)
struct proc *curp;
***************
*** 156,201 ****
struct uio *uio;
{
char *ps;
! int xlen;
int error;
! char psbuf[512]; /* XXX - conservative */
! char *class;
! #if 0
! extern char *cpu_model; /* Yuck */
! #endif
if (uio->uio_rw != UIO_READ)
return (EOPNOTSUPP);
! switch (cpu_class) {
! case CPUCLASS_286:
! class = "286";
! break;
! case CPUCLASS_386:
! class = "386";
! break;
! case CPUCLASS_486:
! class = "486";
! break;
! case CPUCLASS_586:
! class = "586";
! break;
! case CPUCLASS_686:
! class = "686";
! break;
! default:
! class = "unknown";
! break;
}
ps = psbuf;
ps += sprintf(ps,
! "processor : %d\n"
! "cpu : %.3s\n"
! "model : %.20s\n"
! "vendor_id : %.20s\n"
! "stepping : %d\n",
! 0, class, "unknown", cpu_vendor, cpu_id);
xlen = ps - psbuf;
xlen -= uio->uio_offset;
--- 165,338 ----
struct uio *uio;
{
char *ps;
! int xlen, i = 0;
int error;
! char psbuf[4096]; /* XXX - same size as a Linux page */
if (uio->uio_rw != UIO_READ)
return (EOPNOTSUPP);
! ps = psbuf;
! #ifdef SMP
! for (i = 0; i < mp_ncpus; i++ ) {
! #endif
! ps += sprintf(ps,
! "processor\t: %d\n"
! "vendor_id\t: %.20s\n"
! "cpu family\t: %x\n"
! "model\t\t: %x\n"
! "model name\t: %s\n"
! "stepping\t: %d\n"
! "cpu MHz\t\t: %d.%02d\n"
! "cache size\t: %d KB\n"
! "fdiv_bug\t: %s\n"
! "hlt_bug\t\t: %s\n"
! "sep_bug\t\t: %s\n"
! "f00f_bug\t: %s\n"
! "coma_bug\t: %s\n"
! "fpu\t\t: %s\n"
! "fpu_exception\t: %s\n"
! "cpuid level\t: %d\n"
! "wp\t\t: %s\n"
! "flags\t\t: %x\n"
! "bogomips\t: %d.%02d\n\n",
! i,
! cpu_vendor,
! (cpu_id & 0xf00) >> 8,
! (cpu_id & 0xf0) >> 4,
! cpu_model,
! (strcmp(cpu_vendor, "CyrixInstead") == 0)?
! (cyrix_did & 0xf000) >> 12:
! cpu_id & 0xf,
! (tsc_freq + 4999) / 1000000,
! ((tsc_freq + 4999) / 10000) % 100,
! -1,
! "n/a",
! "n/a",
! "n/a",
! #if defined(I586_CPU) && !defined(NO_F00F_HACK)
! "yes",
! #else
! "no",
! #endif
! "n/a",
! (hw_float)? "yes": "no",
! "n/a",
! -1,
! "n/a",
! cpu_feature,
!
! /* bogomips looks close to MHZ * num cpus */
!
! (tsc_freq + 4999)
! #ifdef SMP
! * mp_ncpus
! #endif
! / 1000000
! , ((tsc_freq + 4999)
! #ifdef SMP
! * mp_ncpus
! #endif
! / 10000) % 100);
! #ifdef SMP
}
+ #endif
+
+ xlen = ps - psbuf;
+ 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);
+ }
+
+ extern struct timeval boottime;
+ extern long cp_time[CPUSTATES];
+ extern STAILQ_HEAD(devstatlist, devstat) device_statq;
+ extern int devstat_num_devs;
+
+ int
+ linprocfs_dosstat(curp, p, pfs, uio)
+ struct proc *curp;
+ struct proc *p;
+ struct pfsnode *pfs;
+ struct uio *uio;
+ {
+ char *ps;
+ int xlen, i;
+ int error;
+ char psbuf[4096]; /* XXX - same size as a Linux page */
+ #ifdef SMP
+ extern int mp_ncpus;
+ #endif
+
+ if (uio->uio_rw != UIO_READ)
+ return (EOPNOTSUPP);
ps = psbuf;
ps += sprintf(ps,
! "cpu %ld %ld %ld %ld\n",
! cp_time[CP_USER],
! cp_time[CP_NICE],
! cp_time[CP_SYS],
! cp_time[CP_IDLE] );
!
! #ifdef SMP
! if ( mp_ncpus > 1 ) {
! for (i = 0; i < mp_ncpus; i++ ) {
! ps += sprintf(ps,
! "cpu%d %ld %ld %ld %ld\n",
! i,
! cp_time[CP_USER],
! cp_time[CP_NICE],
! cp_time[CP_SYS],
! cp_time[CP_IDLE] );
! }
! }
! #endif
!
! ps += sprintf(ps,
! "disk %d %d %d %d\n"
! "disk_rio %d %d %d %d\n"
! "disk_wio %d %d %d %d\n"
! "disk_rblk %d %d %d %d\n"
! "disk_wblk %d %d %d %d\n",
! -1, -1, -1, -1,
! -1, -1, -1, -1,
! -1, -1, -1, -1,
! -1, -1, -1, -1,
! -1, -1, -1, -1);
!
! ps += sprintf(ps,
! "page %u %u\n"
! "swap %u %u\n"
! "intr %u",
! cnt.v_swappgsin, cnt.v_swappgsout,
! cnt.v_swapin, cnt.v_swapout,
! cnt.v_intr);
!
! /*
! The individual IRQ interrupts are not tracked, so we just
! display the sum of all interrupts followed by 224 zeros.
! */
! for (i = 0; i < LINUX_NR_IRQS; i++) {
! ps += sprintf(ps, " %d", -1);
! }
!
! /*
! The number of forks on the system is not tracked so processes
! will always be zero.
! */
! ps += sprintf(ps,
! "\nctxt %u\n"
! "btime %ld\n"
! "processes %d\n",
! cnt.v_swtch,
! boottime.tv_sec,
! -1);
xlen = ps - psbuf;
xlen -= uio->uio_offset;
*** ./sys/i386/linux/linprocfs/linprocfs_subr.c.orig Mon Sep 11 13:08:57 2000
--- ./sys/i386/linux/linprocfs/linprocfs_subr.c Tue Sep 12 15:01:26 2000
***************
*** 173,180 ****
--- 173,188 ----
vp->v_type = VREG;
break;
+ case Pstat:
+ pfs->pfs_mode = (VREAD) |
+ (VREAD >> 3) |
+ (VREAD >> 6);
+ vp->v_type = VREG;
+ break;
+
case Pmeminfo:
case Pcpuinfo:
+ case Psstat:
pfs->pfs_mode = (VREAD) |
(VREAD >> 3) |
(VREAD >> 6);
***************
*** 246,256 ****
--- 254,270 ----
case Pmem:
rtval = procfs_domem(curp, p, pfs, uio);
break;
+ case Pstat:
+ rtval = linprocfs_dostatus(curp, p, pfs, uio);
+ break;
case Pmeminfo:
rtval = linprocfs_domeminfo(curp, p, pfs, uio);
break;
case Pcpuinfo:
rtval = linprocfs_docpuinfo(curp, p, pfs, uio);
+ break;
+ case Psstat:
+ rtval = linprocfs_dosstat(curp, p, pfs, uio);
break;
default:
rtval = EOPNOTSUPP;
*** ./sys/i386/linux/linprocfs/linprocfs_vnops.c.orig Mon Sep 11 13:36:17 2000
--- ./sys/i386/linux/linprocfs/linprocfs_vnops.c Tue Sep 12 11:55:49 2000
***************
*** 97,102 ****
--- 97,103 ----
{ DT_DIR, N(".."), Proot, NULL },
{ DT_REG, N("mem"), Pmem, NULL },
{ DT_LNK, N("exe"), Pexe, NULL },
+ { DT_REG, N("stat"), Pstat, NULL },
#undef N
};
static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
***************
*** 530,535 ****
--- 531,538 ----
case Pmeminfo:
case Pcpuinfo:
+ case Psstat:
+ case Pstat:
break;
case Pmem:
***************
*** 689,694 ****
--- 692,699 ----
return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pself));
if (CNEQ(cnp, "meminfo", 7))
return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmeminfo));
+ if (CNEQ(cnp, "stat", 4))
+ return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Psstat));
if (CNEQ(cnp, "cpuinfo", 7))
return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo));
***************
*** 863,868 ****
--- 868,880 ----
dp->d_fileno = PROCFS_FILENO(0, Pcpuinfo);
dp->d_namlen = 7;
bcopy("cpuinfo", dp->d_name, 8);
+ dp->d_type = DT_REG;
+ break;
+
+ case 5:
+ dp->d_fileno = PROCFS_FILENO(0, Psstat);
+ dp->d_namlen = 4;
+ bcopy("stat", dp->d_name, 5);
dp->d_type = DT_REG;
break;
*** ./sys/miscfs/procfs/procfs_status.c.orig Tue Sep 12 14:17:10 2000
--- ./sys/miscfs/procfs/procfs_status.c Thu Sep 14 09:53:30 2000
***************
*** 55,62 ****
--- 55,72 ----
#include <vm/vm_param.h>
#include <sys/exec.h>
+ #ifdef LINPROCFS
+ #include <sys/lock.h>
+ #include <vm/vm_map.h>
+ #include <sys/user.h>
+ #include <machine/pcb.h>
+
+ int
+ linprocfs_dostatus(curp, p, pfs, uio)
+ #else
int
procfs_dostatus(curp, p, pfs, uio)
+ #endif
struct proc *curp;
struct proc *p;
struct pfsnode *pfs;
***************
*** 66,74 ****
struct tty *tp;
struct ucred *cr;
char *ps;
char *sep;
- int pid, ppid, pgid, sid;
int i;
int xlen;
int error;
char psbuf[256]; /* XXX - conservative */
--- 76,86 ----
struct tty *tp;
struct ucred *cr;
char *ps;
+ #ifndef LINPROCFS
char *sep;
int i;
+ #endif
+ int pid, ppid, pgid, sid;
int xlen;
int error;
char psbuf[256]; /* XXX - conservative */
***************
*** 86,101 ****
--- 98,139 ----
euid ruid rgid,egid,groups[1 .. NGROUPS]
*/
ps = psbuf;
+ #ifdef LINPROCFS
+ ps += sprintf(ps,
+ "%d (%s) %c %d %d %d ",
+ pid,
+ p->p_comm,
+ (p->p_stat == SRUN)? 'R':
+ (p->p_stat == SIDL)? 'I':
+ (p->p_stat == SSLEEP)? 'S':
+ (p->p_stat == SSTOP)? 'T':
+ (p->p_stat == SZOMB)? 'T': '?',
+ ppid,
+ pgid,
+ sid);
+ #else
bcopy(p->p_comm, ps, MAXCOMLEN);
ps[MAXCOMLEN] = '\0';
ps += strlen(ps);
ps += sprintf(ps, " %d %d %d %d ", pid, ppid, pgid, sid);
+ #endif
if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp))
+ #ifdef LINPROCFS
+ ps += sprintf(ps, "%u %d ", (unsigned int)tp->t_dev, -1);
+ #else
ps += sprintf(ps, "%d,%d ", major(tp->t_dev), minor(tp->t_dev));
+ #endif
else
+ #ifdef LINPROCFS
+ ps += sprintf(ps, "%d %d", -1, -1);
+ #else
ps += sprintf(ps, "%d,%d ", -1, -1);
+ #endif
+ #ifdef LINPROCFS
+ ps += sprintf(ps, "%d", p->p_flag);
+ #else
sep = "";
if (sess->s_ttyvp) {
ps += sprintf(ps, "%sctty", sep);
***************
*** 107,130 ****
--- 145,209 ----
}
if (*sep != ',')
ps += sprintf(ps, "noflags");
+ #endif
if (p->p_flag & P_INMEM) {
struct timeval ut, st;
calcru(p, &ut, &st, (struct timeval *) NULL);
+ #ifdef LINPROCFS
+ ps += sprintf(ps, " %ld %ld %d %d",
+ ut.tv_sec,
+ st.tv_sec, -1, -1);
+ #else
ps += sprintf(ps, " %ld,%ld %ld,%ld %ld,%ld",
p->p_stats->p_start.tv_sec,
p->p_stats->p_start.tv_usec,
ut.tv_sec, ut.tv_usec,
st.tv_sec, st.tv_usec);
+ #endif
} else
+ #ifdef LINPROCFS
+ ps += sprintf(ps, " -1 -1 -1 -1");
+ #else
ps += sprintf(ps, " -1,-1 -1,-1 -1,-1");
+ #endif
+ #ifdef LINPROCFS
+ ps += sprintf(ps, " %d %d %ld %d %ld %d %d %d %u %d %u "
+ "%u %u %u %d %d %d %ld",
+ p->p_priority,
+ p->p_nice,
+ (long) p->p_runtime,
+ -1,
+ p->p_stats->p_start.tv_sec,
+ -1,
+ -1,
+ -1,
+ p->p_addr->u_pcb.pcb_edi,
+ -1,
+ p->p_addr->u_pcb.pcb_esi,
+ p->p_addr->u_pcb.pcb_esp,
+ p->p_addr->u_pcb.pcb_eip,
+ (unsigned int) p->p_sigacts,
+ -1,
+ -1,
+ -1,
+ (long) p->p_wchan);
+ #else
ps += sprintf(ps, " %s",
(p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan");
+ #endif
cr = p->p_ucred;
+ #ifdef LINPROCFS
+ ps += sprintf(ps, " %d %d %d %d",
+ p->p_swtime,
+ -1,
+ p->p_xstat,
+ -1);
+ #else
ps += sprintf(ps, " %lu %lu %lu",
(u_long)cr->cr_uid,
(u_long)p->p_cred->p_ruid,
***************
*** 140,145 ****
--- 219,225 ----
ps += sprintf(ps, " %s", p->p_prison->pr_host);
else
ps += sprintf(ps, " -");
+ #endif
ps += sprintf(ps, "\n");
xlen = ps - psbuf;
***************
*** 154,159 ****
--- 234,240 ----
return (error);
}
+ #ifndef LINPROCFS
int
procfs_docmdline(curp, p, pfs, uio)
struct proc *curp;
***************
*** 227,229 ****
--- 308,311 ----
FREE(buf, M_TEMP);
return (error);
}
+ #endif
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200009151556.IAA23154>
