/* * dnode.c - Solaris node reading functions for lsof */ /* * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana * 47907. All rights reserved. * * Written by Victor A. Abell * * This software is not subject to any license of the American Telephone * and Telegraph Company or the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * * 1. Neither the authors nor Purdue University are responsible for any * consequences of the use of this software. * * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Credit to the authors and Purdue * University must appear in documentation and sources. * * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 4. This notice may not be removed or altered. */ #ifndef lint static char copyright[] = "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; static char *rcsid = "$Id: dnode.c,v 1.58 2011/08/07 22:53:42 abe Exp $"; #endif #include "lsof.h" #if solaris>=110000 #include #endif /* solaris>=110000 */ #undef fs_bsize #include #if solaris>=110000 && defined(HAS_LIBCTF) /* * Sockfs support for Solaris 11 via libctf */ /* * Sockfs internal structure definitions * * The structure definitions may look like kernel structures, but they are * not. They have been defined to have member names that duplicate those * used by the kernel that are of interest to lsof. Member values are * obtained via the CTF library, libctf. * * Robert Byrnes developed the CTF library access code and contributed it * to lsof. */ struct soaddr { /* sadly, CTF doesn't grok this * structure */ struct sockaddr *soa_sa; /* address */ t_uscalar_t soa_len; /* length in bytes */ t_uscalar_t soa_maxlen; /* maximum length */ }; typedef struct sotpi_info { dev_t sti_dev; /* sonode device */ struct soaddr sti_laddr; /* local address */ struct soaddr sti_faddr; /* peer address */ struct so_ux_addr sti_ux_laddr; /* bound local address */ struct so_ux_addr sti_ux_faddr; /* bound peer address */ t_scalar_t sti_serv_type; /* service type */ } sotpi_info_t; /* * CTF definitions for sockfs */ static int Sockfs_ctfs = 0; /* CTF initialization status for * sockfs */ # if defined(_LP64) #define SOCKFS_MOD_FORMAT "/kernel/fs/%s/sockfs" # else /* !defined(_LP64) */ #define SOCKFS_MOD_FORMAT "/kernel/fs/sockfs" # endif /* defined(_LP64) */ /* sockfs module pathname template to * which the kernel's instruction type * set is added for CTF access */ /* * Sockfs access definitions and structures */ #define SOADDR_TYPE_NAME "soaddr" static CTF_member_t soaddr_members[] = { CTF_MEMBER(soa_sa), #define MX_soa_sa 0 CTF_MEMBER(soa_len), #define MX_soa_len 1 CTF_MEMBER(soa_maxlen), #define MX_soa_maxlen 2 { NULL, 0 } }; #define SOTPI_INFO_TYPE_NAME "sotpi_info_t" static CTF_member_t sotpi_info_members[] = { CTF_MEMBER(sti_dev), #define MX_sti_dev 0 CTF_MEMBER(sti_laddr), #define MX_sti_laddr 1 CTF_MEMBER(sti_faddr), #define MX_sti_faddr 2 CTF_MEMBER(sti_ux_laddr), #define MX_sti_ux_laddr 3 CTF_MEMBER(sti_ux_faddr), #define MX_sti_ux_faddr 4 CTF_MEMBER(sti_serv_type), #define MX_sti_serv_type 5 { NULL, 0 } }; /* * CTF sockfs request table */ static CTF_request_t Sockfs_requests[] = { { SOTPI_INFO_TYPE_NAME, sotpi_info_members }, { NULL, NULL } }; /* * Sockfs function prototypes */ _PROTOTYPE(static int read_nsti,(struct sonode *so, sotpi_info_t *stpi)); #endif /* solaris>=110000 && defined(HAS_LIBCTF) */ #if defined(HAS_ZFS) && defined(HAS_LIBCTF) /* * ZFS support via libctf */ /* * ZFS internal structure definitions * * The structure definitions may look like kernel structures, but they are * not. They have been defined to have member names that duplicate those * used by the kernel that are of interest to lsof. Member values are * obtained via the CTF library, libctf. * * Robert Byrnes developed the CTF library access code and contributed it * to lsof. */ typedef struct zfsvfs { vfs_t *z_vfs; /* pointer to VFS */ } zfsvfs_t; typedef struct znode_phys { uint64_t zp_size; /* file size (ZFS below 5) */ uint64_t zp_links; /* links (ZFS below 5) */ } znode_phys_t; typedef struct znode { zfsvfs_t *z_zfsvfs; /* pointer to associated vfs */ vnode_t *z_vnode; /* pointer to associated vnode */ uint64_t z_id; /* node ID */ znode_phys_t *z_phys; /* pointer to persistent znode (ZFS * below 5) */ uint64_t z_links; /* links (ZFS 5 and above) */ uint64_t z_size; /* file size (ZFS 5 and above) */ } znode_t; /* * CTF definitions for ZFS */ static int ZFS_ctfs = 0; /* CTF initialization status for ZFS */ # if defined(_LP64) #define ZFS_MOD_FORMAT "/kernel/fs/%s/zfs" # else /* !defined(_LP64) */ #define ZFS_MOD_FORMAT "/kernel/fs/zfs" # endif /* defined(_LP64) */ /* ZFS module pathname template to * which the kernel's instruction type * set is added for CTF access */ /* * ZFS access definitions and structures */ #define ZNODE_TYPE_NAME "znode_t" static CTF_member_t znode_members[] = { CTF_MEMBER(z_zfsvfs), #define MX_z_zfsvfs 0 CTF_MEMBER(z_vnode), #define MX_z_vnode 1 CTF_MEMBER(z_id), #define MX_z_id 2 CTF_MEMBER(z_link_node), #define MX_z_link_node 3 CTF_MEMBER(z_phys), #define MX_z_phys 4 CTF_MEMBER(z_links), #define MX_z_links 5 CTF_MEMBER(z_size), #define MX_z_size 6 { NULL, 0 } }; #define ZNODE_PHYS_TYPE_NAME "znode_phys_t" static CTF_member_t znode_phys_members[] = { CTF_MEMBER(zp_size), #define MX_zp_size 0 CTF_MEMBER(zp_links), #define MX_zp_links 1 { NULL, 0 } }; #define ZFSVFS_TYPE_NAME "zfsvfs_t" static CTF_member_t zfsvfs_members[] = { CTF_MEMBER(z_vfs), #define MX_z_vfs 0 { NULL, 0 } }; /* * CTF ZFS request table */ static CTF_request_t ZFS_requests[] = { { ZNODE_TYPE_NAME, znode_members }, { ZNODE_PHYS_TYPE_NAME, znode_phys_members }, { ZFSVFS_TYPE_NAME, zfsvfs_members }, { NULL, NULL } }; /* * Missing members exceptions -- i.e., CTF_getmem won't consider it * an error if any of these members are undefined. */ typedef struct CTF_exception { char *tynm; /* type name */ char *memnm; /* member name */ } CTF_exception_t; static CTF_exception_t CTF_exceptions[] = { { ZNODE_TYPE_NAME, "z_phys" }, { ZNODE_TYPE_NAME, "z_links" }, { ZNODE_TYPE_NAME, "z_size" }, { NULL, NULL } }; /* * ZFS function prototypes */ _PROTOTYPE(static int read_nzn,(KA_T na, KA_T nza, znode_t *z)); _PROTOTYPE(static int read_nznp,(KA_T nza, KA_T nzpa, znode_phys_t *zp)); _PROTOTYPE(static int read_nzvfs,(KA_T nza, KA_T nzva, zfsvfs_t *zv)); #endif /* defined(HAS_ZFS) && defined(HAS_LIBCTF) */ _PROTOTYPE(static struct l_dev *finddev,(dev_t *dev, dev_t *rdev, int flags)); /* * Finddev() "look-in " flags */ #define LOOKDEV_TAB 0x01 /* look in device table */ #define LOOKDEV_CLONE 0x02 /* look in Clone table */ #define LOOKDEV_PSEUDO 0x04 /* look in Pseudo table */ #define LOOKDEV_ALL (LOOKDEV_TAB | LOOKDEV_CLONE | LOOKDEV_PSEUDO) /* look all places */ /* * SAM-FS definitions */ #define SAMFS_NMA_MSG "(limited SAM-FS info)" /* * Voptab definitions */ typedef struct build_v_optab { char *dnm; /* drive_NL name */ char *fsys; /* file system type name */ int nty; /* node type index (i.e., N_*) */ } build_v_optab_t; static build_v_optab_t Build_v_optab[] = { { "auvops", "autofs", N_AUTO }, { "avops", "afs", N_AFS }, { "afsops", "afs", N_AFS }, { "ctfsadir", NULL, N_CTFSADIR }, { "ctfsbund", NULL, N_CTFSBUND }, { "ctfscdir", NULL, N_CTFSCDIR }, { "ctfsctl", NULL, N_CTFSCTL }, { "ctfsevt", NULL, N_CTFSEVT }, { "ctfslate", NULL, N_CTFSLATE }, { "ctfsroot", NULL, N_CTFSROOT }, { "ctfsstat", NULL, N_CTFSSTAT }, { "ctfssym", NULL, N_CTFSSYM }, { "ctfstdir", NULL, N_CTFSTDIR }, { "ctfstmpl", NULL, N_CTFSTMPL }, { "cvops", NULL, N_CACHE }, { "devops", "devfs", N_DEV }, { "doorops", NULL, N_DOOR }, { "fdops", "fd", N_FD }, { "fd_ops", "fd", N_FD }, { "fvops", "fifofs", N_FIFO }, { "hvops", "hsfs", N_HSFS }, { "lvops", "lofs", N_LOFS }, { "mntops", "mntfs", N_MNT }, { "mvops", "mvfs", N_MVFS }, { "n3vops", NULL, N_NFS }, #if solaris>=100000 { "n4vops", NULL, N_NFS4 }, #else /* solaris<100000 */ { "n4vops", NULL, N_NFS }, #endif /* solaris>=100000 */ { "nmvops", "namefs", N_NM }, { "nvops", NULL, N_NFS }, { "pdvops", "pcfs", N_PCFS }, { "pfvops", "pcfs", N_PCFS }, { "portvops", NULL, N_PORT }, { "prvops", "proc", N_PROC }, { "sam1vops", NULL, N_SAMFS }, { "sam2vops", NULL, N_SAMFS }, { "sam3vops", NULL, N_SAMFS }, { "sam4vops", NULL, N_SAMFS }, { "sckvops", "sockfs", N_SOCK }, { "devipnetops", "sdevfs", N_SDEV }, { "devnetops", "sdevfs", N_SDEV }, { "devptsops", "sdevfs", N_SDEV }, { "devvtops", "sdevfs", N_SDEV }, { "socketvops", "sockfs", N_SOCK }, { "sdevops", "sdevfs", N_SDEV }, { "shvops", "sharedfs", N_SHARED }, { "sncavops", "sockfs", N_SOCK }, { "stpivops", "sockfs", N_SOCK }, { "spvops", "specfs", N_REGLR }, { "tvops", "tmpfs", N_TMP }, { "uvops", "ufs", N_REGLR }, { "vvfclops", "vxfs", N_VXFS }, { "vvfops", "vxfs", N_VXFS }, { "vvfcops", "vxfs", N_VXFS }, { "vvops", "vxfs", N_VXFS }, { "vvops_p", "vxfs", N_VXFS }, { "zfsdops", "zfs", N_ZFS }, { "zfseops", "zfs", N_ZFS }, { "zfsfops", "zfs", N_ZFS }, { "zfsshops", "zfs", N_ZFS }, { "zfssymops", "zfs", N_ZFS }, { "zfsxdops", "zfs", N_ZFS }, { NULL, NULL, 0 } /* table end */ }; typedef struct v_optab { char *fsys; /* file system type name */ int fx; /* Fsinfo[] index (-1 if none) */ int nty; /* node type index (i.e., N_*) */ KA_T v_op; /* vnodeops address */ struct v_optab *next; /* next entry */ } v_optab_t; static v_optab_t **FxToVoptab = (v_optab_t **)NULL; /* table to convert file system index * to Voptab address[] -- built by * build_Voptab() */ static v_optab_t **Voptab = (v_optab_t **)NULL; /* table to convert vnode v_op * addresses to file system name and * node type -- built by build_Voptab() * and addressed through the HASHVOP() * macro */ #define VOPHASHBINS 256 /* number of Voptab[] hash bins -- * MUST BE A POWER OF TWO! */ /* * Local function prototypes */ _PROTOTYPE(static void build_Voptab,(void)); _PROTOTYPE(static char isvlocked,(struct vnode *va)); _PROTOTYPE(static int readinode,(KA_T ia, struct inode *i)); _PROTOTYPE(static void read_mi,(KA_T s, dev_t *dev, caddr_t so, int *so_st, KA_T *so_ad, struct l_dev **sdp)); #if solaris>=20500 # if solaris>=20600 _PROTOTYPE(static int read_nan,(KA_T na, KA_T aa, struct fnnode *rn)); _PROTOTYPE(static int read_nson,(KA_T na, KA_T sa, struct sonode *sn)); _PROTOTYPE(static int read_nusa,(struct soaddr *so, struct sockaddr_un *ua)); # else /* solaris<20600 */ _PROTOTYPE(static int read_nan,(KA_T na, KA_T aa, struct autonode *a)); # endif /* solaris>=20600 */ _PROTOTYPE(static int idoorkeep,(struct door_node *d)); _PROTOTYPE(static int read_ndn,(KA_T na, KA_T da, struct door_node *d)); #endif /* solaris>=20500 */ #if solaris>=110000 _PROTOTYPE(static int read_nsdn,(KA_T na, KA_T sa, struct sdev_node *sdn, struct vattr *sdva)); #endif /* solaris>=110000 */ _PROTOTYPE(static int read_nfn,(KA_T na, KA_T fa, struct fifonode *f)); _PROTOTYPE(static int read_nhn,(KA_T na, KA_T ha, struct hsnode *h)); _PROTOTYPE(static int read_nin,(KA_T na, KA_T ia, struct inode *i)); _PROTOTYPE(static int read_nmn,(KA_T na, KA_T ia, struct mvfsnode *m)); _PROTOTYPE(static int read_npn,(KA_T na, KA_T pa, struct pcnode *p)); _PROTOTYPE(static int read_nrn,(KA_T na, KA_T ra, struct rnode *r)); #if solaris>=100000 _PROTOTYPE(static int read_nctfsn,(int ty, KA_T na, KA_T ca, char *cn)); _PROTOTYPE(static int read_nprtn,(KA_T na, KA_T ra, port_t *p)); _PROTOTYPE(static int read_nrn4,(KA_T na, KA_T ra, struct rnode4 *r)); #endif /* solaris>=100000 */ _PROTOTYPE(static int read_nsn,(KA_T na, KA_T sa, struct snode *s)); _PROTOTYPE(static int read_ntn,(KA_T na, KA_T ta, struct tmpnode *t)); _PROTOTYPE(static int read_nvn,(KA_T na, KA_T va, struct vnode *v)); #if defined(HASPROCFS) _PROTOTYPE(static int read_npi,(KA_T na, struct vnode *v, struct pid *pids)); #endif /* defined(HASPROCFS) */ _PROTOTYPE(static char *ent_fa,(KA_T *a1, KA_T *a2, char *d, int *len)); _PROTOTYPE(static int is_socket,(struct vnode *v)); _PROTOTYPE(static int read_cni,(struct snode *s, struct vnode *rv, struct vnode *v, struct snode *rs, struct dev_info *di, char *din, int dinl)); _PROTOTYPE(static int read_ncn,(KA_T na, KA_T ca, struct cnode *cn)); _PROTOTYPE(static int read_nln,(KA_T na, KA_T la, struct lnode *ln)); _PROTOTYPE(static int read_nnn,(KA_T na, KA_T nna, struct namenode *n)); #if solaris<100000 _PROTOTYPE(static void savesockmod,(struct so_so *so, struct so_so *sop, int *so_st)); #else /* solaris>=100000 */ _PROTOTYPE(static int read_ndvn,(KA_T na, KA_T da, struct dv_node *dv, dev_t *dev, unsigned char *devs)); #endif /* solaris<100000 */ /* * Local static values */ static KA_T Spvops = (KA_T)0; /* specfs vnodeops address -- saved * by build_Voptab() */ static KA_T Vvops[VXVOP_NUM]; /* addresses of: * vx_fcl_dnodeops_p (VXVOP_FCL) * fdd_vnops (VXVOP_FDD) * fdd_chain_vnops (VXVOP_FDDCH), * vx_vnodeops (VXVOP_REG) * vx_vnodeops_p (VXVOP_REG_P) * -- saved by build_Voptab() */ /* * Local macros * * GETVOPS() -- get direct or indirect *vnodeops address * * HASHVOP() -- hash the vnode's v_op address */ #if defined(VOPNAME_OPEN) && solaris>=100000 #define GETVOPS(name, nl, ops) \ if (get_Nl_value(name, nl, &ops) < 0) \ ops = (KA_T)0; \ else if (kread(ops, (char *)&ops, sizeof(ops))) \ ops = (KA_T)0 #else /* !defined(VOPNAME_OPEN) || solaris<100000 */ #define GETVOPS(name, nl, ops) \ if (get_Nl_value(name, nl, &ops) < 0) \ ops = (KA_T)0 #endif /* defined(VOPNAME_OPEN) && solaris>=100000 */ #define HASHVOP(ka) ((int)((((ka &0x1fffffff) * 31415) >> 3) & \ (VOPHASHBINS - 1))) /* * build_Voptab() -- build Voptab[] */ static void build_Voptab() { build_v_optab_t *bp; /* Build_v_optab[] pointer */ int fx; /* temporary file system type index */ int h; /* hash index */ int i, j; /* temporary indexes */ KA_T ka; /* temporary kernel address */ v_optab_t *nv, *vp, *vpp; /* Voptab[] working pointers */ int vv = 0; /* number of Vvops[] addresses that * have been located */ /* * If Voptab[] is allocated, return; otherwise allocate space for Voptab[] * and FxToVoptab[] amd fill them. */ if (Voptab) return; /* * During first call, allocate space for Voptab[] and FxToVoptab[]. */ if (!(Voptab = (v_optab_t **)calloc((MALLOC_S)VOPHASHBINS, sizeof(v_optab_t))) ) { (void) fprintf(stderr, "%s: no space for Voptab\n", Pn); Exit(1); } if (!(FxToVoptab = (v_optab_t **)calloc((MALLOC_S)Fsinfomax, sizeof(v_optab_t *))) ) { (void) fprintf(stderr, "%s: no space for FxToVoptab\n", Pn); Exit(1); } for (i = 0; i < VXVOP_NUM; i++) { Vvops[i] = (KA_T)NULL; } /* * Use Build_v_optab[] to build Voptab[]. */ for (bp = Build_v_optab; bp->dnm; bp++) { /* * Get the kernel address for the symbol. Do nothing if it can't * be determined. */ GETVOPS(bp->dnm, Drive_Nl, ka); if (!ka) continue; /* * Check the Voptab[] for the address. */ h = HASHVOP(ka); for (vp = Voptab[h], vpp = (v_optab_t *)NULL; vp; vp = vp->next) { if (vp->v_op == ka) break; vpp = vp; } if (vp) { /* * Ignore duplicates. */ continue; } /* * No Voptab[] entry was found, so allocate space for a new * v_optab_t structure, determine its file system type index, * fill it and link it to the Voptab[]. */ if (!(nv = (v_optab_t *)malloc((MALLOC_S)sizeof(v_optab_t)))) { (void) fprintf(stderr, "%s: out of Voptab space at: %s\n", Pn, bp->dnm); Exit(1); } nv->fsys = bp->fsys; nv->fx = -1; nv->nty = bp->nty; nv->next = (v_optab_t *)NULL; nv->v_op = ka; if (bp->fsys) { for (i = 0; i < Fsinfomax; i++) { if (!strcmp(bp->fsys, Fsinfo[i])) { nv->fx = i; break; } } } if (!Voptab[h]) Voptab[h] = nv; else vpp->next = nv; /* * Handle special v_op addresses: * * special vnode ops; * VxFS ops. */ if (!Spvops) { if (!strcmp(bp->dnm, "spvops")) Spvops = ka; } for (i = 0; (i < VXVOP_NUM) && (vv < VXVOP_NUM); i++) { if (Vvops[i]) continue; switch (i) { case VXVOP_FCL: if (!strcmp(bp->dnm, "vvfclops")) { Vvops[i] = ka; vv++; } break; case VXVOP_FDD: if (!strcmp(bp->dnm, "vvfops")) { Vvops[i] = ka; vv++; } break; case VXVOP_FDDCH: if (!strcmp(bp->dnm, "vvfcops")) { Vvops[i] = ka; vv++; } break; case VXVOP_REG: if (!strcmp(bp->dnm, "vvops")) { Vvops[i] = ka; vv++; } break; case VXVOP_REG_P: if (!strcmp(bp->dnm, "vvops_p")) { Vvops[i] = ka; vv++; } break; } } } /* * Link Voptab[] entries to FxToVoptab[] entries. */ for (h = 0; h < VOPHASHBINS; h++) { for (vp = Voptab[h]; vp; vp = vp->next) { if (!vp->fsys) continue; if (((fx = vp->fx) >= 0) && (fx < Fsinfomax)) { if (!FxToVoptab[fx]) FxToVoptab[fx] = vp; continue; } for (i = 0; i < Fsinfomax; i++) { if (!strcmp(Fsinfo[i], vp->fsys)) { vp->fx = i; if (!FxToVoptab[i]) FxToVoptab[i] = vp; break; } } } } } #if defined(HAS_LIBCTF) /* * CTF_getmem() -- get CTF members */ int CTF_getmem(f, mod, ty, mem) ctf_file_t *f; /* CTF file handle */ const char *mod; /* module name */ const char *ty; /* type */ CTF_member_t *mem; /* member table */ { int err; /* error flag */ ctf_id_t id; /* CTF ID */ CTF_member_t *mp; /* member pointer */ CTF_exception_t *xp; /* exception table pointer */ int xs; /* exception status */ /* * Look up the type. */ if ((id = ctf_lookup_by_name(f, ty)) == CTF_ERR) { (void) fprintf(stderr, "%s: ctf_lookup_by_name: %s: %s: %s\n", Pn, mod, ty, ctf_errmsg(ctf_errno(f))); return(1); } /* * Get member offsets. */ if (ctf_member_iter(f, id, CTF_memCB, mem) == CTF_ERR) { (void) fprintf(stderr, "%s: ctf_member_iter: %s: %s: %s\n", Pn, mod, ty, ctf_errmsg(ctf_errno(f))); return(1); } /* * Examine members. */ for (err = 0, mp = mem; mp->m_name; mp++) { if (mp->m_offset == CTF_MEMBER_UNDEF) { /* * Check for an undefined member exception. Report an error if * no exception is found. */ for (xp = CTF_exceptions, xs = 0; xp->tynm; xp++) { if (!strcmp(xp->tynm, ty) && !strcmp(xp->memnm, mp->m_name)) { xs = 1; break; } } if (!xs) { (void) fprintf(stderr, "%s: getmembers: %s: %s: %s: struct member undefined\n", Pn, mod, ty, mp->m_name); err = 1; } } else { /* * Convert bit offsets to byte offsets. */ if ((mp->m_offset % NBBY) != 0) { (void) fprintf(stderr, "%s: getmembers: %s: %s: %s: struct member is bit field\n", Pn, mod, ty, mp->m_name); err = 1; } else mp->m_offset /= NBBY; } } return(err); } /* * CTF_init - initialize CTF library access */ void CTF_init(i, t, r) int *i; /* initialization status */ char *t; /* kernel module template */ CTF_request_t *r; /* CTF requests */ { int err; /* error status */ ctf_file_t *f; /* CTF file info handle */ # if defined(_LP64) static char isa[256+1]; /* kernel instruction set name */ static int isas = 0; /* isa[] status */ # endif /* defined(_LP64) */ char kernmod[MAXPATHLEN]; /* kernel module pathname */ char *kmp; /* kernel module path name pointer */ static char pfn[256+1]; /* system platform name */ static int pfns = 0; /* pfn[] status: -1 = request failed * 0 = none requested * >0 = available */ char pfxkernmod[MAXPATHLEN]; /* prefixed kernel module name */ struct stat sb; /* stat(2) buffer */ if (*i) return; # if defined(_LP64) /* * If CTF access hasn't been initialized and a 64 bit kernel is in use, * determine the name of the kernel's instruction set, and construct the * pathname of the kernel module, using the supplied template. */ if (!isas) { if (sysinfo(SI_ARCHITECTURE_K, isa, sizeof(isa) - 1) == -1) { (void) fprintf(stderr, "%s: sysinfo: %s\n", Pn, strerror(errno)); Exit(1); } isas = 1; isa[sizeof(isa) - 1] = '\0'; } (void) snprintf(kernmod, sizeof(kernmod) - 1, t, isa); kernmod[sizeof(kernmod) - 1] = '\0'; # else /* !defined(_LP64) */ /* * If CTF access hasn't been initialized and a 32 bit kernel is in use, the * supplied template is the module path name. */ (void) strncpy(kernmod, t, sizeof(kernmod) - 1); # endif /* defined(_LP64) */ kernmod[sizeof(kernmod) - 1] = '\0'; kmp = kernmod; if (statsafely(kmp, &sb)) { /* * The module at the specified path does not exist or is inaccessible. * * Get the platform name and construct a prefix from it for module path * name and see if that exists and is accessible. * * If it is, let CTF_init() use it; otherwise let CTF_init() fail on * the specified path. */ if (pfns >= 0) { if (!pfns) pfns = sysinfo(SI_MACHINE, pfn, sizeof(pfn) - 1); if (pfns > 0) { pfn[sizeof(pfn) - 1] = '\0'; (void) snprintf(pfxkernmod, sizeof(pfxkernmod) - 1, "/platform/%s/%s", pfn, (kernmod[0] == '/') ? &kernmod[1] : kernmod); pfxkernmod[sizeof(pfxkernmod) - 1] = '\0'; if (!stat(pfxkernmod, &sb)) kmp = pfxkernmod; } } } /* * Open the module file and read its CTF info. */ if ((f = ctf_open(kmp, &err)) == NULL) { (void) fprintf(stderr, "%s: ctf_open: %s: %s\n", Pn, kmp, ctf_errmsg(err)); Exit(1); } for (err = 0; r->name; r++) { if (CTF_getmem(f, kmp, r->name, r->mem)) err = 1; } (void) ctf_close(f); if (err) Exit(1); *i = 1; } /* * CTF_memCB() - Callback function for ctf_member_iter() */ int CTF_memCB(name, id, offset, arg) const char *name; /* structure member name */ ctf_id_t id; /* CTF ID */ ulong_t offset; /* member offset */ void *arg; /* member table */ { CTF_member_t *mp; /* * Check for members of interest and record their offsets. */ for (mp = (CTF_member_t *)arg; mp->m_name; mp++) { if (!strcmp(name, mp->m_name)) { mp->m_offset = offset; break; } } return(0); } #endif /* defined(HAS_LIBCTF) */ /* * ent_fa() - enter fattach addresses in NAME column addition */ static char * ent_fa(a1, a2, d, len) KA_T *a1; /* first fattach address (NULL OK) */ KA_T *a2; /* second fattach address */ char *d; /* direction ("->" or "<-") */ int *len; /* returned description length */ { static char buf[1024]; size_t bufl = sizeof(buf); char tbuf[32]; /* * Form the fattach description. */ if (!a1) #if solaris<20600 (void) snpf(buf, bufl, "(FA:%s%s)", d, print_kptr(*a2, (char *)NULL, 0)); #else /* solaris>=20600 */ (void) snpf(buf, bufl, "(FA:%s%s)", d, print_kptr(*a2, (char *)NULL, 0)); #endif /* solaris<20600 */ else #if solaris<20600 (void) snpf(buf, bufl, "(FA:%s%s%s)", print_kptr(*a1, tbuf, sizeof(tbuf)), d, print_kptr(*a2, (char *)NULL, 0)); #else /* solaris>=20600 */ (void) snpf(buf, bufl, "(FA:%s%s%s)", print_kptr(*a1, tbuf, sizeof(tbuf)), d, print_kptr(*a2, (char *)NULL, 0)); #endif /* solaris<20600 */ *len = (int)strlen(buf); return(buf); } /* * is_socket() - is the stream a socket? */ static int is_socket(v) struct vnode *v; /* vnode pointer */ { char *cp, *ep, *pf; int i, j, len, n, pfl; major_t maj; minor_t min; static struct tcpudp { int ds; major_t maj; minor_t min; char *proto; } tcpudp[] = { { 0, 0, 0, "tcp" }, { 0, 0, 0, "udp" }, #if defined(HASIPv6) { 0, 0, 0, "tcp6" }, { 0, 0, 0, "udp6" }, #endif /* defined(HASIPv6) */ }; #define NTCPUDP (sizeof(tcpudp) / sizeof(struct tcpudp)) static int tcpudps = 0; if (!v->v_stream) return(0); maj = (major_t) GET_MAJ_DEV(v->v_rdev); min = (minor_t) GET_MIN_DEV(v->v_rdev); /* * Fill in tcpudp[], as required. */ if (!tcpudps) { #if solaris<80000 pf = "/devices/pseudo/clone"; #else /* solaris>=80000 */ pf = "/devices/pseudo/"; #endif /* solaris<80000 */ for (i = n = 0, pfl = (int)strlen(pf); (i < Ndev) && (n < NTCPUDP); i++) { if (strncmp(Devtp[i].name, pf, pfl) || !(ep = strrchr((cp = &Devtp[i].name[pfl]), ':')) || (strncmp(++ep, "tcp", 3) && strncmp(ep, "udp", 3))) continue; #if solaris<80000 if (*(ep + 3)) #else /* solaris>=80000 */ len = (*(ep + 3) == '6') ? 4 : 3; if (*(ep + len) || ((cp + len) >= ep) || strncmp(cp, ep, len)) #endif /* solaris<80000 */ continue; for (j = 0; j < NTCPUDP; j++) { if (!tcpudp[j].ds && !strcmp(ep, tcpudp[j].proto)) { tcpudp[j].ds = 1; tcpudp[j].maj = (major_t) GET_MAJ_DEV(Devtp[i].rdev); tcpudp[j].min = (minor_t) GET_MIN_DEV(Devtp[i].rdev); n++; break; } } } tcpudps = n ? 1 : -1; } /* * Check for known IPv[46] TCP or UDP device. */ for (i = 0; (i < NTCPUDP) && (tcpudps > 0); i++) { if (tcpudp[i].ds #if solaris<80000 && (maj == tcpudp[i].min) #else /* solaris>=80000 */ && (maj == tcpudp[i].maj) #endif /* solaris<80000 */ ) { process_socket((KA_T)v->v_stream, tcpudp[i].proto); return(1); } } return(0); } /* * isvlocked() - is Solaris vnode locked? */ static char isvlocked(va) struct vnode *va; /* local vnode address */ { #if solaris<20500 struct filock f; KA_T ff; KA_T fp; #endif /* solaris<20500 */ int i, l; #if solaris>=20300 struct lock_descriptor ld; KA_T lf; KA_T lp; # if solaris<20500 #define LOCK_END ld.info.li_sleep.sli_flock.l_len #define LOCK_FLAGS ld.flags #define LOCK_NEXT ld.next #define LOCK_OWNER ld.owner.pid #define LOCK_START ld.start #define LOCK_TYPE ld.type # else /* solaris>=20500 */ #define LOCK_END ld.l_flock.l_len #define LOCK_FLAGS ld.l_state #define LOCK_NEXT ld.l_next #define LOCK_OWNER ld.l_flock.l_pid #define LOCK_START ld.l_start #define LOCK_TYPE ld.l_type # endif /* solaris<20500 */ #endif /* solaris>=20300 */ if (va->v_filocks == NULL) return(' '); #if solaris<20500 # if solaris>20300 || (solaris==20300 && defined(P101318) && P101318>=45) if (Ntype == N_NFS) # endif /* solaris>20300 || (solaris==20300 && defined(P101318) && P101318>=45) */ { ff = fp = (KA_T)va->v_filocks; i = 0; do { if (kread(fp, (char *)&f, sizeof(f))) return(' '); i++; if (f.set.l_pid != (pid_t)Lp->pid) continue; if (f.set.l_whence == 0 && f.set.l_start == 0 && f.set.l_len == MAXEND) l = 1; else l = 0; switch (f.set.l_type & (F_RDLCK | F_WRLCK)) { case F_RDLCK: return(l ? 'R' : 'r'); case F_WRLCK: return(l ? 'W' : 'w'); case F_RDLCK|F_WRLCK: return('u'); default: return('N'); } } while ((fp = (KA_T)f.next) && (fp != ff) && (i < 10000)); } #endif /* solaris<20500 */ #if solaris>=20300 lf = lp = (KA_T)va->v_filocks; i = 0; do { if (kread(lp, (char *)&ld, sizeof(ld))) return(' '); i++; if (!(LOCK_FLAGS & ACTIVE_LOCK) || LOCK_OWNER != (pid_t)Lp->pid) continue; if (LOCK_START == 0 && (LOCK_END == 0 # if solaris<20500 || LOCK_END == MAXEND # else /* solaris>=20500 */ || LOCK_END == MAXEND # endif /* solaris<20500 */ )) l = 1; else l = 0; switch (LOCK_TYPE) { case F_RDLCK: return(l ? 'R' : 'r'); case F_WRLCK: return(l ? 'W' : 'w'); case (F_RDLCK | F_WRLCK): return('u'); default: return('L'); } } while ((lp = (KA_T)LOCK_NEXT) && (lp != lf) && (i < 10000)); return(' '); #endif /* solaris>=20300 */ } /* * finddev() - look up device by device number */ static struct l_dev * finddev(dev, rdev, flags) dev_t *dev; /* device */ dev_t *rdev; /* raw device */ int flags; /* look flags -- see LOOKDEV_* symbol * definitions */ { struct clone *c; struct l_dev *dp; struct pseudo *p; if (!Sdev) readdev(0); /* * Search device table for match. */ #if defined(HASDCACHE) finddev_again: #endif /* defined(HASDCACHE) */ if (flags & LOOKDEV_TAB) { if ((dp = lkupdev(dev, rdev, 0, 0))) return(dp); } /* * Search for clone. */ if ((flags & LOOKDEV_CLONE) && Clone) { for (c = Clone; c; c = c->next) { if (GET_MAJ_DEV(*rdev) == GET_MIN_DEV(c->cd.rdev)) { #if defined(HASDCACHE) if (DCunsafe && !c->cd.v && !vfy_dev(&c->cd)) goto finddev_again; #endif /* defined(HASDCACHE) */ return(&c->cd); } } } /* * Search for pseudo device match on major device only. */ if ((flags & LOOKDEV_PSEUDO) && Pseudo) { for (p = Pseudo; p; p = p->next) { if (GET_MAJ_DEV(*rdev) == GET_MAJ_DEV(p->pd.rdev)) { #if defined(HASDCACHE) if (DCunsafe && !p->pd.v && !vfy_dev(&p->pd)) goto finddev_again; #endif /* defined(HASDCACHE) */ return(&p->pd); } } } return((struct l_dev *)NULL); } #if solaris>=20500 /* * idoorkeep() -- identify door keeper process */ static int idoorkeep(d) struct door_node *d; /* door's node */ { char buf[1024]; size_t bufl = sizeof(buf); struct proc dp; struct pid dpid; /* * Get the proc structure and its pid structure for the door target. */ if (!d->door_target || kread((KA_T)d->door_target, (char *)&dp, sizeof(dp))) return(0); if (!dp.p_pidp || kread((KA_T)dp.p_pidp, (char *)&dpid, sizeof(dpid))) return(0); /* * Form a description of the door. * * Put the description in the NAME column addition field. If there's already * something there, allocate more space and add the door description to it. */ if (Lp->pid == (int)dpid.pid_id) (void) snpf(buf, bufl, "(this PID's door)"); else { (void) snpf(buf, bufl, "(door to %.64s[%ld])", dp.p_user.u_comm, (long)dpid.pid_id); } (void) add_nma(buf, (int)strlen(buf)); return(1); } #endif /* solaris>=20500 */ /* * process_node() - process vnode */ void process_node(va) KA_T va; /* vnode kernel space address */ { struct cnode cn; dev_t dev, rdev, trdev; unsigned char devs = 0; unsigned char fxs = 0; unsigned char ins = 0; unsigned char kvs = 0; unsigned char nns = 0; unsigned char pnl = 0; unsigned char rdevs = 0; unsigned char rvs = 0; unsigned char rfxs = 0; unsigned char sdns = 0; unsigned char tdef; unsigned char trdevs = 0; unsigned char unix_sock = 0; struct dev_info di; char din[DINAMEL]; char *ep; struct fifonode f; char *fa = (char *)NULL; int fal; static int ft = 1; struct vnode fv, rv; int fx, rfx; struct hsnode h; struct inode i; int j; KA_T ka, vka; struct lnode lo; struct vfs kv, rkv; int len, llc, nl, snl, sepl; struct mvfsnode m; struct namenode nn; struct l_vfs *nvfs, *vfs; struct pcnode pc; struct pcfs pcfs; struct rnode r; KA_T realvp = (KA_T)NULL; struct snode rs; struct snode s; #if solaris>=110000 char *nm, *sep; size_t nmrl, tl; struct sdev_node sdn; struct vattr sdva; sotpi_info_t sti; int stis = 0; #endif /* solaris>=110000 */ struct l_dev *sdp = (struct l_dev *)NULL; size_t sz; struct tmpnode t; char tbuf[128], *ty, ubuf[128]; int tbufx; enum vtype type; struct sockaddr_un ua; static struct vnode *v = (struct vnode *)NULL; KA_T vs; int vty = 0; int vty_tmp; #if solaris>=20500 # if solaris>=20600 struct fnnode fnn; struct pairaddr { short f; unsigned short p; } *pa; KA_T peer; struct sonode so; KA_T soa, sona; # else /* solaris<20600 */ struct autonode au; # endif /* solaris>=20600 */ struct door_node dn; int dns = 0; #endif /* solaris >=20500 */ #if solaris<100000 KA_T so_ad[2]; struct so_so soso; int so_st = 0; #else /* solaris>=100000 */ union { ctfs_adirnode_t adir; ctfs_bunode_t bun; ctfs_cdirnode_t cdir; ctfs_ctlnode_t ctl; ctfs_evnode_t ev; ctfs_latenode_t late; ctfs_rootnode_t root; ctfs_symnode_t sym; ctfs_tdirnode_t tdir; ctfs_tmplnode_t tmpl; } ctfs; dev_t dv_dev; struct dv_node dv; unsigned char dv_devs = 0; unsigned char dvs = 0; port_t pn; struct rnode4 r4; #endif /* solaris<100000 */ #if defined(HASPROCFS) struct procfsid *pfi; struct pid pids; #endif /* defined(HASPROCFS) */ #if defined(HAS_AFS) struct afsnode an; #endif /* defined(HAS_AFS) */ #if defined(HASVXFS) struct l_ino vx; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) vfs_t zgvfs; unsigned char zns = 0; znode_t zn; zfsvfs_t zvfs; #endif /* defined(HAS_ZFS) */ /* * Do first-time only operations. */ #if solaris<100000 so_ad[0] = so_ad[1] = (KA_T)0; #endif /* solaris<100000 */ if (ft) { (void) build_Voptab(); ft = 0; } /* * Read the vnode. */ if (!va) { enter_nm("no vnode address"); return; } if (!v) { /* * Allocate space for the vnode or AFS vcache structure. */ #if defined(HAS_AFS) v = alloc_vcache(); #else /* !defined(HAS_AFS) */ v = (struct vnode *) malloc(sizeof(struct vnode)); #endif /* defined(HAS_AFS) */ if (!v) { (void) fprintf(stderr, "%s: can't allocate %s space\n", Pn, #if defined(HAS_AFS) "vcache" #else /* !defined(HAS_AFS) */ "vnode" #endif /* defined(HAS_AFS) */ ); Exit(1); } } if (readvnode(va, v)) { enter_nm(Namech); return; } #if defined(HASNCACHE) Lf->na = va; #endif /* defined(HASNCACHE) */ #if defined(HASFSTRUCT) Lf->fna = va; Lf->fsv |= FSV_NI; #endif /* defined(HASFSTRUCT) */ #if defined(HASLFILEADD) && defined(HAS_V_PATH) Lf->V_path = (KA_T)v->v_path; #endif /* defined(HASLFILEADD) && defined(HAS_V_PATH) */ vs = (KA_T)v->v_stream; /* * Check for a Solaris socket. */ if (is_socket(v)) return; /* * Obtain the Solaris virtual file system structure. */ if ((ka = (KA_T)v->v_vfsp)) { if (kread(ka, (char *)&kv, sizeof(kv))) { vka = va; vfs_read_error: (void) snpf(Namech, Namechl - 1, "vnode at %s: can't read vfs: %s", print_kptr(vka, tbuf, sizeof(tbuf)), print_kptr(ka, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return; } kvs = 1; } else kvs = 0; /* * Derive the virtual file system structure's device number from * its file system ID for NFS and High Sierra file systems. */ if (kvs && ((fx = kv.vfs_fstype - 1) >= 0) && (fx < Fsinfomax)) { fxs = 1; if (strcmp(Fsinfo[fx], "nfs") == 0 || strcmp(Fsinfo[fx], "nfs3") == 0 || strcmp(Fsinfo[fx], "hsfs") == 0) kv.vfs_dev = (dev_t)kv.vfs_fsid.val[0]; } else { fx = -1; fxs = 0; } /* * Determine the Solaris vnode type. */ if ((Ntype = vop2ty(v, fx)) < 0) { if (v->v_type == VFIFO) { vty = N_REGLR; Ntype = N_FIFO; } else if (vs) { Ntype = vty = N_STREAM; Lf->is_stream = 1; } if (Ntype < 0) { (void) snpf(Namech, Namechl - 1, "unknown file system type%s%s%s, v_op: %s", fxs ? " (" : "", fxs ? Fsinfo[fx] : "", fxs ? ")" : "", print_kptr((KA_T)v->v_op, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return; } } else { vty = Ntype; if (v->v_type == VFIFO) Ntype = N_FIFO; else if (vs && Ntype != N_SOCK) { Ntype = vty = N_STREAM; Lf->is_stream = 1; } } /* * See if this Solaris node has been fattach'ed to another node. * If it has, read the namenode, and enter the node addresses in * the NAME column addition. * * See if it's covering a socket as well and process accordingly. */ if (vty == N_NM) { if (read_nnn(va, (KA_T)v->v_data, &nn)) return; nns = 1; if (nn.nm_mountpt) #if solaris>=20500 fa = ent_fa((KA_T *)((Ntype == N_FIFO || v->v_type == VDOOR) ? NULL : &va), (KA_T *)&nn.nm_mountpt, "->", &fal); #else /* solaris<20500 */ fa = ent_fa((KA_T *)((Ntype == N_FIFO) ? NULL : &va), (KA_T *)&nn.nm_mountpt, "->", &fal); #endif /* solaris>=20500 */ if (Ntype != N_FIFO && nn.nm_filevp && !kread((KA_T)nn.nm_filevp, (char *)&rv, sizeof(rv))) { rvs = 1; if ((ka = (KA_T)rv.v_vfsp) && !kread(ka, (char *)&rkv, sizeof(rkv)) && ((rfx = rkv.vfs_fstype - 1) >= 0) && (rfx < Fsinfomax) ) { rfxs = 1; } else { rfx = fx; rfxs = fxs; } #if defined(HASNCACHE) Lf->na = (KA_T)nn.nm_filevp; #endif /* defined(HASNCACHE) */ if (is_socket(&rv)) return; } } if (Selinet && Ntype != N_SOCK) return; /* * See if this Solaris node is served by spec_vnodeops. */ if (Spvops && Spvops == (KA_T)v->v_op) Ntype = N_SPEC; /* * Determine the Solaris lock state. */ Lf->lock = isvlocked(v); /* * Establish the Solaris local virtual file system structure. */ if (!(ka = (KA_T)v->v_vfsp) || !kvs) vfs = (struct l_vfs *)NULL; else if (!(vfs = readvfs(ka, &kv, v))) { vka = va; goto vfs_read_error; } /* * Read the afsnode, autonode, cnode, door_node, fifonode, fnnode, lnode, * inode, pcnode, rnode, snode, tmpnode, znode, etc. */ switch (Ntype) { case N_SPEC: /* * A N_SPEC node is a node that resides in in an underlying file system * type -- e.g. NFS, HSFS. Its vnode points to an snode. Subsequent * node structures are implied by the underlying node type. */ if (read_nsn(va, (KA_T)v->v_data, &s)) return; realvp = (KA_T)s.s_realvp; if (!realvp && s.s_commonvp) { if (read_cni(&s, &rv, v, &rs, &di, din, sizeof(din)) == 1) return; if (!rv.v_stream) { if (din[0]) { (void) snpf(Namech, Namechl, "COMMON: %s", din); Namech[Namechl - 1] = '\0'; Lf->is_com = 1; } break; } } if (!realvp) { /* * If the snode lacks a real vnode (and also lacks a common vnode), * it's original type is N_STREAM or N_REGLR, and it has a stream * pointer, get the module names. */ if ((vty == N_STREAM || vty == N_REGLR) && vs) { Lf->is_stream = 1; vty = N_STREAM; #if solaris<100000 read_mi(vs, (dev_t *)&s.s_dev, (caddr_t)&soso, &so_st, so_ad, &sdp); #else /* solaris>=100000 */ read_mi(vs, (dev_t *)&s.s_dev, NULL, NULL, NULL, &sdp); #endif /* solaris<100000 */ vs = (KA_T)NULL; } } break; #if defined(HAS_AFS) case N_AFS: if (readafsnode(va, v, &an)) return; break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: # if solaris<20600 if (read_nan(va, (KA_T)v->v_data, &au)) # else /* solaris>=20600 */ if (read_nan(va, (KA_T)v->v_data, &fnn)) # endif /* solaris<20600 */ return; break; # if solaris>=100000 case N_DEV: if (read_ndvn(va, (KA_T)v->v_data, &dv, &dv_dev, &dv_devs)) return; dvs = 1; break; # endif /* solaris>=100000 */ case N_DOOR: if (read_ndn(va, (KA_T)v->v_data, &dn)) return; dns = 1; break; #endif /* solaris>=20500 */ case N_CACHE: if (read_ncn(va, (KA_T)v->v_data, &cn)) return; break; #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: if (read_nctfsn(Ntype, va, (KA_T)v->v_data, (char *)&ctfs)) return; break; #endif /* solaris>=100000 */ #if solaris>=20600 case N_SOCK: sona = (KA_T)v->v_data; if (read_nson(va, sona, &so)) return; break; #endif /* solaris>=20600 */ case N_MNT: /* Information comes from the l_vfs structure. */ break; case N_MVFS: if (read_nmn(va, (KA_T)v->v_data, &m)) return; break; case N_NFS: if (read_nrn(va, (KA_T)v->v_data, &r)) return; break; #if solaris>=100000 case N_NFS4: if (read_nrn4(va, (KA_T)v->v_data, &r4)) return; break; #endif /* solaris>=100000 */ case N_NM: if (nns) realvp = (KA_T)nn.nm_filevp; #if defined(HASNCACHE) Lf->na = (KA_T)nn.nm_filevp; #endif /* defined(HASNCACHE) */ break; case N_FD: break; /* no successor node */ case N_FIFO: /* * Solaris FIFO vnodes are usually linked to a fifonode. One * exception is a FIFO vnode served by nm_vnodeops; it is linked * to a namenode, and the namenode points to the fifonode. * * Non-pipe fifonodes are linked to a vnode thorough fn_realvp. */ if (vty == N_NM && nns) { if (nn.nm_filevp) { if (read_nfn(va, (KA_T)nn.nm_filevp, &f)) return; realvp = (KA_T)NULL; vty = N_FIFO; } else { (void) snpf(Namech, Namechl - 1, "FIFO namenode at %s: no fifonode pointer", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; return; } } else { if (read_nfn(va, (KA_T)v->v_data, &f)) return; realvp = (KA_T)f.fn_realvp; } if (!realvp) { Lf->inode = (INODETYPE)(nns ? nn.nm_vattr.va_nodeid : f.fn_ino); #if solaris>=80000 /* Solaris 8 and above hack! */ # if defined(_LP64) if (Lf->inode >= (unsigned long)0xbaddcafebaddcafe) # else /* !defined(_LP64) */ if (Lf->inode >= (unsigned long)0xbaddcafe) # endif /* defined(_LP64) */ Lf->inp_ty = 0; else #endif /* solaris>=80000 Solaris 8 and above hack! */ Lf->inp_ty = 1; enter_dev_ch(print_kptr((KA_T)v->v_data, (char *)NULL, 0)); if (f.fn_flag & ISPIPE) { (void) snpf(tbuf, sizeof(tbuf), "PIPE"); tbufx = (int)strlen(tbuf); } else tbufx = 0; #if solaris<20500 if (f.fn_mate) { (void) snpf(&tbuf[tbufx], sizeof(tbuf) - tbufx, "->%s", print_kptr((KA_T)f.fn_mate, (char *)NULL, 0)); tbufx = (int)strlen(tbuf); } #else /* solaris>=20500 */ if (f.fn_dest) { (void) snpf(&tbuf[tbufx], sizeof(tbuf) - tbufx, "->%s", print_kptr((KA_T)f.fn_dest, (char *)NULL, 0)); tbufx = (int)strlen(tbuf); } #endif /* solaris<20500 */ if (tbufx) (void) add_nma(tbuf, tbufx); break; } break; case N_HSFS: if (read_nhn(va, (KA_T)v->v_data, &h)) return; break; case N_LOFS: llc = 0; do { rvs = 0; if (read_nln(va, llc ? (KA_T)rv.v_data : (KA_T)v->v_data, &lo)) { return; } if (!(realvp = (KA_T)lo.lo_vp)) { (void) snpf(Namech, Namechl - 1, "lnode at %s: no real vnode", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return; } if (read_nvn((KA_T)v->v_data, (KA_T)realvp, &rv)) return; rvs = 1; llc++; if ((ka = (KA_T)rv.v_vfsp) && !kread(ka, (char *)&rkv, sizeof(rkv)) && ((rfx = rkv.vfs_fstype - 1) >= 0) && (rfx < Fsinfomax) ) { rfxs = 1; } else { rfx = fx; rfxs = fxs; } if (((vty_tmp = vop2ty(&rv, rfx)) == N_LOFS) && (llc > 1000)) { (void) snpf(Namech, Namechl - 1, "lnode at %s: loop > 1000", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return; } } while (vty_tmp == N_LOFS); break; case N_PCFS: if (read_npn(va, (KA_T)v->v_data, &pc)) return; break; #if solaris>=100000 case N_PORT: if (read_nprtn(va, (KA_T)v->v_data, &pn)) return; break; #endif /* solaris>=100000 */ #if defined(HASPROCFS) case N_PROC: if (read_npi(va, v, &pids)) return; break; #endif /* defined(HASPROCFS) */ #if solaris>=110000 case N_SDEV: if (read_nsdn(va, (KA_T)v->v_data, &sdn, &sdva)) return; sdns = 1; break; #endif /* solaris>=110000 */ case N_SAMFS: (void) add_nma(SAMFS_NMA_MSG, (int)strlen(SAMFS_NMA_MSG)); break; case N_SHARED: break; /* No more sharedfs information is available. */ case N_STREAM: if (read_nsn(va, (KA_T)v->v_data, &s)) return; if (vs) { Lf->is_stream = 1; #if solaris<100000 read_mi(vs, (dev_t *)&s.s_dev, (caddr_t)&soso, &so_st, so_ad, &sdp); #else /* solaris>=100000 */ read_mi(vs, (dev_t *)&s.s_dev, NULL, NULL, NULL, &sdp); #endif /* solaris<100000 */ vs = (KA_T)NULL; } break; case N_TMP: if (read_ntn(va, (KA_T)v->v_data, &t)) return; break; #if defined(HASVXFS) case N_VXFS: if (read_vxnode(va, v, vfs, fx, &vx, Vvops)) return; break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (read_nzn(va, (KA_T)v->v_data, &zn)) return; zns = 1; break; #endif /* defined(HAS_ZFS) */ case N_REGLR: default: if (read_nin(va, (KA_T)v->v_data, &i)) return; ins = 1; } /* * If the node has a real vnode pointer, follow it. */ if (realvp) { if (rvs) { *v = rv; fx = rfx; fxs = rfxs; } else { if (read_nvn((KA_T)v->v_data, (KA_T)realvp, v)) return; else { #if defined(HASNCACHE) Lf->na = (KA_T)realvp; #endif /* defined(HASNCACHE) */ if ((ka = (KA_T)v->v_vfsp) && !kread(ka, (char *)&kv, sizeof(kv))) { kvs = 1; } if (kvs && ((fx = kv.vfs_fstype - 1) >= 0) && (fx < Fsinfomax) ) { fxs = 1; } } } /* * If the original vnode type is N_STREAM, if there is a stream * pointer and if there is no sdev_node, get the module names. */ if (vty == N_STREAM && vs && !sdns) { Lf->is_stream = 1; #if solaris<100000 read_mi(vs, (dev_t *)&s.s_dev, (caddr_t)&soso, &so_st, so_ad, &sdp); #else /* solaris>=100000 */ read_mi(vs, (dev_t *)&s.s_dev, NULL, NULL, NULL, &sdp); #endif /* solaris<100000 */ vs = (KA_T)NULL; } /* * Get the real vnode's type. */ if ((vty = vop2ty(v, fx)) < 0) { if (Ntype != N_FIFO && vs) vty = N_STREAM; else { #if solaris<100000 (void) snpf(Namech, Namechl - 1, "unknown file system type, v_op: %s", print_kptr((KA_T)v->v_op, (char *)NULL, 0)); #else /* solaris>=100000 */ (void) snpf(Namech, Namechl - 1, "unknown file system type (%s), v_op: %s", fxs ? Fsinfo[fx] : "unknown", print_kptr((KA_T)v->v_op, (char *)NULL, 0)); #endif /* solaris<100000 */ Namech[Namechl - 1] = '\0'; } } if (Ntype == N_NM || Ntype == N_AFS) Ntype = vty; /* * Base further processing on the "real" vnode. */ Lf->lock = isvlocked(v); switch (vty) { #if defined(HAS_AFS) case N_AFS: if (readafsnode(va, v, &an)) return; break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: # if solaris<20600 if (read_nan(va, (KA_T)v->v_data, &au)) # else /* solaris>=20600 */ if (read_nan(va, (KA_T)v->v_data, &fnn)) # endif /* solaris<20600 */ return; break; # if solaris>=100000 case N_DEV: if (read_ndvn(va, (KA_T)v->v_data, &dv, &dv_dev, &dv_devs)) return; dvs = 1; break; # endif /* solaris>=100000 */ case N_DOOR: # if solaris<20600 if (read_ndn(realvp, (KA_T)v->v_data, &dn)) # else /* solaris>=20600 */ if (read_ndn(va, (KA_T)v->v_data, &dn)) # endif /* solaris<20500 */ return; dns = 1; break; #endif /* solaris>=20500 */ case N_CACHE: if (read_ncn(va, (KA_T)v->v_data, &cn)) return; break; #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: if (read_nctfsn(vty, va, (KA_T)v->v_data, (char *)&ctfs)) return; break; #endif /* solaris>=100000 */ case N_HSFS: if (read_nhn(va, (KA_T)v->v_data, &h)) return; break; case N_MNT: /* Information comes from the l_vfs structure. */ break; case N_MVFS: if (read_nmn(va, (KA_T)v->v_data, &m)) return; break; case N_NFS: if (read_nrn(va, (KA_T)v->v_data, &r)) return; break; #if solaris>=100000 case N_NFS4: if (read_nrn4(va, (KA_T)v->v_data, &r4)) return; break; #endif /* solaris>=100000 */ case N_NM: if (read_nnn(va, (KA_T)v->v_data, &nn)) return; nns = 1; break; #if solaris>=100000 case N_PORT: if (read_nprtn(va, (KA_T)v->v_data, &pn)) return; break; #endif /* solaris>=100000 */ case N_PCFS: if (read_npn(va, (KA_T)v->v_data, &pc)) return; break; case N_SAMFS: (void) add_nma(SAMFS_NMA_MSG, (int)strlen(SAMFS_NMA_MSG)); #if solaris>=110000 case N_SDEV: if (read_nsdn(va, (KA_T)v->v_data, &sdn, &sdva)) return; if (Lf->is_stream) { /* * This stream's real node is an sdev_node, so it's not really * a stream. Reverse prior stream settings. */ Lf->is_stream = 0; Namech[0] = '\0'; } sdns = 1; break; #endif /* solaris>=110000 */ break; #if solaris>=20600 case N_SOCK: sona = (KA_T)v->v_data; if (read_nson(va, sona, &so)) return; break; #endif /* solaris>=20600 */ case N_STREAM: if (vs) { Lf->is_stream = 1; #if solaris<100000 read_mi(vs, (dev_t *)&s.s_dev, (caddr_t)&soso, &so_st, so_ad, &sdp); #else /* solaris>=100000 */ read_mi(vs, (dev_t *)&s.s_dev, NULL, NULL, NULL, &sdp); #endif /* solaris<100000 */ vs = (KA_T)NULL; } break; case N_TMP: if (read_ntn(va, (KA_T)v->v_data, &t)) return; break; #if defined(HASVXFS) case N_VXFS: if (read_vxnode(va, v, vfs, fx, &vx, Vvops)) return; break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (read_nzn(va, (KA_T)v->v_data, &zn)) return; zns = 1; break; #endif /* defined(HAS_ZFS) */ case N_REGLR: default: if (read_nin(va, (KA_T)v->v_data, &i)) return; ins = 1; } /* * If this is a Solaris loopback node, use the "real" node type. */ if (Ntype == N_LOFS) Ntype = vty; } /* * Get device and type for printing. */ switch (((Ntype == N_FIFO) || (vty == N_SDEV)) ? vty : Ntype) { #if defined(HAS_AFS) case N_AFS: dev = an.dev; devs = 1; break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: if (kvs) { dev = (dev_t)kv.vfs_fsid.val[0]; devs = 1; } break; # if solaris>=100000 case N_DEV: if (dv_devs) { dev = dv_dev; devs = 1; } else if (vfs) { dev = vfs->dev; devs = 1; } rdev = v->v_rdev; rdevs = 1; break; # endif /* solaris>=100000 */ case N_DOOR: # if solaris<20600 if (kvs) { dev = (dev_t)kv.vfs_fsid.val[0]; devs = 1; } # else /* solaris>=20600 */ if (nns) { dev = (dev_t)nn.nm_vattr.va_fsid; devs = 1; } else if (dns) { dev = (dev_t)dn.door_index; devs = 1; } # endif /* solaris<20600 */ break; #endif /* solaris>=20500 */ case N_CACHE: case N_HSFS: case N_PCFS: if (kvs) { dev = kv.vfs_dev; devs = 1; } break; #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: if (kvs) { dev = kv.vfs_dev; devs = 1; } break; #endif /* solaris>=100000 */ case N_FD: if (kvs) { dev = kv.vfs_dev; devs = 1; } if ((v->v_type == VCHR) || (v->v_type == VBLK)) { rdev = v->v_rdev; rdevs = 1; } break; case N_MNT: #if defined(CVFS_DEVSAVE) if (vfs) { dev = vfs->dev; devs = 1; } #endif /* defined(CVFS_DEVSAVE) */ break; case N_MVFS: #if defined(CVFS_DEVSAVE) if (vfs) { dev = vfs->dev; devs = 1; } #endif /* defined(CVFS_DEVSAVE) */ break; case N_NFS: dev = r.r_attr.va_fsid; devs = 1; break; #if solaris>=100000 case N_NFS4: dev = r4.r_attr.va_fsid; devs = 1; break; #endif /* solaris>=100000 */ case N_NM: if (nns) { dev = (dev_t)nn.nm_vattr.va_fsid; devs = 1; } else enter_dev_ch(" NMFS"); break; #if solaris>=100000 case N_PORT: if (kvs) { dev = kv.vfs_dev; devs = 1; } break; #endif /* solaris>=100000 */ #if defined(HASPROCFS) case N_PROC: if (kvs) { dev = kv.vfs_dev; devs = 1; } break; #endif /* defined(HASPROCFS) */ case N_SAMFS: if ((v->v_type == VCHR) || (v->v_type == VBLK)) { rdev = v->v_rdev; rdevs = 1; } else if (vfs) { dev = vfs->dev; devs = 1; } break; #if solaris>=110000 case N_SDEV: if (sdns) { dev = sdva.va_fsid; rdev = sdva.va_rdev; devs = rdevs = 1; } break; #endif /* solaris>=110000 */ case N_SHARED: if (vfs) { dev = vfs->dev; devs = 1; } break; #if solaris>=20600 case N_SOCK: if (so.so_family == AF_UNIX) /* * Process an AF_UNIX socket node. */ # if solaris>=110000 { /* * Process a Solaris >= 11 AF_UNIX socket node: * * Get its sotpi_info_t structure; */ if (read_nsti(&so, &sti)) return; /* * Get its device numbers. If they are located, start the NAME * column with the device name, followed by "->". */ nm = Namech; nmrl = Namechl - 1; Namech[Namechl - 1] = '\0'; if (!sdp) sdp = finddev(&DevDev, &sti.sti_dev, LOOKDEV_ALL); if (sdp) { dev = DevDev; rdev = v->v_rdev; trdev = sdp->rdev; devs = rdevs = trdevs = 1; Lf->inode = (INODETYPE)sdp->inode; Lf->inp_ty = 1; (void) snpf(nm, nmrl, "%s", sdp->name); tl = strlen(nm); nm += tl; nmrl -= tl; sep = "->"; } else { devs = rdevs = trdevs = 0; sep = ""; } /* * Add the socket node's address to the NAME column. */ sepl = strlen(sep); if (sona && ((nmrl - sepl) > 0)) { (void) snpf(nm, nmrl, "%s%s", sep, print_kptr(sona, (char *)NULL, 0)); tl = strlen(nm); nm += tl; nmrl -= tl; } /* * Add the service type to the NAME column. */ switch (sti.sti_serv_type) { case T_CLTS: ty = "dgram"; break; case T_COTS: ty = "stream"; break; case T_COTS_ORD: ty = "stream-ord"; break; default: ty = (char *)NULL; } if (ty && (nmrl > 1)) { (void) snpf(nm, nmrl, " %s", ty); tl = strlen(nm); nm += tl; nmrl -= tl; } /* * Add the vnode and connected addresses to the NAME column, * as indicated by the socket node state. */ if ((so.so_state & SS_ISBOUND) && (nmrl > 36) && (sti.sti_ux_laddr.soua_magic == SOU_MAGIC_EXPLICIT) ) { (void) snpf(nm, nmrl, " Vn=%s", print_kptr((KA_T)sti.sti_ux_laddr.soua_vp, (char *)NULL, 0) ); tl = strlen(nm); nm += tl; nmrl -= tl; } if ((so.so_state & SS_ISCONNECTED) && (nmrl > 38) && (sti.sti_ux_faddr.soua_magic == SOU_MAGIC_EXPLICIT) ) { (void) snpf(nm, nmrl, " Conn=%s ", print_kptr((KA_T)sti.sti_ux_faddr.soua_vp, (char *)NULL, 0) ); tl = strlen(nm); nm += tl; nmrl -= tl; } /* * Put local and connected UNIX addresses in the NAME column, if * they exist and as indicated by the socket node's state. */ if ((so.so_state & SS_ISBOUND) && ((len = read_nusa(&sti.sti_laddr, &ua)) > 0) && (nmrl > (len + 5)) ) { if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; if (len > nmrl) len = nmrl; if (len > 0) { ua.sun_path[len] = '\0'; (void) snpf(nm, nmrl, " Lcl=%s", ua.sun_path); tl = strlen(nm); nm += tl; nmrl -= tl; } } if ((so.so_state & SS_ISCONNECTED) && ((len = read_nusa(&sti.sti_faddr, &ua)) > 0) && (nmrl > (len + 5)) ) { if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; if (len > nmrl) len = nmrl; if (len > 0) { ua.sun_path[len] = '\0'; (void) snpf(nm, nmrl, " Rem=%s", ua.sun_path); tl = strlen(nm); nm += tl; nmrl -= tl; } } } else { /* * Process Solaris >= 11 AF_INET, AF_INET6 and AF_ROUTE VSOCK * nodes. */ switch (so.so_family) { case AF_INET: case AF_INET6: case AF_ROUTE: if (process_VSOCK((KA_T)va, v, &so)) return; } } # else /* solaris<110000 */ { /* * Process an AF_UNIX socket node for Solaris < 11: * Locate its device numbers; * Enter the sonode address as the device (netstat's local * address); * Get a non-NULL local sockaddr_un and enter it in Namech; * Get a non-NULL foreign sockaddr_un and enter it in Namech; * Check for matches on sockaddr_un.sun_path names. */ if (!sdp) sdp = finddev(&DevDev, # if solaris<100000 &so.so_vnode.v_rdev, # else /* solaris>=100000 */ &so.so_dev, # endif /* solaris<100000 */ LOOKDEV_ALL); if (sdp) { dev = DevDev; # if solaris<100000 rdev = so.so_vnode.v_rdev; # else /* solaris>=100000 */ rdev = so.so_dev; # endif /* solaris<100000 */ trdev = sdp->rdev; devs = rdevs = trdevs = 1; Lf->inode = (INODETYPE)sdp->inode; Lf->inp_ty = 1; (void) snpf(Namech, Namechl - 1, "%s", sdp->name); Namech[Namechl - 1] = '\0'; } else devs = 0; nl = snl = (int)strlen(Namech); if ((len = read_nusa(&so.so_laddr, &ua))) { if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) len = Namechl - nl - sepl - 1; if (len > 0) { ua.sun_path[len] = '\0'; (void) snpf(&Namech[nl], Namechl - nl, "%s%s", sepl ? "->" : "", ua.sun_path); nl += (len + sepl); } } if ((len = read_nusa(&so.so_faddr, &ua))) { if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) len = Namechl - nl - sepl - 1; if (len > 0) { ua.sun_path[len] = 0; (void) snpf(&Namech[nl], Namechl - nl, "%s%s", sepl ? "->" : "", ua.sun_path); nl += (len + sepl); } } if ((nl == snl) # if defined(HASSOUXSOUA) && so.so_ux_laddr.soua_magic == SOU_MAGIC_IMPLICIT # else /* !defined(HASSOUXSOUA) */ && so.so_ux_laddr.sou_magic == SOU_MAGIC_IMPLICIT # endif /* defined(HASSOUXSOUA) */ ) { /* * There are no addresses; this must be a socket pair. * Print its identity. */ pa = (struct pairaddr *)&ua; if (!(peer = (KA_T)((int)pa->p))) # if defined(HASSOUXSOUA) peer = (KA_T)so.so_ux_laddr.soua_vp; # else /* !defined(HASSOUXSOUA) */ peer = (KA_T)so.so_ux_laddr.sou_vp; # endif /* defined(HASSOUXSOUA) */ if (peer) (void) snpf(ubuf, sizeof(ubuf), "(socketpair: %s)", print_kptr(peer, (char *)NULL, 0)); else (void) snpf(ubuf, sizeof(ubuf), "(socketpair)"); len = (int)strlen(ubuf); sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) len = Namechl - nl - sepl - 1; if (len > 0) { (void) snpf(&Namech[nl], Namechl - nl, "%s%s", sepl ? "->" : "", ubuf); nl += (len + sepl); } } /* * Add the local and foreign addresses, ala `netstat -f unix` to * the name. */ # if defined(HASSOUXSOUA) soa = (KA_T)so.so_ux_faddr.soua_vp; # else /* !defined(HASSOUXSOUA) */ soa = (KA_T)so.so_ux_faddr.sou_vp; # endif /* defined(HASSOUXSOUA) */ (void) snpf(ubuf, sizeof(ubuf), "%s(%s%s%s)", Namech[0] ? " " : "", print_kptr((KA_T)v->v_data, (char *)NULL, 0), soa ? "->" : "", soa ? print_kptr(soa, tbuf, sizeof(tbuf)) : ""); len = (int)strlen(ubuf); if (len <= (Namechl - nl - 1)) { (void) snpf(&Namech[nl], Namechl - nl, "%s", ubuf); nl += len; } /* * If there is a bound vnode, add its address to the name. */ if (so.so_ux_bound_vp) { (void) snpf(ubuf, sizeof(ubuf), "%s(Vnode=%s)", Namech[0] ? " " : "", print_kptr((KA_T)so.so_ux_bound_vp, (char *)NULL, 0)); len = (int)strlen(ubuf); if (len <= (Namechl - nl - 1)) { (void) snpf(&Namech[nl], Namechl - nl, "%s", ubuf); nl += len; } } } # endif /* solaris>=110000 */ break; #endif /* solaris>=20600 */ case N_SPEC: #if solaris<100000 if (((Ntype = vty) == N_STREAM) && so_st) { if (Funix) Lf->sf |= SELUNX; unix_sock = 1; if (so_ad[0]) { if (sdp) { if (vfs) { dev = vfs->dev; devs = 1; } rdev = sdp->rdev; rdevs = 1; Lf->inode = (INODETYPE)sdp->inode; Lf->inp_ty = 1; (void) snpf(ubuf, sizeof(ubuf), "(%s%s%s)", print_kptr(so_ad[0], (char *)NULL, 0), so_ad[1] ? "->" : "", so_ad[1] ? print_kptr(so_ad[1], tbuf, sizeof(tbuf)) : ""); } else { enter_dev_ch(print_kptr(so_ad[0], (char *)NULL, 0)); if (so_ad[1]) (void) snpf(ubuf, sizeof(ubuf), "(->%s)", print_kptr(so_ad[1], (char *)NULL, 0)); } if (!Lf->nma && (Lf->nma = (char *) malloc((int)strlen(ubuf) + 1))) { (void) snpf(Lf->nma, (int)strlen(ubuf) + 1, "%s", ubuf); } } else if (soso.lux_dev.addr.tu_addr.ino) { if (vfs) { dev = vfs->dev; devs = 1; } rdev = soso.lux_dev.addr.tu_addr.dev; rdevs = 1; } else { int dc, dl, dr; #if solaris<20400 dl = (soso.lux_dev.addr.tu_addr.dev >> 16) & 0xffff; dr = (soso.rux_dev.addr.tu_addr.dev >> 16) & 0xffff; #else /* solaris>=20400 */ dl = soso.lux_dev.addr.tu_addr.dev & 0xffff; dr = soso.rux_dev.addr.tu_addr.dev & 0xffff; #endif /* solaris<20400 */ dc = (dl << 16) | dr; enter_dev_ch(print_kptr((KA_T)dc, (char *)NULL, 0)); devs = 0; } if (soso.laddr.buf && soso.laddr.len == sizeof(ua)) { if (kread((KA_T)soso.laddr.buf, (char *)&ua, sizeof(ua)) == 0) { ua.sun_path[sizeof(ua.sun_path) - 1] = '\0'; if (ua.sun_path[0]) { if (Sfile && is_file_named(ua.sun_path, Ntype, type, 0)) Lf->sf |= SELNM; len = (int)strlen(ua.sun_path); nl = (int)strlen(Namech); sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) len = Namechl - nl - sepl - 1; if (len > 0) { ua.sun_path[len] = '\0'; (void) snpf(&Namech[nl], Namechl - nl, "%s%s", sepl ? "->" : "", ua.sun_path); } } } } } else #endif /* solaris<100000 */ { if (vfs) { dev = vfs->dev; devs = 1; } rdev = s.s_dev; rdevs = 1; } break; case N_STREAM: if (vfs) { dev = vfs->dev; devs = 1; } rdev = s.s_dev; rdevs = 1; break; case N_TMP: dev = t.tn_attr.va_fsid; devs = 1; break; #if defined(HASVXFS) case N_VXFS: dev = vx.dev; devs = vx.dev_def; if ((v->v_type == VCHR) || (v->v_type == VBLK)) { rdev = vx.rdev; rdevs = vx.rdev_def; } break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (zns) { if (!read_nzvfs((KA_T)v->v_data, (KA_T)zn.z_zfsvfs, &zvfs) && zvfs.z_vfs && !kread((KA_T)zvfs.z_vfs, (char *)&zgvfs, sizeof(zgvfs)) ) { dev = zgvfs.vfs_dev; devs = 1; } } if ((v->v_type == VCHR) || (v->v_type == VBLK)) { rdev = v->v_rdev; rdevs = 1; } break; #endif /* defined(HAS_ZFS) */ default: if (ins) { dev = i.i_dev; devs = 1; } else if (nns) { dev = nn.nm_vattr.va_fsid; devs = 1; } else if (vfs) { dev = vfs->dev; devs = 1; } if ((v->v_type == VCHR) || (v->v_type == VBLK)) { rdev = v->v_rdev; rdevs = 1; } } type = v->v_type; if (devs && vfs && !vfs->dir) { (void) completevfs(vfs, &dev); #if defined(HAS_AFS) if (vfs->dir && (Ntype == N_AFS || vty == N_AFS) && !AFSVfsp) AFSVfsp = (KA_T)v->v_vfsp; #endif /* defined(HAS_AFS) */ } /* * Obtain the inode number. */ switch (vty) { #if defined(HAS_AFS) case N_AFS: if (an.ino_st) { Lf->inode = (INODETYPE)an.inode; Lf->inp_ty = 1; } break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: # if solaris<20600 Lf->inode = (INODETYPE)au.an_nodeid; # else /* solaris>=20600 */ Lf->inode = (INODETYPE)fnn.fn_nodeid; # endif /* solaris<20600 */ Lf->inp_ty = 1; break; # if solaris>=100000 case N_DEV: if (dvs) { Lf->inode = (INODETYPE)dv.dv_ino; Lf->inp_ty = 1; } break; # endif /* solaris>=100000 */ case N_DOOR: if (nns && (Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid)) { Lf->inp_ty = 1; break; } if (dns) { if ((Lf->inode = (INODETYPE)dn.door_index)) Lf->inp_ty = 1; } break; #endif /* solaris>=20500 */ case N_CACHE: Lf->inode = (INODETYPE)cn.c_fileno; Lf->inp_ty = 1; break; #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: /* Method of computing CTFS inode not known. */ break; #endif /* solaris>=10000 */ case N_FD: if (v->v_type == VDIR) Lf->inode = (INODETYPE)2; else Lf->inode = (INODETYPE)(GET_MIN_DEV(v->v_rdev) * 100); Lf->inp_ty = 1; break; case N_HSFS: Lf->inode = (INODETYPE)h.hs_nodeid; Lf->inp_ty = 1; break; case N_MNT: #if defined(HASFSINO) if (vfs) { Lf->inode = vfs->fs_ino; Lf->inp_ty = 1; } #endif /* defined(HASFSINO) */ break; case N_MVFS: Lf->inode = (INODETYPE)m.m_ino; Lf->inp_ty = 1; break; case N_NFS: Lf->inode = (INODETYPE)r.r_attr.va_nodeid; Lf->inp_ty = 1; break; #if solaris>=100000 case N_NFS4: Lf->inode = (INODETYPE)r4.r_attr.va_nodeid; Lf->inp_ty = 1; break; #endif /* solaris>=100000 */ case N_NM: Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid; Lf->inp_ty = 1; break; #if defined(HASPROCFS) case N_PROC: /* * The proc file system inode number is defined when the * prnode is read. */ break; #endif /* defined(HASPROCFS) */ case N_PCFS: if (kvs && kv.vfs_data && !kread((KA_T)kv.vfs_data, (char *)&pcfs, sizeof(pcfs))) { #if solaris>=70000 # if defined(HAS_PC_DIRENTPERSEC) Lf->inode = (INODETYPE)pc_makenodeid(pc.pc_eblkno, pc.pc_eoffset, pc.pc_entry.pcd_attr, IS_FAT32(&pcfs) ? ltohs(pc.pc_entry.pcd_scluster_lo) | (ltohs(pc.pc_entry.un.pcd_scluster_hi) << 16) : ltohs(pc.pc_entry.pcd_scluster_lo), pc_direntpersec(&pcfs)); # else /* !defined(HAS_PC_DIRENTPERSEC) */ Lf->inode = (INODETYPE)pc_makenodeid(pc.pc_eblkno, pc.pc_eoffset, pc.pc_entry.pcd_attr, IS_FAT32(&pcfs) ? ltohs(pc.pc_entry.pcd_scluster_lo) | (ltohs(pc.pc_entry.un.pcd_scluster_hi) << 16) : ltohs(pc.pc_entry.pcd_scluster_lo), pcfs.pcfs_entps); # endif /* defined(HAS_PC_DIRENTPERSEC) */ #else /* solaris<70000 */ Lf->inode = (INODETYPE)pc_makenodeid(pc.pc_eblkno, pc.pc_eoffset, &pc.pc_entry, pcfs.pcfs_entps); #endif /* solaris>=70000 */ Lf->inp_ty = 1; } break; case N_REGLR: if (nns) { if ((Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid)) Lf->inp_ty = 1; } else if (ins) { if ((Lf->inode = (INODETYPE)i.i_number)) Lf->inp_ty = 1; } break; case N_SAMFS: break; /* No more SAM-FS information is available. */ #if solaris>=110000 case N_SDEV: if (sdns) { Lf->inode = (INODETYPE)sdva.va_nodeid; Lf->inp_ty = 1; } break; #endif /* solaris>=110000 */ case N_SHARED: (void) snpf(Lf->iproto, sizeof(Lf->iproto), "SHARED"); Lf->inp_ty = 2; break; case N_STREAM: #if solaris<100000 if (so_st && soso.lux_dev.addr.tu_addr.ino) { if (Lf->inp_ty) { nl = Lf->nma ? (int)strlen(Lf->nma) : 0; (void) snpf(ubuf, sizeof(ubuf), "%s(Inode=%lu)", nl ? " " : "", (unsigned long)soso.lux_dev.addr.tu_addr.ino); len = nl + (int)strlen(ubuf) + 1; if (Lf->nma) Lf->nma = (char *) realloc(Lf->nma, len); else Lf->nma = (char *) malloc(len); if (Lf->nma) (void) snpf(&Lf->nma[nl], len - nl, "%s", ubuf); } else { Lf->inode = (INODETYPE)soso.lux_dev.addr.tu_addr.ino; Lf->inp_ty = 1; } } #endif /* solaris<100000 */ break; case N_TMP: Lf->inode = (INODETYPE)t.tn_attr.va_nodeid; Lf->inp_ty = 1; break; #if defined(HASVXFS) case N_VXFS: if (vx.ino_def) { Lf->inode = (INODETYPE)vx.ino; Lf->inp_ty = 1; } else if (type == VCHR) pnl = 1; break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (zns) { Lf->inode = (INODETYPE)zn.z_id; Lf->inp_ty = 1; } break; #endif /* defined(HAS_ZFS) */ } /* * Obtain the file size. */ if (Foffset) Lf->off_def = 1; else { switch (Ntype) { #if defined(HAS_AFS) case N_AFS: Lf->sz = (SZOFFTYPE)an.size; Lf->sz_def = 1; break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: # if solaris<20600 Lf->sz = (SZOFFTYPE)au.an_size; # else /* solaris >=20600 */ Lf->sz = (SZOFFTYPE)fnn.fn_size; # endif /* solaris < 20600 */ Lf->sz_def = 1; break; #endif /* solaris>=20500 */ case N_CACHE: Lf->sz = (SZOFFTYPE)cn.c_size; Lf->sz_def = 1; break; #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: /* Method of computing CTFS size not known. */ break; #endif /* solaris>=100000 */ case N_FD: if (v->v_type == VDIR) Lf->sz = (Unof + 2) * 16; else Lf->sz = (unsigned long)0; Lf->sz_def = 1; break; #if solaris>=20600 case N_SOCK: Lf->off_def = 1; break; #endif /* solaris>=20600 */ case N_HSFS: Lf->sz = (SZOFFTYPE)h.hs_dirent.ext_size; Lf->sz_def = 1; break; case N_NM: Lf->sz = (SZOFFTYPE)nn.nm_vattr.va_size; Lf->sz_def = 1; break; # if solaris>=100000 case N_DEV: if (!Fsize) Lf->off_def = 1; break; # endif /* solaris>=100000 */ case N_DOOR: case N_FIFO: if (!Fsize) Lf->off_def = 1; break; case N_MNT: #if defined(CVFS_SZSAVE) if (vfs) { Lf->sz = (SZOFFTYPE)vfs->size; Lf->sz_def = 1; } else #endif /* defined(CVFS_SZSAVE) */ Lf->off_def = 1; break; case N_MVFS: /* The location of file size isn't known. */ break; case N_NFS: if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; else { Lf->sz = (SZOFFTYPE)r.r_size; Lf->sz_def = 1; } break; #if solaris>=100000 case N_NFS4: if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; else { Lf->sz = (SZOFFTYPE)r4.r_size; Lf->sz_def = 1; } break; #endif /* solaris>=100000 */ case N_PCFS: Lf->sz = (SZOFFTYPE)pc.pc_size; Lf->sz_def = 1; break; #if solaris>=100000 case N_PORT: Lf->sz = (SZOFFTYPE)pn.port_curr; Lf->sz_def = 1; break; #endif /* solaris>=100000 */ #if defined(HASPROCFS) case N_PROC: /* * The proc file system size is defined when the * prnode is read. */ break; #endif /* defined(HASPROCFS) */ case N_REGLR: if (type == VREG || type == VDIR) { if (ins | nns) { Lf->sz = (SZOFFTYPE)(nns ? nn.nm_vattr.va_size : i.i_size); Lf->sz_def = 1; } } else if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; break; #if solaris>=110000 case N_SDEV: if (sdns) { if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)sdva.va_size; Lf->sz_def = 1; } else if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; } break; #endif /* solaris>=110000 */ case N_SAMFS: break; /* No more SAM-FS information is available. */ case N_SHARED: break; /* No more sharedfs information is available. */ case N_STREAM: if (!Fsize) Lf->off_def = 1; break; case N_TMP: Lf->sz = (SZOFFTYPE)t.tn_attr.va_size; Lf->sz_def = 1; break; #if defined(HASVXFS) case N_VXFS: if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)vx.sz; Lf->sz_def = vx.sz_def; } else if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (zns) { if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)zn.z_size; Lf->sz_def = 1; } else if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; } break; #endif /* defined(HAS_ZFS) */ } } /* * Record link count. */ #if !defined(HASXOPT) if (Fnlink) #endif /* !defined(HASXOPT) */ { switch (Ntype) { #if defined(HAS_AFS) case N_AFS: Lf->nlink = an.nlink; Lf->nlink_def = an.nlink_st; break; #endif /* defined(HAS_AFS) */ #if solaris>=20500 case N_AUTO: break; case N_CACHE: Lf->nlink = (long)cn.c_attr.va_nlink; Lf->nlink_def = 1; break; #endif /* solaris>=20500 */ #if solaris>=100000 case N_CTFSADIR: case N_CTFSBUND: case N_CTFSCDIR: case N_CTFSCTL: case N_CTFSEVT: case N_CTFSLATE: case N_CTFSROOT: case N_CTFSSTAT: case N_CTFSSYM: case N_CTFSTDIR: case N_CTFSTMPL: /* Method of computing CTFS link count not known. */ break; #endif /* solaris>=100000 */ case N_FD: Lf->nlink = (v->v_type == VDIR) ? 2 : 1; Lf->nlink_def = 1; break; #if solaris>=20600 case N_SOCK: /* no link count */ break; #endif /* solaris>=20600 */ case N_HSFS: Lf->nlink = (long)h.hs_dirent.nlink; Lf->nlink_def = 1; break; case N_NM: Lf->nlink = (long)nn.nm_vattr.va_nlink; Lf->nlink_def = 1; break; # if solaris>=100000 case N_DEV: if (dvs) { Lf->nlink = (long)dv.dv_nlink; Lf->nlink_def = 1; } break; # endif /* solaris>=100000 */ case N_DOOR: Lf->nlink = (long)v->v_count; Lf->nlink_def = 1; break; case N_FIFO: break; case N_MNT: #if defined(CVFS_NLKSAVE) if (vfs) { Lf->nlink = (long)vfs->nlink; Lf->nlink_def = 1; } #endif /* defined(CVFS_NLKSAVE) */ break; case N_MVFS: /* no link count */ break; case N_NFS: Lf->nlink = (long)r.r_attr.va_nlink; Lf->nlink_def = 1; break; #if solaris>=100000 case N_NFS4: Lf->nlink = (long)r4.r_attr.va_nlink; Lf->nlink_def = 1; break; #endif /* solaris>=100000 */ case N_PCFS: break; #if defined(HASPROCFS) case N_PROC: break; #endif /* defined(HASPROCFS) */ case N_REGLR: if (ins) { Lf->nlink = (long)i.i_nlink; Lf->nlink_def = 1; } break; case N_SAMFS: break; /* No more SAM-FS information is available. */ #if solaris>=110000 case N_SDEV: if (sdns) { Lf->nlink = (long)sdva.va_nlink; Lf->nlink_def = 1; } break; #endif /* solaris>=110000 */ case N_SHARED: break; /* No more sharedfs information is available. */ case N_STREAM: break; case N_TMP: Lf->nlink = (long)t.tn_attr.va_nlink; Lf->nlink_def = 1; break; #if defined(HASVXFS) case N_VXFS: Lf->nlink = vx.nl; Lf->nlink_def = vx.nl_def; break; #endif /* defined(HASVXFS) */ #if defined(HAS_ZFS) case N_ZFS: if (zns) { Lf->nlink = (long)MIN(zn.z_links, UINT32_MAX); Lf->nlink_def = 1; } break; #endif /* defined(HAS_ZFS) */ } if (Nlink && Lf->nlink_def && (Lf->nlink < Nlink)) Lf->sf |= SELNLINK; } #if defined(HASVXFS) /* * Record a VxFS file. */ # if defined(HASVXFSDNLC) Lf->is_vxfs = (Ntype == N_VXFS) ? 1 : 0; # endif /* defined(HASVXFSDNLC) */ #endif /* defined(HASVXFS) */ /* * Record an NFS selection. */ if (Fnfs) { if ((Ntype == N_NFS) || (Ntype == N_NFS4)) Lf->sf |= SELNFS; } #if solaris>=20500 /* * If this is a Solaris 2.5 and greater autofs entry, save the autonode name * (less than Solaris 2.6) or fnnode name (Solaris 2.6 and greater). */ if (Ntype == N_AUTO && !Namech[0]) { # if solaris<20600 if (au.an_name[0]) (void) snpf(Namech, Namechl - 1, "%s", au.an_name); Namech[Namechl - 1] = '\0'; # else /* solaris>=20600 */ if (fnn.fn_name && (len = fnn.fn_namelen) > 0 && len < (Namechl - 1)) { if (kread((KA_T)fnn.fn_name, Namech, len)) Namech[0] = '\0'; else Namech[len] = '\0'; } # endif /* solaris<20600 */ } /* * If there is no local virtual file system pointer, or if its directory and * file system names are NULL, and if there is a namenode, and if we're using * the device number from it, see if its nm_mountpt vnode pointer leads to a * local virtual file system structure with non-NULL directory and file system * names. If it does, switch to that local virtual file system pointer. */ if (nns && (!vfs || (!vfs->dir && !vfs->fsname)) && devs && (dev == nn.nm_vattr.va_fsid) && nn.nm_mountpt) { if (!readvnode((KA_T)nn.nm_mountpt, &fv) && fv.v_vfsp) { if ((nvfs = readvfs((KA_T)fv.v_vfsp, (struct vfs *)NULL, nn.nm_filevp)) && !nvfs->dir) { (void) completevfs(nvfs, &dev); } # if defined(HASNCACHE) if (nvfs && nvfs->dir && nvfs->fsname) { fa = (char *)NULL; vfs = nvfs; } # endif /* defined(HASNCACHE) */ } } # if defined(HASNCACHE) /* * If there's a namenode and its device and node number match this one, * use the nm_mountpt's address for name cache lookups. */ if (nns && devs && (dev == nn.nm_vattr.va_fsid) && (Lf->inp_ty == 1) && (Lf->inode == (INODETYPE)nn.nm_vattr.va_nodeid)) Lf->na = (KA_T)nn.nm_mountpt; # endif /* defined(HASNCACHE) */ #endif /* solaris>=20500 */ /* * Save the file system names. */ if (vfs) { Lf->fsdir = vfs->dir; Lf->fsdev = vfs->fsname; #if defined(HASMNTSTAT) Lf->mnt_stat = vfs->mnt_stat; #endif /* defined(HASMNTSTAT) */ if (!Lf->fsdir && !Lf->fsdev && kvs && fxs) { /* * The file system names are unknown. * * Set the file system device to the file system type and clear * the doubtful device numbers. */ Lf->fsdev = Fsinfo[fx]; devs = 0; rdevs = 0; } #if defined(HASFSINO) else Lf->fs_ino = vfs->fs_ino; #endif /* defined(HASFSINO) */ } /* * Save the device numbers, and their states. * * Format the vnode type, and possibly the device name. */ switch (type) { case VNON: ty ="VNON"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VREG: case VDIR: ty = (type == VREG) ? "VREG" : "VDIR"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VBLK: ty = "VBLK"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; Ntype = N_BLK; break; case VCHR: Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; if (unix_sock) { ty = "unix"; break; } ty = "VCHR"; if (Lf->is_stream == 0 && Lf->is_com == 0) Ntype = N_CHR; break; #if solaris>=20500 case VDOOR: Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; ty = "DOOR"; if (dns) (void) idoorkeep(&dn); break; #endif /* solaris>=20500 */ case VLNK: ty = "VLNK"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; #if solaris>=100000 case VPORT: ty = "PORT"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; #endif /* solaris>=100000 */ #if solaris>=20600 case VPROC: /* * The proc file system type is defined when the prnode is read. */ Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; ty = (char *)NULL; break; #endif /* solaris>=20600 */ #if defined(HAS_VSOCK) case VSOCK: # if solaris>=20600 if (so.so_family == AF_UNIX) { ty = "unix"; if (Funix) Lf->sf |= SELUNX; } else { if (so.so_family == AF_INET) { # if defined(HASIPv6) ty = "IPv4"; # else /* !defined(HASIPv6) */ ty = "inet"; # endif /* defined(HASIPv6) */ (void) snpf(Namech, Namechl - 1, printsockty(so.so_type)); Namech[Namechl - 1] = '\0'; if (TcpStIn || UdpStIn || TcpStXn || UdpStXn) Lf->sf |= SELEXCLF; else if (Fnet && (FnetTy != 6)) Lf->sf |= SELNET; } # if defined(HASIPv6) else if (so.so_family == AF_INET6) { ty = "IPv6"; (void) snpf(Namech, Namechl - 1, printsockty(so.so_type)); Namech[Namechl - 1] = '\0'; if (TcpStIn || UdpStIn || TcpStXn || UdpStXn) Lf->sf |= SELEXCLF; else if (Fnet && (FnetTy != 4)) Lf->sf |= SELNET; } # endif /* defined(HASIPv6) */ else { ty = "sock"; (void) printunkaf(so.so_family, 0); ep = endnm(&sz); (void) snpf(ep, sz, ", %s", printsockty(so.so_type)); } } # endif /* solaris>=20600 */ Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; #endif /* defined(HAS_VSOCK) */ case VBAD: ty = "VBAD"; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VFIFO: ty = "FIFO"; if (!Lf->dev_ch || Lf->dev_ch[0] == '\0') { Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; } break; default: Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; (void) snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); ty = (char *)NULL; } if (ty) (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); Lf->ntype = Ntype; /* * If this a Solaris common vnode/snode void some information. */ if (Lf->is_com) Lf->sz_def = Lf->inp_ty = 0; /* * If a file attach description remains, put it in the NAME column addition. */ if (fa) (void) add_nma(fa, fal); #if defined(HASBLKDEV) /* * If this is a VBLK file and it's missing an inode number, try to * supply one. */ if ((Lf->inp_ty == 0) && (type == VBLK)) find_bl_ino(); #endif /* defined(HASBLKDEV) */ /* * If this is a VCHR file and it's missing an inode number, try to * supply one. */ if ((Lf->inp_ty == 0) && (type == VCHR)) { find_ch_ino(); /* * If the VCHR inode number still isn't known and this is a COMMON * vnode file or a stream, or if a pseudo node ID lookup has been * requested, see if an inode number can be derived from a pseudo * or clone device node. * * If it can, save the pseudo or clone device for temporary * use when searching for a match with a named file argument. */ if ((Lf->inp_ty == 0) && (Lf->is_com || Lf->is_stream || pnl) && (Clone || Pseudo)) { if (!sdp) { if (rdevs || devs) { if (Lf->is_stream && !pnl) sdp = finddev(devs ? &dev : &DevDev, rdevs ? &rdev : &Lf->dev, LOOKDEV_CLONE); else sdp = finddev(devs ? &dev : &DevDev, rdevs ? &rdev : &Lf->dev, LOOKDEV_PSEUDO); if (!sdp) sdp = finddev(devs ? &dev : &DevDev, rdevs ? &rdev : &Lf->dev, LOOKDEV_ALL); if (sdp) { if (!rdevs) { Lf->rdev = Lf->dev; Lf->rdev_def = rdevs = 1; } if (!devs) { Lf->dev = DevDev; devs = Lf->dev_def = 1; } } } } else { /* * A local device structure has been located. Make sure * that it's accompanied by device settings. */ if (!devs && vfs) { dev = Lf->dev = vfs->dev; devs = Lf->dev_def = 1; } if (!rdevs) { Lf->rdev = rdev = sdp->rdev; Lf->rdev_def = rdevs = 1; } } if (sdp) { /* * Process the local device information. */ trdev = sdp->rdev; Lf->inode = sdp->inode; Lf->inp_ty = trdevs = 1; if (!Namech[0] || Lf->is_com) { (void) snpf(Namech, Namechl - 1, "%s", sdp->name); Namech[Namechl - 1] = '\0'; } if (Lf->is_com && !Lf->nma) { len = (int)strlen("(COMMON)") + 1; if (!(Lf->nma = (char *) malloc(len))) { (void) fprintf(stderr, "%s: no space for (COMMON): PID %d; FD %s\n", Pn, Lp->pid, Lf->fd); Exit(1); } (void) snpf(Lf->nma, len, "(COMMON)"); } } } } /* * Record stream status. */ if (Lf->inp_ty == 0 && Lf->is_stream && strcmp(Lf->iproto, "STR") == 0) Lf->inp_ty = 2; /* * Test for specified file. */ #if defined(HASPROCFS) if (Ntype == N_PROC) { if (Procsrch) { Procfind = 1; Lf->sf |= SELNM; } else { for (pfi = Procfsid; pfi; pfi = pfi->next) { if ((pfi->pid && pfi->pid == pids.pid_id) # if defined(HASPINODEN) || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) # endif /* defined(HASPINODEN) */ ) { pfi->f = 1; if (!Namech[0]) { (void) snpf(Namech, Namechl - 1, "%s", pfi->nm); Namech[Namechl - 1] = '\0'; } Lf->sf |= SELNM; break; } } } } else #endif /* defined(HASPROCFS) */ { if (Sfile) { if (trdevs) { rdev = Lf->rdev; Lf->rdev = trdev; tdef = Lf->rdev_def; Lf->rdev_def = 1; } if (is_file_named(NULL, Ntype, type, 1)) Lf->sf |= SELNM; if (trdevs) { Lf->rdev = rdev; Lf->rdev_def = tdef; } } } /* * Enter name characters. */ if (Namech[0]) enter_nm(Namech); } /* * read_cni() - read common snode information */ static int read_cni(s, rv, v, rs, di, din, dinl) struct snode *s; /* starting snode */ struct vnode *rv; /* "real" vnode receiver */ struct vnode *v; /* starting vnode */ struct snode *rs; /* "real" snode receiver */ struct dev_info *di; /* dev_info structure receiver */ char *din; /* device info name receiver */ int dinl; /* sizeof(*din) */ { char tbuf[32]; if (read_nvn((KA_T)v->v_data, (KA_T)s->s_commonvp, rv)) return(1); if (read_nsn((KA_T)s->s_commonvp, (KA_T)rv->v_data, rs)) return(1); *din = '\0'; if (rs->s_dip) { if (kread((KA_T)rs->s_dip, (char *)di, sizeof(struct dev_info))) { (void) snpf(Namech, Namechl - 1, "common snode at %s: no dev info: %s", print_kptr((KA_T)rv->v_data, tbuf, sizeof(tbuf)), print_kptr((KA_T)rs->s_dip, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } if (di->devi_name && kread((KA_T)di->devi_name, din, dinl-1) == 0) din[dinl-1] = '\0'; } return(0); } /* * readinode() - read inode */ static int readinode(ia, i) KA_T ia; /* inode kernel address */ struct inode *i; /* inode buffer */ { if (kread((KA_T)ia, (char *)i, sizeof(struct inode))) { (void) snpf(Namech, Namechl - 1, "can't read inode at %s", print_kptr((KA_T)ia, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=20500 /* * read_ndn() - read node's door node */ static int read_ndn(na, da, dn) KA_T na; /* containing vnode's address */ KA_T da; /* door node's address */ struct door_node *dn; /* door node receiver */ { char tbuf[32]; if (!da || kread((KA_T)da, (char *)dn, sizeof(struct door_node))) { (void) snpf(Namech, Namechl - 1, "vnode at %s: can't read door_node: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(da, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=20500 */ /* * read_mi() - read stream's module information */ static void read_mi(s, rdev, so, so_st, so_ad, sdp) KA_T s; /* kernel stream pointer address */ dev_t *rdev; /* raw device pointer */ caddr_t so; /* so_so return (Solaris) */ int *so_st; /* so_so status */ KA_T *so_ad; /* so_so addresses */ struct l_dev **sdp; /* returned device pointer */ { struct l_dev *dp; int i, j, k, nl; KA_T ka; struct module_info mi; char mn[STRNML]; struct stdata sd; struct queue q; struct qinit qi; KA_T qp; /* * If there is no stream pointer, or we can't read the stream head, * return. */ if (!s) return; if (kread((KA_T)s, (char *)&sd, sizeof(sd))) { (void) snpf(Namech, Namechl - 1, "can't read stream head: %s", print_kptr(s, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return; } /* * Follow the stream head to each of its queue structures, retrieving the * module names from each queue's q_info->qi_minfo->mi_idname chain of * structures. Separate each additional name from the previous one with * "->". * * Ignore failures to read all but queue structure chain entries. * * Ignore module names that end in "head". */ k = 0; Namech[0] = '\0'; if (!(dp = finddev(&DevDev, rdev, LOOKDEV_CLONE))) dp = finddev(&DevDev, rdev, LOOKDEV_ALL); if (dp) { (void) snpf(Namech, Namechl - 1, "%s", dp->name); Namech[Namechl - 1] = '\0'; k = (int)strlen(Namech); *sdp = dp; } else (void) snpf(Lf->iproto, sizeof(Lf->iproto), "STR"); nl = sizeof(mn) - 1; mn[nl] = '\0'; qp = (KA_T)sd.sd_wrq; for (i = 0; qp && i < 20; i++, qp = (KA_T)q.q_next) { if (!qp || kread(qp, (char *)&q, sizeof(q))) break; if ((ka = (KA_T)q.q_qinfo) == (KA_T)NULL || kread(ka, (char *)&qi, sizeof(qi))) continue; if ((ka = (KA_T)qi.qi_minfo) == (KA_T)NULL || kread(ka, (char *)&mi, sizeof(mi))) continue; if ((ka = (KA_T)mi.mi_idname) == (KA_T)NULL || kread(ka, mn, nl)) continue; if ((j = (int)strlen(mn)) < 1) continue; if (j >= 4 && strcmp(&mn[j - 4], "head") == 0) continue; #if solaris<100000 if (strcmp(mn, "sockmod") == 0) { /* * Save the Solaris sockmod device and inode numbers. */ if (so) { struct so_so s; if (!kread((KA_T)q.q_ptr, (char *)&s, sizeof(s))) { if (!(*so_st)) so_ad[0] = (KA_T)q.q_ptr; else so_ad[1] = (KA_T)q.q_ptr; (void) savesockmod(&s, (struct so_so *)so, so_st); } } } #endif /* solaris<100000 */ if (k) { if ((k + 2) > (Namechl - 1)) break; (void) snpf(&Namech[k], Namechl - k, "->"); k += 2; } if ((k + j) > (Namechl - 1)) break; (void) snpf(&Namech[k], Namechl - k, "%s", mn); k += j; } } #if solaris>=20500 /* * read_nan(na, ca, cn) - read node's autofs node */ static int read_nan(na, aa, rn) KA_T na; /* containing node's address */ KA_T aa; /* autofs node address */ # if solaris<20600 struct autonode *rn; /* autofs node receiver */ # else /* solaris>=20600 */ struct fnnode *rn; /* autofs node receiver */ # endif /* solaris<20600 */ { char tbuf[32]; # if solaris<20600 if (!aa || kread((KA_T)aa, (char *)rn, sizeof(struct autonode))) # else /* solaris>=20600 */ if (!aa || kread((KA_T)aa, (char *)rn, sizeof(struct fnnode))) # endif /* solaris<20600 */ { (void) snpf(Namech, Namechl - 1, # if solaris<20600 "node at %s: can't read autonode: %s", # else /* solaris>=20600 */ "node at %s: can't read fnnode: %s", # endif /* solaris<20600 */ print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(aa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=20500 */ /* * read_ncn(na, ca, cn) - read node's cache node */ static int read_ncn(na, ca, cn) KA_T na; /* containing node's address */ KA_T ca; /* cache node address */ struct cnode *cn; /* cache node receiver */ { char tbuf[32]; if (!ca || kread((KA_T)ca, (char *)cn, sizeof(struct cnode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read cnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ca, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=100000 /* * read_nctfsn(ty, na, ca, cn) - read node's cache node */ static int read_nctfsn(ty, na, ca, cn) int ty; /* node type -- i.e., N_CTFS* */ KA_T na; /* containing node's address */ KA_T ca; /* cache node address */ char *cn; /* CTFS node receiver */ { char *cp, *nm, tbuf[32]; READLEN_T sz; switch (ty) { case N_CTFSADIR: nm = "ADIR"; sz = (READLEN_T)sizeof(ctfs_adirnode_t); break; case N_CTFSBUND: nm = "BUND"; sz = (READLEN_T)sizeof(ctfs_bunode_t); break; case N_CTFSCDIR: nm = "CDIR"; sz = (READLEN_T)sizeof(ctfs_cdirnode_t); break; case N_CTFSCTL: nm = "CTL"; sz = (READLEN_T)sizeof(ctfs_ctlnode_t); break; case N_CTFSEVT: nm = "EVT"; sz = (READLEN_T)sizeof(ctfs_evnode_t); break; case N_CTFSLATE: nm = "LATE"; sz = (READLEN_T)sizeof(ctfs_latenode_t); break; case N_CTFSROOT: nm = "ROOT"; sz = (READLEN_T)sizeof(ctfs_rootnode_t); break; case N_CTFSSTAT: nm = "STAT"; sz = (READLEN_T)sizeof(ctfs_ctlnode_t); break; case N_CTFSSYM: nm = "SYM"; sz = (READLEN_T)sizeof(ctfs_symnode_t); break; case N_CTFSTDIR: nm = "TDIR"; sz = (READLEN_T)sizeof(ctfs_tdirnode_t); break; case N_CTFSTMPL: nm = "TMPL"; sz = (READLEN_T)sizeof(ctfs_tmplnode_t); break; default: (void) snpf(Namech, Namechl - 1, "unknown CTFS node type: %d", ty); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } if (!ca || kread((KA_T)ca, cn, sz)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read CTFS %s node: %s", print_kptr(na, tbuf, sizeof(tbuf)), nm, print_kptr(ca, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=100000 */ /* * read_nfn() - read node's fifonode */ static int read_nfn(na, fa, f) KA_T na; /* containing node's address */ KA_T fa; /* fifonode address */ struct fifonode *f; /* fifonode receiver */ { char tbuf[32]; if (!fa || readfifonode(fa, f)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read fifonode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(fa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nhn() - read node's High Sierra node */ static int read_nhn(na, ha, h) KA_T na; /* containing node's address */ KA_T ha; /* hsnode address */ struct hsnode *h; /* hsnode receiver */ { char tbuf[32]; if (!ha || readhsnode(ha, h)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read hsnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ha, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nin() - read node's inode */ static int read_nin(na, ia, i) KA_T na; /* containing node's address */ KA_T ia; /* kernel inode address */ struct inode *i; /* inode receiver */ { char tbuf[32]; if (!ia || readinode(ia, i)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read inode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ia, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nln(na, la, ln) - read node's loopback node */ static int read_nln(na, la, ln) KA_T na; /* containing node's address */ KA_T la; /* loopback node address */ struct lnode *ln; /* loopback node receiver */ { char tbuf[32]; if (!la || kread((KA_T)la, (char *)ln, sizeof(struct lnode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read lnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(la, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nnn() - read node's namenode */ static int read_nnn(na, nna, nn) KA_T na; /* containing node's address */ KA_T nna; /* namenode address */ struct namenode *nn; /* namenode receiver */ { char tbuf[32]; if (!nna || kread((KA_T)nna, (char *)nn, sizeof(struct namenode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read namenode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(nna, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nmn() - read node's mvfsnode */ static int read_nmn(na, ma, m) KA_T na; /* containing node's address */ KA_T ma; /* kernel mvfsnode address */ struct mvfsnode *m; /* mvfsnode receiver */ { char tbuf[32]; if (!ma || kread((KA_T)ma, (char *)m, sizeof(struct mvfsnode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read mvfsnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ma, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if defined(HASPROCFS) /* * read_npi() - read node's /proc file system information */ static int read_npi(na, v, pids) KA_T na; /* containing node's address */ struct vnode *v; /* containing vnode */ struct pid *pids; /* pid structure receiver */ { struct as as; struct proc p; struct prnode pr; char tbuf[32]; #if solaris>=20600 prcommon_t pc, ppc; int pcs, ppcs, prpcs, prppcs; struct proc pp; pid_t prpid; id_t prtid; char *ty = (char *)NULL; #endif /* solaris>=20600 */ if (!v->v_data || kread((KA_T)v->v_data, (char *)&pr, sizeof(pr))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read prnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr((KA_T)v->v_data, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } #if solaris<20600 /* * For Solaris < 2.6: * * Read the proc structure, get the process size and PID; * * Return the PID; * * Enter a name, constructed from the file system and PID; * * Enter an inode number, constructed from the PID. */ if (!pr.pr_proc) { if (v->v_type == VDIR) { (void) snpf(Namech, Namechl - 1, "/%s", HASPROCFS); Namech[Namechl - 1] = '\0'; enter_nm(Namech); Lf->inode = (INODETYPE)PR_ROOTINO; Lf->inp_ty = 1; } else { (void) snpf(Namech, Namechl - 1, "/%s/", HASPROCFS); Namech[Namechl - 1] = '\0'; enter_nm(Namech); Lf->inp_ty = 0; } return(0); } if (kread((KA_T)pr.pr_proc, (char *)&p, sizeof(p))) { (void) snpf(Namech, Namechl - 1, "prnode at %s: can't read proc: %s", print_kptr((KA_T)v->v_data, tbuf, sizeof(tbuf)), print_kptr((KA_T)pr.pr_proc, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } if (p.p_as && !kread((KA_T)p.p_as, (char *)&as, sizeof(as))) { Lf->sz = (SZOFFTYPE)as.a_size; Lf->sz_def = 1; } if (!p.p_pidp || kread((KA_T)p.p_pidp, (char *)pids, sizeof(struct pid))) { (void) snpf(Namech, Namechl - 1, "proc struct at %s: can't read pid: %s", print_kptr((KA_T)pr.pr_proc, tbuf, sizeof(tbuf)), print_kptr((KA_T)p.p_pidp, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } (void) snpf(Namech, Namechl, "/%s/%d", HASPROCFS, (int)pids->pid_id); Namech[Namechl - 1] = '\0'; Lf->inode = (INODETYPE)ptoi(pids->pid_id); Lf->inp_ty = 1; #else /* solaris>=20600 */ /* * Enter the >= Solaris 2.6 inode number. */ Lf->inode = (INODETYPE)pr.pr_ino; Lf->inp_ty = 1; /* * Read the >= Solaris 2.6 prnode common structures. * * Return the PID number. * * Identify the lwp PID (the thread ID). */ if (pr.pr_common && kread((KA_T)pr.pr_common, (char *)&pc, sizeof(pc)) == 0) { pcs = 1; if (pc.prc_proc && kread((KA_T)pc.prc_proc, (char *)&p, sizeof(p)) == 0) prpcs = 1; else prpcs = 0; } else pcs = prpcs = 0; if (pr.pr_pcommon && kread((KA_T)pr.pr_pcommon, (char *)&ppc, sizeof(ppc)) == 0) { ppcs = 1; if (ppc.prc_proc && kread((KA_T)ppc.prc_proc, (char *)&pp, sizeof(pp)) == 0) prppcs = 1; else prppcs = 0; } else ppcs = prppcs = 0; if (pcs && pc.prc_pid) pids->pid_id = prpid = pc.prc_pid; else if (ppcs && ppc.prc_pid) pids->pid_id = prpid = ppc.prc_pid; else pids->pid_id = prpid = (pid_t)0; if (pcs && pc.prc_tid) prtid = pc.prc_tid; else if (ppcs && ppc.prc_tid) prtid = ppc.prc_tid; else prtid = (id_t)0; /* * Identify the Solaris 2.6 /proc file system name, file size, and file type. */ switch (pr.pr_type) { case PR_PROCDIR: (void) snpf(Namech, Namechl - 1, "/%s", HASPROCFS); ty = "PDIR"; break; case PR_PIDDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); ty = "PDIR"; break; case PR_AS: (void) snpf(Namech, Namechl - 1, "/%s/%d/as", HASPROCFS, (int)prpid); ty = "PAS"; if (prpcs && kread((KA_T)pc.prc_proc, (char *)&p, sizeof(p)) == 0 && p.p_as && kread((KA_T)p.p_as, (char *)&as, sizeof(as)) == 0) { Lf->sz = (SZOFFTYPE)as.a_size; Lf->sz_def = 1; } break; case PR_CTL: (void) snpf(Namech, Namechl - 1, "/%s/%d/ctl", HASPROCFS, (int)prpid); ty = "PCTL"; break; case PR_STATUS: (void) snpf(Namech, Namechl - 1, "/%s/%d/status", HASPROCFS, (int)prpid); ty = "PSTA"; break; case PR_LSTATUS: (void) snpf(Namech, Namechl - 1, "/%s/%d/lstatus", HASPROCFS, (int)prpid); ty = "PLST"; break; case PR_PSINFO: (void) snpf(Namech, Namechl - 1, "/%s/%d/psinfo", HASPROCFS, (int)prpid); ty = "PSIN"; break; case PR_LPSINFO: (void) snpf(Namech, Namechl - 1, "/%s/%d/lpsinfo", HASPROCFS, (int)prpid); ty = "PLPI"; break; case PR_MAP: (void) snpf(Namech, Namechl - 1, "/%s/%d/map", HASPROCFS, (int)prpid); ty = "PMAP"; break; case PR_RMAP: (void) snpf(Namech, Namechl - 1, "/%s/%d/rmap", HASPROCFS, (int)prpid); ty = "PRMP"; break; case PR_XMAP: (void) snpf(Namech, Namechl - 1, "/%s/%d/xmap", HASPROCFS, (int)prpid); ty = "PXMP"; break; case PR_CRED: (void) snpf(Namech, Namechl - 1, "/%s/%d/cred", HASPROCFS, (int)prpid); ty = "PCRE"; break; case PR_SIGACT: (void) snpf(Namech, Namechl - 1, "/%s/%d/sigact", HASPROCFS, (int)prpid); ty = "PSGA"; break; case PR_AUXV: (void) snpf(Namech, Namechl - 1, "/%s/%d/auxv", HASPROCFS, (int)prpid); ty = "PAXV"; break; # if defined(HASPR_LDT) case PR_LDT: (void) snpf(Namech, Namechl - 1, "/%s/%d/ldt", HASPROCFS, (int)prpid); ty = "PLDT"; break; # endif /* defined(HASPR_LDT) */ case PR_USAGE: (void) snpf(Namech, Namechl - 1, "/%s/%d/usage", HASPROCFS, (int)prpid); ty = "PUSG"; break; case PR_LUSAGE: (void) snpf(Namech, Namechl - 1, "/%s/%d/lusage", HASPROCFS, (int)prpid); ty = "PLU"; break; case PR_PAGEDATA: (void) snpf(Namech, Namechl - 1, "/%s/%d/pagedata", HASPROCFS, (int)prpid); ty = "PGD"; break; case PR_WATCH: (void) snpf(Namech, Namechl - 1, "/%s/%d/watch", HASPROCFS, (int)prpid); ty = "PW"; break; case PR_CURDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d/cwd", HASPROCFS, (int)prpid); ty = "PCWD"; break; case PR_ROOTDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d/root", HASPROCFS, (int)prpid); ty = "PRTD"; break; case PR_FDDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d/fd", HASPROCFS, (int)prpid); ty = "PFDR"; break; case PR_FD: (void) snpf(Namech, Namechl - 1, "/%s/%d/fd/%d", HASPROCFS, (int)prpid, pr.pr_index); ty = "PFD"; break; case PR_OBJECTDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d/object", HASPROCFS, (int)prpid); ty = "PODR"; break; case PR_OBJECT: (void) snpf(Namech, Namechl - 1, "/%s/%d/object/", HASPROCFS, (int)prpid); ty = "POBJ"; break; case PR_LWPDIR: (void) snpf(Namech, Namechl - 1, "/%s/%d/lpw", HASPROCFS, (int)prpid); ty = "PLDR"; break; case PR_LWPIDDIR: (void) snpf(Namech, Namechl, "/%s/%d/lwp/%d", HASPROCFS, (int)prpid, (int)prtid); ty = "PLDR"; break; case PR_LWPCTL: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpctl", HASPROCFS, (int)prpid, (int)prtid); ty = "PLC"; break; case PR_LWPSTATUS: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpstatus", HASPROCFS, (int)prpid, (int)prtid); ty = "PLWS"; break; case PR_LWPSINFO: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpsinfo", HASPROCFS, (int)prpid, (int)prtid); ty = "PLWI"; break; case PR_LWPUSAGE: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpusage", HASPROCFS, (int)prpid, (int)prtid); ty = "PLWU"; break; case PR_XREGS: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/xregs", HASPROCFS, (int)prpid, (int)prtid); ty = "PLWX"; break; # if defined(HASPR_GWINDOWS) case PR_GWINDOWS: (void) snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/gwindows", HASPROCFS, (int)prpid, (int)prtid); ty = "PLWG"; break; # endif /* defined(HASPR_GWINDOWS) */ case PR_PIDFILE: (void) snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); ty = "POPF"; break; case PR_LWPIDFILE: (void) snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); ty = "POLP"; break; case PR_OPAGEDATA: (void) snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); ty = "POPG"; break; default: ty = (char *)NULL; } if (ty) (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); else (void) snpf(Lf->type, sizeof(Lf->type), "%04o", (pr.pr_type & 0xfff)); /* * Record the Solaris 2.6 /proc file system inode number. */ Lf->inode = (INODETYPE)pr.pr_ino; Lf->inp_ty = 1; # endif /* solaris<20600 */ Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(0); } #endif /* defined(HASPROCFS) */ /* * read_npn() - read node's pcnode */ static int read_npn(na, pa, p) KA_T na; /* containing node's address */ KA_T pa; /* pcnode address */ struct pcnode *p; /* pcnode receiver */ { char tbuf[32]; if (!pa || kread(pa, (char *)p, sizeof(struct pcnode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read pcnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(pa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=100000 /* * read_nprtn() - read node's port node */ static int read_nprtn(na, pa, p) KA_T na; /* containing node's address */ KA_T pa; /* port node address */ port_t *p; /* port node receiver */ { char tbuf[32]; if (!pa || kread(pa, (char *)p, sizeof(port_t))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read port node: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(pa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=100000 */ /* * read_nrn() - read node's rnode */ static int read_nrn(na, ra, r) KA_T na; /* containing node's address */ KA_T ra; /* rnode address */ struct rnode *r; /* rnode receiver */ { char tbuf[32]; if (!ra || readrnode(ra, r)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read rnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ra, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=100000 /* * read_nrn4() - read node's rnode4 */ static int read_nrn4(na, ra, r) KA_T na; /* containing node's address */ KA_T ra; /* rnode address */ struct rnode4 *r; /* rnode receiver */ { char tbuf[32]; if (!ra || kread((KA_T)ra, (char *)r, sizeof(struct rnode4)) ) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read rnode4: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ra, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=100000 */ #if solaris>=110000 /* * read_nsdn() - read node's sdev_node */ static int read_nsdn(na, sa, sdn, sdva) KA_T na; /* containing node's adress */ KA_T sa; /* sdev_node address */ struct sdev_node *sdn; /* sdev_node receiver */ struct vattr *sdva; /* sdev_node's vattr receiver */ { KA_T va; char tbuf[32], tbuf1[32]; if (!sa || kread((KA_T)sa, (char *)sdn, sizeof(struct sdev_node))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read sdev_node: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(sa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } if (!(va = (KA_T)sdn->sdev_attr) || kread(va, (char *)sdva, sizeof(struct vattr)) ) { (void) snpf(Namech, Namechl - 1, "node at %s; sdev_node at %s: can't read vattr: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(sa, tbuf1, sizeof(tbuf1)), print_kptr(va, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=110000 */ #if solaris>=20600 /* * read_nson() - read node's sonode */ static int read_nson(na, sa, sn) KA_T na; /* containing node's address */ KA_T sa; /* sonode address */ struct sonode *sn; /* sonode receiver */ { char tbuf[32]; if (!sa || kread((KA_T)sa, (char *)sn, sizeof(struct sonode))) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read sonode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(sa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=20600 */ /* * read_nsn() - read node's snode */ static int read_nsn(na, sa, s) KA_T na; /* containing node's address */ KA_T sa; /* snode address */ struct snode *s; /* snode receiver */ { char tbuf[32]; if (!sa || readsnode(sa, s)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read snode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(sa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=110000 /* * read_nsti() - read socket node's info */ static int read_nsti(so, stpi) struct sonode *so; /* socket's sonode */ sotpi_info_t *stpi; /* local socket info receiver */ { char tbuf[32]; (void) CTF_init(&Sockfs_ctfs, SOCKFS_MOD_FORMAT, Sockfs_requests); if (!so || !so->so_priv || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_dev) || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_laddr) || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_faddr) || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_ux_laddr) || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_ux_faddr) || CTF_MEMBER_READ(so->so_priv,stpi,sotpi_info_members, sti_serv_type) ) { (void) snpf(Namech, Namechl - 1, "sonode at %s: can't read so_priv: %s", print_kptr((KA_T)so, tbuf, sizeof(tbuf)), print_kptr((KA_T)so->so_priv, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* solaris>=110000 */ /* * read_ntn() - read node's tmpnode */ static int read_ntn(na, ta, t) KA_T na; /* containing node's address */ KA_T ta; /* tmpnode address */ struct tmpnode *t; /* tmpnode receiver */ { char tbuf[32]; if (!ta || readtnode(ta, t)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read tnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ta, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if solaris>=20600 /* * read_nusa() - read sondode's UNIX socket address */ static int read_nusa(so, ua) struct soaddr *so; /* kernel socket info structure */ struct sockaddr_un *ua; /* local sockaddr_un address */ { KA_T a; int len; int min = offsetof(struct sockaddr_un, sun_path); ua->sun_path[0] = '\0'; if (!(a = (KA_T)so->soa_sa) || (len = so->soa_len) < (min + 2) || len > (int)sizeof(struct sockaddr_un) || kread(a, (char *)ua, len) || ua->sun_family != AF_UNIX) return(0); len -= min; if (len >= sizeof(ua->sun_path)) len = sizeof(ua->sun_path) - 1; ua->sun_path[len] = '\0'; return((int)strlen(ua->sun_path)); } #endif /* solaris>=20600 */ /* * read_nvn() - read node's vnode */ static int read_nvn(na, va, v) KA_T na; /* node's address */ KA_T va; /* vnode address */ struct vnode *v; /* vnode receiver */ { char tbuf[32]; if (readvnode(va, v)) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read real vnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(va, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #if defined(HAS_ZFS) /* * read_nzn() - read node's ZFS node */ static int read_nzn(na, nza, zn) KA_T na; /* containing node's address */ KA_T nza; /* znode address */ znode_t *zn; /* znode receiver */ { int err = 0; /* error flag */ CTF_member_t *mp; /* member pointer */ char tbuf[32]; /* temporary buffer */ znode_phys_t zp; /* physical znode */ (void) CTF_init(&ZFS_ctfs, ZFS_MOD_FORMAT, ZFS_requests); if (!nza || CTF_MEMBER_READ(nza, zn, znode_members, z_zfsvfs) || CTF_MEMBER_READ(nza, zn, znode_members, z_vnode) || CTF_MEMBER_READ(nza, zn, znode_members, z_id) || CTF_MEMBER_READ(nza, zn, znode_members, z_phys) || CTF_MEMBER_READ(nza, zn, znode_members, z_links) || CTF_MEMBER_READ(nza, zn, znode_members, z_size) ) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read znode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(nza, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } /* * If the physical znode pointer is defined, read the physizal znode * and propagate its values to the znode. */ if (znode_members[MX_z_phys].m_offset != CTF_MEMBER_UNDEF) { err = read_nznp(nza, (KA_T)zn->z_phys, &zp); if (!err) { zn->z_links = zp.zp_links; zn->z_size = zp.zp_size; } } else { /* * Make sure z_link and z_size are defined when z_phys isn't. */ if (znode_members[MX_z_links].m_offset == CTF_MEMBER_UNDEF) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read z_links: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(nza, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); err = 1; } if (znode_members[MX_z_size].m_offset == CTF_MEMBER_UNDEF) { (void) snpf(Namech, Namechl - 1, "node at %s: can't read z_size: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(nza, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); err = 1; } } return(err); } /* * read_nznp() - read znode's persistent znode */ static int read_nznp(nza, nzpa, zp) KA_T nza; /* containing znode's address */ KA_T nzpa; /* persistent znode address */ znode_phys_t *zp; /* persistent znode receiver */ { char tbuf[32]; (void) CTF_init(&ZFS_ctfs, ZFS_MOD_FORMAT, ZFS_requests); if (!nzpa || CTF_MEMBER_READ(nzpa, zp, znode_phys_members, zp_size) || CTF_MEMBER_READ(nzpa, zp, znode_phys_members, zp_links) ) { (void) snpf(Namech, Namechl - 1, "znode at %s: " "can't read znode_phys: %s", print_kptr(nza, tbuf, sizeof(tbuf)), print_kptr(nzpa, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } /* * read_nzvfs() - read znode's associated vfs */ static int read_nzvfs(nza, nzva, zv) KA_T nza; /* containing znode's address */ KA_T nzva; /* associated vfs address */ zfsvfs_t *zv; /* associated vfs receiver */ { char tbuf[32]; (void) CTF_init(&ZFS_ctfs, ZFS_MOD_FORMAT, ZFS_requests); if (!nzva || CTF_MEMBER_READ(nzva, zv, zfsvfs_members, z_vfs) ) { (void) snpf(Namech, Namechl - 1, "znode at %s: can't read zfsvfs: %s", print_kptr(nza, tbuf, sizeof(tbuf)), print_kptr(nzva, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } return(0); } #endif /* defined(HAS_ZFS) */ #if solaris<100000 /* * savesockmod() - save addresses from sockmod so_so structure */ static void savesockmod(so, sop, so_st) struct so_so *so; /* new so_so structure pointer */ struct so_so *sop; /* previous so_so structure pointer */ int *so_st; /* status of *sop (0 if not loaded) */ { #if solaris<20500 dev_t d1, d2, d3; #endif /* solaris<20500 */ #define luxadr lux_dev.addr.tu_addr #define luxdev lux_dev.addr.tu_addr.dev #define luxino lux_dev.addr.tu_addr.ino #define ruxadr rux_dev.addr.tu_addr #define ruxdev rux_dev.addr.tu_addr.dev #define ruxino rux_dev.addr.tu_addr.ino #if solaris<20500 /* * If either address in the new structure is missing a device number, clear * its corresponding inode number. Then sort the inode-less device numbers. */ if (!so->luxdev) so->luxino = (ino_t)0; if (!so->ruxdev) so->ruxino = (ino_t)0; if (!so->luxino && !so->ruxino) { if (so->luxdev > so->ruxdev) { d2 = so->luxdev; d1 = so->luxdev = so->ruxdev; so->ruxdev = d2; } else { d1 = so->luxdev; d2 = so->ruxdev; } } else d1 = d2 = (dev_t)0; /* * If the previous structure hasn't been loaded, save the new one in it with * adjusted or sorted addresses. */ if (!*so_st) { if (so->luxdev && so->luxino) { *sop = *so; sop->ruxdev = (dev_t)0; sop->ruxino = (ino_t)0; *so_st = 1; return; } if (so->ruxdev && so->ruxino) { *sop = *so; sop->luxadr = sop->ruxadr; sop->ruxdev = (dev_t)0; sop->ruxino = (ino_t)0; *so_st = 1; return; } *sop = *so; *so_st = 1; return; } /* * See if the new sockmod addresses need to be merged with the previous * ones: * * * Don't merge if the previous so_so structure's lux_dev has a non- * zero device and a non-zero inode number. * * * If either of the device/inode pairs in the new structure is non- * zero, propagate them to the previous so_so structure. * * * Don't merge if the both device numbers in the new structure are * zero. */ if (sop->luxdev && sop->luxino) return; if (so->luxdev && so->luxino) { sop->luxadr = so->luxadr; sop->ruxdev = (dev_t)0; sop->ruxino = (ino_t)0; return; } if (so->ruxdev && so->ruxino) { sop->luxadr = so->ruxadr; sop->ruxdev = (dev_t)0; sop->ruxino = (ino_t)0; return; } if (!so->luxdev && !so->ruxdev) return; /* * Check the previous structure's device numbers: * * * If both are zero, replace the previous structure with the new one. * * * Choose the minimum and maximum non-zero device numbers contained in * either structure. */ if (!sop->luxdev && !sop->ruxdev) { *sop = *so; return; } if (!sop->luxdev && (d1 || d2)) { if (d1) { sop->luxdev = d1; d1 = (dev_t)0; } else { sop->luxdev = d2; d2 = (dev_t)0; } if (sop->luxdev > sop->ruxdev) { d3 = sop->luxdev; sop->luxdev = sop->ruxdev; sop->ruxdev = d3; } } if (!sop->ruxdev && (d1 || d2)) { if (d1) { sop->ruxdev = d1; d1 = (dev_t)0; } else { sop->ruxdev = d2; d2 = (dev_t)0; } if (sop->luxdev > sop->ruxdev) { d3 = sop->luxdev; sop->luxdev = sop->ruxdev; sop->ruxdev = d3; } } if (sop->luxdev && sop->ruxdev) { if (d1) { if (d1 < sop->luxdev) sop->luxdev = d1; else if (d1 > sop->ruxdev) sop->ruxdev = d1; } if (d2) { if (d2 < sop->luxdev) sop->luxdev = d2; else if (d2 > sop->ruxdev) sop->ruxdev = d2; } } #else /* solaris>=20500 */ /* * Save the first sockmod structure. */ if (!*so_st) { *so_st = 1; *sop = *so; } #endif /* solaris<20500 */ } #endif /* solaris<100000 */ /* * vop2ty() - convert vnode operation switch address to internal type */ int vop2ty(vp, fx) struct vnode *vp; /* local vnode pointer */ int fx; /* file system index (-1 if none) */ { int h; register int i; KA_T ka; int nty; v_optab_t *nv, *v, *vt; #if defined(HAS_AFS) static int afs = 0; /* afs test status: -1 = no AFS * 0 = not tested * 1 = AFS */ #endif /* defined(HAS_AFS) */ /* * Locate the node type by hashing the vnode's v_op address into the Voptab[]. */ if (!(ka = (KA_T)vp->v_op)) return(-1); h = HASHVOP(ka); for (v = Voptab[h]; v; v = v->next) { if (ka == v->v_op) break; } if (!v) { /* * If there's no entry in the Voptab[] for the v_op address, see if * an entry can be found via the file system type and FxToVoptab[]. */ if ((fx >= 0) && (fx < Fsinfomax) && (v = FxToVoptab[fx])) { /* * There's an FxToVoptab[] mapping, so add an entry to Voptab[] * for the v_op address. */ if (!(nv = (v_optab_t *)malloc((MALLOC_S)sizeof(v_optab_t)))) { (void) fprintf(stderr, "%s: can't add \"%s\" to Voptab\n", Pn, Fsinfo[fx]); Exit(1); } *nv = *v; nv->v_op = ka; h = HASHVOP(ka); nv->next = Voptab[h]; Voptab[h] = v = nv; } } if (!v) return(-1); #if defined(HAS_AFS) /* * Do special AFS checks. */ if (v->nty == N_AFS) { if (vp->v_data || !vp->v_vfsp) return(-1); switch (afs) { case -1: return(-1); case 0: if (!hasAFS(vp)) { afs = -1; return(-1); } afs = 1; return(N_AFS); case 1: if ((KA_T)vp->v_vfsp == AFSVfsp) return(N_AFS); } return(-1); } #endif /* defined(HAS_AFS) */ return(v->nty); } #if solaris>=100000 /* * read_ndvn() -- read node's dv_node */ static int read_ndvn(na, da, dv, dev, devs) KA_T na; /* containing vnode's address */ KA_T da; /* containing vnode's v_data */ struct dv_node *dv; /* dv_node receiver */ dev_t *dev; /* underlying file system device * number receptor */ unsigned char *devs; /* status of *dev */ { struct vnode rv; struct snode s; char tbuf[32]; struct vfs v; /* * Read the snode. */ if (!da || kread((KA_T)da, (char *)&s, sizeof(s))) { (void) snpf(Namech, Namechl - 1, "dv_node vnode at %s: can't read snode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(da, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } /* * Read the snode's real vnode. */ if (!s.s_realvp || kread((KA_T)s.s_realvp, (char *)&rv, sizeof(struct dv_node))) { (void) snpf(Namech, Namechl - 1, "dv_node snode at %s: can't read real vnode: %s", print_kptr(da, tbuf, sizeof(tbuf)), print_kptr((KA_T)s.s_realvp, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } /* * Read the real vnode's dv_node. */ if (!rv.v_data || kread((KA_T)rv.v_data, (char *)dv, sizeof(rv))) { (void) snpf(Namech, Namechl - 1, "dv_node real vnode at %s: can't read dv_node: %s", print_kptr((KA_T)s.s_realvp, tbuf, sizeof(tbuf)), print_kptr((KA_T)rv.v_data, (char *)NULL, 0)); Namech[Namechl - 1] = '\0'; enter_nm(Namech); return(1); } /* * Return the device number of the underlying file system, if possible. */ if (rv.v_vfsp && !kread((KA_T)rv.v_vfsp, (char *)&v, sizeof(v))) { *dev = v.vfs_dev; *devs = 1; } return(0); } #endif /* solaris<100000 */