X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fcommon%2Ftrace-chunk.c;h=ff80ae1a89f81b26815719e07fe643bf5031ed8b;hb=d2dc232d580ae18400445b6e34fabe1023208f20;hp=313d49375d6ed0e03cec04af05619aa961b545b2;hpb=4b050fdd4674dd33baf805bbffec487bb42bd88d;p=lttng-tools.git diff --git a/src/common/trace-chunk.c b/src/common/trace-chunk.c index 313d49375..ff80ae1a8 100644 --- a/src/common/trace-chunk.c +++ b/src/common/trace-chunk.c @@ -368,7 +368,7 @@ void lttng_trace_chunk_fini(struct lttng_trace_chunk *chunk) } if (chunk->chunk_directory) { lttng_directory_handle_put(chunk->chunk_directory); - chunk->chunk_directory = NULL; + chunk->chunk_directory = NULL; } free(chunk->name); chunk->name = NULL; @@ -406,9 +406,9 @@ struct lttng_trace_chunk *lttng_trace_chunk_create( uint64_t chunk_id, time_t chunk_creation_time, const char *path) { struct lttng_trace_chunk *chunk; - char chunk_creation_datetime_buf[16] = {}; + char chunk_creation_datetime_buf[16] = {}; const char *chunk_creation_datetime_str = "(formatting error)"; - struct tm timeinfo_buf, *timeinfo; + struct tm timeinfo_buf, *timeinfo; timeinfo = localtime_r(&chunk_creation_time, &timeinfo_buf); if (timeinfo) { @@ -440,7 +440,7 @@ struct lttng_trace_chunk *lttng_trace_chunk_create( ERR("Failed to allocate trace chunk name storage"); goto error; } - } + } if (path) { chunk->path = strdup(path); if (!chunk->path) { @@ -455,7 +455,7 @@ struct lttng_trace_chunk *lttng_trace_chunk_create( } } - DBG("Chunk name set to \"%s\"", chunk->name ? : "(none)"); + DBG("Chunk name set to \"%s\"", chunk->name ? : "(none)"); end: return chunk; error: @@ -642,10 +642,10 @@ enum lttng_trace_chunk_status lttng_trace_chunk_get_name( enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; pthread_mutex_lock(&chunk->lock); - if (name_overridden) { + if (name_overridden) { *name_overridden = chunk->name_overridden; - } - if (!chunk->name) { + } + if (!chunk->name) { status = LTTNG_TRACE_CHUNK_STATUS_NONE; goto end; } @@ -966,8 +966,8 @@ enum lttng_trace_chunk_status lttng_trace_chunk_get_credentials( pthread_mutex_lock(&chunk->lock); if (chunk->credentials.is_set) { if (chunk->credentials.value.use_current_user) { - credentials->uid = geteuid(); - credentials->gid = getegid(); + LTTNG_OPTIONAL_SET(&credentials->uid, geteuid()); + LTTNG_OPTIONAL_SET(&credentials->gid, getegid()); } else { *credentials = chunk->credentials.value.user; } @@ -1077,9 +1077,8 @@ enum lttng_trace_chunk_status lttng_trace_chunk_set_as_owner( * A nameless chunk does not need its own output directory. * The session's output directory will be used. */ - const bool reference_acquired = - lttng_directory_handle_get( - session_output_directory); + reference_acquired = lttng_directory_handle_get( + session_output_directory); assert(reference_acquired); chunk_directory_handle = session_output_directory; @@ -1586,7 +1585,7 @@ int lttng_trace_chunk_move_to_completed_post_release( ret = lttng_directory_handle_create_subdirectory_as_user( trace_chunk->session_output_directory, - DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY, + DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY, DIR_CREATION_MODE, !trace_chunk->credentials.value.use_current_user ? &trace_chunk->credentials.value.user : @@ -1794,10 +1793,10 @@ enum lttng_trace_chunk_status lttng_trace_chunk_set_close_command( DBG("Overriding trace chunk close command from \"%s\" to \"%s\"", close_command_names[chunk->close_command.value], close_command_names[close_command]); - } else { + } else { DBG("Setting trace chunk close command to \"%s\"", close_command_names[close_command]); - } + } /* * Unset close command for no-op for backward compatibility with relayd * 2.11. @@ -1828,6 +1827,37 @@ const char *lttng_trace_chunk_command_type_get_name( } } +LTTNG_HIDDEN +bool lttng_trace_chunk_ids_equal(const struct lttng_trace_chunk *chunk_a, + const struct lttng_trace_chunk *chunk_b) +{ + bool equal = false; + + if (chunk_a == chunk_b) { + equal = true; + goto end; + } + + if (!!chunk_a ^ !!chunk_b) { + goto end; + } + + if (chunk_a->id.is_set ^ chunk_a->id.is_set) { + /* One id is set and not the other, thus they are not equal. */ + goto end; + } + + if (!chunk_a->id.is_set) { + /* Both ids are unset. */ + equal = true; + } else { + equal = chunk_a->id.value == chunk_b->id.value; + } + +end: + return equal; +} + LTTNG_HIDDEN bool lttng_trace_chunk_get(struct lttng_trace_chunk *chunk) { @@ -1840,7 +1870,6 @@ void free_lttng_trace_chunk_registry_element(struct rcu_head *node) struct lttng_trace_chunk_registry_element *element = container_of(node, typeof(*element), rcu_node); - lttng_trace_chunk_fini(&element->chunk); free(element); } @@ -1861,6 +1890,24 @@ void lttng_trace_chunk_release(struct urcu_ref *ref) if (chunk->in_registry_element) { struct lttng_trace_chunk_registry_element *element; + /* + * Release internal chunk attributes immediately and + * only use the deferred `call_rcu` work to reclaim the + * storage. + * + * This ensures that file handles are released as soon as + * possible which works around a problem we encounter with PRAM fs + * mounts (and possibly other non-POSIX compliant file systems): + * directories that contain files which are open can't be + * rmdir(). + * + * This means that the recording of a snapshot could be + * completed, but that it would be impossible for the user to + * delete it until the deferred clean-up released the file + * handles to its contents. + */ + lttng_trace_chunk_fini(chunk); + element = container_of(chunk, typeof(*element), chunk); if (element->registry) { rcu_read_lock(); @@ -1970,7 +2017,20 @@ LTTNG_HIDDEN struct lttng_trace_chunk * lttng_trace_chunk_registry_publish_chunk( struct lttng_trace_chunk_registry *registry, - uint64_t session_id, struct lttng_trace_chunk *chunk) + uint64_t session_id, + struct lttng_trace_chunk *chunk) +{ + bool unused; + + return lttng_trace_chunk_registry_publish_chunk_published( + registry, session_id, chunk, &unused); +} + +struct lttng_trace_chunk * +lttng_trace_chunk_registry_publish_chunk_published( + struct lttng_trace_chunk_registry *registry, + uint64_t session_id, struct lttng_trace_chunk *chunk, + bool *previously_published) { struct lttng_trace_chunk_registry_element *element; unsigned long element_hash; @@ -1996,15 +2056,16 @@ lttng_trace_chunk_registry_publish_chunk( struct lttng_trace_chunk_registry_element *published_element; published_node = cds_lfht_add_unique(registry->ht, - element_hash, + element_hash, lttng_trace_chunk_registry_element_match, - element, + element, &element->trace_chunk_registry_ht_node); if (published_node == &element->trace_chunk_registry_ht_node) { /* Successfully published the new element. */ - element->registry = registry; + element->registry = registry; /* Acquire a reference for the caller. */ if (lttng_trace_chunk_get(&element->chunk)) { + *previously_published = false; break; } else { /* @@ -2031,6 +2092,7 @@ lttng_trace_chunk_registry_publish_chunk( if (lttng_trace_chunk_get(published_chunk)) { lttng_trace_chunk_put(&element->chunk); element = published_element; + *previously_published = true; break; } /* @@ -2099,7 +2161,7 @@ lttng_trace_chunk_registry_find_chunk( const struct lttng_trace_chunk_registry *registry, uint64_t session_id, uint64_t chunk_id) { - return _lttng_trace_chunk_registry_find_chunk(registry, + return _lttng_trace_chunk_registry_find_chunk(registry, session_id, &chunk_id); } @@ -2144,7 +2206,7 @@ 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, + return _lttng_trace_chunk_registry_find_chunk(registry, session_id, NULL); }