root/sys/miscfs/procfs/procfs.h
/*      $NetBSD: procfs.h,v 1.87 2024/07/01 01:35:53 christos Exp $     */

/*
 * Copyright (c) 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Jan-Simon Pendry.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)procfs.h    8.9 (Berkeley) 5/14/95
 */

/*
 * Copyright (c) 1993 Jan-Simon Pendry
 *
 * This code is derived from software contributed to Berkeley by
 * Jan-Simon Pendry.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)procfs.h    8.9 (Berkeley) 5/14/95
 */

/* This also pulls in __HAVE_PROCFS_MACHDEP */
#include <sys/ptrace.h>

#ifdef _KERNEL
#include <sys/proc.h>

/*
 * The different types of node in a procfs filesystem
 */
typedef enum {
        PFSauxv,        /* ELF Auxiliary Vector */
        PFSchroot,      /* the process's current root directory */
        PFScmdline,     /* process command line args */
        PFScpuinfo,     /* CPU info (if -o linux) */
        PFScpustat,     /* status info (if -o linux) */
        PFScurproc,     /* symbolic link for curproc */
        PFScwd,         /* the process's current working directory */
        PFSdevices,     /* major/device name mappings (if -o linux) */
        PFSemul,        /* the process's emulation */
        PFSenviron,     /* process environment */
        PFSexe,         /* symlink to the executable file */
        PFSfd,          /* a directory containing the processes open fd's */
        PFSfile,        /* the executable file */
        PFSfpregs,      /* the process's FP register set */
        PFSloadavg,     /* load average (if -o linux) */
        PFSlimit,       /* resource limits */
        PFSlimits,      /* resource limits, Linux style (if -o linux) */
        PFSmap,         /* memory map */
        PFSmaps,        /* memory map, Linux style (if -o linux) */
        PFSmem,         /* the process's memory image */
        PFSmeminfo,     /* system memory info (if -o linux) */
        PFSmounts,      /* mounted filesystems (if -o linux) */
        PFSmqueue,      /* sys/fs/mqueue subdirectory (if -o linux) */
        PFSmq_msg_def,  /* sys/fs/mqueue/msg_default (if -o linux) */
        PFSmq_msg_max,  /* sys/fs/mqueue/msg_max (if -o linux) */
        PFSmq_siz_def,  /* sys/fs/mqueue/msgsize_default (if -o linux) */
        PFSmq_siz_max,  /* sys/fs/mqueue/msgsize_max (if -o linux) */
        PFSmq_qmax,     /* sys/fs/mqueue/queues_max (if -o linux) */
        PFSnote,        /* process notifier */
        PFSnotepg,      /* process group notifier */
        PFSproc,        /* a process-specific sub-directory */
        PFSregs,        /* the process's register set */
        PFSroot,        /* the filesystem root */
        PFSself,        /* like curproc, but this is the Linux name */
        PFSstat,        /* process status (if -o linux) */
        PFSstatm,       /* process memory info (if -o linux) */
        PFSstatus,      /* process status */
        PFSsys,         /* sys subdirectory (if -o linux) */
        PFSsysfs,       /* sys/fs subdirectory (if -o linux) */
        PFSsysvipc,     /* sysvipc subdirectory (if -o linux) */
        PFSsysvipc_msg, /* sysvipc msg info (if -o linux) */
        PFSsysvipc_sem, /* sysvipc sem info (if -o linux) */
        PFSsysvipc_shm, /* sysvipc shm info (if -o linux) */
        PFStask,        /* task subdirectory (if -o linux) */
        PFSuptime,      /* elapsed time since (if -o linux) */
        PFSversion,     /* kernel version (if -o linux) */
#ifdef __HAVE_PROCFS_MACHDEP
        PROCFS_MACHDEP_NODE_TYPES
#endif
        PFSlast,        /* track number of types */
} pfstype;

/*
 * control data for the proc file system.
 */
struct pfskey {
        pfstype         pk_type;        /* type of procfs node */
        pid_t           pk_pid;         /* associated process */
        int             pk_fd;          /* associated fd if not -1 */
};
struct pfsnode {
        LIST_ENTRY(pfsnode) pfs_hash;   /* per pid hash list */
        struct vnode    *pfs_vnode;     /* vnode associated with this pfsnode */
        struct mount    *pfs_mount;     /* mount associated with this pfsnode */
        struct pfskey   pfs_key;
#define pfs_type pfs_key.pk_type
#define pfs_pid pfs_key.pk_pid
#define pfs_fd pfs_key.pk_fd
        mode_t          pfs_mode;       /* mode bits for stat() */
        u_long          pfs_flags;      /* open flags */
        uint64_t        pfs_fileno;     /* unique file id */
};

