Print this page
12046 Provide /proc/<PID>/fdinfo/

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/proc/prsubr.c
          +++ new/usr/src/uts/common/fs/proc/prsubr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
  25   26   */
  26   27  
  27   28  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  28      -/*        All Rights Reserved   */
       29 +/*        All Rights Reserved   */
  29   30  
  30   31  #include <sys/types.h>
  31   32  #include <sys/t_lock.h>
  32   33  #include <sys/param.h>
  33   34  #include <sys/cmn_err.h>
  34   35  #include <sys/cred.h>
  35   36  #include <sys/priv.h>
  36   37  #include <sys/debug.h>
  37   38  #include <sys/errno.h>
  38   39  #include <sys/inline.h>
↓ open down ↓ 19 lines elided ↑ open up ↑
  58   59  #include <sys/poll.h>
  59   60  #include <sys/shm_impl.h>
  60   61  #include <sys/fault.h>
  61   62  #include <sys/syscall.h>
  62   63  #include <sys/procfs.h>
  63   64  #include <sys/processor.h>
  64   65  #include <sys/cpuvar.h>
  65   66  #include <sys/copyops.h>
  66   67  #include <sys/time.h>
  67   68  #include <sys/msacct.h>
       69 +#include <sys/flock_impl.h>
       70 +#include <sys/stropts.h>
       71 +#include <sys/strsubr.h>
       72 +#include <sys/pathname.h>
       73 +#include <sys/mode.h>
       74 +#include <sys/socketvar.h>
       75 +#include <sys/autoconf.h>
       76 +#include <sys/dtrace.h>
       77 +#include <sys/timod.h>
       78 +#include <netinet/udp.h>
       79 +#include <netinet/tcp.h>
       80 +#include <inet/cc.h>
  68   81  #include <vm/as.h>
  69   82  #include <vm/rm.h>
  70   83  #include <vm/seg.h>
  71   84  #include <vm/seg_vn.h>
  72   85  #include <vm/seg_dev.h>
  73   86  #include <vm/seg_spt.h>
  74   87  #include <vm/page.h>
  75   88  #include <sys/vmparam.h>
  76   89  #include <sys/swap.h>
  77   90  #include <fs/proc/prdata.h>
↓ open down ↓ 1369 lines elided ↑ open up ↑
1447 1460  
1448 1461          len = (int)(cp - cbuf);
1449 1462  
1450 1463          do {
1451 1464                  *s++ = *--cp;
1452 1465          } while (cp > cbuf);
1453 1466  
1454 1467          return (len);
1455 1468  }
1456 1469  
     1470 +file_t *
     1471 +pr_getf(proc_t *p, uint_t fd, short *flag)
     1472 +{
     1473 +        uf_entry_t *ufp;
     1474 +        uf_info_t *fip;
     1475 +        file_t *fp;
     1476 +
     1477 +        ASSERT(MUTEX_HELD(&p->p_lock));
     1478 +
     1479 +        fip = P_FINFO(p);
     1480 +
     1481 +        if (fd >= fip->fi_nfiles)
     1482 +                return (NULL);
     1483 +
     1484 +        mutex_exit(&p->p_lock);
     1485 +        mutex_enter(&fip->fi_lock);
     1486 +        UF_ENTER(ufp, fip, fd);
     1487 +        if ((fp = ufp->uf_file) != NULL && fp->f_count > 0) {
     1488 +                if (flag != NULL)
     1489 +                        *flag = ufp->uf_flag;
     1490 +                ufp->uf_refcnt++;
     1491 +        } else {
     1492 +                fp = NULL;
     1493 +        }
     1494 +        UF_EXIT(ufp);
     1495 +        mutex_exit(&fip->fi_lock);
     1496 +        mutex_enter(&p->p_lock);
     1497 +
     1498 +        return (fp);
     1499 +}
     1500 +
