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
43void
44procstat_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