aboutsummaryrefslogtreecommitdiff
path: root/lib/libprocstat
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2022-04-03 14:42:03 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2022-04-09 21:47:49 +0000
commit039d1496b0790a27cbec18e06b9494bf41254019 (patch)
treefe51d2abfb5c8b85ba4c39cc2cc4b54fdeb69a65 /lib/libprocstat
parenteca39864f702e577eba3bc7e9992d1e5e56eba58 (diff)
Diffstat (limited to 'lib/libprocstat')
-rw-r--r--lib/libprocstat/Symbol.map5
-rw-r--r--lib/libprocstat/libprocstat.c135
-rw-r--r--lib/libprocstat/libprocstat.h26
3 files changed, 166 insertions, 0 deletions
diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map
index cea784900536..3d0f37b5981e 100644
--- a/lib/libprocstat/Symbol.map
+++ b/lib/libprocstat/Symbol.map
@@ -44,3 +44,8 @@ FBSD_1.6 {
procstat_get_pts_info;
procstat_get_vnode_info;
};
+
+FBSD_1.7 {
+ procstat_getadvlock;
+ procstat_freeadvlock;
+}; \ No newline at end of file
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 850d37598423..5948bf72230d 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -2644,3 +2644,138 @@ procstat_freekstack(struct procstat *procstat __unused,
free(kkstp);
}
+
+static struct advlock_list *
+procstat_getadvlock_sysctl(struct procstat *procstat __unused)
+{
+ struct advlock_list *res;
+ struct advlock *a;
+ void *buf;
+ char *c;
+ struct kinfo_lockf *kl;
+ size_t buf_len;
+ int error;
+ static const int kl_name[] = { CTL_KERN, KERN_LOCKF };
+
+ res = malloc(sizeof(*res));
+ if (res == NULL)
+ return (NULL);
+ STAILQ_INIT(res);
+ buf = NULL;
+
+ buf_len = 0;
+ error = sysctl(kl_name, nitems(kl_name), NULL, &buf_len, NULL, 0);
+ if (error != 0) {
+ warn("sysctl KERN_LOCKF size");
+ goto fail;
+ }
+ buf_len *= 2;
+ buf = malloc(buf_len);
+ if (buf == NULL) {
+ warn("malloc");
+ goto fail;
+ }
+ error = sysctl(kl_name, nitems(kl_name), buf, &buf_len, NULL, 0);
+ if (error != 0) {
+ warn("sysctl KERN_LOCKF data");
+ goto fail;
+ }
+
+ for (c = buf; (char *)c < (char *)buf + buf_len;
+ c += kl->kl_structsize) {
+ kl = (struct kinfo_lockf *)(void *)c;
+ if (sizeof(*kl) < (size_t)kl->kl_structsize) {
+ warn("ABI broken");
+ goto fail;
+ }
+ a = malloc(sizeof(*a));
+ if (a == NULL) {
+ warn("malloc advlock");
+ goto fail;
+ }
+ switch (kl->kl_rw) {
+ case KLOCKF_RW_READ:
+ a->rw = PS_ADVLOCK_RO;
+ break;
+ case KLOCKF_RW_WRITE:
+ a->rw = PS_ADVLOCK_RW;
+ break;
+ default:
+ warn("ABI broken");
+ free(a);
+ goto fail;
+ }
+ switch (kl->kl_type) {
+ case KLOCKF_TYPE_FLOCK:
+ a->type = PS_ADVLOCK_TYPE_FLOCK;
+ break;
+ case KLOCKF_TYPE_PID:
+ a->type = PS_ADVLOCK_TYPE_PID;
+ break;
+ case KLOCKF_TYPE_REMOTE:
+ a->type = PS_ADVLOCK_TYPE_REMOTE;
+ break;
+ default:
+ warn("ABI broken");
+ free(a);
+ goto fail;
+ }
+ a->pid = kl->kl_pid;
+ a->sysid = kl->kl_sysid;
+ a->file_fsid = kl->kl_file_fsid;
+ a->file_rdev = kl->kl_file_rdev;
+ a->file_fileid = kl->kl_file_fileid;
+ a->start = kl->kl_start;
+ a->len = kl->kl_len;
+ if (kl->kl_path[0] != '\0') {
+ a->path = strdup(kl->kl_path);
+ if (a->path == NULL) {
+ warn("malloc");
+ free(a);
+ goto fail;
+ }
+ } else
+ a->path = NULL;
+ STAILQ_INSERT_TAIL(res, a, next);
+ }
+
+ free(buf);
+ return (res);
+
+fail:
+ free(buf);
+ procstat_freeadvlock(procstat, res);
+ return (NULL);
+}
+
+struct advlock_list *
+procstat_getadvlock(struct procstat *procstat)
+{
+ switch(procstat->type) {
+ case PROCSTAT_KVM:
+ warnx("kvm method is not supported");
+ return (NULL);
+ case PROCSTAT_SYSCTL:
+ return (procstat_getadvlock_sysctl(procstat));
+ case PROCSTAT_CORE:
+ warnx("core method is not supported");
+ return (NULL);
+ default:
+ warnx("unknown access method: %d", procstat->type);
+ return (NULL);
+ }
+}
+
+void
+procstat_freeadvlock(struct procstat *procstat __unused,
+ struct advlock_list *lst)
+{
+ struct advlock *a, *a1;
+
+ STAILQ_FOREACH_SAFE(a, lst, next, a1) {
+ free(__DECONST(char *, a->path));
+ free(a);
+ }
+ free(lst);
+}
+
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index 0624ec5289d4..8736870d163e 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -168,8 +168,33 @@ struct sockstat {
STAILQ_HEAD(filestat_list, filestat);
+struct advlock {
+ int rw; /* PS_ADVLOCK_RO/RW */
+ int type; /* PS_ADVLOCK_TYPE_ */
+ int pid;
+ int sysid;
+ uint64_t file_fsid;
+ uint64_t file_rdev;
+ uint64_t file_fileid;
+ off_t start;
+ off_t len; /* len == 0 till the EOF */
+ const char *path;
+ STAILQ_ENTRY(advlock) next;
+};
+
+#define PS_ADVLOCK_RO 0x01
+#define PS_ADVLOCK_RW 0x02
+
+#define PS_ADVLOCK_TYPE_FLOCK 0x01
+#define PS_ADVLOCK_TYPE_PID 0x02
+#define PS_ADVLOCK_TYPE_REMOTE 0x03
+
+STAILQ_HEAD(advlock_list, advlock);
+
__BEGIN_DECLS
void procstat_close(struct procstat *procstat);
+void procstat_freeadvlock(struct procstat *procstat,
+ struct advlock_list *advlocks);
void procstat_freeargv(struct procstat *procstat);
#ifndef ZFS
void procstat_freeauxv(struct procstat *procstat, Elf_Auxinfo *auxv);
@@ -185,6 +210,7 @@ void procstat_freeptlwpinfo(struct procstat *procstat,
struct ptrace_lwpinfo *pl);
void procstat_freevmmap(struct procstat *procstat,
struct kinfo_vmentry *vmmap);
+struct advlock_list *procstat_getadvlock(struct procstat *procstat);
struct filestat_list *procstat_getfiles(struct procstat *procstat,
struct kinfo_proc *kp, int mmapped);
struct kinfo_proc *procstat_getprocs(struct procstat *procstat,