]> git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/lsfd.h
Merge branch 'lsfd--signalfd' of https://github.com/masatake/util-linux
[thirdparty/util-linux.git] / misc-utils / lsfd.h
1 /*
2 * lsfd(1) - list file descriptors
3 *
4 * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
5 * Written by Masatake YAMATO <yamato@redhat.com>
6 *
7 * Very generally based on lsof(8) by Victor A. Abell <abe@purdue.edu>
8 * It supports multiple OSes. lsfd specializes to Linux.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it would be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 #ifndef UTIL_LINUX_LSFD_H
25 #define UTIL_LINUX_LSFD_H
26
27 #include <stdbool.h>
28 #include <sys/stat.h>
29 #include <dirent.h>
30 #include <inttypes.h>
31
32 #include "list.h"
33 #include "path.h"
34 #include "strutils.h"
35
36 /*
37 * column IDs
38 */
39 enum {
40 COL_AINODECLASS,
41 COL_ASSOC,
42 COL_BLKDRV,
43 COL_CHRDRV,
44 COL_COMMAND,
45 COL_DELETED,
46 COL_DEV,
47 COL_DEVTYPE,
48 COL_ENDPOINTS,
49 COL_EVENTFD_ID,
50 COL_EVENTPOLL_TFDS,
51 COL_FD,
52 COL_FLAGS,
53 COL_FUID, /* file */
54 COL_INET_LADDR,
55 COL_INET_RADDR,
56 COL_INET6_LADDR,
57 COL_INET6_RADDR,
58 COL_INODE,
59 COL_KNAME,
60 COL_KTHREAD,
61 COL_MAJMIN,
62 COL_MAPLEN,
63 COL_MISCDEV,
64 COL_MNT_ID,
65 COL_MODE,
66 COL_NAME,
67 COL_NETLINK_GROUPS,
68 COL_NETLINK_LPORT,
69 COL_NETLINK_PROTOCOL,
70 COL_NLINK,
71 COL_NS_NAME,
72 COL_NS_TYPE,
73 COL_OWNER, /* file */
74 COL_PACKET_IFACE,
75 COL_PACKET_PROTOCOL,
76 COL_PARTITION,
77 COL_PID,
78 COL_PIDFD_COMM,
79 COL_PIDFD_NSPID,
80 COL_PIDFD_PID,
81 COL_PING_ID,
82 COL_POS,
83 COL_RAW_PROTOCOL,
84 COL_RDEV,
85 COL_SIGNALFD_MASK,
86 COL_SIZE,
87 COL_SOCK_LISTENING,
88 COL_SOCK_NETNS,
89 COL_SOCK_PROTONAME,
90 COL_SOCK_STATE,
91 COL_SOCK_TYPE,
92 COL_SOURCE,
93 COL_STTYPE,
94 COL_TCP_LADDR,
95 COL_TCP_RADDR,
96 COL_TCP_LPORT,
97 COL_TCP_RPORT,
98 COL_TID,
99 COL_TIMERFD_CLOCKID,
100 COL_TIMERFD_INTERVAL,
101 COL_TIMERFD_REMAINING,
102 COL_TYPE,
103 COL_UDP_LADDR,
104 COL_UDP_RADDR,
105 COL_UDP_LPORT,
106 COL_UDP_RPORT,
107 COL_UDPLITE_LADDR,
108 COL_UDPLITE_RADDR,
109 COL_UDPLITE_LPORT,
110 COL_UDPLITE_RPORT,
111 COL_UID, /* process */
112 COL_UNIX_PATH,
113 COL_USER, /* process */
114 LSFD_N_COLS /* This must be at last. */
115 };
116
117 /*
118 * Process structure
119 */
120 enum association {
121 ASSOC_EXE = 1,
122 ASSOC_CWD,
123 ASSOC_ROOT,
124 ASSOC_NS_CGROUP,
125 ASSOC_NS_IPC,
126 ASSOC_NS_MNT,
127 ASSOC_NS_NET,
128 ASSOC_NS_PID,
129 ASSOC_NS_PID4C,
130 ASSOC_NS_TIME,
131 ASSOC_NS_TIME4C,
132 ASSOC_NS_USER,
133 ASSOC_NS_UTS,
134 ASSOC_MEM, /* private file mapping */
135 ASSOC_SHM, /* shared file mapping */
136 N_ASSOCS,
137 };
138
139 struct proc {
140 pid_t pid;
141 struct proc * leader;
142 char *command;
143 uid_t uid;
144 ino_t ns_mnt;
145 struct list_head procs;
146 struct list_head files;
147 unsigned int kthread: 1;
148 };
149
150 struct proc *get_proc(pid_t pid);
151
152 /*
153 * File class
154 */
155 struct file {
156 struct list_head files;
157 const struct file_class *class;
158 int association;
159 char *name;
160 struct stat stat;
161 mode_t mode;
162 struct proc *proc;
163
164 uint64_t pos;
165 uint64_t map_start;
166 uint64_t map_end;
167
168 unsigned int sys_flags;
169 unsigned int mnt_id;
170 };
171
172 #define is_opened_file(_f) ((_f)->association >= 0)
173 #define is_mapped_file(_f) (is_association((_f), SHM) || is_association((_f), MEM))
174 #define is_association(_f, a) ((_f)->association < 0 && (_f)->association == -ASSOC_ ## a)
175
176 struct file_class {
177 const struct file_class *super;
178 size_t size;
179 void (*initialize_class)(void);
180 void (*finalize_class)(void);
181 bool (*fill_column)(struct proc *proc,
182 struct file *file,
183 struct libscols_line *ln,
184 int column_id,
185 size_t column_index);
186 int (*handle_fdinfo)(struct file *file, const char *key, const char* value);
187 void (*attach_xinfo)(struct file *file);
188 void (*initialize_content)(struct file *file);
189 void (*free_content)(struct file *file);
190 const struct ipc_class *(*get_ipc_class)(struct file *file);
191 };
192
193 extern const struct file_class file_class, cdev_class, bdev_class, sock_class, unkn_class, fifo_class,
194 nsfs_file_class, mqueue_file_class;
195
196 /*
197 * IPC
198 */
199 struct ipc {
200 const struct ipc_class *class;
201 struct list_head endpoints;
202 struct list_head ipcs;
203 };
204
205 struct ipc_endpoint {
206 struct ipc *ipc;
207 struct list_head endpoints;
208 };
209
210 struct ipc_class {
211 size_t size;
212 unsigned int (*get_hash)(struct file *file);
213 bool (*is_suitable_ipc)(struct ipc *ipc, struct file *file);
214 void (*free)(struct ipc *ipc);
215 };
216
217 struct ipc *new_ipc(const struct ipc_class *class);
218 struct ipc *get_ipc(struct file *file);
219 void add_ipc(struct ipc *ipc, unsigned int hash);
220 void init_endpoint(struct ipc_endpoint *endpoint);
221 void add_endpoint(struct ipc_endpoint *endpoint, struct ipc *ipc);
222 #define foreach_endpoint(E,ENDPOINT) list_for_each_backwardly(E, &((ENDPOINT).ipc->endpoints))
223
224 /*
225 * Name managing
226 */
227 struct name_manager;
228
229 struct name_manager *new_name_manager(void);
230 void free_name_manager(struct name_manager *nm);
231 const char *get_name(struct name_manager *nm, unsigned long id);
232 unsigned long add_name(struct name_manager *nm, const char *name);
233
234 const char *get_partition(dev_t dev);
235 const char *get_blkdrv(unsigned long major);
236 const char *get_chrdrv(unsigned long major);
237 const char *get_miscdev(unsigned long minor);
238 const char *get_nodev_filesystem(unsigned long minor);
239 void add_nodev(unsigned long minor, const char *filesystem);
240
241 static inline void xstrappend(char **a, const char *b)
242 {
243 if (strappend(a, b) < 0)
244 err(XALLOC_EXIT_CODE, _("failed to allocate memory for string"));
245 }
246
247 static inline void xstrputc(char **a, char c)
248 {
249 char b[] = {c, '\0'};
250 xstrappend(a, b);
251 }
252
253 /*
254 * Net namespace
255 */
256 void load_sock_xinfo(struct path_cxt *pc, const char *name, ino_t netns);
257 bool is_nsfs_dev(dev_t dev);
258
259 /*
260 * POSIX Mqueue
261 */
262 /* 0 is assumed as the major dev for DEV. */
263 bool is_mqueue_dev(dev_t dev);
264
265 #endif /* UTIL_LINUX_LSFD_H */