1457 1501  void
     1502 +pr_releasef(proc_t *p, uint_t fd)
     1503 +{
     1504 +        uf_entry_t *ufp;
     1505 +        uf_info_t *fip;
     1506 +
     1507 +        ASSERT(MUTEX_HELD(&p->p_lock));
     1508 +
     1509 +        fip = P_FINFO(p);
     1510 +
     1511 +        mutex_exit(&p->p_lock);
     1512 +        mutex_enter(&fip->fi_lock);
     1513 +        UF_ENTER(ufp, fip, fd);
     1514 +        ASSERT(ufp->uf_refcnt > 0);
     1515 +        ufp->uf_refcnt--;
     1516 +        UF_EXIT(ufp);
     1517 +        mutex_exit(&fip->fi_lock);
     1518 +        mutex_enter(&p->p_lock);
     1519 +}
     1520 +
     1521 +void
1458 1522  pr_object_name(char *name, vnode_t *vp, struct vattr *vattr)
1459 1523  {
1460 1524          char *s = name;
1461 1525          struct vfs *vfsp;
1462 1526          struct vfssw *vfsswp;
1463 1527  
1464 1528          if ((vfsp = vp->v_vfsp) != NULL &&
1465 1529              ((vfsswp = vfssw + vfsp->vfs_fstype), vfsswp->vsw_name) &&
1466 1530              *vfsswp->vsw_name) {
1467 1531                  (void) strcpy(s, vfsswp->vsw_name);
↓ open down ↓ 88 lines elided ↑ open up ↑
1556 1620                  list_insert_after(iolhead, iol, newiol);
1557 1621                  iol = list_next(iolhead, iol);
1558 1622                  ASSERT(iol == newiol);
1559 1623          }
1560 1624          new = (char *)PIOL_DATABUF(iol) + iol->piol_usedsize;
1561 1625          iol->piol_usedsize += itemsize;
1562 1626          bzero(new, itemsize);
1563 1627          return (new);
1564 1628  }
1565 1629  
     1630 +void
     1631 +pr_iol_freelist(list_t *iolhead)
     1632 +{
     1633 +        piol_t  *iol;
     1634 +
     1635 +        while ((iol = list_head(iolhead)) != NULL) {
     1636 +                list_remove(iolhead, iol);
     1637 +                kmem_free(iol, iol->piol_size);
     1638 +        }
     1639 +        list_destroy(iolhead);
     1640 +}
     1641 +
