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.