#define PROCFS_NOTELEN  64      /* max length of a note (/proc/$pid/note) */
#define PROCFS_MAXNAMLEN        255

#endif /* _KERNEL */

struct procfs_args {
        int version;
        int flags;
};

#define PROCFS_ARGSVERSION      1

#define PROCFSMNT_LINUXCOMPAT   0x01

#define PROCFSMNT_BITS "\177\20" \
    "b\00linuxcompat\0"

/*
 * Kernel stuff follows
 */
#ifdef _KERNEL
#define CNEQ(cnp, s, len) \
         ((cnp)->cn_namelen == (len) && \
          (memcmp((s), (cnp)->cn_nameptr, (len)) == 0))

#define UIO_MX 32

static __inline ino_t
procfs_fileno(pid_t _pid, pfstype _type, int _fd)
{
        ino_t _ino;
        switch (_type) {
        case PFSroot:
                return 2;
        case PFScurproc:
                return 3;
        case PFSself:
                return 4;
        default:
                _ino = _pid + 1;
                if (_fd != -1)
                        _ino = _ino << 32 | _fd;
                return _ino * PFSlast + _type;
        }
}

#define PROCFS_FILENO(pid, type, fd) procfs_fileno(pid, type, fd)

#define PROCFS_TYPE(type)       ((type) % PFSlast)

struct procfsmount {
        int pmnt_flags;
};

#define VFSTOPROC(mp)   ((struct procfsmount *)(mp)->mnt_data)

/*
 * Convert between pfsnode vnode
 */
#define VTOPFS(vp)      ((struct pfsnode *)(vp)->v_data)
#define PFSTOV(pfs)     ((pfs)->pfs_vnode)

typedef struct vfs_namemap vfs_namemap_t;
struct vfs_namemap {
        const char *nm_name;
        int nm_val;
};

int vfs_getuserstr(struct uio *, char *, int *);
const vfs_namemap_t *vfs_findname(const vfs_namemap_t *, const char *, int);

struct mount;

struct proc *procfs_proc_find(struct mount *, pid_t);
bool procfs_use_linux_compat(struct mount *);

static inline bool
procfs_proc_is_linux_compat(void)
{
        const char *emulname = curlwp->l_proc->p_emul->e_name;
        return (strncmp(emulname, "linux", 5) == 0);
}

int procfs_proc_lock(struct mount *, int, struct proc **, int);
void procfs_proc_unlock(struct proc *);
int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int);
int procfs_donote(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_doregs(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_dofpregs(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_domem(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_do_pid_stat(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_dostatus(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_domap(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *, int);
int procfs_doprocargs(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *, int);
int procfs_domeminfo(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dodevices(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_docpuinfo(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_docpustat(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_doloadavg(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_do_pid_statm(struct lwp *, struct lwp *, struct pfsnode *,
    struct uio *);
int procfs_dofd(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_douptime(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domounts(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_doemul(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_doversion(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_doauxv(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dolimits(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domq_msg_def(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domq_msg_max(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domq_siz_def(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domq_siz_max(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_domq_qmax(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dosysvipc_msg(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dosysvipc_sem(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);
int procfs_dosysvipc_shm(struct lwp *, struct proc *, struct pfsnode *,
    struct uio *);

void procfs_hashrem(struct pfsnode *);
int procfs_getfp(struct pfsnode *, struct proc *, struct file **);

/* functions to check whether or not files should be displayed */
int procfs_validauxv(struct lwp *, struct mount *);
int procfs_validfile(struct lwp *, struct mount *);
int procfs_validfpregs(struct lwp *, struct mount *);
int procfs_validregs(struct lwp *, struct mount *);
int procfs_validmap(struct lwp *, struct mount *);

int procfs_rw(void *);

int procfs_getcpuinfstr(char *, size_t *);

#define PROCFS_LOCKED   0x01
#define PROCFS_WANT     0x02

extern int (**procfs_vnodeop_p)(void *);
extern struct vfsops procfs_vfsops;

int     procfs_root(struct mount *, int, struct vnode **);

#ifdef __HAVE_PROCFS_MACHDEP
struct vattr;

void    procfs_machdep_allocvp(struct vnode *);
int     procfs_machdep_rw(struct lwp *, struct lwp *, struct pfsnode *,
            struct uio *);
int     procfs_machdep_getattr(struct vnode *, struct vattr *, struct proc *);
#endif

#endif /* _KERNEL */