View Single Post

   
  #4 (permalink)  
Old 01-16-2008, 06:38 PM
Mike Stroyan
 
Posts: n/a
Default Re: Finding filename corresponding to fileid

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

--
Mike Stroyan, mike.stroyan@hp.com
Reply With Quote