Skip site navigation (1)Skip section navigation (2)
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>