KVM method support for procstat_getgroups, procstat_getumask,
procstat_getrlimit, and procstat_getosrel. MFC after: 3 weeks
This commit is contained in:
parent
a5058251d5
commit
49b0478cb5
@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/elf.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#define _WANT_UCRED
|
||||
#include <sys/ucred.h>
|
||||
#undef _WANT_UCRED
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/stat.h>
|
||||
@ -141,19 +144,30 @@ static int procstat_get_vnode_info_sysctl(struct filestat *fst,
|
||||
struct vnstat *vn, char *errbuf);
|
||||
static gid_t *procstat_getgroups_core(struct procstat_core *core,
|
||||
unsigned int *count);
|
||||
static gid_t * procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp,
|
||||
unsigned int *count);
|
||||
static gid_t *procstat_getgroups_sysctl(pid_t pid, unsigned int *count);
|
||||
static struct kinfo_kstack *procstat_getkstack_sysctl(pid_t pid,
|
||||
int *cntp);
|
||||
static int procstat_getosrel_core(struct procstat_core *core,
|
||||
int *osrelp);
|
||||
static int procstat_getosrel_kvm(kvm_t *kd, struct kinfo_proc *kp,
|
||||
int *osrelp);
|
||||
static int procstat_getosrel_sysctl(pid_t pid, int *osrelp);
|
||||
static int procstat_getpathname_core(struct procstat_core *core,
|
||||
char *pathname, size_t maxlen);
|
||||
static int procstat_getpathname_sysctl(pid_t pid, char *pathname,
|
||||
size_t maxlen);
|
||||
static int procstat_getrlimit_core(struct procstat_core *core, int which,
|
||||
struct rlimit* rlimit);
|
||||
static int procstat_getrlimit_kvm(kvm_t *kd, struct kinfo_proc *kp,
|
||||
int which, struct rlimit* rlimit);
|
||||
static int procstat_getrlimit_sysctl(pid_t pid, int which,
|
||||
struct rlimit* rlimit);
|
||||
static int procstat_getumask_core(struct procstat_core *core,
|
||||
unsigned short *maskp);
|
||||
static int procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp,
|
||||
unsigned short *maskp);
|
||||
static int procstat_getumask_sysctl(pid_t pid, unsigned short *maskp);
|
||||
static int vntype2psfsttype(int type);
|
||||
|
||||
@ -1789,6 +1803,46 @@ procstat_freevmmap(struct procstat *procstat __unused,
|
||||
free(vmmap);
|
||||
}
|
||||
|
||||
static gid_t *
|
||||
procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp)
|
||||
{
|
||||
struct proc proc;
|
||||
struct ucred ucred;
|
||||
gid_t *groups;
|
||||
size_t len;
|
||||
|
||||
assert(kd != NULL);
|
||||
assert(kp != NULL);
|
||||
if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc,
|
||||
sizeof(proc))) {
|
||||
warnx("can't read proc struct at %p for pid %d",
|
||||
kp->ki_paddr, kp->ki_pid);
|
||||
return (NULL);
|
||||
}
|
||||
if (proc.p_ucred == NOCRED)
|
||||
return (NULL);
|
||||
if (!kvm_read_all(kd, (unsigned long)proc.p_ucred, &ucred,
|
||||
sizeof(ucred))) {
|
||||
warnx("can't read ucred struct at %p for pid %d",
|
||||
proc.p_ucred, kp->ki_pid);
|
||||
return (NULL);
|
||||
}
|
||||
len = ucred.cr_ngroups * sizeof(gid_t);
|
||||
groups = malloc(len);
|
||||
if (groups == NULL) {
|
||||
warn("malloc(%zu)", len);
|
||||
return (NULL);
|
||||
}
|
||||
if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups, len)) {
|
||||
warnx("can't read groups at %p for pid %d",
|
||||
ucred.cr_groups, kp->ki_pid);
|
||||
free(groups);
|
||||
return (NULL);
|
||||
}
|
||||
*cntp = ucred.cr_ngroups;
|
||||
return (groups);
|
||||
}
|
||||
|
||||
static gid_t *
|
||||
procstat_getgroups_sysctl(pid_t pid, unsigned int *cntp)
|
||||
{
|
||||
@ -1834,8 +1888,7 @@ procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
{
|
||||
switch(procstat->type) {
|
||||
case PROCSTAT_KVM:
|
||||
warnx("kvm method is not supported");
|
||||
return (NULL);
|
||||
return (procstat_getgroups_kvm(procstat->kd, kp, cntp));
|
||||
case PROCSTAT_SYSCTL:
|
||||
return (procstat_getgroups_sysctl(kp->ki_pid, cntp));
|
||||
case PROCSTAT_CORE:
|
||||
@ -1853,6 +1906,24 @@ procstat_freegroups(struct procstat *procstat __unused, gid_t *groups)
|
||||
free(groups);
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned short *maskp)
|
||||
{
|
||||
struct filedesc fd;
|
||||
|
||||
assert(kd != NULL);
|
||||
assert(kp != NULL);
|
||||
if (kp->ki_fd == NULL)
|
||||
return (-1);
|
||||
if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &fd, sizeof(fd))) {
|
||||
warnx("can't read filedesc at %p for pid %d", kp->ki_fd,
|
||||
kp->ki_pid);
|
||||
return (-1);
|
||||
}
|
||||
*maskp = fd.fd_cmask;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getumask_sysctl(pid_t pid, unsigned short *maskp)
|
||||
{
|
||||
@ -1895,8 +1966,7 @@ procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
{
|
||||
switch(procstat->type) {
|
||||
case PROCSTAT_KVM:
|
||||
warnx("kvm method is not supported");
|
||||
return (-1);
|
||||
return (procstat_getumask_kvm(procstat->kd, kp, maskp));
|
||||
case PROCSTAT_SYSCTL:
|
||||
return (procstat_getumask_sysctl(kp->ki_pid, maskp));
|
||||
case PROCSTAT_CORE:
|
||||
@ -1907,6 +1977,33 @@ procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getrlimit_kvm(kvm_t *kd, struct kinfo_proc *kp, int which,
|
||||
struct rlimit* rlimit)
|
||||
{
|
||||
struct proc proc;
|
||||
unsigned long offset;
|
||||
|
||||
assert(kd != NULL);
|
||||
assert(kp != NULL);
|
||||
assert(which >= 0 && which < RLIM_NLIMITS);
|
||||
if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc,
|
||||
sizeof(proc))) {
|
||||
warnx("can't read proc struct at %p for pid %d",
|
||||
kp->ki_paddr, kp->ki_pid);
|
||||
return (-1);
|
||||
}
|
||||
if (proc.p_limit == NULL)
|
||||
return (-1);
|
||||
offset = (unsigned long)proc.p_limit + sizeof(struct rlimit) * which;
|
||||
if (!kvm_read_all(kd, offset, rlimit, sizeof(*rlimit))) {
|
||||
warnx("can't read rlimit struct at %p for pid %d",
|
||||
(void *)offset, kp->ki_pid);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getrlimit_sysctl(pid_t pid, int which, struct rlimit* rlimit)
|
||||
{
|
||||
@ -1958,8 +2055,8 @@ procstat_getrlimit(struct procstat *procstat, struct kinfo_proc *kp, int which,
|
||||
{
|
||||
switch(procstat->type) {
|
||||
case PROCSTAT_KVM:
|
||||
warnx("kvm method is not supported");
|
||||
return (-1);
|
||||
return (procstat_getrlimit_kvm(procstat->kd, kp, which,
|
||||
rlimit));
|
||||
case PROCSTAT_SYSCTL:
|
||||
return (procstat_getrlimit_sysctl(kp->ki_pid, which, rlimit));
|
||||
case PROCSTAT_CORE:
|
||||
@ -2031,6 +2128,23 @@ procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getosrel_kvm(kvm_t *kd, struct kinfo_proc *kp, int *osrelp)
|
||||
{
|
||||
struct proc proc;
|
||||
|
||||
assert(kd != NULL);
|
||||
assert(kp != NULL);
|
||||
if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc,
|
||||
sizeof(proc))) {
|
||||
warnx("can't read proc struct at %p for pid %d",
|
||||
kp->ki_paddr, kp->ki_pid);
|
||||
return (-1);
|
||||
}
|
||||
*osrelp = proc.p_osrel;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
procstat_getosrel_sysctl(pid_t pid, int *osrelp)
|
||||
{
|
||||
@ -2071,8 +2185,7 @@ procstat_getosrel(struct procstat *procstat, struct kinfo_proc *kp, int *osrelp)
|
||||
{
|
||||
switch(procstat->type) {
|
||||
case PROCSTAT_KVM:
|
||||
warnx("kvm method is not supported");
|
||||
return (-1);
|
||||
return (procstat_getosrel_kvm(procstat->kd, kp, osrelp));
|
||||
case PROCSTAT_SYSCTL:
|
||||
return (procstat_getosrel_sysctl(kp->ki_pid, osrelp));
|
||||
case PROCSTAT_CORE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user