1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2022 The FreeBSD Foundation
5  *
6  * Portions of this software were developed by Konstantin Belousov
7  * under sponsorship from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/param.h>
32 #include <sys/sysctl.h>
33 #include <sys/user.h>
34 
35 #include <err.h>
36 #include <libprocstat.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include "procstat.h"
42 
43 void
44 procstat_advlocks(struct procstat *prstat, struct kinfo_proc *kipp __unused)
45 {
46 	struct advlock_list *advl;
47 	struct advlock *a;
48 	static const char advisory_lock_item[] = "advisory_lock";
49 
50 	if ((procstat_opts & PS_OPT_NOHEADER) == 0)
51 		xo_emit("{T:/%2s %5s %5s %5s %18s %18s %8s %9s %9s %s}\n",
52 		    "RW", "TYPE", "PID", "SYSID", "FSID", "RDEV", "INO",
53 		    "START", "LEN", "PATH");
54 
55 	xo_open_list(advisory_lock_item);
56 	advl = procstat_getadvlock(prstat);
57 	if (advl == NULL) {
58 		xo_close_list(advisory_lock_item);
59 		return;
60 	}
61 
62 	STAILQ_FOREACH(a, advl, next) {
63 		xo_open_instance(advisory_lock_item);
64 		switch (a->rw) {
65 		case PS_ADVLOCK_RO:
66 			xo_emit("{:rw/%s} ", "RO");
67 			break;
68 		case PS_ADVLOCK_RW:
69 			xo_emit("{:rw/%s} ", "RW");
70 			break;
71 		default:
72 			xo_emit("{:rw/%s} ", "??");
73 			break;
74 		}
75 		switch (a->type) {
76 		case PS_ADVLOCK_TYPE_FLOCK:
77 			xo_emit("{:type/%s} ", "FLOCK");
78 			break;
79 		case PS_ADVLOCK_TYPE_PID:
80 			xo_emit("{:type/%s} ", "FCNTL");
81 			break;
82 		case PS_ADVLOCK_TYPE_REMOTE:
83 			xo_emit("{:type/%s} ", "LOCKD");
84 			break;
85 		default:
86 			xo_emit("{:type/%s} ", "?????");
87 			break;
88 		}
89 		xo_emit("{:pid/%5d} ", a->pid);
90 		xo_emit("{:sysid/%5d} ", a->sysid);
91 		xo_emit("{:fsid/%18#jx} ", (uintmax_t)a->file_fsid);
92 		xo_emit("{:rdev/%#18jx} ", (uintmax_t)a->file_rdev);
93 		xo_emit("{:ino/%8ju} ", (uintmax_t)a->file_fileid);
94 		xo_emit("{:start/%9ju} ", (uintmax_t)a->start);
95 		xo_emit("{:len/%9ju} ", (uintmax_t)a->len);
96 		xo_emit("{:path/%s}", a->path == NULL ? "" : a->path);
97 		xo_emit("\n");
98 		xo_close_instance(advisory_lock_item);
99 	}
100 	xo_close_list(advisory_lock_item);
101 	procstat_freeadvlock(prstat, advl);
102 }
103