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