cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / ctfser / ctfser.c
CommitLineData
013f35c6 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
013f35c6 3 *
0235b0db 4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
013f35c6
PP
5 */
6
86d8b7b8 7#define BT_LOG_OUTPUT_LEVEL (ctfser->log_level)
013f35c6 8#define BT_LOG_TAG "CTFSER"
86d8b7b8 9#include "logging/log.h"
013f35c6
PP
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>
578e048b 17#include "common/assert.h"
013f35c6
PP
18#include <stdarg.h>
19#include <ctype.h>
20#include <glib.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <wchar.h>
91d81473 24#include "common/macros.h"
578e048b
MJ
25#include "common/common.h"
26#include "ctfser/ctfser.h"
27#include "compat/unistd.h"
28#include "compat/fcntl.h"
013f35c6
PP
29
30static inline
86d8b7b8 31uint64_t get_packet_size_increment_bytes(struct bt_ctfser *ctfser)
013f35c6 32{
86d8b7b8 33 return bt_common_get_page_size(ctfser->log_level) * 8;
013f35c6
PP
34}
35
36static inline
37void mmap_align_ctfser(struct bt_ctfser *ctfser)
38{
9223d1f3
MJ
39 ctfser->base_mma = mmap_align(ctfser->cur_packet_size_bytes,
40 PROT_READ | PROT_WRITE,
86d8b7b8 41 MAP_SHARED, ctfser->fd, ctfser->mmap_offset, ctfser->log_level);
013f35c6
PP
42}
43
013f35c6
PP
44int _bt_ctfser_increase_cur_packet_size(struct bt_ctfser *ctfser)
45{
46 int ret;
47
48 BT_ASSERT(ctfser);
3f7d4d90 49 BT_LOGD("Increasing stream file's current packet size: "
013f35c6
PP
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
86d8b7b8
PP
63 ctfser->cur_packet_size_bytes += get_packet_size_increment_bytes(
64 ctfser);
013f35c6
PP
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
3f7d4d90 84 BT_LOGD("Increased packet size: "
013f35c6
PP
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
92end:
93 return ret;
94}
95
86d8b7b8 96int bt_ctfser_init(struct bt_ctfser *ctfser, const char *path, int log_level)
013f35c6
PP
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);
86d8b7b8 104 ctfser->log_level = log_level;
013f35c6
PP
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
115end:
116 return ret;
117}
118
013f35c6
PP
119int bt_ctfser_fini(struct bt_ctfser *ctfser)
120{
121 int ret = 0;
122
123 if (ctfser->fd == -1) {
124 goto free_path;
125 }
126
a086573a
JR
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
013f35c6
PP
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
013f35c6
PP
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
166free_path:
167 if (ctfser->path) {
168 g_string_free(ctfser->path, TRUE);
169 ctfser->path = NULL;
170 }
171
172end:
173 return ret;
174}
175
013f35c6
PP
176int bt_ctfser_open_packet(struct bt_ctfser *ctfser)
177{
178 int ret = 0;
179
3f7d4d90 180 BT_LOGD("Opening packet: path=\"%s\", fd=%d, "
013f35c6
PP
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 */
86d8b7b8
PP
206 ctfser->cur_packet_size_bytes = get_packet_size_increment_bytes(
207 ctfser);
013f35c6
PP
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
3f7d4d90 231 BT_LOGD("Opened packet: path=\"%s\", fd=%d, "
013f35c6
PP
232 "cur-packet-size-bytes=%" PRIu64,
233 ctfser->path->str, ctfser->fd,
234 ctfser->cur_packet_size_bytes);
235
236end:
237 return ret;
238}
239
013f35c6
PP
240void bt_ctfser_close_current_packet(struct bt_ctfser *ctfser,
241 uint64_t packet_size_bytes)
242{
3f7d4d90 243 BT_LOGD("Closing packet: path=\"%s\", fd=%d, "
013f35c6
PP
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;
3f7d4d90 259 BT_LOGD("Closed packet: path=\"%s\", fd=%d, "
013f35c6
PP
260 "stream-file-size-bytes=%" PRIu64,
261 ctfser->path->str, ctfser->fd,
262 ctfser->stream_size_bytes);
263}
This page took 0.081533 seconds and 4 git commands to generate.