intel_rdt: refactor pids monitoring code.
[collectd.git] / src / utils_proc_pids.h
1 /**
2  * collectd - src/utils_config_pids.h
3  *
4  * Copyright(c) 2018 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  **/
28
29 #include <dirent.h>
30 #include <sys/types.h>
31
32 /*
33  * Process name inside comm file is limited to 16 chars.
34  * More info here: http://man7.org/linux/man-pages/man5/proc.5.html
35  */
36 #define MAX_PROC_NAME_LEN 16
37
38 /* Helper typedef for process name array
39  * Extra 1 char is added for string null termination.
40  */
41 typedef char proc_comm_t[MAX_PROC_NAME_LEN + 1];
42
43 /* Linked one-way list of pids. */
44 typedef struct pids_list_s {
45   pid_t pid;
46   struct pids_list_s *next;
47 } pids_list_t;
48
49 /* Holds process name and list of pids assigned to that name */
50 typedef struct proc_pids_s {
51   proc_comm_t proccess_name;
52   pids_list_t *pids;
53 } proc_pids_t;
54
55 /*
56  * NAME
57  *   pids_list_free
58  *
59  * DESCRIPTION
60  *   Free all elements of given pids list
61  *
62  * PARAMETERS
63  *   `list'     Head of target pids_list.
64  */
65 void pids_list_free(pids_list_t *list);
66
67 /*
68  * NAME
69  *   is_proc_name_valid
70  *
71  * DESCRIPTION
72  *   Checks if given string as valid process name.
73  *
74  * PARAMETERS
75  *   `name'     null-terminated char array
76  *
77  * RETURN VALUE
78  *   If given name is a valid process name, returns 1,
79  *   Otherwise returns 0.
80  */
81 int is_proc_name_valid(const char *name);
82
83 /*
84  * NAME
85  *   pids_list_add_pid
86  *
87  * DESCRIPTION
88  *   Adds pid at the end of the pids list.
89  *   Allocates memory for new pid element, it is up to user to free it.
90  *
91  * PARAMETERS
92  *   `list'     Head of target pids_list.
93  *   `pid'      Pid to be added.
94  *
95  * RETURN VALUE
96  *   On success, returns 0.
97  *   -1 on memory allocation error.
98  */
99 int pids_list_add_pid(pids_list_t **list, const pid_t pid);
100
101 /*
102  * NAME
103  *   pids_list_contains_pid
104  *
105  * DESCRIPTION
106  *   Tests if pids list contains specific pid.
107  *
108  * PARAMETERS
109  *   `list'     Head of pids_list.
110  *   `pid'      Pid to be searched for.
111  *
112  * RETURN VALUE
113  *   If PID found in list, returns 1,
114  *   Otherwise returns 0.
115  */
116 int pids_list_contains_pid(pids_list_t *list, const pid_t pid);
117
118 /*
119  * NAME
120  *   pids_list_add_pids_list
121  *
122  * DESCRIPTION
123  *   Adds pids list at the end of the pids list.
124  *   Allocates memory for new pid elements, it is up to user to free it.
125  *   Increases dst_num by a number of added PIDs.
126  *
127  * PARAMETERS
128  *   `dst'      Head of target PIDs list.
129  *   `src'      Head of source PIDs list.
130  *   `dst_num'  Variable to be increased by a number of appended PIDs.
131  *
132  * RETURN VALUE
133  *   On success, returns 0.
134  *   -1 on memory allocation error.
135  */
136 int pids_list_add_pids_list(pids_list_t **dst, pids_list_t *src,
137                             size_t *dst_num);
138 /*
139  * NAME
140  *   read_proc_name
141  *
142  * DESCRIPTION
143  *   Reads process name from given pid directory.
144  *   Strips new-line character (\n).
145  *
146  * PARAMETERS
147  *   `procfs_path` Path to systems proc directory (e.g. /proc)
148  *   `pid_entry'   Dirent for PID directory
149  *   `name'        Output buffer for process name, recommended proc_comm.
150  *   `out_size'    Output buffer size, recommended sizeof(proc_comm)
151  *
152  * RETURN VALUE
153  *   On success, the number of read bytes (includes stripped \n).
154  *   -1 on file open error
155  */
156 int read_proc_name(const char *procfs_path, const struct dirent *pid_entry,
157                    char *name, const size_t out_size);
158
159 /*
160  * NAME
161  *   get_pid_number
162  *
163  * DESCRIPTION
164  *   Gets pid number for given /proc/pid directory entry or
165  *   returns error if input directory does not hold PID information.
166  *
167  * PARAMETERS
168  *   `entry'    Dirent for PID directory
169  *   `pid'      PID number to be filled
170  *
171  * RETURN VALUE
172  *   0 on success. -1 on error.
173  */
174 int get_pid_number(struct dirent *entry, pid_t *pid);
175
176 /*
177  * NAME
178  *   pids_list_to_array
179  *
180  * DESCRIPTION
181  *   Copies element from list to array. Assumes the space for the array is
182  *   allocated.
183  *
184  * PARAMETERS
185  *   `array'      First element of target array
186  *   `list'       Head of the list
187  *   `array_length' Length (element count) of the target array
188  */
189 void pids_list_to_array(pid_t *array, pids_list_t *list,
190                         const size_t array_length);
191
192 /*
193  * NAME
194  *   initialize_proc_pids
195  *
196  * DESCRIPTION
197  *   Helper function to properly initialize array of proc_pids.
198  *   Allocates memory for proc_pids structs.
199  *
200  * PARAMETERS
201  *   `procs_names_array'      Array of null-terminated strings with
202  *                            process' names to be copied to new array
203  *   `procs_names_array_size' procs_names_array element count
204  *   `proc_pids_array'        Address of pointer, under which new
205  *                            array of proc_pids will be allocated.
206  *                            Must be NULL.
207  * RETURN VALUE
208  *   0 on success. Negative number on error:
209  *   -1: allocation error
210  */
211 int initialize_proc_pids(const char **procs_names_array,
212                          const size_t procs_names_array_size,
213                          proc_pids_t **proc_pids_array);
214
215 /*
216  * NAME
217  *   fetch_pids_for_procs
218  *
219  * DESCRIPTION
220  *   Finds PIDs matching given process's names.
221  *   Searches all PID directories in /proc fs and
222  *   allocates memory for proc_pids structs, it is up to user to free it.
223  *   Output array will have same element count as input array.
224  *
225  * PARAMETERS
226  *   `procfs_path'            Path to systems proc directory (e.g. /proc)
227  *   `procs_names_array'      Array of null-terminated strings with
228  *                            process' names to be copied to new array
229  *   `procs_names_array_size' procs_names_array element count
230  *   `proc_pids_array'        Address of pointer, under which new
231  *                            array of proc_pids will be allocated.
232  *                            Must be NULL.
233  *
234  * RETURN VALUE
235  *   0 on success. -1 on error.
236  */
237 int fetch_pids_for_procs(const char *procfs_path,
238                          const char **procs_names_array,
239                          const size_t procs_names_array_size,
240                          proc_pids_t **proc_pids_array);
241
242 /*
243  * NAME
244  *   pids_list_diff
245  *
246  * DESCRIPTION
247  *   Searches for differences in two given lists
248  *
249  * PARAMETERS
250  *   `prev'            List of pids before changes
251  *   `curr'            List of pids after changes
252  *   `added'           Result array storing new pids which appeared in `curr'
253  *   `added_num'       `added_num' array length
254  *   `removed'         Result array storing pids which disappeared in `prev'
255  *   `removed_num'     `removed' array length
256  * RETURN VALUE
257  *   0 on success. Negative number on error.
258  */
259 int pids_list_diff(pids_list_t *prev, pids_list_t *curr, pids_list_t **added,
260                    size_t *added_num, pids_list_t **removed,
261                    size_t *removed_num);