2aaed4ef96850eee2caf82d9bfb28b2b678d3c81
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry-session.cpp
1 /*
2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include "ust-registry.hpp"
9
10 #include <common/compat/directory-handle.hpp>
11 #include <common/error.hpp>
12 #include <common/exception.hpp>
13 #include <common/runas.hpp>
14
15 #include <fcntl.h>
16 #include <sstream>
17 #include <string>
18
19 ust_registry_session::ust_registry_session(uint32_t bits_per_long,
20 uint32_t uint8_t_alignment,
21 uint32_t uint16_t_alignment,
22 uint32_t uint32_t_alignment,
23 uint32_t uint64_t_alignment,
24 uint32_t long_alignment,
25 int byte_order,
26 uint32_t major,
27 uint32_t minor,
28 const char *root_shm_path,
29 const char *shm_path,
30 uid_t euid,
31 gid_t egid,
32 uint64_t tracing_id) :
33 _bits_per_long{bits_per_long},
34 _uint8_t_alignment{uint8_t_alignment},
35 _uint16_t_alignment{uint16_t_alignment},
36 _uint32_t_alignment{uint32_t_alignment},
37 _uint64_t_alignment{uint64_t_alignment},
38 _long_alignment{long_alignment},
39 _byte_order{byte_order},
40 _uid{euid},
41 _gid{egid},
42 _app_tracer_version_major{major},
43 _app_tracer_version_minor{minor},
44 _tracing_id{tracing_id}
45 {
46 pthread_mutex_init(&_lock, NULL);
47 strncpy(_root_shm_path, root_shm_path, sizeof(_root_shm_path));
48 _root_shm_path[sizeof(_root_shm_path) - 1] = '\0';
49 if (shm_path[0]) {
50 strncpy(_shm_path, shm_path, sizeof(_shm_path));
51 _shm_path[sizeof(_shm_path) - 1] = '\0';
52 strncpy(_metadata_path, shm_path, sizeof(_metadata_path));
53 _metadata_path[sizeof(_metadata_path) - 1] = '\0';
54 strncat(_metadata_path, "/metadata",
55 sizeof(_metadata_path) - strlen(_metadata_path) - 1);
56 }
57
58 if (_shm_path[0]) {
59 if (run_as_mkdir_recursive(_shm_path, S_IRWXU | S_IRWXG, euid, egid)) {
60 LTTNG_THROW_POSIX("run_as_mkdir_recursive", errno);
61 }
62 }
63
64 if (_metadata_path[0]) {
65 /* Create metadata file. */
66 const int ret = run_as_open(_metadata_path, O_WRONLY | O_CREAT | O_EXCL,
67 S_IRUSR | S_IWUSR, euid, egid);
68
69 if (ret < 0) {
70 std::stringstream ss;
71
72 ss << "Opening metadata file '" << _metadata_path << "'";
73 LTTNG_THROW_POSIX(ss.str(), errno);
74 }
75
76 _metadata_fd = ret;
77 }
78
79 _enums.reset(lttng_ht_new(0, LTTNG_HT_TYPE_STRING));
80 if (!_enums) {
81 LTTNG_THROW_POSIX("Failed to create enums hash table", ENOMEM);
82 }
83
84 /* hash/match functions are specified at call site. */
85 _enums->match_fct = NULL;
86 _enums->hash_fct = NULL;
87
88 _channels.reset(lttng_ht_new(0, LTTNG_HT_TYPE_U64));
89 if (!_channels) {
90 LTTNG_THROW_POSIX("Failed to create channels hash table", ENOMEM);
91 }
92
93 if (lttng_uuid_generate(_uuid)) {
94 LTTNG_THROW_POSIX("Failed to generate UST uuid", errno);
95 }
96 }
97
98 ust_registry_session::~ust_registry_session()
99 {
100 int ret;
101 struct lttng_ht_iter iter;
102 struct ust_registry_channel *chan;
103 struct ust_registry_enum *reg_enum;
104
105 /* On error, EBUSY can be returned if lock. Code flow error. */
106 ret = pthread_mutex_destroy(&_lock);
107 LTTNG_ASSERT(!ret);
108
109 if (_channels) {
110 rcu_read_lock();
111 /* Destroy all event associated with this registry. */
112 cds_lfht_for_each_entry (_channels->ht, &iter.iter, chan, node.node) {
113 /* Delete the node from the ht and free it. */
114 ret = lttng_ht_del(_channels.get(), &iter);
115 LTTNG_ASSERT(!ret);
116 ust_registry_channel_destroy(chan, true);
117 }
118
119 rcu_read_unlock();
120 }
121
122 free(_metadata);
123 if (_metadata_fd >= 0) {
124 ret = close(_metadata_fd);
125 if (ret) {
126 PERROR("close");
127 }
128
129 ret = run_as_unlink(_metadata_path, _uid, _gid);
130 if (ret) {
131 PERROR("unlink");
132 }
133 }
134
135 if (_root_shm_path[0]) {
136 /* Try to delete the directory hierarchy. */
137 (void) run_as_rmdir_recursive(_root_shm_path, _uid, _gid,
138 LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
139 }
140
141 /* Destroy the enum hash table */
142 if (_enums) {
143 rcu_read_lock();
144 /* Destroy all enum entries associated with this registry. */
145 cds_lfht_for_each_entry (_enums->ht, &iter.iter, reg_enum, node.node) {
146 ust_registry_destroy_enum(this, reg_enum);
147 }
148
149 rcu_read_unlock();
150 }
151 }
152
153 void ust_registry_session::statedump()
154 {
155 pthread_mutex_lock(&_lock);
156 const int ret = ust_metadata_session_statedump(this);
157 pthread_mutex_unlock(&_lock);
158 if (ret) {
159 LTTNG_THROW_ERROR(
160 "Failed to generate session metadata during registry session creation");
161 }
162 }
This page took 0.032286 seconds and 3 git commands to generate.