View Single Post

   
  #5 (permalink)  
Old 01-16-2008, 06:40 PM
Prashant
 
Posts: n/a
Default Re: Finding filename corresponding to fileid

Mike Stroyan <stroyan@hpstryn.fc.hp.com> wrote in message news:<tJdSb.13409$lZ5.11745@news.cpqcorp.net>...
> Prashant <prashant_a_a@yahoo.com> wrote:
>
> |>> I have a fileid for a file which I found out from a call to pstat_getproc().
> |>> How can I find filename associated with the fileid?
> ...
> |I require it to work on HP-UX 11.00 and 11.11 both.
> |pstat_getpathname() seems to be unavailable with 11.00.
>
> If you don't have pstat_getpathname then you will need to walk the
> directory tree to search for on or more paths that match the fileid.
> The init_cache and findpath functions in the following program build
> up and read from a list of paths and corresponding file ids.
>
>
> # This is a shell archive. Remove anything before this line,
> # then unpack it by saving it in a file and typing "sh file".
> #
> # Wrapped by Mike Stroyan <stroyan@hpstryn> on Thu Jan 29 13:04:51 2004
> #
> # This archive contains:
> # procvm.c
> #
>
> LANG=""; export LANG
> PATH=/bin:/usr/bin:/usr/sbin:/usr/ccs/bin:$PATH; export PATH
> EXIT_STATUS=0
>
> echo x - procvm.c
> cat >procvm.c <<'@EOF'
> #define _PSTAT64
> #include <sys/param.h>
> #include <sys/pstat.h>
> #include <sys/fstyp.h>
> #include <sys/statvfs.h>
> #include <sys/unistd.h>
> #include <sys/vfs.h>
> #include <malloc.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <limits.h>
> #include <mntent.h>
>
> char *mountpoint(long fsid)
> {
> static int init = 0;
> FILE *mnttab;
> struct statvfs buf;
> struct fsrecord { long fsid; char *name; struct fsrecord *next;};
> static struct fsrecord *list = NULL;
> struct fsrecord *record;
> struct mntent *mnt_entry;
>
> if (!init) {
> init = 1;
> if ((mnttab = setmntent(MNT_MNTTAB, "r")) != NULL) {
> while (mnt_entry = getmntent(mnttab)) {
> statvfs(mnt_entry->mnt_dir, &buf);
> record = (struct fsrecord *) malloc(sizeof(struct fsrecord));
> record->fsid = buf.f_fsid;
> record->name = strdup(mnt_entry->mnt_dir);
> record->next = list;
> list = record;
> }
> endmntent(mnttab);
> }
> }
> for (record = list; record != NULL; record = record->next) {
> if (record->fsid == fsid) return record->name;
> }
> return "";
> }
>
> #include <sys/stat.h>
> #include <ftw.h>
>
> struct namestruct {
> char *name;
> ino_t st_ino;
> };
>
> struct dirstruct {
> long f_fsid;
> struct namestruct *names;
> int namecachesize;
> };
>
> struct dirstruct *dircache = NULL;
> int dircachesize = 0;
> size_t dircachealloc = 0;
> struct namestruct *namecache = NULL;
> int namecachesize = 0;
> size_t namecachealloc = 0;
>
> int cache_names(
> const char *obj_path,
> const struct stat *obj_stat,
> int obj_flags,
> struct FTW obj_FTW)
> {
> if (namecachesize>=namecachealloc) {
> namecachealloc += 1000;
> namecache = (struct namestruct *) realloc((void*)namecache,
> namecachealloc*sizeof(struct namestruct));
> if (!namecache) {
> perror("realloc failed");
> exit(1);
> }
> }
> namecache[namecachesize].name = strdup(obj_path);
> namecache[namecachesize].st_ino = obj_stat->st_ino;
> namecachesize += 1;
> return 0;
> }
>
> void init_cache(char *dir)
> {
> struct statvfs buf;
>
> if (dircachesize>=dircachealloc) {
> dircachealloc += 100;
> dircache = (struct dirstruct *) realloc((void*)dircache,
> dircachealloc*sizeof(struct dirstruct));
> if (!dircache) {
> perror("realloc failed");
> exit(1);
> }
> }
> nftw(dir, cache_names, 40, FTW_PHYS|FTW_MOUNT|FTW_SERR);
> statvfs(dir, &buf);
> dircache[dircachesize].f_fsid = buf.f_fsid;
> dircache[dircachesize].names = namecache;
> dircache[dircachesize].namecachesize = namecachesize;
> dircachesize +=1;
> /* Reset for next use. */
> namecache = NULL;
> namecachesize = 0;
> namecachealloc = 0;
> }
>
> char *findpath(struct psfileid id)
> {
> int i, j;
> for(i=0; i<dircachesize; i++) {
> if (id.psf_fsid.psfs_id == dircache[i].f_fsid) {
> for(j=0; j<dircache[i].namecachesize ; j++) {
> if (id.psf_fileid == dircache[i].names[j].st_ino) {
> return dircache[i].names[j].name;
> }
> }
> }
> }
> return "unknown";
> }
>
> void pstatvm(int pid)
> {
> struct pst_vm_status pst;
> int idx, count;
> char fstypename[FSTYPSZ];
>
> idx=0;
> count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
> while (count > 0) {
> printf("pid: %d, region: %d\n", pid, idx);
> printf("pst_space: 0x%llx\n", (long long)pst.pst_space);
> printf("pst_vaddr: 0x%llx\n", (long long)pst.pst_vaddr);
> printf("pst_length: 0x%llx\n", (long long)pst.pst_length);
> printf("pst_phys_pages: 0x%llx\n", (long long)pst.pst_phys_pages);
> #ifdef PST_N_PG_SIZES /* only on 11.0 and later */
> {
> int i;
> printf("pst_pagesize_hint: %lld\n",
> (long long)pst.pst_pagesize_hint);
> /* Sizes are 4K, 8K, 16K, etc. PA2.0 only uses 4K, 16K, etc. */
> printf("page sizes: ");
> for (i=0; i<PST_N_PG_SIZES; i++) {
> printf("%lld ", (long long)pst.pst_vps_pgsizes[i]);
> }
> printf("\n");
> }
> #endif /* PST_N_PG_SIZES */
> printf("pst_flags: 0x%llx ", (long long)pst.pst_flags);
> if (pst.pst_flags & PS_MEMORY_LOCKED) printf("PS_MEMORY_LOCKED ");
> if (pst.pst_flags & PS_EXECUTABLE) printf("PS_EXECUTABLE ");
> if (pst.pst_flags & PS_SHARED) printf("PS_SHARED ");
> if (pst.pst_flags & PS_SHARED_LIBRARY) printf("PS_SHARED_LIBRARY");
> printf("\n");
> printf("pst_type: 0x%llx ", (long long)pst.pst_type);
> switch ((long)pst.pst_type) {
> case PS_NOTUSED: printf("PS_NOTUSED\n"); break;
> case PS_USER_AREA: printf("PS_USER_AREA\n"); break;
> case PS_TEXT: printf("PS_TEXT\n"); break;
> case PS_DATA: printf("PS_DATA\n"); break;
> case PS_STACK: printf("PS_STACK\n"); break;
> case PS_SHARED_MEMORY: printf("PS_SHARED_MEMORY\n"); break;
> case PS_NULLDEREF: printf("PS_NULLDEREF\n"); break;
> case PS_IO: printf("PS_IO\n"); break;
> case PS_MMF: printf("PS_MMF\n"); break;
> case PS_GRAPHICS: printf("PS_GRAPHICS\n"); break;
> case PS_GRAPHICS_DMA: printf("PS_GRAPHICS_DMA\n"); break;
> }
> printf("pst_permission: 0x%llx ", (long long)pst.pst_permission);
> if (pst.pst_permission & PS_PROT_READ) printf("PS_PROT_READ ");
> if (pst.pst_permission & PS_PROT_WRITE) printf("PS_PROT_WRITE ");
> if (pst.pst_permission & PS_PROT_EXECUTE) printf("PS_PROT_EXECUTE ");
> printf("\n");
> printf("pst_id.psf_fsid.psfs_id: 0x%llx ", (long long)pst.pst_id.psf_fsid.psfs_id);
> printf("%s\n", mountpoint(pst.pst_id.psf_fsid.psfs_id));
> sysfs(GETFSTYP, (int) pst.pst_id.psf_fsid.psfs_type, fstypename);
> printf("pst_id.psf_fsid.psfs_type: %d %s\n",
> (int) pst.pst_id.psf_fsid.psfs_type, fstypename);
>
> printf("pst_id.psf_fileid: %lld\n", (long long)pst.pst_id.psf_fileid);
> if (pst.pst_id.psf_fileid != -1)
> printf("path: %s\n", findpath(pst.pst_id));
> printf("\n");
>
> idx++;
> count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
> }
> }
>
> void pstatvm_all(void)
> {
> #define BURST ((size_t)10)
>
> struct pst_status pst[BURST];
> int i, count;
> int idx = 0; /* index within the context */
>
> /* loop until count == 0, will occur when all have been returned */
> while ((count = pstat_getproc(pst, sizeof(pst[0]), BURST, idx)) > 0)
> {
> /* got count (max of BURST) this time. process them */
> for (i = 0; i < count; i++) {
> if (pst[i].pst_pid==0) continue; /* Can't getprocvm real pid 0 */
> printf("command: %s, ", pst[i].pst_ucomm);
> #ifdef PST_N_PG_SIZES /* only on 11.0 and later */
> printf("+pi: %lld, +pd: %lld, ",
> (long long) pst[i].pst_text_size,
> (long long) pst[i].pst_data_size);
> /* Page sizes are in 4K units. 0 represents default.
> 0 D
> 1 4K
> 4 16K
> 16 64K
> 64 256K
> 256 1M
> 1024 4M
> 4096 16M
> 16384 64M
> */
> #endif
> pstatvm(pst[i].pst_pid);
> }
>
> /*
> * now go back and do it again, using the next index after
> * the current 'burst'
> */
> idx = pst[count-1].pst_idx + 1;
> }
>
> if (count == -1)
> perror("pstat_getproc()");
>
> #undef BURST
> }
>
> main(int argc, char *argv[])
> {
> int i, default_paths = 1, error = 0;
> char *shlibpath, *dir;
> extern int optind;
> extern char *optarg;
> char opt;
>
> while ((opt = getopt(argc, argv, "ni:")) != EOF) {
> switch (opt) {
> case 'i':
> shlibpath = strdup(optarg);
> for (dir=strtok(shlibpath,":"); dir; dir=strtok(NULL,":"))
> init_cache(dir);
> break;
>
> case 'n':
> default_paths = 0;
> break;
>
> default:
> error = 1;
> break;
> }
> }
>
> if (error) {
> fprintf(stderr, "Usage: procvm [-i dirlist] [-n] [pids]\n");
> exit(1);
> }
>
> if (default_paths) {
> init_cache("/usr/lib");
> init_cache("/opt/graphics");
> shlibpath = strdup(getenv("PATH"));
> if (shlibpath) {
> for (dir=strtok(shlibpath,":"); dir; dir=strtok(NULL,":"))
> init_cache(dir);
> }
> shlibpath = strdup(getenv("SHLIB_PATH"));
> if (shlibpath) {
> for (dir=strtok(shlibpath,":"); dir; dir=strtok(NULL,":"))
> init_cache(dir);
> }
> }
>
> if (optind < argc) {
> for (i=optind; i<argc; i++)
> pstatvm(atoi(argv[i]));
> } else {
> pstatvm_all();
> }
> }
> @EOF
>
> chmod 644 procvm.c
>
>
> if [ $EXIT_STATUS -eq 1 ];then
> exit 1
> fi
> exit 0


With some chopping and changing with above code, I could find the name
of the executable from pid. Thanks a lot!

-Prashant.
Reply With Quote