cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / ctfser / ctfser.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #define BT_LOG_OUTPUT_LEVEL (ctfser->log_level)
8 #define BT_LOG_TAG "CTFSER"
9 #include "logging/log.h"
10
11 #include <unistd.h>
12 #include <string.h>
13 #include <inttypes.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include "common/assert.h"
18 #include <stdarg.h>
19 #include <ctype.h>
20 #include <glib.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <wchar.h>
24 #include "common/macros.h"
25 #include "common/common.h"
26 #include "ctfser/ctfser.h"
27 #include "compat/unistd.h"
28 #include "compat/fcntl.h"
29
30 static inline
31 uint64_t get_packet_size_increment_bytes(struct bt_ctfser *ctfser)
32 {
33 return bt_common_get_page_size(ctfser->log_level) * 8;
34 }
35
36 static inline
37 void mmap_align_ctfser(struct bt_ctfser *ctfser)
38 {
39 ctfser->base_mma = mmap_align(ctfser->cur_packet_size_bytes,
40 PROT_READ | PROT_WRITE,
41 MAP_SHARED, ctfser->fd, ctfser->mmap_offset, ctfser->log_level);
42 }
43
44 int _bt_ctfser_increase_cur_packet_size(struct bt_ctfser *ctfser)
45 {
46 int ret;
47
48 BT_ASSERT(ctfser);
49 BT_LOGD("Increasing stream file's current packet size: "
50 "path=\"%s\", fd=%d, "
51 "offset-in-cur-packet-bits=%" PRIu64 ", "
52 "cur-packet-size-bytes=%" PRIu64,
53 ctfser->path->str, ctfser->fd,
54 ctfser->offset_in_cur_packet_bits,
55 ctfser->cur_packet_size_bytes);
56 ret = munmap_align(ctfser->base_mma);
57 if (ret) {
58 BT_LOGE_ERRNO("Failed to perform an aligned memory unmapping",
59 ": ret=%d", ret);
60 goto end;
61 }
62
63 ctfser->cur_packet_size_bytes += get_packet_size_increment_bytes(
64 ctfser);
65
66 do {
67 ret = bt_posix_fallocate(ctfser->fd, ctfser->mmap_offset,
68 ctfser->cur_packet_size_bytes);
69 } while (ret == EINTR);
70
71 if (ret) {
72 BT_LOGE("Failed to preallocate memory space: ret=%d", ret);
73 goto end;
74 }
75
76 mmap_align_ctfser(ctfser);
77 if (ctfser->base_mma == MAP_FAILED) {
78 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
79 ": ret=%d", ret);
80 ret = -1;
81 goto end;
82 }
83
84 BT_LOGD("Increased packet size: "
85 "path=\"%s\", fd=%d, "
86 "offset-in-cur-packet-bits=%" PRIu64 ", "
87 "new-packet-size-bytes=%" PRIu64,
88 ctfser->path->str, ctfser->fd,
89 ctfser->offset_in_cur_packet_bits,
90 ctfser->cur_packet_size_bytes);
91
92 end:
93 return ret;
94 }
95
96 int bt_ctfser_init(struct bt_ctfser *ctfser, const char *path, int log_level)
97 {
98 int ret = 0;
99
100 BT_ASSERT(ctfser);
101 memset(ctfser, 0, sizeof(*ctfser));
102 ctfser->fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
103 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
104 ctfser->log_level = log_level;
105 if (ctfser->fd < 0) {
106 BT_LOGW_ERRNO("Failed to open stream file for writing",
107 ": path=\"%s\", ret=%d",
108 path, ctfser->fd);
109 ret = -1;
110 goto end;
111 }
112
113 ctfser->path = g_string_new(path);
114
115 end:
116 return ret;
117 }
118
119 int bt_ctfser_fini(struct bt_ctfser *ctfser)
120 {
121 int ret = 0;
122
123 if (ctfser->fd == -1) {
124 goto free_path;
125 }
126
127 if (ctfser->base_mma) {
128 /* Unmap old base */
129 ret = munmap_align(ctfser->base_mma);
130 if (ret) {
131 BT_LOGE_ERRNO("Failed to unmap stream file",
132 ": ret=%d, size-bytes=%" PRIu64,
133 ret, ctfser->stream_size_bytes);
134 goto end;
135 }
136
137 ctfser->base_mma = NULL;
138 }
139
140 /*
141 * Truncate the stream file's size to the minimum required to
142 * fit the last packet as we might have grown it too much during
143 * the last memory map.
144 */
145 do {
146 ret = ftruncate(ctfser->fd, ctfser->stream_size_bytes);
147 } while (ret == -1 && errno == EINTR);
148
149 if (ret) {
150 BT_LOGE_ERRNO("Failed to truncate stream file",
151 ": ret=%d, size-bytes=%" PRIu64,
152 ret, ctfser->stream_size_bytes);
153 goto end;
154 }
155
156
157 ret = close(ctfser->fd);
158 if (ret) {
159 BT_LOGE_ERRNO("Failed to close stream file",
160 ": ret=%d", ret);
161 goto end;
162 }
163
164 ctfser->fd = -1;
165
166 free_path:
167 if (ctfser->path) {
168 g_string_free(ctfser->path, TRUE);
169 ctfser->path = NULL;
170 }
171
172 end:
173 return ret;
174 }
175
176 int bt_ctfser_open_packet(struct bt_ctfser *ctfser)
177 {
178 int ret = 0;
179
180 BT_LOGD("Opening packet: path=\"%s\", fd=%d, "
181 "prev-packet-size-bytes=%" PRIu64,
182 ctfser->path->str, ctfser->fd,
183 ctfser->prev_packet_size_bytes);
184
185 if (ctfser->base_mma) {
186 /* Unmap old base (previous packet) */
187 ret = munmap_align(ctfser->base_mma);
188 if (ret) {
189 BT_LOGE_ERRNO("Failed to unmap stream file",
190 ": ret=%d, size-bytes=%" PRIu64,
191 ret, ctfser->stream_size_bytes);
192 goto end;
193 }
194
195 ctfser->base_mma = NULL;
196 }
197
198 /*
199 * Add the previous packet's size to the memory map address
200 * offset to start writing immediately after it.
201 */
202 ctfser->mmap_offset += ctfser->prev_packet_size_bytes;
203 ctfser->prev_packet_size_bytes = 0;
204
205 /* Make initial space for the current packet */
206 ctfser->cur_packet_size_bytes = get_packet_size_increment_bytes(
207 ctfser);
208
209 do {
210 ret = bt_posix_fallocate(ctfser->fd, ctfser->mmap_offset,
211 ctfser->cur_packet_size_bytes);
212 } while (ret == EINTR);
213
214 if (ret) {
215 BT_LOGE("Failed to preallocate memory space: ret=%d", ret);
216 goto end;
217 }
218
219 /* Start writing at the beginning of the current packet */
220 ctfser->offset_in_cur_packet_bits = 0;
221
222 /* Get new base address */
223 mmap_align_ctfser(ctfser);
224 if (ctfser->base_mma == MAP_FAILED) {
225 BT_LOGE_ERRNO("Failed to perform an aligned memory mapping",
226 ": ret=%d", ret);
227 ret = -1;
228 goto end;
229 }
230
231 BT_LOGD("Opened packet: path=\"%s\", fd=%d, "
232 "cur-packet-size-bytes=%" PRIu64,
233 ctfser->path->str, ctfser->fd,
234 ctfser->cur_packet_size_bytes);
235
236 end:
237 return ret;
238 }
239
240 void bt_ctfser_close_current_packet(struct bt_ctfser *ctfser,
241 uint64_t packet_size_bytes)
242 {
243 BT_LOGD("Closing packet: path=\"%s\", fd=%d, "
244 "offset-in-cur-packet-bits=%" PRIu64
245 "cur-packet-size-bytes=%" PRIu64,
246 ctfser->path->str, ctfser->fd,
247 ctfser->offset_in_cur_packet_bits,
248 ctfser->cur_packet_size_bytes);
249
250 /*
251 * This will be used during the next call to
252 * bt_ctfser_open_packet(): we add
253 * `ctfser->prev_packet_size_bytes` to the current memory map
254 * address offset (first byte of _this_ packet), effectively
255 * making _this_ packet the required size.
256 */
257 ctfser->prev_packet_size_bytes = packet_size_bytes;
258 ctfser->stream_size_bytes += packet_size_bytes;
259 BT_LOGD("Closed packet: path=\"%s\", fd=%d, "
260 "stream-file-size-bytes=%" PRIu64,
261 ctfser->path->str, ctfser->fd,
262 ctfser->stream_size_bytes);
263 }
This page took 0.035973 seconds and 4 git commands to generate.