[comp.unix.ultrix] The proc struct in ULTRIX kernel

jay@argosy.UUCP (Jay O'Conor) (06/26/90)

In article <833@engcon.marshall.ltv.com> norris@engcon.marshall.ltv.com (DDDAVID) writes:
>I'm having problems understanding how the user structure and
>the proc structure in the ULTRIX kernel are associated.  On 
>other systems (Convex, Sun),  the proc structure has a pointer
>to the user structure and the user structure has a pointer to
>the proc struct.  In ULTRIX, the user structure has a pointer
>to the proc struct, but not vice-versa.
>
>A particular proc struct is fairly easy to track down in the proc 
>table, but in ULTRIX I can't figure out how to find the user
>struct associated with this proc struct.  I know this must be
>possible, because "ps" and "pstat" uses the user struct to
>display the command name, etc.  Anyone that will shed some
>light on the subject would be greatly appreciated.


Well, I'm fairly new to Ultrix, so what I say may be corrected by more
experienced Ultrix gurus out there.  Since I didn't see any response to
this, I thought I'd go ahead and answer it myself.

The answer is that all the user structures are at the same virtual
address!  Every u area is at 2Gb (0x80000000).  It would be kind of 
silly to have a pointer in every proc struct to point to the u area if
all of them are going to be the same anyway!

I realize that I'm opening myself up to all sorts of flames having
limited experience with Ultrix.  For all you would be flamers out there,
if I've gotten any facts incorrect, please go easy on me.  I'd be happy
to be educated by more knowledgeable Ultrix gurus out there.

Jay O'Conor
jay@maspar.com

thomas@mipsbx.nac.dec.com (Matt Thomas) (06/27/90)

This what I use in my port of the fstat program to ULTRIX (V4 or V3).
If NPROC is defined, this it's V4 otherwise V3.  Standard disclaimers
about not being supported and may change at any moment, etc.

static
getu()
{
	register struct pte *pteaddr;
	struct pte apte, arguutl[CLSIZE+HIGHPAGES];
	register int i;
        struct dmap l_dmap;
	int ncl, size, ublkno;

	size = sflg ? ctob(UPAGES) : sizeof (struct user);
	if ((mproc->p_sched & SLOAD) == 0) {
		if (swap < 0)
			return(0);
#ifdef NPROC
		kread(mproc->p_smap, &l_dmap, sizeof(struct dmap));
		kread(l_dmap.dm_ptdaddr, &ublkno, sizeof(int));
		(void) lseek(swap, (long)dtob(ublkno), 0);
#else
		(void) lseek(swap, (long)dtob(mproc->p_swaddr), 0);
#endif
		if (read(swap, (char *)&user.user, size) != size) {
			fprintf(stderr, "%s: cant read u for pid %d from %s\n",
			    pname, mproc->p_pid, swapfile);
			return (0);
		}
		return(1);
	}
#ifdef vax
	pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
#endif vax
#ifdef mips
	pteaddr = &Usrptma[btokmx(mproc->p_stakbr) + mproc->p_stakpt - 1];
#endif mips
	if (kread((ls_t)pteaddr, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
		(void) printf(
		  "%s: can't read indir pte to get u for pid %d from %s\n",
		  pname, mproc->p_pid, swapfile);
		return(0);
	}
#ifdef vax
	(void)lseek(mem, (ls_t)(ctob(apte.pg_pfnum+1) - (HIGHPAGES+CLSIZE)
	    * sizeof(struct pte)), L_SET);
	if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
#endif vax
#ifdef mips
	if (mproc->p_type & SSYS)
		goto read_ptes;
	(void)lseek(mem, (ls_t)(ctob(apte.pg_pfnum) + NBPG
	   - (HIGHPAGES+1) * sizeof(struct pte)), L_SET);
	if (read(mem, (char *)arguutl, CLSIZE*sizeof(struct pte))
	   != CLSIZE*sizeof(struct pte)) {
#endif mips
		(void) printf(
		  "%s: can't read page table for u of pid %d from %s\n",
		  pname, mproc->p_pid, kmemfile);
		return(0);
	}
#ifdef mips
read_ptes:
	if (kread((ls_t)mproc->p_addr, (char *)&arguutl[CLSIZE],
	   UPAGES*sizeof(struct pte)) != UPAGES*sizeof(struct pte)) {
		(void) printf(
		  "%s: can't read (user) page table for u of pid %d from %s\n",
		  pname, mproc->p_pid, kmemfile);
		return (0);
	}
#endif mips

	ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
#if defined(vax) && defined(NPROC)
	for (pteaddr = &arguutl[UPAGES + ncl*CLSIZE];
	    pteaddr > &arguutl[UPAGES];
	    pteaddr -= CLSIZE) {
		(void)lseek(mem, (ls_t)ctob(pteaddr->pg_pfnum), L_SET);
		if (read(mem, user.upages[pteaddr - &arguutl[CLSIZE + UPAGES]],
CLSIZE*NBPG) != CLSIZE*NBPG) {
			(void) printf(
			  "%s: can't read page %u of u of pid %d from %s\n",
			  pname,
			pteaddr->pg_pfnum, mproc->p_pid, corefile);
			return(0);
		}
	}
#endif
#if defined(mips) || !defined(NPROC)
	while (--ncl >= 0) {
		i = ncl * CLSIZE;
		(void)lseek(mem, (ls_t)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET);
		if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
			(void) printf(
			  "%s: can't read page %u of u of pid %d from %s\n",
			  pname,
			  arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, corefile);
			return(0);
		}
	}
#endif
	return(1);
}

-- 
Matt Thomas                     Internet:   thomas@wrl.dec.com
DECnet-ULTRIX Development       UUCP:       ...!decwrl!thomas
Digital Equipment Corporation   Disclaimer: This message reflects my own
Littleton, MA                               warped views, etc.