#include <common/time.hpp>
#include <common/trace-chunk-registry.hpp>
#include <common/trace-chunk.hpp>
+#include <common/urcu.hpp>
#include <common/utils.hpp>
#include <lttng/constant.h>
* since only one thread may access a chunk during its destruction (the last
* to release its reference to the chunk).
*/
-typedef int (*chunk_command)(struct lttng_trace_chunk *trace_chunk);
+using chunk_command = int (*)(struct lttng_trace_chunk *);
/* Move a completed trace chunk to the 'completed' trace archive folder. */
static int lttng_trace_chunk_move_to_completed_post_release(struct lttng_trace_chunk *trace_chunk);
const char *path,
int fd)
{
- struct fs_handle_untracked *handle = NULL;
+ struct fs_handle_untracked *handle = nullptr;
bool reference_acquired;
char *path_copy = strdup(path);
handle->location.directory_handle = directory_handle;
/* Ownership is transferred. */
handle->location.path = path_copy;
- path_copy = NULL;
+ path_copy = nullptr;
end:
free(path_copy);
- return handle ? &handle->parent : NULL;
+ return handle ? &handle->parent : nullptr;
}
static int fs_handle_untracked_get_fd(struct fs_handle *_handle)
generate_chunk_name(uint64_t chunk_id, time_t creation_timestamp, const time_t *close_timestamp)
{
int ret = 0;
- char *new_name = NULL;
+ char *new_name = nullptr;
char start_datetime[ISO8601_STR_LEN] = {};
/* Add 1 for a '-' prefix. */
char end_datetime_suffix[ISO8601_STR_LEN + 1] = {};
return new_name;
error:
free(new_name);
- return NULL;
+ return nullptr;
}
static void lttng_trace_chunk_init(struct lttng_trace_chunk *chunk)
{
urcu_ref_init(&chunk->ref);
- pthread_mutex_init(&chunk->lock, NULL);
+ pthread_mutex_init(&chunk->lock, nullptr);
lttng_dynamic_pointer_array_init(&chunk->top_level_directories, free);
lttng_dynamic_pointer_array_init(&chunk->files, free);
}
{
if (chunk->session_output_directory) {
lttng_directory_handle_put(chunk->session_output_directory);
- chunk->session_output_directory = NULL;
+ chunk->session_output_directory = nullptr;
}
if (chunk->chunk_directory) {
lttng_directory_handle_put(chunk->chunk_directory);
- chunk->chunk_directory = NULL;
+ chunk->chunk_directory = nullptr;
}
free(chunk->name);
- chunk->name = NULL;
+ chunk->name = nullptr;
free(chunk->path);
- chunk->path = NULL;
+ chunk->path = nullptr;
lttng_dynamic_pointer_array_reset(&chunk->top_level_directories);
lttng_dynamic_pointer_array_reset(&chunk->files);
pthread_mutex_destroy(&chunk->lock);
}
-static struct lttng_trace_chunk *lttng_trace_chunk_allocate(void)
+static struct lttng_trace_chunk *lttng_trace_chunk_allocate()
{
- struct lttng_trace_chunk *chunk = NULL;
+ struct lttng_trace_chunk *chunk = nullptr;
chunk = zmalloc<lttng_trace_chunk>();
if (!chunk) {
return chunk;
}
-struct lttng_trace_chunk *lttng_trace_chunk_create_anonymous(void)
+struct lttng_trace_chunk *lttng_trace_chunk_create_anonymous()
{
DBG("Creating anonymous trace chunk");
return lttng_trace_chunk_allocate();
LTTNG_OPTIONAL_SET(&chunk->id, chunk_id);
LTTNG_OPTIONAL_SET(&chunk->timestamp_creation, chunk_creation_time);
if (chunk_id != 0) {
- chunk->name = generate_chunk_name(chunk_id, chunk_creation_time, NULL);
+ chunk->name = generate_chunk_name(chunk_id, chunk_creation_time, nullptr);
if (!chunk->name) {
ERR("Failed to allocate trace chunk name storage");
goto error;
return chunk;
error:
lttng_trace_chunk_put(chunk);
- return NULL;
+ return nullptr;
}
void lttng_trace_chunk_set_fd_tracker(struct lttng_trace_chunk *chunk,
error_unlock:
pthread_mutex_unlock(&source_chunk->lock);
lttng_trace_chunk_put(new_chunk);
- return NULL;
+ return nullptr;
}
enum lttng_trace_chunk_status lttng_trace_chunk_get_id(struct lttng_trace_chunk *chunk,
{
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
- struct lttng_directory_handle *rename_directory = NULL;
+ struct lttng_directory_handle *rename_directory = nullptr;
char *new_path, *old_path;
int ret;
chunk->session_output_directory,
path,
LTTNG_OPTIONAL_GET(chunk->credentials).use_current_user ?
- NULL :
+ nullptr :
&chunk->credentials.value.user);
if (ret) {
PERROR("Failed to move trace chunk directory \"%s\" to \"%s\"",
* handle.
*/
chunk->chunk_directory = rename_directory;
- rename_directory = NULL;
+ rename_directory = nullptr;
} else if (old_path && old_path[0] == '\0') {
size_t i,
count = lttng_dynamic_pointer_array_get_count(
path,
DIR_CREATION_MODE,
LTTNG_OPTIONAL_GET(chunk->credentials).use_current_user ?
- NULL :
+ nullptr :
&chunk->credentials.value.user);
if (ret) {
PERROR("Failed to create trace chunk rename directory \"%s\"", path);
rename_directory,
top_level_name,
LTTNG_OPTIONAL_GET(chunk->credentials).use_current_user ?
- NULL :
+ nullptr :
&chunk->credentials.value.user);
if (ret) {
PERROR("Failed to move \"%s\" to trace chunk rename directory",
* handle.
*/
chunk->chunk_directory = rename_directory;
- rename_directory = NULL;
+ rename_directory = nullptr;
} else if (old_path) {
size_t i,
count = lttng_dynamic_pointer_array_get_count(
rename_directory,
top_level_name,
LTTNG_OPTIONAL_GET(chunk->credentials).use_current_user ?
- NULL :
+ nullptr :
&chunk->credentials.value.user);
if (ret) {
PERROR("Failed to move \"%s\" to trace chunk rename directory",
* handle.
*/
chunk->chunk_directory = rename_directory;
- rename_directory = NULL;
+ rename_directory = nullptr;
/* Remove old directory. */
status = (lttng_trace_chunk_status) lttng_directory_handle_remove_subdirectory(
{
int ret;
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
- struct lttng_directory_handle *chunk_directory_handle = NULL;
+ struct lttng_directory_handle *chunk_directory_handle = nullptr;
bool reference_acquired;
pthread_mutex_lock(&chunk->lock);
DIR_CREATION_MODE,
!chunk->credentials.value.use_current_user ?
&chunk->credentials.value.user :
- NULL);
+ nullptr);
if (ret) {
PERROR("Failed to create chunk output directory \"%s\"", chunk->path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
chunk_directory_handle = session_output_directory;
}
chunk->chunk_directory = chunk_directory_handle;
- chunk_directory_handle = NULL;
+ chunk_directory_handle = nullptr;
reference_acquired = lttng_directory_handle_get(session_output_directory);
LTTNG_ASSERT(reference_acquired);
chunk->session_output_directory = session_output_directory;
pthread_mutex_lock(&chunk->lock);
if (!chunk->session_output_directory) {
status = LTTNG_TRACE_CHUNK_STATUS_NONE;
- *handle = NULL;
+ *handle = nullptr;
goto end;
} else {
const bool reference_acquired =
chunk->chunk_directory,
path,
DIR_CREATION_MODE,
- chunk->credentials.value.use_current_user ? NULL : &chunk->credentials.value.user);
+ chunk->credentials.value.use_current_user ? nullptr :
+ &chunk->credentials.value.user);
if (ret) {
PERROR("Failed to create trace chunk subdirectory \"%s\"", path);
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
int ret;
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
- if (lttng_trace_chunk_find_file(chunk, path, NULL)) {
+ if (lttng_trace_chunk_find_file(chunk, path, nullptr)) {
return LTTNG_TRACE_CHUNK_STATUS_OK;
}
DBG("Adding new file \"%s\" to trace chunk \"%s\"", path, chunk->name ?: "(unnamed)");
file_path,
flags,
mode,
- chunk->credentials.value.use_current_user ? NULL :
+ chunk->credentials.value.use_current_user ? nullptr :
&chunk->credentials.value.user);
if (ret >= 0) {
*out_handle =
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
}
- ret = lttng_directory_handle_unlink_file_as_user(
- chunk->chunk_directory,
- file_path,
- chunk->credentials.value.use_current_user ? NULL : &chunk->credentials.value.user);
+ ret = lttng_directory_handle_unlink_file_as_user(chunk->chunk_directory,
+ file_path,
+ chunk->credentials.value.use_current_user ?
+ nullptr :
+ &chunk->credentials.value.user);
if (ret < 0) {
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
goto end;
ret = lttng_directory_handle_remove_subdirectory_recursive_as_user(
chunk->chunk_directory,
path,
- chunk->credentials.value.use_current_user ? NULL : &chunk->credentials.value.user,
+ chunk->credentials.value.use_current_user ? nullptr :
+ &chunk->credentials.value.user,
LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG);
if (ret < 0) {
status = LTTNG_TRACE_CHUNK_STATUS_ERROR;
static int lttng_trace_chunk_move_to_completed_post_release(struct lttng_trace_chunk *trace_chunk)
{
int ret = 0;
- char *archived_chunk_name = NULL;
+ char *archived_chunk_name = nullptr;
const uint64_t chunk_id = LTTNG_OPTIONAL_GET(trace_chunk->id);
const time_t creation_timestamp = LTTNG_OPTIONAL_GET(trace_chunk->timestamp_creation);
const time_t close_timestamp = LTTNG_OPTIONAL_GET(trace_chunk->timestamp_close);
- struct lttng_directory_handle *archived_chunks_directory = NULL;
+ struct lttng_directory_handle *archived_chunks_directory = nullptr;
enum lttng_trace_chunk_status status;
if (!trace_chunk->mode.is_set || trace_chunk->mode.value != TRACE_CHUNK_MODE_OWNER ||
DIR_CREATION_MODE,
!trace_chunk->credentials.value.use_current_user ?
&trace_chunk->credentials.value.user :
- NULL);
+ nullptr);
if (ret) {
PERROR("Failed to create \"" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY
"\" directory for archived trace chunks");
* the creation of the next chunk. This happens if a rotation is
* performed while tracing is stopped.
*/
- if (!trace_chunk->path || strcmp(trace_chunk->path, DEFAULT_CHUNK_TMP_OLD_DIRECTORY)) {
+ if (!trace_chunk->path || strcmp(trace_chunk->path, DEFAULT_CHUNK_TMP_OLD_DIRECTORY) != 0) {
status = lttng_trace_chunk_rename_path_no_lock(trace_chunk,
DEFAULT_CHUNK_TMP_OLD_DIRECTORY);
if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
archived_chunks_directory,
archived_chunk_name,
LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ?
- NULL :
+ nullptr :
&trace_chunk->credentials.value.user);
if (ret) {
PERROR("Failed to rename folder \"%s\" to \"%s\"",
}
if (!ret) {
lttng_directory_handle_put(trace_chunk->chunk_directory);
- trace_chunk->chunk_directory = NULL;
+ trace_chunk->chunk_directory = nullptr;
if (trace_chunk->path && trace_chunk->path[0] != '\0') {
status = (lttng_trace_chunk_status)
}
}
free(trace_chunk->path);
- trace_chunk->path = NULL;
+ trace_chunk->path = nullptr;
end:
return ret;
}
element = lttng::utils::container_of(chunk,
<tng_trace_chunk_registry_element::chunk);
if (element->registry) {
- rcu_read_lock();
+ lttng::urcu::read_lock_guard read_lock;
cds_lfht_del(element->registry->ht, &element->trace_chunk_registry_ht_node);
- rcu_read_unlock();
call_rcu(&element->rcu_node, free_lttng_trace_chunk_registry_element);
} else {
/* Never published, can be free'd immediately. */
urcu_ref_put(&chunk->ref, lttng_trace_chunk_release);
}
-struct lttng_trace_chunk_registry *lttng_trace_chunk_registry_create(void)
+struct lttng_trace_chunk_registry *lttng_trace_chunk_registry_create()
{
struct lttng_trace_chunk_registry *registry;
}
registry->ht = cds_lfht_new(
- DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+ DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
if (!registry->ht) {
goto error;
}
return registry;
error:
lttng_trace_chunk_registry_destroy(registry);
- return NULL;
+ return nullptr;
}
void lttng_trace_chunk_registry_destroy(struct lttng_trace_chunk_registry *registry)
return;
}
if (registry->ht) {
- int ret = cds_lfht_destroy(registry->ht, NULL);
+ int ret = cds_lfht_destroy(registry->ht, nullptr);
LTTNG_ASSERT(!ret);
}
free(registry);
if (chunk->session_output_directory) {
/* Transferred ownership. */
element->chunk.session_output_directory = chunk->session_output_directory;
- chunk->session_output_directory = NULL;
+ chunk->session_output_directory = nullptr;
}
if (chunk->chunk_directory) {
/* Transferred ownership. */
element->chunk.chunk_directory = chunk->chunk_directory;
- chunk->chunk_directory = NULL;
+ chunk->chunk_directory = nullptr;
}
/*
* The original chunk becomes invalid; the name and path attributes are
* transferred to the new chunk instance.
*/
- chunk->name = NULL;
- chunk->path = NULL;
+ chunk->name = nullptr;
+ chunk->path = nullptr;
element->chunk.fd_tracker = chunk->fd_tracker;
element->chunk.in_registry_element = true;
end:
pthread_mutex_lock(&chunk->lock);
element = lttng_trace_chunk_registry_element_create_from_chunk(chunk, session_id);
pthread_mutex_unlock(&chunk->lock);
+
+ lttng::urcu::read_lock_guard read_lock;
if (!element) {
goto end;
}
* chunk is now invalid, the only valid operation is a 'put' from the
* caller.
*/
- chunk = NULL;
+ chunk = nullptr;
element_hash = lttng_trace_chunk_registry_element_hash(element);
- rcu_read_lock();
- while (1) {
+ while (true) {
struct cds_lfht_node *published_node;
struct lttng_trace_chunk *published_chunk;
struct lttng_trace_chunk_registry_element *published_element;
* chunk.
*/
}
- rcu_read_unlock();
end:
- return element ? &element->chunk : NULL;
+ return element ? &element->chunk : nullptr;
}
/*
const unsigned long element_hash = lttng_trace_chunk_registry_element_hash(&target_element);
struct cds_lfht_node *published_node;
struct lttng_trace_chunk_registry_element *published_element;
- struct lttng_trace_chunk *published_chunk = NULL;
+ struct lttng_trace_chunk *published_chunk = nullptr;
struct cds_lfht_iter iter;
- rcu_read_lock();
+ lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(registry->ht,
element_hash,
lttng_trace_chunk_registry_element_match,
published_chunk = &published_element->chunk;
}
end:
- rcu_read_unlock();
return published_chunk;
}
struct cds_lfht_node *published_node;
struct cds_lfht_iter iter;
- rcu_read_lock();
+ lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(registry->ht,
element_hash,
lttng_trace_chunk_registry_element_match,
*chunk_exists = !cds_lfht_is_node_deleted(published_node);
end:
- rcu_read_unlock();
return ret;
}
lttng_trace_chunk_registry_find_anonymous_chunk(const struct lttng_trace_chunk_registry *registry,
uint64_t session_id)
{
- return _lttng_trace_chunk_registry_find_chunk(registry, session_id, NULL);
+ return _lttng_trace_chunk_registry_find_chunk(registry, session_id, nullptr);
}
unsigned int
unsigned int trace_chunks_left = 0;
DBG("Releasing trace chunk registry to all trace chunks");
- rcu_read_lock();
- cds_lfht_for_each_entry (registry->ht, &iter, chunk_element, trace_chunk_registry_ht_node) {
- const char *chunk_id_str = "none";
- char chunk_id_buf[MAX_INT_DEC_LEN(uint64_t)];
-
- pthread_mutex_lock(&chunk_element->chunk.lock);
- if (chunk_element->chunk.id.is_set) {
- int fmt_ret;
-
- fmt_ret = snprintf(chunk_id_buf,
- sizeof(chunk_id_buf),
- "%" PRIu64,
- chunk_element->chunk.id.value);
- if (fmt_ret < 0 || fmt_ret >= sizeof(chunk_id_buf)) {
- chunk_id_str = "formatting error";
- } else {
- chunk_id_str = chunk_id_buf;
+
+ {
+ lttng::urcu::read_lock_guard read_lock;
+
+ cds_lfht_for_each_entry (
+ registry->ht, &iter, chunk_element, trace_chunk_registry_ht_node) {
+ const char *chunk_id_str = "none";
+ char chunk_id_buf[MAX_INT_DEC_LEN(uint64_t)];
+
+ pthread_mutex_lock(&chunk_element->chunk.lock);
+ if (chunk_element->chunk.id.is_set) {
+ int fmt_ret;
+
+ fmt_ret = snprintf(chunk_id_buf,
+ sizeof(chunk_id_buf),
+ "%" PRIu64,
+ chunk_element->chunk.id.value);
+ if (fmt_ret < 0 || fmt_ret >= sizeof(chunk_id_buf)) {
+ chunk_id_str = "formatting error";
+ } else {
+ chunk_id_str = chunk_id_buf;
+ }
}
+
+ DBG("Releasing reference to trace chunk: session_id = %" PRIu64
+ "chunk_id = %s, name = \"%s\", status = %s",
+ chunk_element->session_id,
+ chunk_id_str,
+ chunk_element->chunk.name ?: "none",
+ chunk_element->chunk.close_command.is_set ? "open" : "closed");
+ pthread_mutex_unlock(&chunk_element->chunk.lock);
+ lttng_trace_chunk_put(&chunk_element->chunk);
+ trace_chunks_left++;
}
+ }
- DBG("Releasing reference to trace chunk: session_id = %" PRIu64
- "chunk_id = %s, name = \"%s\", status = %s",
- chunk_element->session_id,
- chunk_id_str,
- chunk_element->chunk.name ?: "none",
- chunk_element->chunk.close_command.is_set ? "open" : "closed");
- pthread_mutex_unlock(&chunk_element->chunk.lock);
- lttng_trace_chunk_put(&chunk_element->chunk);
- trace_chunks_left++;
- }
- rcu_read_unlock();
DBG("Released reference to %u trace chunks in %s()", trace_chunks_left, __FUNCTION__);
return trace_chunks_left;