intel_rdt: refactored proc utils to increase efficiency
[collectd.git] / src / utils_proc_pids.h
1 /**
2  * collectd - src/utils_config_pids.h
3  *
4  * Copyright(c) 2018-2019 Intel Corporation. All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *   Starzyk, Mateusz <mateuszx.starzyk@intel.com>
26  *   Wojciech Andralojc <wojciechx.andralojc@intel.com>
27  *   Michał Aleksiński <michalx.aleksinski@intel.com>
28  **/
29
30 #include <dirent.h>
31 #include <sys/types.h>
32
33 /*
34  * Process name inside comm file is limited to 16 chars.
35  * More info here: http://man7.org/linux/man-pages/man5/proc.5.html
36  */
37 #define MAX_PROC_NAME_LEN 16
38
39 /* Helper typedef for process name array
40  * Extra 1 char is added for string null termination.
41  */
42 typedef char proc_comm_t[MAX_PROC_NAME_LEN + 1];
43
44 /* List of pids. */
45 typedef struct pids_list_s {
46   pid_t *pids;
47   size_t size;
48   size_t allocated;
49 } pids_list_t;
50
51 /* Holds process name and list of pids assigned to that name */
52 typedef struct proc_pids_s {
53   proc_comm_t process_name;
54   pids_list_t *prev;
55   pids_list_t *curr;
56 } proc_pids_t;
57
58 /*
59  * NAME
60  *   pids_list_free
61  *
62  * DESCRIPTION
63  *   Free all elements of given pids list
64  *
65  * PARAMETERS
66  *   `list'     Head of target pids_list.
67  */
68 void pids_list_free(pids_list_t *list);
69
70 /*
71  * NAME
72  *   is_proc_name_valid
73  *
74  * DESCRIPTION
75  *   Checks if given string as valid process name.
76  *
77  * PARAMETERS
78  *   `name'     null-terminated char array
79  *
80  * RETURN VALUE
81  *   If given name is a valid process name, returns 1,
82  *   Otherwise returns 0.
83  */
84 int is_proc_name_valid(const char *name);
85
86 /*
87  * NAME
88  *   pids_list_add_pid
89  *
90  * DESCRIPTION
91  *   Adds pid at the end of the pids array.
92  *   Reallocates memory for new pid element, it is up to user to free it.
93  *
94  * PARAMETERS
95  *   `list'     Target pids_list.
96  *   `pid'      Pid to be added.
97  *
98  * RETURN VALUE
99  *   On success, returns 0.
100  *   -1 on memory allocation error.
101  */
102 int pids_list_add_pid(pids_list_t *list, const pid_t pid);
103
104 /*
105  * NAME
106  *   pids_list_clear
107  *
108  * DESCRIPTION
109  *   Remove all pids from the list
110  *
111  * PARAMETERS
112  *   `list'     Target pids_list.
113  *
114  * RETURN VALUE
115  *   On success, return 0
116  */
117 int pids_list_clear(pids_list_t *list);
118
119 /*
120  * NAME
121  *   pids_list_add_list
122  *
123  * DESCRIPTION
124  *   Adds pids list at the end of the pids list.
125  *   Allocates memory for new pid elements, it is up to user to free it.
126  *
127  * PARAMETERS
128  *   `dst'      Target PIDs list.
129  *   `src'      Source PIDs list.
130  *
131  * RETURN VALUE
132  *   On success, returns 0.
133  *   -1 on memory allocation error.
134  */
135 #
136 int pids_list_add_list(pids_list_t *dst, pids_list_t *src);
137
138 /*
139  * NAME
140  *   pids_list_contains_pid
141  *
142  * DESCRIPTION
143  *   Tests if pids list contains specific pid.
144  *
145  * PARAMETERS
146  *   `list'     pids_list to check.
147  *   `pid'      Pid to be searched for.
148  *
149  * RETURN VALUE
150  *   If PID found in list, returns 1,
151  *   Otherwise returns 0.
152  */
153 int pids_list_contains_pid(pids_list_t *list, const pid_t pid);
154
155 /*
156  * NAME
157  *   read_proc_name
158  *
159  * DESCRIPTION
160  *   Reads process name from given pid directory.
161  *   Strips new-line character (\n).
162  *
163  * PARAMETERS
164  *   `procfs_path' Path to systems proc directory (e.g. /proc)
165  *   `pid_entry'   Dirent for PID directory
166  *   `name'        Output buffer for process name, recommended proc_comm.
167  *   `out_size'    Output buffer size, recommended sizeof(proc_comm)
168  *
169  * RETURN VALUE
170  *   On success, the number of read bytes (includes stripped \n).
171  *   -1 on file open error
172  */
173 int read_proc_name(const char *procfs_path, const struct dirent *pid_entry,
174                    char *name, const size_t out_size);
175
176 /*
177  * NAME
178  *   get_pid_number
179  *
180  * DESCRIPTION
181  *   Gets pid number for given /proc/pid directory entry or
182  *   returns error if input directory does not hold PID information.
183  *
184  * PARAMETERS
185  *   `entry'    Dirent for PID directory
186  *   `pid'      PID number to be filled
187  *
188  * RETURN VALUE
189  *   0 on success. -1 on error.
190  */
191 int get_pid_number(struct dirent *entry, pid_t *pid);
192
193 /*
194  * NAME
195  *   initialize_proc_pids
196  *
197  * DESCRIPTION
198  *   Helper function to properly initialize array of proc_pids.
199  *   Allocates memory for proc_pids structs.
200  *
201  * PARAMETERS
202  *   `procs_names_array'      Array of null-terminated strings with
203  *                            process' names to be copied to new array
204  *   `procs_names_array_size' procs_names_array element count
205  *   `proc_pids'              Address of pointer, under which new
206  *                            array of proc_pids will be allocated.
207  *                            Must be NULL.
208  * RETURN VALUE
209  *   0 on success. Negative number on error:
210  *   -1: allocation error
211  */
212 int initialize_proc_pids(const char **procs_names_array,
213                          const size_t procs_names_array_size,
214                          proc_pids_t **proc_pids[]);
215
216 /*
217  * NAME
218  *   update_proc_pids
219  *
220  * DESCRIPTION
221  *   Updates PIDs matching processes's names.
222  *   Searches all PID directories in /proc fs and updates current pids_list.
223  *
224  * PARAMETERS
225  *   `procfs_path'     Path to systems proc directory (e.g. /proc)
226  *   `proc_pids'       Array of proc_pids pointers to be updated.
227  *   `proc_pids_num'   proc_pids element count
228  *
229  * RETURN VALUE
230  *   0 on success. -1 on error.
231  */
232 int update_proc_pids(const char *procfs_path, proc_pids_t *proc_pids[],
233                      size_t proc_pids_num);
234
235 /*
236  * NAME
237  *   pids_list_diff
238  *
239  * DESCRIPTION
240  *   Searches for differences in two given lists
241  *
242  * PARAMETERS
243  *   `proc'            List of pids
244  *   `added'           New pids which appeared
245  *   `removed'         Result array storing pids which disappeared
246  * RETURN VALUE
247  *   0 on success. Negative number on error.
248  */
249 int pids_list_diff(proc_pids_t *proc, pids_list_t *added, pids_list_t *removed);
250
251 /*
252  * NAME
253  *   proc_pids_free
254  *
255  * DESCRIPTION
256  *   Releses memory allocatd for proc_pids
257  *
258  * PARAMETERS
259  *   `proc_pids'       Array of proc_pids
260  *   `proc_pids_num'   proc_pids element count
261  *
262  * RETURN VALUE
263  *   0 on success. -1 on error.
264  */
265 int proc_pids_free(proc_pids_t *proc_pids[], size_t proc_pids_num);