1566 1642  int
1567 1643  pr_iol_copyout_and_free(list_t *iolhead, caddr_t *tgt, int errin)
1568 1644  {
1569 1645          int error = errin;
1570 1646          piol_t  *iol;
1571 1647  
1572 1648          while ((iol = list_head(iolhead)) != NULL) {
1573 1649                  list_remove(iolhead, iol);
1574 1650                  if (!error) {
1575 1651                          if (copyout(PIOL_DATABUF(iol), *tgt,
↓ open down ↓ 792 lines elided ↑ open up ↑
2368 2444                          psp->pr_size = btopr(as->a_resvsize) *
2369 2445                              (PAGESIZE / 1024);
2370 2446                          psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024);
2371 2447                          psp->pr_pctmem = rm_pctmemory(as);
2372 2448                          AS_LOCK_EXIT(as);
2373 2449                          mutex_enter(&p->p_lock);
2374 2450                  }
2375 2451          }
2376 2452  }
2377 2453  
     2454 +static size_t
     2455 +prfdinfomisc(list_t *data, uint_t type, void *val, off_t vlen)
     2456 +{
     2457 +        pr_misc_header_t *misc;
     2458 +        size_t len;
     2459 +
     2460 +        len = sizeof (*misc) + vlen;
     2461 +
     2462 +        if (data != NULL) {
     2463 +                misc = pr_iol_newbuf(data, len);
     2464 +                misc->pr_misc_type = type;
     2465 +                misc->pr_misc_size = len;
     2466 +                misc++;
     2467 +                bcopy((char *)val, (char *)misc, vlen);
     2468 +        }
     2469 +
     2470 +        return (len);
     2471 +}
     2472 +
     2473 +/*
     2474 + * There's no elegant way to determine if a character device
     2475 + * supports TLI, so just check a hardcoded list of known TLI
     2476 + * devices.
     2477 + */
     2478 +
     2479 +static boolean_t
     2480 +pristli(vnode_t *vp)
     2481 +{
     2482 +        static const char *tlidevs[] = {
     2483 +            "udp", "udp6", "tcp", "tcp6", NULL
     2484 +        };
     2485 +        struct devnames *dnp;
     2486 +        major_t major;
     2487 +        uint_t i;
     2488 +
     2489 +        ASSERT(vp != NULL);
     2490 +        ASSERT(vp->v_type == VCHR);
     2491 +
     2492 +        if (vp->v_rdev == 0)
     2493 +                return (B_FALSE);
     2494 +
     2495 +        major = getmajor(vp->v_rdev);
     2496 +        if (major == DDI_MAJOR_T_NONE || major > devcnt)
     2497 +                return (B_FALSE);
     2498 +
     2499 +        dnp = &devnamesp[major];
     2500 +
     2501 +        for (i = 0; tlidevs[i] != NULL; i++) {
     2502 +                if (strcmp(dnp->dn_name, tlidevs[i]) == 0)
     2503 +                        return (B_TRUE);
     2504 +        }
     2505 +
     2506 +        return (B_FALSE);
     2507 +}
     2508 +
     2509 +static size_t
     2510 +prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred)
     2511 +{
     2512 +        char pathname[MAXPATHLEN];
     2513 +        vnode_t *vrootp;
     2514 +        size_t sz = 0;
     2515 +
     2516 +        mutex_enter(&p->p_lock);
     2517 +        if ((vrootp = PTOU(p)->u_rdir) == NULL)
     2518 +                vrootp = rootdir;
     2519 +        VN_HOLD(vrootp);
     2520 +        mutex_exit(&p->p_lock);
     2521 +
     2522 +        if (vnodetopath(vrootp, vp, pathname, sizeof (pathname), cred) == 0) {
     2523 +                sz += prfdinfomisc(data, PR_PATHNAME,
     2524 +                    pathname, strlen(pathname));
     2525 +        }
     2526 +        VN_RELE(vrootp);
     2527 +
     2528 +        return (sz);
     2529 +}
     2530 +
     2531 +static size_t
     2532 +prfdinfotlisockopt(vnode_t *vp, list_t *data, cred_t *cred)
     2533 +{
     2534 +        strcmd_t strcmd;
     2535 +        int32_t rval;
     2536 +        size_t sz = 0;
     2537 +
     2538 +        strcmd.sc_cmd = TI_GETMYNAME;
     2539 +        strcmd.sc_timeout = 1;
     2540 +        strcmd.sc_len = STRCMDBUFSIZE;
     2541 +
     2542 +        if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred,
     2543 +            &rval, NULL) == 0 && strcmd.sc_len > 0) {
     2544 +                sz += prfdinfomisc(data, PR_SOCKETNAME, strcmd.sc_buf,
     2545 +                    strcmd.sc_len);
     2546 +        }
     2547 +
     2548 +        strcmd.sc_cmd = TI_GETPEERNAME;
     2549 +        strcmd.sc_timeout = 1;
     2550 +        strcmd.sc_len = STRCMDBUFSIZE;
     2551 +
     2552 +        if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred,
     2553 +            &rval, NULL) == 0 && strcmd.sc_len > 0) {
     2554 +                sz += prfdinfomisc(data, PR_PEERSOCKNAME, strcmd.sc_buf,
     2555 +                    strcmd.sc_len);
     2556 +        }
     2557 +
     2558 +        return (sz);
     2559 +}
     2560 +
     2561 +static size_t
     2562 +prfdinfosockopt(vnode_t *vp, list_t *data, cred_t *cred)
     2563 +{
     2564 +        sonode_t *so;
     2565 +        socklen_t vlen;
     2566 +        size_t sz = 0;
     2567 +        uint_t i;
     2568 +
     2569 +        if (vp->v_stream) {
     2570 +                so = VTOSO(vp->v_stream->sd_vnode);
     2571 +
     2572 +                if (so->so_version == SOV_STREAM)
     2573 +                        so = NULL;
     2574 +        } else {
     2575 +                so = VTOSO(vp);
     2576 +        }
     2577 +
     2578 +        if (so == NULL)
     2579 +                return (0);
     2580 +
     2581 +        DTRACE_PROBE1(sonode, sonode_t *, so);
     2582 +
     2583 +        /* prmisc - PR_SOCKETNAME */
     2584 +
     2585 +        struct sockaddr_storage buf;
     2586 +        struct sockaddr *name = (struct sockaddr *)&buf;
     2587 +
     2588 +        vlen = sizeof (buf);
     2589 +        if (SOP_GETSOCKNAME(so, name, &vlen, cred) == 0 && vlen > 0)
     2590 +                sz += prfdinfomisc(data, PR_SOCKETNAME, name, vlen);
     2591 +
     2592 +        /* prmisc - PR_PEERSOCKNAME */
     2593 +
     2594 +        vlen = sizeof (buf);
     2595 +        if (SOP_GETPEERNAME(so, name, &vlen, B_FALSE, cred) == 0 && vlen > 0)
     2596 +                sz += prfdinfomisc(data, PR_PEERSOCKNAME, name, vlen);
     2597 +
     2598 +        /* prmisc - PR_SOCKOPTS_BOOL_OPTS */
     2599 +
     2600 +        static struct boolopt {
     2601 +                int             level;
     2602 +                int             opt;
     2603 +                int             bopt;
     2604 +        } boolopts[] = {
     2605 +                { SOL_SOCKET, SO_DEBUG,         PR_SO_DEBUG },
     2606 +                { SOL_SOCKET, SO_REUSEADDR,     PR_SO_REUSEADDR },
     2607 +#ifdef SO_REUSEPORT
     2608 +                /* SmartOS and OmniOS have SO_REUSEPORT */
     2609 +                { SOL_SOCKET, SO_REUSEPORT,     PR_SO_REUSEPORT },
     2610 +#endif
     2611 +                { SOL_SOCKET, SO_KEEPALIVE,     PR_SO_KEEPALIVE },
     2612 +                { SOL_SOCKET, SO_DONTROUTE,     PR_SO_DONTROUTE },
     2613 +                { SOL_SOCKET, SO_BROADCAST,     PR_SO_BROADCAST },
     2614 +                { SOL_SOCKET, SO_OOBINLINE,     PR_SO_OOBINLINE },
     2615 +                { SOL_SOCKET, SO_DGRAM_ERRIND,  PR_SO_DGRAM_ERRIND },
     2616 +                { SOL_SOCKET, SO_ALLZONES,      PR_SO_ALLZONES },
     2617 +                { SOL_SOCKET, SO_MAC_EXEMPT,    PR_SO_MAC_EXEMPT },
     2618 +                { SOL_SOCKET, SO_MAC_IMPLICIT,  PR_SO_MAC_IMPLICIT },
     2619 +                { SOL_SOCKET, SO_EXCLBIND,      PR_SO_EXCLBIND },
     2620 +                { SOL_SOCKET, SO_VRRP,          PR_SO_VRRP },
     2621 +                { IPPROTO_UDP, UDP_NAT_T_ENDPOINT,
     2622 +                    PR_UDP_NAT_T_ENDPOINT }
     2623 +        };
     2624 +        prsockopts_bool_opts_t opts;
     2625 +        int val;
     2626 +
     2627 +        if (data != NULL) {
     2628 +                opts.prsock_bool_opts = 0;
     2629 +
     2630 +                for (i = 0; i < sizeof (boolopts) / sizeof (boolopts[0]);
     2631 +                    i++) {
     2632 +                        vlen = sizeof (val);
     2633 +                        if (SOP_GETSOCKOPT(so, boolopts[i].level,
     2634 +                            boolopts[i].opt, &val, &vlen, 0, cred) == 0 &&
     2635 +                            val != 0) {
     2636 +                                opts.prsock_bool_opts |= boolopts[i].bopt;
     2637 +                        }
     2638 +                }
     2639 +        }
     2640 +
     2641 +        sz += prfdinfomisc(data, PR_SOCKOPTS_BOOL_OPTS, &opts, sizeof (opts));
     2642 +
     2643 +        /* prmisc - PR_SOCKOPT_LINGER */
     2644 +
     2645 +        struct linger l;
     2646 +
     2647 +        vlen = sizeof (l);
     2648 +        if (SOP_GETSOCKOPT(so, SOL_SOCKET, SO_LINGER, &l, &vlen,
     2649 +            0, cred) == 0 && vlen > 0) {
     2650 +                sz += prfdinfomisc(data, PR_SOCKOPT_LINGER, &l, vlen);
     2651 +        }
     2652 +
     2653 +        /* prmisc - PR_SOCKOPT_* int types */
     2654 +
     2655 +        static struct sopt {
     2656 +                int             level;
     2657 +                int             opt;
     2658 +                int             bopt;
     2659 +        } sopts[] = {
     2660 +                { SOL_SOCKET, SO_TYPE,          PR_SOCKOPT_TYPE },
     2661 +                { SOL_SOCKET, SO_SNDBUF,        PR_SOCKOPT_SNDBUF },
     2662 +                { SOL_SOCKET, SO_RCVBUF,        PR_SOCKOPT_RCVBUF }
     2663 +        };
     2664 +
     2665 +        for (i = 0; i < sizeof (sopts) / sizeof (sopts[0]); i++) {
     2666 +                vlen = sizeof (val);
     2667 +                if (SOP_GETSOCKOPT(so, sopts[i].level, sopts[i].opt,
     2668 +                    &val, &vlen, 0, cred) == 0 && vlen > 0) {
     2669 +                        sz += prfdinfomisc(data, sopts[i].bopt, &val, vlen);
     2670 +                }
     2671 +        }
     2672 +
     2673 +        /* prmisc - PR_SOCKOPT_IP_NEXTHOP */
     2674 +
     2675 +        in_addr_t nexthop_val;
     2676 +
     2677 +        vlen = sizeof (nexthop_val);
     2678 +        if (SOP_GETSOCKOPT(so, IPPROTO_IP, IP_NEXTHOP,
     2679 +            &nexthop_val, &vlen, 0, cred) == 0 && vlen > 0) {
     2680 +                sz += prfdinfomisc(data, PR_SOCKOPT_IP_NEXTHOP,
     2681 +                    &nexthop_val, vlen);
     2682 +        }
     2683 +
     2684 +        /* prmisc - PR_SOCKOPT_IPV6_NEXTHOP */
     2685 +
     2686 +        struct sockaddr_in6 nexthop6_val;
     2687 +
     2688 +        vlen = sizeof (nexthop6_val);
     2689 +        if (SOP_GETSOCKOPT(so, IPPROTO_IPV6, IPV6_NEXTHOP,
     2690 +            &nexthop6_val, &vlen, 0, cred) == 0 && vlen > 0) {
     2691 +                sz += prfdinfomisc(data, PR_SOCKOPT_IPV6_NEXTHOP,
     2692 +                    &nexthop6_val, vlen);
     2693 +        }
     2694 +
     2695 +        /* prmisc - PR_SOCKOPT_TCP_CONGESTION */
     2696 +
     2697 +        char cong[CC_ALGO_NAME_MAX];
     2698 +
     2699 +        vlen = sizeof (cong);
     2700 +        if (SOP_GETSOCKOPT(so, IPPROTO_TCP, TCP_CONGESTION,
     2701 +            &cong, &vlen, 0, cred) == 0 && vlen > 0) {
     2702 +                sz += prfdinfomisc(data, PR_SOCKOPT_TCP_CONGESTION, cong, vlen);
     2703 +        }
     2704 +
     2705 +        /* prmisc - PR_SOCKFILTERS_PRIV */
     2706 +
     2707 +        struct fil_info fi;
     2708 +
     2709 +        vlen = sizeof (fi);
     2710 +        if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST,
     2711 +            &fi, &vlen, 0, cred) == 0 && vlen != 0) {
     2712 +                pr_misc_header_t *misc;
     2713 +                size_t len;
     2714 +
     2715 +                /*
     2716 +                 * We limit the number of returned filters to 32.
     2717 +                 * This is the maximum number that pfiles will print
     2718 +                 * anyway.
     2719 +                 */
     2720 +                vlen = MIN(32, fi.fi_pos + 1);
     2721 +                vlen *= sizeof (fi);
     2722 +
     2723 +                len = sizeof (*misc) + vlen;
     2724 +                sz += len;
     2725 +
     2726 +                if (data != NULL) {
     2727 +                        misc = pr_iol_newbuf(data, len);
     2728 +                        misc->pr_misc_type = PR_SOCKFILTERS_PRIV;
     2729 +                        misc->pr_misc_size = len;
     2730 +                        misc++;
     2731 +                        len = vlen;
     2732 +                        if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST,
     2733 +                            misc, &vlen, 0, cred) == 0) {
     2734 +                                /*
     2735 +                                 * In case the number of filters has reduced
     2736 +                                 * since the first call, explicitly zero out
     2737 +                                 * any unpopulated space.
     2738 +                                 */
     2739 +                                if (vlen < len)
     2740 +                                        bzero(misc + vlen, len - vlen);
     2741 +                        } else {
     2742 +                                /* Something went wrong, zero out the result */
     2743 +                                bzero(misc, vlen);
     2744 +                        }
     2745 +                }
     2746 +        }
     2747 +
     2748 +        return (sz);
     2749 +}
     2750 +
     2751 +u_offset_t
     2752 +prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred)
     2753 +{
     2754 +        u_offset_t sz;
     2755 +
     2756 +        /*
     2757 +         * All fdinfo files will be at least this big -
     2758 +         * sizeof fdinfo struct + zero length trailer
     2759 +         */
     2760 +        sz = offsetof(prfdinfov2_t, pr_misc) + sizeof (pr_misc_header_t);
     2761 +
     2762 +        /* Pathname */
     2763 +        if (vp->v_type != VSOCK && vp->v_type != VDOOR)
     2764 +                sz += prfdinfopath(p, vp, NULL, cred);
     2765 +
     2766 +        /* Socket options */
     2767 +        if (vp->v_type == VSOCK)
     2768 +                sz += prfdinfosockopt(vp, NULL, cred);
     2769 +
     2770 +        /* TLI/XTI sockets */
     2771 +        if (vp->v_type == VCHR && pristli(vp) && vp->v_stream != NULL)
     2772 +                sz += prfdinfotlisockopt(vp, NULL, cred);
     2773 +
     2774 +        return (sz);
     2775 +}
     2776 +
     2777 +int
     2778 +prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfov2_t *fdinfo, cred_t *cred,
     2779 +    list_t *data)
     2780 +{
     2781 +        vattr_t vattr;
     2782 +        int error;
     2783 +
     2784 +        if (vp == NULL)
     2785 +                return (ENOENT);
     2786 +
     2787 +        /*
     2788 +         * Initialise defaults for values that do not default to zero.
     2789 +         */
     2790 +        fdinfo->pr_uid = (uid_t)-1;
     2791 +        fdinfo->pr_gid = (gid_t)-1;
     2792 +        fdinfo->pr_size = -1;
     2793 +        fdinfo->pr_locktype = F_UNLCK;
     2794 +        fdinfo->pr_lockpid = -1;
     2795 +        fdinfo->pr_locksysid = -1;
     2796 +        fdinfo->pr_peerpid = -1;
     2797 +
     2798 +        /* Offset */
     2799 +
     2800 +        switch (vp->v_type) {
     2801 +        case VFIFO:
     2802 +        case VDOOR:
     2803 +        case VSOCK:
     2804 +                /* Do not provide an offset for these file types */
     2805 +                fdinfo->pr_offset = -1;
     2806 +                break;
     2807 +        }
     2808 +
     2809 +        /* Attributes */
     2810 +        vattr.va_mask = AT_STAT;
     2811 +        if (VOP_GETATTR(vp, &vattr, 0, cred, NULL) == 0) {
     2812 +                fdinfo->pr_major = getmajor(vattr.va_fsid);
     2813 +                fdinfo->pr_minor = getminor(vattr.va_fsid);
     2814 +                fdinfo->pr_rmajor = getmajor(vattr.va_rdev);
     2815 +                fdinfo->pr_rminor = getminor(vattr.va_rdev);
     2816 +                fdinfo->pr_ino = (ino64_t)vattr.va_nodeid;
     2817 +                fdinfo->pr_size = (off64_t)vattr.va_size;
     2818 +                fdinfo->pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode;
     2819 +                fdinfo->pr_uid = vattr.va_uid;
     2820 +                fdinfo->pr_gid = vattr.va_gid;
     2821 +                if (vp->v_type == VSOCK)
     2822 +                        fdinfo->pr_fileflags |= sock_getfasync(vp);
     2823 +        }
     2824 +
     2825 +        /* locks */
     2826 +
     2827 +        flock64_t bf;
     2828 +
     2829 +        bzero(&bf, sizeof (bf));
     2830 +        bf.l_type = F_WRLCK;
     2831 +
     2832 +        if (VOP_FRLOCK(vp, F_GETLK, &bf,
     2833 +            (uint16_t)(fdinfo->pr_fileflags & 0xffff), 0, NULL,
     2834 +            cred, NULL) == 0 && bf.l_type != F_UNLCK) {
     2835 +                fdinfo->pr_locktype = bf.l_type;
     2836 +                fdinfo->pr_lockpid = bf.l_pid;
     2837 +                fdinfo->pr_locksysid = bf.l_sysid;
     2838 +        }
     2839 +
     2840 +        /* peer cred */
     2841 +
     2842 +        k_peercred_t kpc;
     2843 +
     2844 +        switch (vp->v_type) {
     2845 +        case VFIFO:
     2846 +        case VSOCK: {
     2847 +                int32_t rval;
     2848 +
     2849 +                error = VOP_IOCTL(vp, _I_GETPEERCRED, (intptr_t)&kpc,
     2850 +                    FKIOCTL, cred, &rval, NULL);
     2851 +                break;
     2852 +        }
     2853 +        case VCHR: {
     2854 +                struct strioctl strioc;
     2855 +                int32_t rval;
     2856 +
     2857 +                if (vp->v_stream == NULL) {
     2858 +                        error = ENOTSUP;
     2859 +                        break;
     2860 +                }
     2861 +                strioc.ic_cmd = _I_GETPEERCRED;
     2862 +                strioc.ic_timout = INFTIM;
     2863 +                strioc.ic_len = (int)sizeof (k_peercred_t);
     2864 +                strioc.ic_dp = (char *)&kpc;
     2865 +
     2866 +                error = strdoioctl(vp->v_stream, &strioc, FNATIVE | FKIOCTL,
     2867 +                    STR_NOSIG | K_TO_K, cred, &rval);
     2868 +                break;
     2869 +        }
     2870 +        default:
     2871 +                error = ENOTSUP;
     2872 +        }
     2873 +
     2874 +        if (error == 0 && kpc.pc_cr != NULL) {
     2875 +                proc_t *peerp;
     2876 +
     2877 +                fdinfo->pr_peerpid = kpc.pc_cpid;
     2878 +
     2879 +                crfree(kpc.pc_cr);
     2880 +
     2881 +                mutex_enter(&pidlock);
     2882 +                if ((peerp = prfind(fdinfo->pr_peerpid)) != NULL) {
     2883 +                        user_t *up;
     2884 +
     2885 +                        mutex_enter(&peerp->p_lock);
     2886 +                        mutex_exit(&pidlock);
     2887 +
     2888 +                        up = PTOU(peerp);
     2889 +                        bcopy(up->u_comm, fdinfo->pr_peername,
     2890 +                            MIN(sizeof (up->u_comm),
     2891 +                            sizeof (fdinfo->pr_peername) - 1));
     2892 +
     2893 +                        mutex_exit(&peerp->p_lock);
     2894 +                } else {
     2895 +                        mutex_exit(&pidlock);
     2896 +                }
     2897 +        }
     2898 +
     2899 +        /*
     2900 +         * Don't attempt to determine the vnode path for a socket or a door
     2901 +         * as it will cause a linear scan of the dnlc table given there is no
     2902 +         * v_path associated with the vnode.
     2903 +         */
     2904 +        if (vp->v_type != VSOCK && vp->v_type != VDOOR)
     2905 +                (void) prfdinfopath(p, vp, data, cred);
     2906 +
     2907 +        if (vp->v_type == VSOCK)
     2908 +                (void) prfdinfosockopt(vp, data, cred);
     2909 +
     2910 +        /* TLI/XTI stream sockets */
     2911 +        if (vp->v_type == VCHR && pristli(vp) && vp->v_stream != NULL)
     2912 +                (void) prfdinfotlisockopt(vp, data, cred);
     2913 +
     2914 +        /*
     2915 +         * Add a terminating record with a zero size (pr_iol_newbuf will
     2916 +         * bzero the memory)
     2917 +         */
     2918 +        (void) pr_iol_newbuf(data, sizeof (pr_misc_header_t));
     2919 +
     2920 +        return (0);
     2921 +}
     2922 +
