summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5c1f54d)
Currently, the lttng_directory_handle API assumes that the caller has
exclusive ownership of the lttng_directory_handle. Directory handles
are passed by reference and populated by an "init" method and
finalized using the "fini" method.
In order to allow multiple references to a path or directory file
descriptor in follow-up patches, the API is moved to a model where
directory handles are dynamically allocated and released using the
"put" method.
No change in behaviour is intended by this change beyond adapting the
API.
The objective of the change is to make it easier to implement copy
operations of trace chunks that are configured to use an fd-tracker
and reduce the number of open file descriptors when
lttng_directory_handles are copied.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Ibc8e97ea9e949adafef44533c30b61e3a9fa1f7d
15 files changed:
struct lttng_trace_chunk *chunk = NULL, *published_chunk = NULL;
enum lttng_error_code reply_code = LTTNG_OK;
enum lttng_trace_chunk_status chunk_status;
struct lttng_trace_chunk *chunk = NULL, *published_chunk = NULL;
enum lttng_error_code reply_code = LTTNG_OK;
enum lttng_trace_chunk_status chunk_status;
- struct lttng_directory_handle session_output;
+ struct lttng_directory_handle *session_output = NULL;
if (!session || !conn->version_check_done) {
ERR("Trying to create a trace chunk before version check");
if (!session || !conn->version_check_done) {
ERR("Trying to create a trace chunk before version check");
- ret = session_init_output_directory_handle(
- conn->session, &session_output);
- if (ret) {
+ session_output = session_create_output_directory_handle(
+ conn->session);
+ if (!session_output) {
reply_code = LTTNG_ERR_CREATE_DIR_FAIL;
goto end;
}
reply_code = LTTNG_ERR_CREATE_DIR_FAIL;
goto end;
}
- chunk_status = lttng_trace_chunk_set_as_owner(chunk, &session_output);
- lttng_directory_handle_fini(&session_output);
+ chunk_status = lttng_trace_chunk_set_as_owner(chunk, session_output);
+ lttng_directory_handle_put(session_output);
+ session_output = NULL;
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
reply_code = LTTNG_ERR_UNK;
ret = -1;
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
reply_code = LTTNG_ERR_UNK;
ret = -1;
end_no_reply:
lttng_trace_chunk_put(chunk);
lttng_trace_chunk_put(published_chunk);
end_no_reply:
lttng_trace_chunk_put(chunk);
lttng_trace_chunk_put(published_chunk);
+ lttng_directory_handle_put(session_output);
int ret = 0;
struct lttng_trace_chunk *chunk = NULL;
enum lttng_trace_chunk_status status;
int ret = 0;
struct lttng_trace_chunk *chunk = NULL;
enum lttng_trace_chunk_status status;
- struct lttng_directory_handle output_directory;
+ struct lttng_directory_handle *output_directory;
- ret = session_init_output_directory_handle(session, &output_directory);
- if (ret) {
+ output_directory = session_create_output_directory_handle(session);
+ if (!output_directory) {
- status = lttng_trace_chunk_set_as_owner(chunk, &output_directory);
+ status = lttng_trace_chunk_set_as_owner(chunk, output_directory);
if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ret = -1;
goto end;
}
if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ret = -1;
goto end;
}
+ output_directory = NULL;
session->current_trace_chunk = chunk;
chunk = NULL;
end:
lttng_trace_chunk_put(chunk);
session->current_trace_chunk = chunk;
chunk = NULL;
end:
lttng_trace_chunk_put(chunk);
- lttng_directory_handle_fini(&output_directory);
+ lttng_directory_handle_put(output_directory);
-int session_init_output_directory_handle(struct relay_session *session,
- struct lttng_directory_handle *handle)
+struct lttng_directory_handle *session_create_output_directory_handle(
+ struct relay_session *session)
* e.g. /home/user/lttng-traces/hostname/session_name
*/
char *full_session_path = NULL;
* e.g. /home/user/lttng-traces/hostname/session_name
*/
char *full_session_path = NULL;
+ struct lttng_directory_handle *handle = NULL;
pthread_mutex_lock(&session->lock);
full_session_path = create_output_path(session->output_path);
if (!full_session_path) {
pthread_mutex_lock(&session->lock);
full_session_path = create_output_path(session->output_path);
if (!full_session_path) {
- ret = lttng_directory_handle_init(handle, full_session_path);
- if (ret) {
- goto end;
- }
+ handle = lttng_directory_handle_create(full_session_path);
end:
pthread_mutex_unlock(&session->lock);
free(full_session_path);
end:
pthread_mutex_unlock(&session->lock);
free(full_session_path);
int session_close(struct relay_session *session);
int session_abort(struct relay_session *session);
int session_close(struct relay_session *session);
int session_abort(struct relay_session *session);
-int session_init_output_directory_handle(struct relay_session *session,
- struct lttng_directory_handle *handle);
+struct lttng_directory_handle *session_create_output_directory_handle(
+ struct relay_session *session);
void print_sessions(void);
void print_sessions(void);
msg.u.create_trace_chunk.chunk_id = chunk_id;
if (chunk_has_local_output) {
msg.u.create_trace_chunk.chunk_id = chunk_id;
if (chunk_has_local_output) {
- chunk_status = lttng_trace_chunk_get_chunk_directory_handle(
+ chunk_status = lttng_trace_chunk_borrow_chunk_directory_handle(
chunk, &chunk_directory_handle);
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ret = -LTTNG_ERR_FATAL;
chunk, &chunk_directory_handle);
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ret = -LTTNG_ERR_FATAL;
const time_t chunk_creation_ts = time(NULL);
bool is_local_trace;
const char *base_path;
const time_t chunk_creation_ts = time(NULL);
bool is_local_trace;
const char *base_path;
- struct lttng_directory_handle session_output_directory;
+ struct lttng_directory_handle *session_output_directory = NULL;
const struct lttng_credentials session_credentials = {
.uid = session->uid,
.gid = session->gid,
const struct lttng_credentials session_credentials = {
.uid = session->uid,
.gid = session->gid,
- ret = lttng_directory_handle_init(&session_output_directory,
- base_path);
- if (ret) {
+ session_output_directory = lttng_directory_handle_create(base_path);
+ if (!session_output_directory) {
goto error;
}
chunk_status = lttng_trace_chunk_set_as_owner(trace_chunk,
goto error;
}
chunk_status = lttng_trace_chunk_set_as_owner(trace_chunk,
- &session_output_directory);
- lttng_directory_handle_fini(&session_output_directory);
+ session_output_directory);
+ lttng_directory_handle_put(session_output_directory);
+ session_output_directory = NULL;
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
goto error;
}
end:
return trace_chunk;
error:
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
goto error;
}
end:
return trace_chunk;
error:
+ lttng_directory_handle_put(session_output_directory);
lttng_trace_chunk_put(trace_chunk);
trace_chunk = NULL;
goto end;
lttng_trace_chunk_put(trace_chunk);
trace_chunk = NULL;
goto end;
uid_t uid, gid_t gid, int flags);
static
void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle);
uid_t uid, gid_t gid, int flags);
static
void lttng_directory_handle_invalidate(struct lttng_directory_handle *handle);
+static
+void lttng_directory_handle_release(struct urcu_ref *ref);
#ifdef COMPAT_DIRFD
LTTNG_HIDDEN
#ifdef COMPAT_DIRFD
LTTNG_HIDDEN
-int lttng_directory_handle_init(struct lttng_directory_handle *new_handle,
- const char *path)
+struct lttng_directory_handle *lttng_directory_handle_create(const char *path)
{
const struct lttng_directory_handle cwd_handle = {
.dirfd = AT_FDCWD,
};
/* Open a handle to the CWD if NULL is passed. */
{
const struct lttng_directory_handle cwd_handle = {
.dirfd = AT_FDCWD,
};
/* Open a handle to the CWD if NULL is passed. */
- return lttng_directory_handle_init_from_handle(new_handle,
- path,
- &cwd_handle);
+ return lttng_directory_handle_create_from_handle(path, &cwd_handle);
-int lttng_directory_handle_init_from_handle(
- struct lttng_directory_handle *new_handle, const char *path,
- const struct lttng_directory_handle *handle)
+struct lttng_directory_handle *lttng_directory_handle_create_from_handle(
+ const char *path,
+ const struct lttng_directory_handle *ref_handle)
+ int dirfd;
+ struct lttng_directory_handle *handle = NULL;
- ret = lttng_directory_handle_copy(handle, new_handle);
+ handle = lttng_directory_handle_copy(ref_handle);
goto end;
}
if (!*path) {
ERR("Failed to initialize directory handle: provided path is an empty string");
goto end;
}
if (!*path) {
ERR("Failed to initialize directory handle: provided path is an empty string");
- ret = openat(handle->dirfd, path, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
- if (ret == -1) {
+
+ dirfd = openat(ref_handle->dirfd, path, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
+ if (dirfd == -1) {
PERROR("Failed to initialize directory handle to \"%s\"", path);
goto end;
}
PERROR("Failed to initialize directory handle to \"%s\"", path);
goto end;
}
- new_handle->dirfd = ret;
- ret = 0;
+
+ handle = lttng_directory_handle_create_from_dirfd(dirfd);
+ if (!handle) {
+ goto error_close;
+ }
+ return handle;
+error_close:
+ if (close(dirfd)) {
+ PERROR("Failed to close directory file descriptor");
+ }
+ return NULL;
-int lttng_directory_handle_init_from_dirfd(
- struct lttng_directory_handle *handle, int dirfd)
+struct lttng_directory_handle *lttng_directory_handle_create_from_dirfd(
+ int dirfd)
+ struct lttng_directory_handle *handle = zmalloc(sizeof(*handle));
+
+ if (!handle) {
+ goto end;
+ }
+ urcu_ref_init(&handle->ref);
+end:
+ return handle;
-LTTNG_HIDDEN
-void lttng_directory_handle_fini(struct lttng_directory_handle *handle)
+static
+void lttng_directory_handle_release(struct urcu_ref *ref)
+ struct lttng_directory_handle *handle =
+ container_of(ref, struct lttng_directory_handle, ref);
if (handle->dirfd == AT_FDCWD || handle->dirfd == -1) {
goto end;
if (handle->dirfd == AT_FDCWD || handle->dirfd == -1) {
goto end;
ret = close(handle->dirfd);
if (ret == -1) {
PERROR("Failed to close directory file descriptor of directory handle");
ret = close(handle->dirfd);
if (ret == -1) {
PERROR("Failed to close directory file descriptor of directory handle");
}
end:
lttng_directory_handle_invalidate(handle);
}
end:
lttng_directory_handle_invalidate(handle);
-int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
- struct lttng_directory_handle *new_copy)
+struct lttng_directory_handle *lttng_directory_handle_copy(
+ const struct lttng_directory_handle *handle)
+ struct lttng_directory_handle *new_handle = NULL;
if (handle->dirfd == AT_FDCWD) {
if (handle->dirfd == AT_FDCWD) {
- new_copy->dirfd = handle->dirfd;
+ new_handle = lttng_directory_handle_create_from_dirfd(AT_FDCWD);
- new_copy->dirfd = dup(handle->dirfd);
- if (new_copy->dirfd == -1) {
- PERROR("Failed to duplicate directory fd of directory handle");
- ret = -1;
+ const int new_dirfd = dup(handle->dirfd);
+
+ if (new_dirfd == -1) {
+ PERROR("Failed to duplicate directory file descriptor of directory handle");
+ goto end;
+ }
+ new_handle = lttng_directory_handle_create_from_dirfd(
+ new_dirfd);
+ if (!new_handle && close(new_dirfd)) {
+ PERROR("Failed to close directory file descriptor of directory handle");
+end:
+ return new_handle;
+static
+struct lttng_directory_handle *_lttng_directory_handle_create(char *path)
+{
+ struct lttng_directory_handle *handle = zmalloc(sizeof(*handle));
+
+ if (!handle) {
+ goto end;
+ }
+ urcu_ref_init(&handle->ref);
+ handle->base_path = path;
+end:
+ return handle;
+}
+
-int lttng_directory_handle_init(struct lttng_directory_handle *handle,
+struct lttng_directory_handle *lttng_directory_handle_create(
const char *path)
{
int ret;
const char *path)
{
int ret;
size_t cwd_len, path_len;
char cwd_buf[LTTNG_PATH_MAX] = {};
char handle_buf[LTTNG_PATH_MAX] = {};
size_t cwd_len, path_len;
char cwd_buf[LTTNG_PATH_MAX] = {};
char handle_buf[LTTNG_PATH_MAX] = {};
+ struct lttng_directory_handle *new_handle = NULL;
bool add_cwd_slash = false, add_trailing_slash = false;
const struct lttng_directory_handle cwd_handle = {
.base_path = handle_buf,
bool add_cwd_slash = false, add_trailing_slash = false;
const struct lttng_directory_handle cwd_handle = {
.base_path = handle_buf,
- ret = lttng_directory_handle_init_from_handle(handle, path,
- &cwd_handle);
+ new_handle = lttng_directory_handle_create_from_handle(path, &cwd_handle);
-int lttng_directory_handle_init_from_handle(
- struct lttng_directory_handle *new_handle, const char *path,
- const struct lttng_directory_handle *handle)
+struct lttng_directory_handle *lttng_directory_handle_create_from_handle(
+ const char *path,
+ const struct lttng_directory_handle *ref_handle)
{
int ret;
size_t path_len, handle_path_len;
bool add_trailing_slash;
struct stat stat_buf;
{
int ret;
size_t path_len, handle_path_len;
bool add_trailing_slash;
struct stat stat_buf;
+ struct lttng_directory_handle *new_handle = NULL;
+ char *new_path = NULL;
- assert(handle && handle->base_path);
+ assert(ref_handle && ref_handle->base_path);
- ret = lttng_directory_handle_stat(handle, path, &stat_buf);
+ ret = lttng_directory_handle_stat(ref_handle, path, &stat_buf);
if (ret == -1) {
PERROR("Failed to create directory handle");
goto end;
if (ret == -1) {
PERROR("Failed to create directory handle");
goto end;
char full_path[LTTNG_PATH_MAX];
/* Best effort for logging purposes. */
char full_path[LTTNG_PATH_MAX];
/* Best effort for logging purposes. */
- ret = get_full_path(handle, path, full_path,
+ ret = get_full_path(ref_handle, path, full_path,
sizeof(full_path));
if (ret) {
full_path[0] = '\0';
sizeof(full_path));
if (ret) {
full_path[0] = '\0';
ERR("Failed to initialize directory handle to \"%s\": not a directory",
full_path);
ERR("Failed to initialize directory handle to \"%s\": not a directory",
full_path);
- ret = lttng_directory_handle_copy(handle, new_handle);
+ new_handle = lttng_directory_handle_copy(ref_handle);
goto end;
}
if (*path == '/') {
goto end;
}
if (*path == '/') {
- new_handle->base_path = strdup(path);
- ret = new_handle->base_path ? 0 : -1;
+ new_path = strdup(path);
+ if (!new_path) {
+ goto end;
+ }
+ /* Takes ownership of new_path. */
+ new_handle = _lttng_directory_handle_create(new_path);
+ new_path = NULL;
goto end;
}
add_trailing_slash = path[path_len - 1] != '/';
goto end;
}
add_trailing_slash = path[path_len - 1] != '/';
- handle_path_len = strlen(handle->base_path) + path_len +
+ handle_path_len = strlen(ref_handle->base_path) + path_len +
!!add_trailing_slash;
if (handle_path_len >= LTTNG_PATH_MAX) {
ERR("Failed to initialize directory handle as the resulting path's length (%zu bytes) exceeds the maximal allowed length (%d bytes)",
handle_path_len, LTTNG_PATH_MAX);
!!add_trailing_slash;
if (handle_path_len >= LTTNG_PATH_MAX) {
ERR("Failed to initialize directory handle as the resulting path's length (%zu bytes) exceeds the maximal allowed length (%d bytes)",
handle_path_len, LTTNG_PATH_MAX);
- new_handle->base_path = zmalloc(handle_path_len);
- if (!new_handle->base_path) {
+ new_path = zmalloc(handle_path_len);
+ if (!new_path) {
PERROR("Failed to initialize directory handle");
PERROR("Failed to initialize directory handle");
goto end;
}
ret = sprintf(new_handle->base_path, "%s%s%s",
goto end;
}
ret = sprintf(new_handle->base_path, "%s%s%s",
path,
add_trailing_slash ? "/" : "");
if (ret == -1 || ret >= handle_path_len) {
ERR("Failed to initialize directory handle: path formatting failed");
path,
add_trailing_slash ? "/" : "");
if (ret == -1 || ret >= handle_path_len) {
ERR("Failed to initialize directory handle: path formatting failed");
+ new_handle = _lttng_directory_handle_create(new_path);
+ new_path = NULL;
+ free(new_path);
+ return new_handle;
-int lttng_directory_handle_init_from_dirfd(
- struct lttng_directory_handle *handle, int dirfd)
+struct lttng_directory_handle *lttng_directory_handle_create_from_dirfd(
+ int dirfd)
{
assert(dirfd == AT_FDCWD);
{
assert(dirfd == AT_FDCWD);
- return lttng_directory_handle_init(handle, NULL);
+ return lttng_directory_handle_create(NULL);
-LTTNG_HIDDEN
-void lttng_directory_handle_fini(struct lttng_directory_handle *handle)
+static
+void lttng_directory_handle_release(struct urcu_ref *ref)
+ struct lttng_directory_handle *handle =
+ container_of(ref, struct lttng_directory_handle, ref);
+
free(handle->base_path);
lttng_directory_handle_invalidate(handle);
free(handle->base_path);
lttng_directory_handle_invalidate(handle);
-int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
- struct lttng_directory_handle *new_copy)
+struct lttng_directory_handle *lttng_directory_handle_copy(
+ const struct lttng_directory_handle *handle)
- new_copy->base_path = strdup(handle->base_path);
- return new_copy->base_path ? 0 : -1;
+ struct lttng_directory_handle *new_handle = NULL;
+ char *new_path = NULL;
+
+ if (handle->base_path) {
+ new_path = strdup(handle->base_path);
+ if (!new_path) {
+ goto end;
+ }
+ }
+ new_handle = _lttng_directory_handle_create(new_path);
+end:
+ return new_handle;
-LTTNG_HIDDEN
-struct lttng_directory_handle
-lttng_directory_handle_move(struct lttng_directory_handle *original)
-{
- const struct lttng_directory_handle tmp = *original;
-
- lttng_directory_handle_invalidate(original);
- return tmp;
-}
-
static
int create_directory_recursive(const struct lttng_directory_handle *handle,
const char *path, mode_t mode)
static
int create_directory_recursive(const struct lttng_directory_handle *handle,
const char *path, mode_t mode)
+LTTNG_HIDDEN
+bool lttng_directory_handle_get(struct lttng_directory_handle *handle)
+{
+ return urcu_ref_get_unless_zero(&handle->ref);
+}
+
+LTTNG_HIDDEN
+void lttng_directory_handle_put(struct lttng_directory_handle *handle)
+{
+ if (!handle) {
+ return;
+ }
+ assert(handle->ref.refcount);
+ urcu_ref_put(&handle->ref, lttng_directory_handle_release);
+}
+
LTTNG_HIDDEN
int lttng_directory_handle_create_subdirectory_as_user(
const struct lttng_directory_handle *handle,
LTTNG_HIDDEN
int lttng_directory_handle_create_subdirectory_as_user(
const struct lttng_directory_handle *handle,
#include <common/macros.h>
#include <common/credentials.h>
#include <common/macros.h>
#include <common/credentials.h>
enum lttng_directory_handle_rmdir_recursive_flags {
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG = (1U << 0),
enum lttng_directory_handle_rmdir_recursive_flags {
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG = (1U << 0),
*/
#ifdef COMPAT_DIRFD
struct lttng_directory_handle {
*/
#ifdef COMPAT_DIRFD
struct lttng_directory_handle {
#else
struct lttng_directory_handle {
#else
struct lttng_directory_handle {
char *base_path;
};
#endif
/*
char *base_path;
};
#endif
/*
- * Initialize a directory handle to the provided path. Passing a NULL path
+ * Create a directory handle to the provided path. Passing a NULL path
* returns a handle to the current working directory.
*
* returns a handle to the current working directory.
*
- * An initialized directory handle must be finalized using
- * lttng_directory_handle_fini().
+ * The reference to the directory handle must be released using
+ * lttng_directory_handle_put().
-int lttng_directory_handle_init(struct lttng_directory_handle *handle,
+struct lttng_directory_handle *lttng_directory_handle_create(
- * Initialize a new directory handle to a path relative to an existing handle.
+ * Create a new directory handle to a path relative to an existing handle.
*
* The provided path must already exist. Note that the creation of a
* subdirectory and the creation of a handle are kept as separate operations
*
* The provided path must already exist. Note that the creation of a
* subdirectory and the creation of a handle are kept as separate operations
*
* Passing a NULL path effectively copies the original handle.
*
*
* Passing a NULL path effectively copies the original handle.
*
- * An initialized directory handle must be finalized using
- * lttng_directory_handle_fini().
+ * The reference to the directory handle must be released using
+ * lttng_directory_handle_put().
-int lttng_directory_handle_init_from_handle(
- struct lttng_directory_handle *new_handle,
+struct lttng_directory_handle *lttng_directory_handle_create_from_handle(
- const struct lttng_directory_handle *handle);
+ const struct lttng_directory_handle *ref_handle);
- * Initialize a new directory handle from an existing directory fd.
+ * Create a new directory handle from an existing directory fd.
*
* The new directory handle assumes the ownership of the directory fd.
* Note that this method should only be used in very specific cases, such as
* re-creating a directory handle from a dirfd passed over a unix socket.
*
*
* The new directory handle assumes the ownership of the directory fd.
* Note that this method should only be used in very specific cases, such as
* re-creating a directory handle from a dirfd passed over a unix socket.
*
- * An initialized directory handle must be finalized using
- * lttng_directory_handle_fini().
+ * The reference to the directory handle must be released using
+ * lttng_directory_handle_put().
-int lttng_directory_handle_init_from_dirfd(
- struct lttng_directory_handle *handle, int dirfd);
+struct lttng_directory_handle *lttng_directory_handle_create_from_dirfd(
+ int dirfd);
/*
* Copy a directory handle.
/*
* Copy a directory handle.
+ *
+ * The reference to the directory handle must be released using
+ * lttng_directory_handle_put().
-int lttng_directory_handle_copy(const struct lttng_directory_handle *handle,
- struct lttng_directory_handle *new_copy);
+struct lttng_directory_handle *lttng_directory_handle_copy(
+ const struct lttng_directory_handle *handle);
- * Move a directory handle. The original directory handle may no longer be
- * used after this call. This call cannot fail; directly assign the
- * return value to the new directory handle.
- *
- * It is safe (but unnecessary) to call lttng_directory_handle_fini on the
- * original handle.
+ * Acquire a reference to a directory handle.
-struct lttng_directory_handle
-lttng_directory_handle_move(struct lttng_directory_handle *original);
+bool lttng_directory_handle_get(struct lttng_directory_handle *handle);
- * Release the resources of a directory handle.
+ * Release a reference to a directory handle.
-void lttng_directory_handle_fini(struct lttng_directory_handle *handle);
+void lttng_directory_handle_put(struct lttng_directory_handle *handle);
/*
* Create a subdirectory relative to a directory handle.
/*
* Create a subdirectory relative to a directory handle.
*/
chunk_status = lttng_trace_chunk_set_as_user(created_chunk,
chunk_directory_handle);
*/
chunk_status = lttng_trace_chunk_set_as_user(created_chunk,
chunk_directory_handle);
+ chunk_directory_handle = NULL;
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ERR("Failed to set trace chunk's directory handle");
ret_code = LTTCOMM_CONSUMERD_CREATE_TRACE_CHUNK_FAILED;
if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
ERR("Failed to set trace chunk's directory handle");
ret_code = LTTCOMM_CONSUMERD_CREATE_TRACE_CHUNK_FAILED;
*msg.u.create_trace_chunk.override_name ?
msg.u.create_trace_chunk.override_name :
NULL;
*msg.u.create_trace_chunk.override_name ?
msg.u.create_trace_chunk.override_name :
NULL;
- LTTNG_OPTIONAL(struct lttng_directory_handle) chunk_directory_handle =
- LTTNG_OPTIONAL_INIT;
+ struct lttng_directory_handle *chunk_directory_handle = NULL;
/*
* The session daemon will only provide a chunk directory file
/*
* The session daemon will only provide a chunk directory file
DBG("Received trace chunk directory fd (%d)",
chunk_dirfd);
DBG("Received trace chunk directory fd (%d)",
chunk_dirfd);
- ret = lttng_directory_handle_init_from_dirfd(
- &chunk_directory_handle.value,
+ chunk_directory_handle = lttng_directory_handle_create_from_dirfd(
+ if (!chunk_directory_handle) {
ERR("Failed to initialize chunk directory handle from directory file descriptor");
if (close(chunk_dirfd)) {
PERROR("Failed to close chunk directory file descriptor");
}
goto error_fatal;
}
ERR("Failed to initialize chunk directory handle from directory file descriptor");
if (close(chunk_dirfd)) {
PERROR("Failed to close chunk directory file descriptor");
}
goto error_fatal;
}
- chunk_directory_handle.is_set = true;
}
ret_code = lttng_consumer_create_trace_chunk(
}
ret_code = lttng_consumer_create_trace_chunk(
msg.u.create_trace_chunk.credentials.is_set ?
&credentials :
NULL,
msg.u.create_trace_chunk.credentials.is_set ?
&credentials :
NULL,
- chunk_directory_handle.is_set ?
- &chunk_directory_handle.value :
- NULL);
-
- if (chunk_directory_handle.is_set) {
- lttng_directory_handle_fini(
- &chunk_directory_handle.value);
- }
+ chunk_directory_handle);
+ lttng_directory_handle_put(chunk_directory_handle);
goto end_msg_sessiond;
}
case LTTNG_CONSUMER_CLOSE_TRACE_CHUNK:
goto end_msg_sessiond;
}
case LTTNG_CONSUMER_CLOSE_TRACE_CHUNK:
{
const char *path;
mode_t mode;
{
const char *path;
mode_t mode;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
path = data->u.mkdir.path;
mode = data->u.mkdir.mode;
path = data->u.mkdir.path;
mode = data->u.mkdir.mode;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.mkdir.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.mkdir.dirfd);
+ if (!handle) {
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ ret_value->u.ret = -1;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.mkdir.dirfd = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
/* Ownership of dirfd is transferred to the handle. */
data->u.mkdir.dirfd = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
- ret_value->u.ret =
- lttng_directory_handle_create_subdirectory_recursive(
- &handle, path, mode);
+ ret_value->u.ret = lttng_directory_handle_create_subdirectory_recursive(
+ handle, path, mode);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
return ret_value->u.ret;
}
{
const char *path;
mode_t mode;
{
const char *path;
mode_t mode;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
path = data->u.mkdir.path;
mode = data->u.mkdir.mode;
path = data->u.mkdir.path;
mode = data->u.mkdir.mode;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.mkdir.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.mkdir.dirfd);
+ if (!handle) {
+ ret_value->u.ret = -1;
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.mkdir.dirfd = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
/* Ownership of dirfd is transferred to the handle. */
data->u.mkdir.dirfd = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
- ret_value->u.ret =
- lttng_directory_handle_create_subdirectory(
- &handle, path, mode);
+ ret_value->u.ret = lttng_directory_handle_create_subdirectory(
+ handle, path, mode);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
return ret_value->u.ret;
}
int _open(struct run_as_data *data, struct run_as_ret *ret_value)
{
int fd;
int _open(struct run_as_data *data, struct run_as_ret *ret_value)
{
int fd;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.open.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.open.dirfd);
+ if (!handle) {
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ ret_value->u.ret = -1;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.open.dirfd = -1;
/* Ownership of dirfd is transferred to the handle. */
data->u.open.dirfd = -1;
- fd = lttng_directory_handle_open_file(&handle,
+ fd = lttng_directory_handle_open_file(handle,
data->u.open.path, data->u.open.flags,
data->u.open.mode);
if (fd < 0) {
data->u.open.path, data->u.open.flags,
data->u.open.mode);
if (fd < 0) {
ret_value->_errno = errno;
ret_value->_error = fd < 0;
ret_value->_errno = errno;
ret_value->_error = fd < 0;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
static
int _unlink(struct run_as_data *data, struct run_as_ret *ret_value)
{
return ret_value->u.ret;
}
static
int _unlink(struct run_as_data *data, struct run_as_ret *ret_value)
{
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.unlink.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.unlink.dirfd);
+ if (!handle) {
+ ret_value->u.ret = -1;
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.unlink.dirfd = -1;
/* Ownership of dirfd is transferred to the handle. */
data->u.unlink.dirfd = -1;
- ret_value->u.ret = lttng_directory_handle_unlink_file(&handle,
+ ret_value->u.ret = lttng_directory_handle_unlink_file(handle,
data->u.unlink.path);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
data->u.unlink.path);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
static
int _rmdir(struct run_as_data *data, struct run_as_ret *ret_value)
{
return ret_value->u.ret;
}
static
int _rmdir(struct run_as_data *data, struct run_as_ret *ret_value)
{
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.rmdir.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.rmdir.dirfd);
+ if (!handle) {
+ ret_value->u.ret = -1;
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.rmdir.dirfd = -1;
ret_value->u.ret = lttng_directory_handle_remove_subdirectory(
/* Ownership of dirfd is transferred to the handle. */
data->u.rmdir.dirfd = -1;
ret_value->u.ret = lttng_directory_handle_remove_subdirectory(
- &handle, data->u.rmdir.path);
+ handle, data->u.rmdir.path);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
static
int _rmdir_recursive(struct run_as_data *data, struct run_as_ret *ret_value)
{
return ret_value->u.ret;
}
static
int _rmdir_recursive(struct run_as_data *data, struct run_as_ret *ret_value)
{
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
- (void) lttng_directory_handle_init_from_dirfd(&handle,
- data->u.rmdir.dirfd);
+ handle = lttng_directory_handle_create_from_dirfd(data->u.rmdir.dirfd);
+ if (!handle) {
+ ret_value->u.ret = -1;
+ ret_value->_errno = errno;
+ ret_value->_error = true;
+ goto end;
+ }
/* Ownership of dirfd is transferred to the handle. */
data->u.rmdir.dirfd = -1;
ret_value->u.ret = lttng_directory_handle_remove_subdirectory_recursive(
/* Ownership of dirfd is transferred to the handle. */
data->u.rmdir.dirfd = -1;
ret_value->u.ret = lttng_directory_handle_remove_subdirectory_recursive(
- &handle, data->u.rmdir.path, data->u.rmdir.flags);
+ handle, data->u.rmdir.path, data->u.rmdir.flags);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
+end:
return ret_value->u.ret;
}
return ret_value->u.ret;
}
int _rename(struct run_as_data *data, struct run_as_ret *ret_value)
{
const char *old_path, *new_path;
int _rename(struct run_as_data *data, struct run_as_ret *ret_value)
{
const char *old_path, *new_path;
- struct lttng_directory_handle old_handle, new_handle;
+ struct lttng_directory_handle *old_handle = NULL, *new_handle = NULL;
old_path = data->u.rename.old_path;
new_path = data->u.rename.new_path;
old_path = data->u.rename.old_path;
new_path = data->u.rename.new_path;
- (void) lttng_directory_handle_init_from_dirfd(&old_handle,
+ old_handle = lttng_directory_handle_create_from_dirfd(
data->u.rename.dirfds[0]);
data->u.rename.dirfds[0]);
- (void) lttng_directory_handle_init_from_dirfd(&new_handle,
+ if (!old_handle) {
+ ret_value->u.ret = -1;
+ goto end;
+ }
+ new_handle = lttng_directory_handle_create_from_dirfd(
data->u.rename.dirfds[1]);
data->u.rename.dirfds[1]);
+ if (!new_handle) {
+ ret_value->u.ret = -1;
+ goto end;
+ }
/* Ownership of dirfds are transferred to the handles. */
data->u.rename.dirfds[0] = data->u.rename.dirfds[1] = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
ret_value->u.ret = lttng_directory_handle_rename(
/* Ownership of dirfds are transferred to the handles. */
data->u.rename.dirfds[0] = data->u.rename.dirfds[1] = -1;
/* Safe to call as we have transitioned to the requested uid/gid. */
ret_value->u.ret = lttng_directory_handle_rename(
- &old_handle, old_path, &new_handle, new_path);
+ old_handle, old_path, new_handle, new_path);
+end:
+ lttng_directory_handle_put(old_handle);
+ lttng_directory_handle_put(new_handle);
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
ret_value->_errno = errno;
ret_value->_error = (ret_value->u.ret) ? true : false;
- lttng_directory_handle_fini(&old_handle);
- lttng_directory_handle_fini(&new_handle);
return ret_value->u.ret;
}
return ret_value->u.ret;
}
LTTNG_OPTIONAL(time_t) timestamp_creation;
LTTNG_OPTIONAL(time_t) timestamp_close;
LTTNG_OPTIONAL(struct chunk_credentials) credentials;
LTTNG_OPTIONAL(time_t) timestamp_creation;
LTTNG_OPTIONAL(time_t) timestamp_close;
LTTNG_OPTIONAL(struct chunk_credentials) credentials;
- LTTNG_OPTIONAL(struct lttng_directory_handle) session_output_directory;
- LTTNG_OPTIONAL(struct lttng_directory_handle) chunk_directory;
+ struct lttng_directory_handle *session_output_directory;
+ struct lttng_directory_handle *chunk_directory;
LTTNG_OPTIONAL(enum lttng_trace_chunk_command_type) close_command;
};
LTTNG_OPTIONAL(enum lttng_trace_chunk_command_type) close_command;
};
static
void lttng_trace_chunk_fini(struct lttng_trace_chunk *chunk)
{
static
void lttng_trace_chunk_fini(struct lttng_trace_chunk *chunk)
{
- if (chunk->session_output_directory.is_set) {
- lttng_directory_handle_fini(
- &chunk->session_output_directory.value);
+ if (chunk->session_output_directory) {
+ lttng_directory_handle_put(
+ chunk->session_output_directory);
+ chunk->session_output_directory = NULL;
- if (chunk->chunk_directory.is_set) {
- lttng_directory_handle_fini(&chunk->chunk_directory.value);
+ if (chunk->chunk_directory) {
+ lttng_directory_handle_put(chunk->chunk_directory);
+ chunk->chunk_directory = NULL;
}
free(chunk->name);
chunk->name = NULL;
}
free(chunk->name);
chunk->name = NULL;
new_chunk->timestamp_creation = source_chunk->timestamp_creation;
new_chunk->timestamp_close = source_chunk->timestamp_close;
new_chunk->credentials = source_chunk->credentials;
new_chunk->timestamp_creation = source_chunk->timestamp_creation;
new_chunk->timestamp_close = source_chunk->timestamp_close;
new_chunk->credentials = source_chunk->credentials;
- if (source_chunk->session_output_directory.is_set) {
- if (lttng_directory_handle_copy(
- &source_chunk->session_output_directory.value,
- &new_chunk->session_output_directory.value)) {
- goto error_unlock;
- } else {
- new_chunk->session_output_directory.is_set = true;
- }
+ if (source_chunk->session_output_directory) {
+ const bool reference_acquired = lttng_directory_handle_get(
+ source_chunk->session_output_directory);
+
+ assert(reference_acquired);
+ new_chunk->session_output_directory =
+ source_chunk->session_output_directory;
- if (source_chunk->chunk_directory.is_set) {
- if (lttng_directory_handle_copy(
- &source_chunk->chunk_directory.value,
- &new_chunk->chunk_directory.value)) {
- goto error_unlock;
- } else {
- new_chunk->chunk_directory.is_set = true;
- }
+ if (source_chunk->chunk_directory) {
+ const bool reference_acquired = lttng_directory_handle_get(
+ source_chunk->chunk_directory);
+
+ assert(reference_acquired);
+ new_chunk->chunk_directory = source_chunk->chunk_directory;
}
new_chunk->close_command = source_chunk->close_command;
pthread_mutex_unlock(&source_chunk->lock);
}
new_chunk->close_command = source_chunk->close_command;
pthread_mutex_unlock(&source_chunk->lock);
{
int ret;
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
{
int ret;
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
- struct lttng_directory_handle chunk_directory_handle;
+ struct lttng_directory_handle *chunk_directory_handle = NULL;
+ bool reference_acquired;
pthread_mutex_lock(&chunk->lock);
if (chunk->mode.is_set) {
pthread_mutex_lock(&chunk->lock);
if (chunk->mode.is_set) {
- ret = lttng_directory_handle_init_from_handle(&chunk_directory_handle,
+ chunk_directory_handle = lttng_directory_handle_create_from_handle(
chunk->name,
session_output_directory);
chunk->name,
session_output_directory);
+ if (!chunk_directory_handle) {
/* The function already logs on all error paths. */
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
/* The function already logs on all error paths. */
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
- LTTNG_OPTIONAL_SET(&chunk->session_output_directory,
- lttng_directory_handle_move(session_output_directory));
- LTTNG_OPTIONAL_SET(&chunk->chunk_directory,
- lttng_directory_handle_move(&chunk_directory_handle));
+ chunk->chunk_directory = chunk_directory_handle;
+ chunk_directory_handle = NULL;
+ reference_acquired = lttng_directory_handle_get(
+ session_output_directory);
+ assert(reference_acquired);
+ chunk->session_output_directory = session_output_directory;
LTTNG_OPTIONAL_SET(&chunk->mode, TRACE_CHUNK_MODE_OWNER);
end:
pthread_mutex_unlock(&chunk->lock);
LTTNG_OPTIONAL_SET(&chunk->mode, TRACE_CHUNK_MODE_OWNER);
end:
pthread_mutex_unlock(&chunk->lock);
struct lttng_directory_handle *chunk_directory)
{
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
struct lttng_directory_handle *chunk_directory)
{
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
+ bool reference_acquired;
pthread_mutex_lock(&chunk->lock);
if (chunk->mode.is_set) {
pthread_mutex_lock(&chunk->lock);
if (chunk->mode.is_set) {
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
- LTTNG_OPTIONAL_SET(&chunk->chunk_directory,
- lttng_directory_handle_move(chunk_directory));
+ reference_acquired = lttng_directory_handle_get(chunk_directory);
+ assert(reference_acquired);
+ chunk->chunk_directory = chunk_directory;
LTTNG_OPTIONAL_SET(&chunk->mode, TRACE_CHUNK_MODE_USER);
end:
pthread_mutex_unlock(&chunk->lock);
LTTNG_OPTIONAL_SET(&chunk->mode, TRACE_CHUNK_MODE_USER);
end:
pthread_mutex_unlock(&chunk->lock);
-enum lttng_trace_chunk_status lttng_trace_chunk_get_chunk_directory_handle(
+enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle(
struct lttng_trace_chunk *chunk,
const struct lttng_directory_handle **handle)
{
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
pthread_mutex_lock(&chunk->lock);
struct lttng_trace_chunk *chunk,
const struct lttng_directory_handle **handle)
{
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
pthread_mutex_lock(&chunk->lock);
- if (!chunk->chunk_directory.is_set) {
+ if (!chunk->chunk_directory) {
status = LTTNG_TRACE_CHUNK_STATUS_NONE;
goto end;
}
status = LTTNG_TRACE_CHUNK_STATUS_NONE;
goto end;
}
- *handle = &chunk->chunk_directory.value;
+ *handle = chunk->chunk_directory;
end:
pthread_mutex_unlock(&chunk->lock);
return status;
end:
pthread_mutex_unlock(&chunk->lock);
return status;
status = LTTNG_TRACE_CHUNK_STATUS_INVALID_OPERATION;
goto end;
}
status = LTTNG_TRACE_CHUNK_STATUS_INVALID_OPERATION;
goto end;
}
- if (!chunk->chunk_directory.is_set) {
+ if (!chunk->chunk_directory) {
ERR("Attempted to create trace chunk subdirectory \"%s\" before setting the chunk output directory",
path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
ERR("Attempted to create trace chunk subdirectory \"%s\" before setting the chunk output directory",
path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
ret = lttng_directory_handle_create_subdirectory_recursive_as_user(
goto end;
}
ret = lttng_directory_handle_create_subdirectory_recursive_as_user(
- &chunk->chunk_directory.value, path,
+ chunk->chunk_directory, path,
DIR_CREATION_MODE,
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
DIR_CREATION_MODE,
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
- if (!chunk->chunk_directory.is_set) {
+ if (!chunk->chunk_directory) {
ERR("Attempted to open trace chunk file \"%s\" before setting the chunk output directory",
file_path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
ret = lttng_directory_handle_open_file_as_user(
ERR("Attempted to open trace chunk file \"%s\" before setting the chunk output directory",
file_path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
ret = lttng_directory_handle_open_file_as_user(
- &chunk->chunk_directory.value, file_path, flags, mode,
+ chunk->chunk_directory, file_path, flags, mode,
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
if (ret < 0) {
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
if (ret < 0) {
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
- if (!chunk->chunk_directory.is_set) {
+ if (!chunk->chunk_directory) {
ERR("Attempted to unlink trace chunk file \"%s\" before setting the chunk output directory",
file_path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
ret = lttng_directory_handle_unlink_file_as_user(
ERR("Attempted to unlink trace chunk file \"%s\" before setting the chunk output directory",
file_path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
ret = lttng_directory_handle_unlink_file_as_user(
- &chunk->chunk_directory.value, file_path,
+ chunk->chunk_directory, file_path,
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
if (ret < 0) {
chunk->credentials.value.use_current_user ?
NULL : &chunk->credentials.value.user);
if (ret < 0) {
LTTNG_OPTIONAL_GET(trace_chunk->timestamp_creation);
const time_t close_timestamp =
LTTNG_OPTIONAL_GET(trace_chunk->timestamp_close);
LTTNG_OPTIONAL_GET(trace_chunk->timestamp_creation);
const time_t close_timestamp =
LTTNG_OPTIONAL_GET(trace_chunk->timestamp_close);
- LTTNG_OPTIONAL(struct lttng_directory_handle) archived_chunks_directory = {};
+ struct lttng_directory_handle *archived_chunks_directory = NULL;
if (!trace_chunk->mode.is_set ||
trace_chunk->mode.value != TRACE_CHUNK_MODE_OWNER ||
if (!trace_chunk->mode.is_set ||
trace_chunk->mode.value != TRACE_CHUNK_MODE_OWNER ||
- !trace_chunk->session_output_directory.is_set) {
+ !trace_chunk->session_output_directory) {
/*
* This command doesn't need to run if the output is remote
* or if the trace chunk is not owned by this process.
/*
* This command doesn't need to run if the output is remote
* or if the trace chunk is not owned by this process.
* is renamed to match the chunk's name.
*/
if (chunk_id == 0) {
* is renamed to match the chunk's name.
*/
if (chunk_id == 0) {
- struct lttng_directory_handle temporary_rename_directory;
+ struct lttng_directory_handle *temporary_rename_directory =
+ NULL;
size_t i, count = lttng_dynamic_pointer_array_get_count(
size_t i, count = lttng_dynamic_pointer_array_get_count(
- &trace_chunk->top_level_directories);
+ &trace_chunk->top_level_directories);
ret = lttng_directory_handle_create_subdirectory_as_user(
ret = lttng_directory_handle_create_subdirectory_as_user(
- &trace_chunk->session_output_directory.value,
+ trace_chunk->session_output_directory,
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY,
DIR_CREATION_MODE,
!trace_chunk->credentials.value.use_current_user ?
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY,
DIR_CREATION_MODE,
!trace_chunk->credentials.value.use_current_user ?
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY);
}
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY);
}
- ret = lttng_directory_handle_init_from_handle(&temporary_rename_directory,
+ temporary_rename_directory = lttng_directory_handle_create_from_handle(
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY,
DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY,
- &trace_chunk->session_output_directory.value);
- if (ret) {
+ trace_chunk->session_output_directory);
+ if (!temporary_rename_directory) {
ERR("Failed to get handle to temporary trace chunk rename directory");
goto end;
}
ERR("Failed to get handle to temporary trace chunk rename directory");
goto end;
}
&trace_chunk->top_level_directories, i);
ret = lttng_directory_handle_rename_as_user(
&trace_chunk->top_level_directories, i);
ret = lttng_directory_handle_rename_as_user(
- &trace_chunk->session_output_directory.value,
+ trace_chunk->session_output_directory,
- &temporary_rename_directory,
+ temporary_rename_directory,
top_level_name,
LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ?
NULL :
top_level_name,
LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ?
NULL :
if (ret) {
PERROR("Failed to move \"%s\" to temporary trace chunk rename directory",
top_level_name);
if (ret) {
PERROR("Failed to move \"%s\" to temporary trace chunk rename directory",
top_level_name);
- lttng_directory_handle_fini(
- &temporary_rename_directory);
+ lttng_directory_handle_put(
+ temporary_rename_directory);
- lttng_directory_handle_fini(&temporary_rename_directory);
+ lttng_directory_handle_put(temporary_rename_directory);
directory_to_rename = DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY;
free_directory_to_rename = false;
} else {
directory_to_rename = DEFAULT_TEMPORARY_CHUNK_RENAME_DIRECTORY;
free_directory_to_rename = false;
} else {
}
ret = lttng_directory_handle_create_subdirectory_as_user(
}
ret = lttng_directory_handle_create_subdirectory_as_user(
- &trace_chunk->session_output_directory.value,
+ trace_chunk->session_output_directory,
DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY,
DIR_CREATION_MODE,
!trace_chunk->credentials.value.use_current_user ?
DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY,
DIR_CREATION_MODE,
!trace_chunk->credentials.value.use_current_user ?
- ret = lttng_directory_handle_init_from_handle(
- &archived_chunks_directory.value,
+ archived_chunks_directory = lttng_directory_handle_create_from_handle(
DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY,
DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY,
- &trace_chunk->session_output_directory.value);
- if (ret) {
+ trace_chunk->session_output_directory);
+ if (!archived_chunks_directory) {
PERROR("Failed to get handle to archived trace chunks directory");
goto end;
}
PERROR("Failed to get handle to archived trace chunks directory");
goto end;
}
- archived_chunks_directory.is_set = true;
ret = lttng_directory_handle_rename_as_user(
ret = lttng_directory_handle_rename_as_user(
- &trace_chunk->session_output_directory.value,
+ trace_chunk->session_output_directory,
- &archived_chunks_directory.value,
+ archived_chunks_directory,
archived_chunk_name,
LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ?
NULL :
archived_chunk_name,
LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ?
NULL :
- if (archived_chunks_directory.is_set) {
- lttng_directory_handle_fini(&archived_chunks_directory.value);
- }
+ lttng_directory_handle_put(archived_chunks_directory);
free(archived_chunk_name);
if (free_directory_to_rename) {
free(directory_to_rename);
free(archived_chunk_name);
if (free_directory_to_rename) {
free(directory_to_rename);
element->chunk = *chunk;
lttng_trace_chunk_init(&element->chunk);
element->chunk = *chunk;
lttng_trace_chunk_init(&element->chunk);
- if (chunk->session_output_directory.is_set) {
- element->chunk.session_output_directory.value =
- lttng_directory_handle_move(
- &chunk->session_output_directory.value);
- }
- if (chunk->chunk_directory.is_set) {
- element->chunk.chunk_directory.value =
- lttng_directory_handle_move(
- &chunk->chunk_directory.value);
+ if (chunk->session_output_directory) {
+ /* Transferred ownership. */
+ element->chunk.session_output_directory =
+ chunk->session_output_directory;
+ chunk->session_output_directory = NULL;
+ }
+ if (chunk->chunk_directory) {
+ /* Transferred ownership. */
+ element->chunk.chunk_directory = chunk->chunk_directory;
+ chunk->chunk_directory = NULL;
}
/*
* The original chunk becomes invalid; the name attribute is transferred
}
/*
* The original chunk becomes invalid; the name attribute is transferred
enum lttng_trace_chunk_status lttng_trace_chunk_set_credentials_current_user(
struct lttng_trace_chunk *chunk);
enum lttng_trace_chunk_status lttng_trace_chunk_set_credentials_current_user(
struct lttng_trace_chunk *chunk);
-/* session_output_directory ownership is transferred to the chunk on success. */
LTTNG_HIDDEN
enum lttng_trace_chunk_status lttng_trace_chunk_set_as_owner(
struct lttng_trace_chunk *chunk,
struct lttng_directory_handle *session_output_directory);
LTTNG_HIDDEN
enum lttng_trace_chunk_status lttng_trace_chunk_set_as_owner(
struct lttng_trace_chunk *chunk,
struct lttng_directory_handle *session_output_directory);
-/* chunk_output_directory ownership is transferred to the chunk on success. */
LTTNG_HIDDEN
enum lttng_trace_chunk_status lttng_trace_chunk_set_as_user(
struct lttng_trace_chunk *chunk,
struct lttng_directory_handle *chunk_directory);
LTTNG_HIDDEN
LTTNG_HIDDEN
enum lttng_trace_chunk_status lttng_trace_chunk_set_as_user(
struct lttng_trace_chunk *chunk,
struct lttng_directory_handle *chunk_directory);
LTTNG_HIDDEN
-enum lttng_trace_chunk_status lttng_trace_chunk_get_chunk_directory_handle(
+enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle(
struct lttng_trace_chunk *chunk,
const struct lttng_directory_handle **handle);
struct lttng_trace_chunk *chunk,
const struct lttng_directory_handle **handle);
*msg.u.create_trace_chunk.override_name ?
msg.u.create_trace_chunk.override_name :
NULL;
*msg.u.create_trace_chunk.override_name ?
msg.u.create_trace_chunk.override_name :
NULL;
- LTTNG_OPTIONAL(struct lttng_directory_handle) chunk_directory_handle =
- LTTNG_OPTIONAL_INIT;
+ struct lttng_directory_handle *chunk_directory_handle = NULL;
/*
* The session daemon will only provide a chunk directory file
/*
* The session daemon will only provide a chunk directory file
DBG("Received trace chunk directory fd (%d)",
chunk_dirfd);
DBG("Received trace chunk directory fd (%d)",
chunk_dirfd);
- ret = lttng_directory_handle_init_from_dirfd(
- &chunk_directory_handle.value,
+ chunk_directory_handle = lttng_directory_handle_create_from_dirfd(
+ if (!chunk_directory_handle) {
ERR("Failed to initialize chunk directory handle from directory file descriptor");
if (close(chunk_dirfd)) {
PERROR("Failed to close chunk directory file descriptor");
}
goto error_fatal;
}
ERR("Failed to initialize chunk directory handle from directory file descriptor");
if (close(chunk_dirfd)) {
PERROR("Failed to close chunk directory file descriptor");
}
goto error_fatal;
}
- chunk_directory_handle.is_set = true;
}
ret_code = lttng_consumer_create_trace_chunk(
}
ret_code = lttng_consumer_create_trace_chunk(
msg.u.create_trace_chunk.credentials.is_set ?
&credentials :
NULL,
msg.u.create_trace_chunk.credentials.is_set ?
&credentials :
NULL,
- chunk_directory_handle.is_set ?
- &chunk_directory_handle.value :
- NULL);
-
- if (chunk_directory_handle.is_set) {
- lttng_directory_handle_fini(
- &chunk_directory_handle.value);
- }
+ chunk_directory_handle);
+ lttng_directory_handle_put(chunk_directory_handle);
goto end_msg_sessiond;
}
case LTTNG_CONSUMER_CLOSE_TRACE_CHUNK:
goto end_msg_sessiond;
}
case LTTNG_CONSUMER_CLOSE_TRACE_CHUNK:
int utils_mkdir(const char *path, mode_t mode, int uid, int gid)
{
int ret;
int utils_mkdir(const char *path, mode_t mode, int uid, int gid)
{
int ret;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
const struct lttng_credentials creds = {
.uid = (uid_t) uid,
.gid = (gid_t) gid,
};
const struct lttng_credentials creds = {
.uid = (uid_t) uid,
.gid = (gid_t) gid,
};
- ret = lttng_directory_handle_init(&handle, NULL);
- if (ret) {
+ handle = lttng_directory_handle_create(NULL);
+ if (!handle) {
+ ret = -1;
goto end;
}
ret = lttng_directory_handle_create_subdirectory_as_user(
goto end;
}
ret = lttng_directory_handle_create_subdirectory_as_user(
(uid >= 0 || gid >= 0) ? &creds : NULL);
(uid >= 0 || gid >= 0) ? &creds : NULL);
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid)
{
int ret;
int utils_mkdir_recursive(const char *path, mode_t mode, int uid, int gid)
{
int ret;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
const struct lttng_credentials creds = {
.uid = (uid_t) uid,
.gid = (gid_t) gid,
};
const struct lttng_credentials creds = {
.uid = (uid_t) uid,
.gid = (gid_t) gid,
};
- ret = lttng_directory_handle_init(&handle, NULL);
- if (ret) {
+ handle = lttng_directory_handle_create(NULL);
+ if (!handle) {
+ ret = -1;
goto end;
}
ret = lttng_directory_handle_create_subdirectory_recursive_as_user(
goto end;
}
ret = lttng_directory_handle_create_subdirectory_recursive_as_user(
(uid >= 0 || gid >= 0) ? &creds : NULL);
(uid >= 0 || gid >= 0) ? &creds : NULL);
- lttng_directory_handle_fini(&handle);
+ lttng_directory_handle_put(handle);
int utils_recursive_rmdir(const char *path)
{
int ret;
int utils_recursive_rmdir(const char *path)
{
int ret;
- struct lttng_directory_handle handle;
+ struct lttng_directory_handle *handle;
- ret = lttng_directory_handle_init(&handle, NULL);
- if (ret) {
+ handle = lttng_directory_handle_create(NULL);
+ if (!handle) {
+ ret = -1;
- ret = lttng_directory_handle_remove_subdirectory(&handle, path);
- lttng_directory_handle_fini(&handle);
+ ret = lttng_directory_handle_remove_subdirectory(handle, path);
+ lttng_directory_handle_put(handle);
static int test_rmdir_fail_non_empty(const char *test_dir)
{
int ret, tests_ran = 0;
static int test_rmdir_fail_non_empty(const char *test_dir)
{
int ret, tests_ran = 0;
- struct lttng_directory_handle test_dir_handle;
+ struct lttng_directory_handle *test_dir_handle;
char *created_dir = NULL;
const char test_root_name[] = "fail_non_empty";
char *test_dir_path = NULL;
diag("rmdir (fail if non-empty)");
char *created_dir = NULL;
const char test_root_name[] = "fail_non_empty";
char *test_dir_path = NULL;
diag("rmdir (fail if non-empty)");
- ret = lttng_directory_handle_init(&test_dir_handle, test_dir);
- ok(ret == 0, "Initialized directory handle from the test directory");
+ test_dir_handle = lttng_directory_handle_create(test_dir);
+ ok(test_dir_handle, "Initialized directory handle from the test directory");
+ if (!test_dir_handle) {
+ ret = -1;
- ret = create_non_empty_hierarchy_with_root(&test_dir_handle, test_root_name);
+ ret = create_non_empty_hierarchy_with_root(test_dir_handle, test_root_name);
if (ret) {
diag("Failed to setup folder/file hierarchy to run test");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
if (ret) {
diag("Failed to setup folder/file hierarchy to run test");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
- &test_dir_handle, test_root_name,
+ test_dir_handle, test_root_name,
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG);
ok(ret == -1, "Error returned when attempting to recursively remove non-empty hierarchy with LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG");
tests_ran++;
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG);
ok(ret == -1, "Error returned when attempting to recursively remove non-empty hierarchy with LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG");
tests_ran++;
- ret = remove_file_from_hierarchy(&test_dir_handle, test_root_name);
+ ret = remove_file_from_hierarchy(test_dir_handle, test_root_name);
if (ret) {
diag("Failed to remove file from test folder hierarchy");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
if (ret) {
diag("Failed to remove file from test folder hierarchy");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
- &test_dir_handle, test_root_name,
+ test_dir_handle, test_root_name,
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when recursively removing empty hierarchy with LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG");
tests_ran++;
LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when recursively removing empty hierarchy with LTTNG_DIRECTORY_HANDLE_FAIL_NON_EMPTY_FLAG");
tests_ran++;
tests_ran++;
ret = 0;
end:
tests_ran++;
ret = 0;
end:
- lttng_directory_handle_fini(&test_dir_handle);
+ lttng_directory_handle_put(test_dir_handle);
free(created_dir);
free(test_dir_path);
return ret == 0 ? tests_ran : ret;
free(created_dir);
free(test_dir_path);
return ret == 0 ? tests_ran : ret;
static int test_rmdir_skip_non_empty(const char *test_dir)
{
int ret, tests_ran = 0;
static int test_rmdir_skip_non_empty(const char *test_dir)
{
int ret, tests_ran = 0;
- struct lttng_directory_handle test_dir_handle;
+ struct lttng_directory_handle *test_dir_handle;
char *created_dir = NULL;
const char test_root_name[] = "skip_non_empty";
char *test_dir_path = NULL;
diag("rmdir (skip if non-empty)");
char *created_dir = NULL;
const char test_root_name[] = "skip_non_empty";
char *test_dir_path = NULL;
diag("rmdir (skip if non-empty)");
- ret = lttng_directory_handle_init(&test_dir_handle, test_dir);
- ok(ret == 0, "Initialized directory handle from the test directory");
+ test_dir_handle = lttng_directory_handle_create(test_dir);
+ ok(test_dir_handle, "Initialized directory handle from the test directory");
+ if (!test_dir_handle) {
+ ret = -1;
- ret = create_non_empty_hierarchy_with_root(&test_dir_handle, test_root_name);
+ ret = create_non_empty_hierarchy_with_root(test_dir_handle, test_root_name);
if (ret) {
diag("Failed to setup folder/file hierarchy to run test");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
if (ret) {
diag("Failed to setup folder/file hierarchy to run test");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
- &test_dir_handle, test_root_name,
+ test_dir_handle, test_root_name,
LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when attempting to recursively remove non-empty hierarchy with LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG");
tests_ran++;
LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when attempting to recursively remove non-empty hierarchy with LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG");
tests_ran++;
ok(dir_exists(test_dir_path), "Test directory still exists after skip");
tests_ran++;
ok(dir_exists(test_dir_path), "Test directory still exists after skip");
tests_ran++;
- ret = remove_file_from_hierarchy(&test_dir_handle, test_root_name);
+ ret = remove_file_from_hierarchy(test_dir_handle, test_root_name);
if (ret) {
diag("Failed to remove file from test folder hierarchy");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
if (ret) {
diag("Failed to remove file from test folder hierarchy");
goto end;
}
ret = lttng_directory_handle_remove_subdirectory_recursive(
- &test_dir_handle, test_root_name,
+ test_dir_handle, test_root_name,
LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when recursively removing empty hierarchy with LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG");
tests_ran++;
LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
ok(ret == 0, "No error returned when recursively removing empty hierarchy with LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG");
tests_ran++;
tests_ran++;
ret = 0;
end:
tests_ran++;
ret = 0;
end:
- lttng_directory_handle_fini(&test_dir_handle);
+ lttng_directory_handle_put(test_dir_handle);
free(created_dir);
free(test_dir_path);
return ret == 0 ? tests_ran : ret;
free(created_dir);
free(test_dir_path);
return ret == 0 ? tests_ran : ret;