Implements `lttng_event_notifier_notification_{create,destroy}()`
[lttng-tools.git] / src / bin / lttng-sessiond / clear.c
1 /*
2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <assert.h>
10 #include <inttypes.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include <common/defaults.h>
15 #include <common/error.h>
16 #include <common/utils.h>
17
18 #include "clear.h"
19 #include "session.h"
20 #include "ust-app.h"
21 #include "kernel.h"
22 #include "cmd.h"
23
24 struct cmd_clear_session_reply_context {
25 int reply_sock_fd;
26 };
27
28 static
29 void cmd_clear_session_reply(const struct ltt_session *session,
30 void *_reply_context)
31 {
32 int ret;
33 ssize_t comm_ret;
34 const struct cmd_clear_session_reply_context *reply_context =
35 _reply_context;
36 struct lttcomm_lttng_msg llm = {
37 .cmd_type = LTTNG_CLEAR_SESSION,
38 .ret_code = LTTNG_OK,
39 .pid = UINT32_MAX,
40 .cmd_header_size = 0,
41 .data_size = 0,
42 };
43
44 DBG("End of clear command: replying to client");
45 comm_ret = lttcomm_send_unix_sock(reply_context->reply_sock_fd,
46 &llm, sizeof(llm));
47 if (comm_ret != (ssize_t) sizeof(llm)) {
48 ERR("Failed to send result of session \"%s\" clear to client",
49 session->name);
50 }
51 ret = close(reply_context->reply_sock_fd);
52 if (ret) {
53 PERROR("Failed to close client socket in deferred session clear reply");
54 }
55 free(_reply_context);
56 }
57
58 int cmd_clear_session(struct ltt_session *session, int *sock_fd)
59 {
60 int ret = LTTNG_OK;
61 struct cmd_clear_session_reply_context *reply_context = NULL;
62 bool session_was_active = false;
63 struct ltt_kernel_session *ksession;
64 struct ltt_ust_session *usess;
65
66 ksession = session->kernel_session;
67 usess = session->ust_session;
68
69 if (sock_fd) {
70 reply_context = zmalloc(sizeof(*reply_context));
71 if (!reply_context) {
72 ret = LTTNG_ERR_NOMEM;
73 goto end;
74 }
75 reply_context->reply_sock_fd = *sock_fd;
76 }
77
78 if (!session->has_been_started) {
79 /*
80 * Nothing to be cleared, this is not an error: there is
81 * indeed nothing to do, and there is no reason why we
82 * should return an error to the user.
83 */
84 goto end;
85 }
86
87 /* Unsupported feature in lttng-relayd before 2.11. */
88 if (session->consumer->type == CONSUMER_DST_NET &&
89 (session->consumer->relay_major_version == 2 &&
90 session->consumer->relay_minor_version < 12)) {
91 ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY;
92 goto end;
93 }
94 if (session->consumer->type == CONSUMER_DST_NET &&
95 !session->consumer->relay_allows_clear) {
96 ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY;
97 goto end;
98 }
99
100 /*
101 * After a stop followed by a clear, all subsequent clear are
102 * effect-less until start is performed.
103 */
104 if (session->cleared_after_last_stop) {
105 ret = LTTNG_OK;
106 goto end;
107 }
108
109 /*
110 * After a stop followed by a rotation, all subsequent clear are effect-less
111 * until start is performed.
112 */
113 if (session->rotated_after_last_stop) {
114 ret = LTTNG_OK;
115 goto end;
116 }
117
118 session_was_active = session->active;
119 if (session_was_active) {
120 ret = stop_kernel_session(ksession);
121 if (ret != LTTNG_OK) {
122 goto end;
123 }
124 if (usess && usess->active) {
125 ret = ust_app_stop_trace_all(usess);
126 if (ret < 0) {
127 ret = LTTNG_ERR_UST_STOP_FAIL;
128 goto end;
129 }
130 }
131 }
132
133 /*
134 * Clear active kernel and UST session buffers.
135 */
136 if (session->kernel_session) {
137 ret = kernel_clear_session(session);
138 if (ret != LTTNG_OK) {
139 goto end;
140 }
141 }
142 if (session->ust_session) {
143 ret = ust_app_clear_session(session);
144 if (ret != LTTNG_OK) {
145 goto end;
146 }
147 }
148
149 if (session->output_traces) {
150 /*
151 * Use rotation to delete local and remote stream files.
152 */
153 if (reply_context) {
154 ret = session_add_clear_notifier(session,
155 cmd_clear_session_reply,
156 (void *) reply_context);
157 if (ret) {
158 ret = LTTNG_ERR_FATAL;
159 goto end;
160 }
161 /*
162 * On success, ownership of reply_context has been
163 * passed to session_add_clear_notifier().
164 */
165 reply_context = NULL;
166 *sock_fd = -1;
167 }
168 ret = cmd_rotate_session(session, NULL, true,
169 LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE);
170 if (ret != LTTNG_OK) {
171 goto end;
172 }
173 }
174 if (!session->active) {
175 session->cleared_after_last_stop = true;
176 }
177 if (session_was_active) {
178 /* Kernel tracing */
179 if (ksession != NULL) {
180 DBG("Start kernel tracing session \"%s\"",
181 session->name);
182 ret = start_kernel_session(ksession);
183 if (ret != LTTNG_OK) {
184 goto end;
185 }
186 }
187
188 /* Flag session that trace should start automatically */
189 if (usess) {
190 int int_ret = ust_app_start_trace_all(usess);
191
192 if (int_ret < 0) {
193 ret = LTTNG_ERR_UST_START_FAIL;
194 goto end;
195 }
196 }
197
198 /*
199 * Open a packet in every stream of the session to ensure that
200 * viewers can correctly identify the boundaries of the periods
201 * during which tracing was active for this session.
202 */
203 ret = session_open_packets(session);
204 if (ret != LTTNG_OK) {
205 goto end;
206 }
207 }
208 ret = LTTNG_OK;
209 end:
210 free(reply_context);
211 return ret;
212 }
This page took 0.034172 seconds and 4 git commands to generate.