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.