2378 2923  #ifdef _SYSCALL32_IMPL
2379 2924  void
2380 2925  prgetpsinfo32(proc_t *p, psinfo32_t *psp)
2381 2926  {
2382 2927          kthread_t *t;
2383 2928          struct cred *cred;
2384 2929          hrtime_t hrutime, hrstime;
2385 2930  
2386 2931          ASSERT(MUTEX_HELD(&p->p_lock));
2387 2932  
↓ open down ↓ 275 lines elided ↑ open up ↑
2663 3208  #define PR_COPY_FIELD(s, d, field)       d->field = s->field
2664 3209  
2665 3210  #define PR_COPY_FIELD_ILP32(s, d, field)                                \
2666 3211          if (s->pr_dmodel == PR_MODEL_ILP32) {                   \
2667 3212                  d->field = s->field;                            \
2668 3213          }
2669 3214  
2670 3215  #define PR_COPY_TIMESPEC(s, d, field)                           \
2671 3216          TIMESPEC_TO_TIMESPEC32(&d->field, &s->field);
2672 3217  
2673      -#define PR_COPY_BUF(s, d, field)                                \
     3218 +#define PR_COPY_BUF(s, d, field)                                \
2674 3219          bcopy(s->field, d->field, sizeof (d->field));
2675 3220  
2676 3221  #define PR_IGNORE_FIELD(s, d, field)
2677 3222  
2678 3223  void
2679 3224  lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest)
2680 3225  {
2681 3226          bzero(dest, sizeof (*dest));
2682 3227  
2683 3228          PR_COPY_FIELD(src, dest, pr_flag);
↓ open down ↓ 1694 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX