Fix: sessiond: ust-app: per-pid buffers: Create empty ust/ directory
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 56860d714e3a6e5a605e75c56a1fb200037fd1bb..58308dec801f0bef53dedada426ba7bd574e51e8 100644 (file)
@@ -27,7 +27,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <urcu/compiler.h>
-#include <lttng/ust-error.h>
 #include <signal.h>
 
 #include <common/common.h>
@@ -38,7 +37,8 @@
 #include "health-sessiond.h"
 #include "ust-app.h"
 #include "ust-consumer.h"
-#include "ust-ctl.h"
+#include "lttng-ust-ctl.h"
+#include "lttng-ust-error.h"
 #include "utils.h"
 #include "session.h"
 #include "lttng-sessiond.h"
@@ -741,6 +741,10 @@ error:
  * nullified. The session lock MUST be held unless the application is
  * in the destroy path.
  *
+ * Do not hold the registry lock while communicating with the consumerd, because
+ * doing so causes inter-process deadlocks between consumerd and sessiond with
+ * the metadata request notification.
+ *
  * Return 0 on success else a negative value.
  */
 static int close_metadata(struct ust_registry_session *registry,
@@ -748,6 +752,8 @@ static int close_metadata(struct ust_registry_session *registry,
 {
        int ret;
        struct consumer_socket *socket;
+       uint64_t metadata_key;
+       bool registry_was_already_closed;
 
        assert(registry);
        assert(consumer);
@@ -755,8 +761,19 @@ static int close_metadata(struct ust_registry_session *registry,
        rcu_read_lock();
 
        pthread_mutex_lock(&registry->lock);
+       metadata_key = registry->metadata_key;
+       registry_was_already_closed = registry->metadata_closed;
+       if (metadata_key != 0) {
+               /*
+                * Metadata closed. Even on error this means that the consumer
+                * is not responding or not found so either way a second close
+                * should NOT be emit for this registry.
+                */
+               registry->metadata_closed = 1;
+       }
+       pthread_mutex_unlock(&registry->lock);
 
-       if (!registry->metadata_key || registry->metadata_closed) {
+       if (metadata_key == 0 || registry_was_already_closed) {
                ret = 0;
                goto end;
        }
@@ -766,23 +783,15 @@ static int close_metadata(struct ust_registry_session *registry,
                        consumer);
        if (!socket) {
                ret = -1;
-               goto error;
+               goto end;
        }
 
-       ret = consumer_close_metadata(socket, registry->metadata_key);
+       ret = consumer_close_metadata(socket, metadata_key);
        if (ret < 0) {
-               goto error;
+               goto end;
        }
 
-error:
-       /*
-        * Metadata closed. Even on error this means that the consumer is not
-        * responding or not found so either way a second close should NOT be emit
-        * for this registry.
-        */
-       registry->metadata_closed = 1;
 end:
-       pthread_mutex_unlock(&registry->lock);
        rcu_read_unlock();
        return ret;
 }
@@ -1100,7 +1109,7 @@ struct ust_app_event *alloc_ust_app_event(char *name,
        /* Init most of the default value by allocating and zeroing */
        ua_event = zmalloc(sizeof(struct ust_app_event));
        if (ua_event == NULL) {
-               PERROR("malloc");
+               PERROR("Failed to allocate ust_app_event structure");
                goto error;
        }
 
@@ -1993,7 +2002,8 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
                        app->byte_order, app->version.major, app->version.minor,
                        reg_pid->root_shm_path, reg_pid->shm_path,
                        ua_sess->effective_credentials.uid,
-                       ua_sess->effective_credentials.gid);
+                       ua_sess->effective_credentials.gid, ua_sess->tracing_id,
+                       app->uid);
        if (ret < 0) {
                /*
                 * reg_pid->registry->reg.ust is NULL upon error, so we need to
@@ -2060,7 +2070,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
                        app->uint64_t_alignment, app->long_alignment,
                        app->byte_order, app->version.major,
                        app->version.minor, reg_uid->root_shm_path,
-                       reg_uid->shm_path, usess->uid, usess->gid);
+                       reg_uid->shm_path, usess->uid, usess->gid,
+                       ua_sess->tracing_id, app->uid);
        if (ret < 0) {
                /*
                 * reg_uid->registry->reg.ust is NULL upon error, so we need to
@@ -3131,7 +3142,7 @@ int create_ust_app_event(struct ust_app_session *ua_sess,
 
        ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
        if (ua_event == NULL) {
-               /* Only malloc can failed so something is really wrong */
+               /* Only failure mode of alloc_ust_app_event(). */
                ret = -ENOMEM;
                goto end;
        }
@@ -3140,8 +3151,19 @@ int create_ust_app_event(struct ust_app_session *ua_sess,
        /* Create it on the tracer side */
        ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
        if (ret < 0) {
-               /* Not found previously means that it does not exist on the tracer */
-               assert(ret != -LTTNG_UST_ERR_EXIST);
+               /*
+                * Not found previously means that it does not exist on the
+                * tracer. If the application reports that the event existed,
+                * it means there is a bug in the sessiond or lttng-ust
+                * (or corruption, etc.)
+                */
+               if (ret == -LTTNG_UST_ERR_EXIST) {
+                       ERR("Tracer for application reported that an event being created already existed: "
+                                       "event_name = \"%s\", pid = %d, ppid = %d, uid = %d, gid = %d",
+                                       uevent->attr.name,
+                                       app->pid, app->ppid, app->uid,
+                                       app->gid);
+               }
                goto error;
        }
 
@@ -4199,7 +4221,7 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess,
                        if (session_was_created) {
                                destroy_app_session(app, ua_sess);
                        }
-                       goto error_rcu_unlock;
+                       /* Continue to the next application. */
                }
        }
 
@@ -4411,7 +4433,7 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
        health_code_update();
 
 skip_setup:
-       /* This start the UST tracing */
+       /* This starts the UST tracing */
        pthread_mutex_lock(&app->sock_lock);
        ret = ustctl_start_session(app->sock, ua_sess->handle);
        pthread_mutex_unlock(&app->sock_lock);
@@ -5883,6 +5905,7 @@ enum lttng_error_code ust_app_snapshot_record(
        enum lttng_error_code status = LTTNG_OK;
        struct lttng_ht_iter iter;
        struct ust_app *app;
+       char *trace_path = NULL;
 
        assert(usess);
        assert(output);
@@ -5897,7 +5920,6 @@ enum lttng_error_code ust_app_snapshot_record(
                cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) {
                        struct buffer_reg_channel *reg_chan;
                        struct consumer_socket *socket;
-                       char *trace_path = NULL;
                        char pathname[PATH_MAX];
 
                        if (!reg->registry->reg.ust->metadata_key) {
@@ -5926,6 +5948,8 @@ enum lttng_error_code ust_app_snapshot_record(
                                status = LTTNG_ERR_INVALID;
                                goto error;
                        }
+                       /* Free path allowed on previous iteration. */
+                       free(trace_path);
                        trace_path = setup_channel_trace_path(usess->consumer, pathname);
                        if (!trace_path) {
                                status = LTTNG_ERR_INVALID;
@@ -5940,14 +5964,12 @@ enum lttng_error_code ust_app_snapshot_record(
                                                usess->gid, trace_path, wait,
                                                nb_packets_per_stream);
                                if (status != LTTNG_OK) {
-                                       free(trace_path);
                                        goto error;
                                }
                        }
                        status = consumer_snapshot_channel(socket,
                                        reg->registry->reg.ust->metadata_key, output, 1,
                                        usess->uid, usess->gid, trace_path, wait, 0);
-                       free(trace_path);
                        if (status != LTTNG_OK) {
                                goto error;
                        }
@@ -5962,7 +5984,6 @@ enum lttng_error_code ust_app_snapshot_record(
                        struct ust_app_channel *ua_chan;
                        struct ust_app_session *ua_sess;
                        struct ust_registry_session *registry;
-                       char *trace_path = NULL;
                        char pathname[PATH_MAX];
 
                        ua_sess = lookup_session_by_app(usess, app);
@@ -5988,6 +6009,8 @@ enum lttng_error_code ust_app_snapshot_record(
                                PERROR("snprintf snapshot path");
                                goto error;
                        }
+                       /* Free path allowed on previous iteration. */
+                       free(trace_path);
                        trace_path = setup_channel_trace_path(usess->consumer, pathname);
                        if (!trace_path) {
                                status = LTTNG_ERR_INVALID;
@@ -6007,10 +6030,8 @@ enum lttng_error_code ust_app_snapshot_record(
                                case LTTNG_OK:
                                        break;
                                case LTTNG_ERR_CHAN_NOT_FOUND:
-                                       free(trace_path);
                                        continue;
                                default:
-                                       free(trace_path);
                                        goto error;
                                }
                        }
@@ -6025,7 +6046,6 @@ enum lttng_error_code ust_app_snapshot_record(
                                        ua_sess->effective_credentials.uid,
                                        ua_sess->effective_credentials.gid,
                                        trace_path, wait, 0);
-                       free(trace_path);
                        switch (status) {
                        case LTTNG_OK:
                                break;
@@ -6043,6 +6063,7 @@ enum lttng_error_code ust_app_snapshot_record(
        }
 
 error:
+       free(trace_path);
        rcu_read_unlock();
        return status;
 }
@@ -6465,6 +6486,17 @@ enum lttng_error_code ust_app_create_channel_subdirectories(
        {
                struct ust_app *app;
 
+               /*
+                * Create the toplevel ust/ directory in case no apps are running.
+                */
+               chunk_status = lttng_trace_chunk_create_subdirectory(
+                               usess->current_trace_chunk,
+                               DEFAULT_UST_TRACE_DIR);
+               if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+                       ret = LTTNG_ERR_CREATE_DIR_FAIL;
+                       goto error;
+               }
+
                cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app,
                                pid_n.node) {
                        struct ust_app_session *ua_sess;
This page took 0.026765 seconds and 4 git commands to generate.