2 * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 * 2018 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <common/common.h>
25 #include <common/fd-tracker/fd-tracker.h>
26 #include <common/fd-tracker/utils.h>
27 #include <common/utils.h>
29 #include "stream-fd.h"
30 #include "lttng-relayd.h"
33 struct fs_handle
*handle
;
37 static struct stream_fd
*_stream_fd_alloc(void)
41 sf
= zmalloc(sizeof(*sf
));
45 urcu_ref_init(&sf
->ref
);
50 static struct stream_fd
*stream_fd_suspendable_create(struct fs_handle
*handle
)
52 struct stream_fd
*stream_fd
= _stream_fd_alloc();
58 stream_fd
->handle
= handle
;
63 struct stream_fd
*stream_fd_open(const char *path
)
65 struct stream_fd
*stream_fd
= NULL
;
67 struct fs_handle
*handle
;
69 handle
= fd_tracker_open_fs_handle(the_fd_tracker
, path
,
75 stream_fd
= stream_fd_suspendable_create(handle
);
79 close_ret
= fs_handle_close(handle
);
81 ERR("Failed to close filesystem handle of stream at %s", path
);
89 struct fs_handle
*create_write_fs_handle(const char *path
)
91 struct fs_handle
*handle
;
93 * With the session rotation feature on the relay, we might need to seek
94 * and truncate a tracefile, so we need read and write access.
96 int flags
= O_RDWR
| O_CREAT
| O_TRUNC
;
97 /* Open with 660 mode */
98 mode_t mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
;
100 handle
= fd_tracker_open_fs_handle(the_fd_tracker
, path
, flags
, &mode
);
102 ERR("Failed to open fs handle to %s", path
);
109 * Stream file are created by on the consumerd/data-reception end. Those
110 * stream fds can be suspended as there is no expectation that the files
111 * will be unlinked and then need to be appended-to.
113 * Hence, the file descriptors are created as suspendable to allow the
114 * fd-tracker to reduce the number of active fds..
116 struct stream_fd
*stream_fd_create(const char *path_name
, const char *file_name
,
117 uint64_t size
, uint64_t count
, const char *suffix
)
119 struct stream_fd
*stream_fd
= NULL
;
120 struct fs_handle
*handle
;
124 ret
= utils_stream_file_name(path
, path_name
, file_name
,
125 size
, count
, suffix
);
130 handle
= create_write_fs_handle(path
);
135 stream_fd
= stream_fd_suspendable_create(handle
);
139 close_ret
= fs_handle_close(handle
);
141 ERR("Failed to close filesystem handle of stream at %s", path
);
150 * This unlink wrapper allows the fd_tracker to check if any other
151 * fs_handle references the stream before unlinking it. If the relay holds
152 * this file open, it is essential to unlink it through an fs_handle as this
153 * will delay the actual unlink() until all handles have released this file.
155 * The file is renamed and unlinked once the last handle to its inode has been
159 int unlink_through_handle(const char *path
)
161 int ret
= 0, close_ret
;
162 struct fs_handle
*handle
;
164 * Since this operation is only performed to perform the unlink
165 * through the fs_handle and fd-tracker system, the flag is opened
166 * without the O_CREAT. There is no need to perform the unlink if
167 * the file doesn't already exist.
169 int flags
= O_RDONLY
;
171 DBG("Unlinking stream at %s through a filesystem handle", path
);
172 handle
= fd_tracker_open_fs_handle(the_fd_tracker
, path
, flags
, NULL
);
174 /* There is nothing to do. */
175 DBG("File %s does not exist, ignoring unlink", path
);
179 ret
= fs_handle_unlink(handle
);
180 close_ret
= fs_handle_close(handle
);
182 ERR("Failed to close handle after performing an unlink operation on a filesystem handle");
186 DBG("Unlinking stream at %s failed with error code %i", path
, ret
);
191 int stream_fd_rotate(struct stream_fd
*stream_fd
, const char *path_name
,
192 const char *file_name
, uint64_t size
,
193 uint64_t count
, uint64_t *new_count
)
201 utils_stream_file_rotation_get_new_count(count
, new_count
,
204 ret
= utils_stream_file_name(path
, path_name
, file_name
,
210 ret
= fs_handle_close(stream_fd
->handle
);
211 stream_fd
->handle
= NULL
;
213 PERROR("Closing stream tracefile handle");
218 ret
= unlink_through_handle(path
);
224 ret
= utils_stream_file_name(path
, path_name
, file_name
,
225 size
, new_count
? *new_count
: 0, NULL
);
230 stream_fd
->handle
= create_write_fs_handle(path
);
231 if (!stream_fd
->handle
) {
242 void stream_fd_get(struct stream_fd
*sf
)
244 urcu_ref_get(&sf
->ref
);
247 static void stream_fd_release(struct urcu_ref
*ref
)
249 struct stream_fd
*sf
= caa_container_of(ref
, struct stream_fd
, ref
);
252 ret
= fs_handle_close(sf
->handle
);
254 PERROR("Error closing stream handle");
259 void stream_fd_put(struct stream_fd
*sf
)
261 urcu_ref_put(&sf
->ref
, stream_fd_release
);
264 int stream_fd_get_fd(struct stream_fd
*sf
)
266 return fs_handle_get_fd(sf
->handle
);
269 void stream_fd_put_fd(struct stream_fd
*sf
)
271 fs_handle_put_fd(sf
->handle
);
This page took 0.036725 seconds and 5 git commands to generate.