centralize sessiond config option handling
[lttng-tools.git] / src / bin / lttng-sessiond / sessiond-config.c
1 /*
2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 #include "sessiond-config.h"
19 #include <assert.h>
20 #include "lttng-ust-ctl.h"
21 #include <common/defaults.h>
22 #include <limits.h>
23 #include <errno.h>
24 #include <ctype.h>
25 #include <common/error.h>
26 #include <common/utils.h>
27 #include <common/compat/getenv.h>
28
29 static
30 struct sessiond_config sessiond_config_build_defaults = {
31 .quiet = false,
32 .verbose = 0,
33 .verbose_consumer = 0,
34
35 .agent_tcp_port = DEFAULT_AGENT_TCP_PORT,
36 .app_socket_timeout = DEFAULT_APP_SOCKET_RW_TIMEOUT,
37
38 .no_kernel = false,
39 .background = false,
40 .daemonize = false,
41 .sig_parent = false,
42
43 .tracing_group_name.value = DEFAULT_TRACING_GROUP,
44 .kmod_probes_list.value = NULL,
45 .kmod_extra_probes_list.value = NULL,
46
47 .rundir.value = NULL,
48
49 .apps_unix_sock_path.value = NULL,
50 .client_unix_sock_path.value = NULL,
51 .wait_shm_path.value = NULL,
52 .health_unix_sock_path.value = NULL,
53 .lttng_ust_clock_plugin.value = NULL,
54 .pid_file_path.value = NULL,
55 .lock_file_path.value = NULL,
56 .agent_port_file_path.value = NULL,
57 .load_session_path.value = NULL,
58
59 .consumerd32_path.value = NULL,
60 .consumerd32_bin_path.value = NULL,
61 .consumerd32_lib_dir.value = NULL,
62 .consumerd32_err_unix_sock_path.value = NULL,
63 .consumerd32_cmd_unix_sock_path.value = NULL,
64
65 .consumerd64_path.value = NULL,
66 .consumerd64_bin_path.value = NULL,
67 .consumerd64_lib_dir.value = NULL,
68 .consumerd64_err_unix_sock_path.value = NULL,
69 .consumerd64_cmd_unix_sock_path.value = NULL,
70
71 .kconsumerd_path.value = NULL,
72 .kconsumerd_err_unix_sock_path.value = NULL,
73 .kconsumerd_cmd_unix_sock_path.value = NULL,
74 };
75
76 static
77 void config_string_fini(struct config_string *str)
78 {
79 config_string_set(str, NULL);
80 }
81
82 static
83 void config_string_set_static(struct config_string *config_str,
84 const char *value)
85 {
86 config_string_set(config_str, (char *) value);
87 config_str->should_free = false;
88 }
89
90 /* Only use for dynamically-allocated strings. */
91 LTTNG_HIDDEN
92 void config_string_set(struct config_string *config_str, char *value)
93 {
94 assert(config_str);
95 if (config_str->should_free) {
96 free(config_str->value);
97 config_str->should_free = false;
98 }
99
100 config_str->should_free = !!value;
101 config_str->value = value;
102 }
103
104 LTTNG_HIDDEN
105 int sessiond_config_apply_env_config(struct sessiond_config *config)
106 {
107 int ret = 0;
108 const char *env_value;
109
110 env_value = getenv(DEFAULT_APP_SOCKET_TIMEOUT_ENV);
111 if (env_value) {
112 char *endptr;
113 long int_val;
114
115 errno = 0;
116 int_val = strtoul(env_value, &endptr, 0);
117 if (errno != 0 || int_val > INT_MAX ||
118 (int_val < 0 && int_val != -1)) {
119 ERR("Invalid value \"%s\" used for \"%s\" environment variable",
120 env_value, DEFAULT_APP_SOCKET_TIMEOUT_ENV);
121 ret = -1;
122 goto end;
123 }
124
125 config->app_socket_timeout = int_val;
126 }
127
128 env_value = lttng_secure_getenv("LTTNG_CONSUMERD32_BIN");
129 if (env_value) {
130 config_string_set_static(&config->consumerd32_bin_path,
131 env_value);
132 }
133 env_value = lttng_secure_getenv("LTTNG_CONSUMERD64_BIN");
134 if (env_value) {
135 config_string_set_static(&config->consumerd64_bin_path,
136 env_value);
137 }
138
139 env_value = lttng_secure_getenv("LTTNG_CONSUMERD32_LIBDIR");
140 if (env_value) {
141 config_string_set_static(&config->consumerd32_lib_dir,
142 env_value);
143 }
144 env_value = lttng_secure_getenv("LTTNG_CONSUMERD64_LIBDIR");
145 if (env_value) {
146 config_string_set_static(&config->consumerd64_lib_dir,
147 env_value);
148 }
149
150 env_value = lttng_secure_getenv("LTTNG_UST_CLOCK_PLUGIN");
151 if (env_value) {
152 config_string_set_static(&config->lttng_ust_clock_plugin,
153 env_value);
154 }
155
156 env_value = lttng_secure_getenv(DEFAULT_LTTNG_KMOD_PROBES);
157 if (env_value) {
158 config_string_set_static(&config->kmod_probes_list,
159 env_value);
160 }
161
162 env_value = lttng_secure_getenv(DEFAULT_LTTNG_EXTRA_KMOD_PROBES);
163 if (env_value) {
164 config_string_set_static(&config->kmod_extra_probes_list,
165 env_value);
166 }
167 end:
168 return ret;
169 }
170
171 static
172 int config_set_paths_root(struct sessiond_config *config)
173 {
174 int ret = 0;
175
176 config_string_set(&config->rundir, strdup(DEFAULT_LTTNG_RUNDIR));
177 if (!config->rundir.value) {
178 ERR("Failed to set rundir");
179 ret = -1;
180 goto end;
181 }
182
183 config_string_set_static(&config->apps_unix_sock_path,
184 DEFAULT_GLOBAL_APPS_UNIX_SOCK);
185 config_string_set_static(&config->client_unix_sock_path,
186 DEFAULT_GLOBAL_CLIENT_UNIX_SOCK);
187 config_string_set_static(&config->wait_shm_path,
188 DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH);
189 config_string_set_static(&config->health_unix_sock_path,
190 DEFAULT_GLOBAL_HEALTH_UNIX_SOCK);
191 config_string_set_static(&config->kconsumerd_err_unix_sock_path,
192 DEFAULT_KCONSUMERD_ERR_SOCK_PATH);
193 config_string_set_static(&config->kconsumerd_cmd_unix_sock_path,
194 DEFAULT_KCONSUMERD_CMD_SOCK_PATH);
195 end:
196 return ret;
197 }
198
199 static
200 int config_set_paths_non_root(struct sessiond_config *config)
201 {
202 int ret = 0;
203 const char *home_path = utils_get_home_dir();
204 char *str;
205
206 if (home_path == NULL) {
207 ERR("Can't get HOME directory for sockets creation.");
208 ret = -1;
209 goto end;
210 }
211
212 /*
213 * Create rundir from home path. This will create something like
214 * $HOME/.lttng
215 */
216 ret = asprintf(&str, DEFAULT_LTTNG_HOME_RUNDIR, home_path);
217 if (ret < 0) {
218 ERR("Failed to set rundir");
219 goto end;
220 }
221 config_string_set(&config->rundir, str);
222 str = NULL;
223
224 ret = asprintf(&str, DEFAULT_HOME_APPS_UNIX_SOCK, home_path);
225 if (ret < 0) {
226 ERR("Failed to set default home apps unix socket path");
227 goto end;
228 }
229 config_string_set(&config->apps_unix_sock_path, str);
230 str = NULL;
231
232 ret = asprintf(&str, DEFAULT_HOME_CLIENT_UNIX_SOCK, home_path);
233 if (ret < 0) {
234 ERR("Failed to set default home client unix socket path");
235 goto end;
236 }
237 config_string_set(&config->client_unix_sock_path, str);
238 str = NULL;
239
240 ret = asprintf(&str, DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
241 if (ret < 0) {
242 ERR("Failed to set default home apps wait shm path");
243 goto end;
244 }
245 config_string_set(&config->wait_shm_path, str);
246 str = NULL;
247
248 ret = asprintf(&str, DEFAULT_HOME_HEALTH_UNIX_SOCK, home_path);
249 if (ret < 0) {
250 ERR("Failed to set default home health UNIX socket path");
251 goto end;
252 }
253 config_string_set(&config->health_unix_sock_path, str);
254 str = NULL;
255
256 ret = 0;
257 end:
258 return ret;
259 }
260
261 LTTNG_HIDDEN
262 int sessiond_config_init(struct sessiond_config *config)
263 {
264 int ret;
265 bool is_root = (getuid() == 0);
266 char *str;
267
268 assert(config);
269 memcpy(config, &sessiond_config_build_defaults, sizeof(*config));
270
271 if (is_root) {
272 ret = config_set_paths_root(config);
273 } else {
274 ret = config_set_paths_non_root(config);
275 }
276
277 /* 32 bits consumerd path setup */
278 ret = asprintf(&str, DEFAULT_USTCONSUMERD32_PATH,
279 config->rundir.value);
280 if (ret < 0) {
281 ERR("Failed to set 32-bit consumer path");
282 goto end;
283 }
284 config_string_set(&config->consumerd32_path, str);
285 str = NULL;
286
287 ret = asprintf(&str, DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH,
288 config->rundir.value);
289 if (ret < 0) {
290 ERR("Failed to set 32-bit consumer error socket path");
291 goto end;
292 }
293 config_string_set(&config->consumerd32_err_unix_sock_path, str);
294 str = NULL;
295
296 ret = asprintf(&str, DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH,
297 config->rundir.value);
298 if (ret < 0) {
299 ERR("Failed to set 32-bit consumer command socket path");
300 goto end;
301 }
302 config_string_set(&config->consumerd32_cmd_unix_sock_path, str);
303 str = NULL;
304
305 /* 64 bits consumerd path setup */
306 ret = asprintf(&str, DEFAULT_USTCONSUMERD64_PATH,
307 config->rundir.value);
308 if (ret < 0) {
309 ERR("Failed to set 64-bit consumer path");
310 goto end;
311 }
312 config_string_set(&config->consumerd64_path, str);
313 str = NULL;
314
315 ret = asprintf(&str, DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH,
316 config->rundir.value);
317 if (ret < 0) {
318 ERR("Failed to set 64-bit consumer error socket path");
319 goto end;
320 }
321 config_string_set(&config->consumerd64_err_unix_sock_path, str);
322 str = NULL;
323
324 ret = asprintf(&str, DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH,
325 config->rundir.value);
326 if (ret < 0) {
327 ERR("Failed to set 64-bit consumer command socket path");
328 goto end;
329 }
330 config_string_set(&config->consumerd64_cmd_unix_sock_path, str);
331 str = NULL;
332
333 /* kconsumerd consumerd path setup */
334 ret = asprintf(&str, DEFAULT_KCONSUMERD_PATH,
335 config->rundir.value);
336 if (ret < 0) {
337 ERR("Failed to set kernel consumer path");
338 goto end;
339 }
340 config_string_set(&config->kconsumerd_path, str);
341 str = NULL;
342
343 ret = asprintf(&str, "%s/%s", config->rundir.value,
344 DEFAULT_LTTNG_SESSIOND_PIDFILE);
345 if (ret < 0) {
346 ERR("Failed to set PID file path");
347 goto end;
348 }
349 config_string_set(&config->pid_file_path, str);
350 str = NULL;
351
352 ret = asprintf(&str, "%s/%s", config->rundir.value,
353 DEFAULT_LTTNG_SESSIOND_LOCKFILE);
354 if (ret < 0) {
355 ERR("Failed to set lock file path");
356 goto end;
357 }
358 config_string_set(&config->lock_file_path, str);
359 str = NULL;
360
361 ret = asprintf(&str, "%s/%s", config->rundir.value,
362 DEFAULT_LTTNG_SESSIOND_AGENTPORT_FILE);
363 if (ret < 0) {
364 ERR("Failed to set agent port file path");
365 goto end;
366 }
367 config_string_set(&config->agent_port_file_path, str);
368 str = NULL;
369
370 /*
371 * Allow INSTALL_BIN_PATH to be used as a target path for the
372 * native architecture size consumer if CONFIG_CONSUMER*_PATH
373 * has not been defined.
374 */
375 #if (CAA_BITS_PER_LONG == 32)
376 config_string_set_static(&config->consumerd32_bin_path,
377 INSTALL_BIN_PATH "/" DEFAULT_CONSUMERD_FILE);
378 config_string_set_static(&config->consumerd32_lib_dir,
379 INSTALL_LIB_PATH);
380 #elif (CAA_BITS_PER_LONG == 64)
381 config_string_set_static(&config->consumerd64_bin_path,
382 INSTALL_BIN_PATH "/" DEFAULT_CONSUMERD_FILE);
383 config_string_set_static(&config->consumerd64_lib_dir,
384 INSTALL_LIB_PATH);
385 #else
386 #error "Unknown bitness"
387 #endif
388 ret = 0;
389 end:
390 return ret;
391 }
392
393 LTTNG_HIDDEN
394 void sessiond_config_fini(struct sessiond_config *config)
395 {
396 config_string_fini(&config->tracing_group_name);
397 config_string_fini(&config->kmod_probes_list);
398 config_string_fini(&config->kmod_extra_probes_list);
399 config_string_fini(&config->apps_unix_sock_path);
400 config_string_fini(&config->client_unix_sock_path);
401 config_string_fini(&config->wait_shm_path);
402 config_string_fini(&config->health_unix_sock_path);
403 config_string_fini(&config->lttng_ust_clock_plugin);
404 config_string_fini(&config->pid_file_path);
405 config_string_fini(&config->lock_file_path);
406 config_string_fini(&config->load_session_path);
407 config_string_fini(&config->agent_port_file_path);
408 config_string_fini(&config->consumerd32_path);
409 config_string_fini(&config->consumerd32_bin_path);
410 config_string_fini(&config->consumerd32_lib_dir);
411 config_string_fini(&config->consumerd32_err_unix_sock_path);
412 config_string_fini(&config->consumerd32_cmd_unix_sock_path);
413 config_string_fini(&config->consumerd64_path);
414 config_string_fini(&config->consumerd64_bin_path);
415 config_string_fini(&config->consumerd64_lib_dir);
416 config_string_fini(&config->consumerd64_err_unix_sock_path);
417 config_string_fini(&config->consumerd64_cmd_unix_sock_path);
418 config_string_fini(&config->kconsumerd_path);
419 config_string_fini(&config->kconsumerd_err_unix_sock_path);
420 config_string_fini(&config->kconsumerd_cmd_unix_sock_path);
421 }
422
423 static
424 int resolve_path(struct config_string *path)
425 {
426 int ret = 0;
427 char *absolute_path;
428
429 if (!path->value || path->value[0] == '/') {
430 goto end;
431 }
432
433 absolute_path = utils_expand_path(path->value);
434 if (!absolute_path) {
435 ret = -1;
436 goto end;
437 }
438
439 config_string_set(path, absolute_path);
440 end:
441 return ret;
442 }
443
444 #define RESOLVE_CHECK(path_config_str) \
445 if (resolve_path(path_config_str)) \
446 return -1
447
448 LTTNG_HIDDEN
449 int sessiond_config_resolve_paths(struct sessiond_config *config)
450 {
451 RESOLVE_CHECK(&config->apps_unix_sock_path);
452 RESOLVE_CHECK(&config->client_unix_sock_path);
453 RESOLVE_CHECK(&config->wait_shm_path);
454 RESOLVE_CHECK(&config->health_unix_sock_path);
455 RESOLVE_CHECK(&config->lttng_ust_clock_plugin);
456 RESOLVE_CHECK(&config->pid_file_path);
457 RESOLVE_CHECK(&config->lock_file_path);
458 RESOLVE_CHECK(&config->load_session_path);
459 RESOLVE_CHECK(&config->agent_port_file_path);
460 RESOLVE_CHECK(&config->consumerd32_path);
461 RESOLVE_CHECK(&config->consumerd32_bin_path);
462 RESOLVE_CHECK(&config->consumerd32_lib_dir);
463 RESOLVE_CHECK(&config->consumerd32_err_unix_sock_path);
464 RESOLVE_CHECK(&config->consumerd32_cmd_unix_sock_path);
465 RESOLVE_CHECK(&config->consumerd64_path);
466 RESOLVE_CHECK(&config->consumerd64_bin_path);
467 RESOLVE_CHECK(&config->consumerd64_lib_dir);
468 RESOLVE_CHECK(&config->consumerd64_err_unix_sock_path);
469 RESOLVE_CHECK(&config->consumerd64_cmd_unix_sock_path);
470 RESOLVE_CHECK(&config->kconsumerd_path);
471 RESOLVE_CHECK(&config->kconsumerd_err_unix_sock_path);
472 RESOLVE_CHECK(&config->kconsumerd_cmd_unix_sock_path);
473 return 0;
474 }
475
476 LTTNG_HIDDEN
477 void sessiond_config_log(struct sessiond_config *config)
478 {
479 DBG_NO_LOC("[sessiond configuration]");
480 DBG_NO_LOC("\tverbose: %i", config->verbose);
481 DBG_NO_LOC("\tverbose consumer: %i", config->verbose_consumer);
482 DBG_NO_LOC("\tquiet mode: %s", config->quiet ? "True" : "False");
483 DBG_NO_LOC("\tagent_tcp_port: %i", config->agent_tcp_port);
484 DBG_NO_LOC("\tapplication socket timeout: %i", config->app_socket_timeout);
485 DBG_NO_LOC("\tno-kernel: %s", config->no_kernel ? "True" : "False");
486 DBG_NO_LOC("\tbackground: %s", config->background ? "True" : "False");
487 DBG_NO_LOC("\tdaemonize: %s", config->daemonize ? "True" : "False");
488 DBG_NO_LOC("\tsignal parent on start: %s", config->sig_parent ? "True" : "False");
489 DBG_NO_LOC("\ttracing group name: %s", config->tracing_group_name.value ? : "Unknown");
490 DBG_NO_LOC("\tkmod_probe_list: %s", config->kmod_probes_list.value ? : "None");
491 DBG_NO_LOC("\tkmod_extra_probe_list: %s", config->kmod_extra_probes_list.value ? : "None");
492 DBG_NO_LOC("\trundir: %s", config->rundir.value ? : "Unknown");
493 DBG_NO_LOC("\tapplication socket path: %s", config->apps_unix_sock_path.value ? : "Unknown");
494 DBG_NO_LOC("\tclient socket path: %s", config->client_unix_sock_path.value ? : "Unknown");
495 DBG_NO_LOC("\twait shm path: %s", config->wait_shm_path.value ? : "Unknown");
496 DBG_NO_LOC("\thealth socket path: %s", config->health_unix_sock_path.value ? : "Unknown");
497 DBG_NO_LOC("\tLTTNG_UST_CLOCK_PLUGIN: %s", config->lttng_ust_clock_plugin.value ? : "None");
498 DBG_NO_LOC("\tpid file path: %s", config->pid_file_path.value ? : "Unknown");
499 DBG_NO_LOC("\tlock file path: %s", config->lock_file_path.value ? : "Unknown");
500 DBG_NO_LOC("\tsession load path: %s", config->load_session_path.value ? : "None");
501 DBG_NO_LOC("\tagent port file path: %s", config->agent_port_file_path.value ? : "Unknown");
502 }
This page took 0.065371 seconds and 5 git commands to generate.