Fix: lttng list command with network path
authorDavid Goulet <dgoulet@efficios.com>
Fri, 17 Aug 2012 16:47:16 +0000 (12:47 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Fri, 17 Aug 2012 16:47:16 +0000 (12:47 -0400)
With network consumer, the session path was simply NULL or set to the
wrong local filesystem path when a consumer was set to use the network.

This commit adds the support for network path description when a lttng
list command is received.

Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/main.c
src/common/uri.c
src/common/uri.h
src/lib/lttng-ctl/lttng-ctl.c

index 9ff4eceb2c84ba3469ef22a5c59b59e57ca16672..3503e0415489636654d5a3fa037b4909a68907c3 100644 (file)
@@ -272,7 +272,8 @@ malloc_error:
 /*
  * Set network URI to the consumer output object.
  *
- * Return 0 on success. Negative value on error.
+ * Return 0 on success. Return 1 if the URI were equal. Else, negative value on
+ * error.
  */
 int consumer_set_network_uri(struct consumer_output *obj,
                struct lttng_uri *uri)
@@ -294,6 +295,7 @@ int consumer_set_network_uri(struct consumer_output *obj,
                        /* Assign default port. */
                        uri->port = DEFAULT_NETWORK_CONTROL_PORT;
                }
+               DBG3("Consumer control URI set with port %d", uri->port);
                break;
        case LTTNG_STREAM_DATA:
                dst_uri = &obj->dst.net.data;
@@ -302,6 +304,7 @@ int consumer_set_network_uri(struct consumer_output *obj,
                        /* Assign default port. */
                        uri->port = DEFAULT_NETWORK_DATA_PORT;
                }
+               DBG3("Consumer data URI set with port %d", uri->port);
                break;
        default:
                ERR("Set network uri type unknown %d", uri->stype);
@@ -312,7 +315,7 @@ int consumer_set_network_uri(struct consumer_output *obj,
        if (!ret) {
                /* Same URI, don't touch it and return success. */
                DBG3("URI network compare are the same");
-               goto end;
+               goto equal;
        }
 
        /* URIs were not equal, replacing it. */
@@ -347,9 +350,9 @@ int consumer_set_network_uri(struct consumer_output *obj,
                DBG3("Consumer set network uri subdir path %s", tmp_path);
        }
 
-end:
        return 0;
-
+equal:
+       return 1;
 error:
        return -1;
 }
index d0b1e17e544ef21b110381ea266f5037172e80f0..495465b6f76ada3b870f3074ec4ee7106a4764b8 100644 (file)
@@ -2418,6 +2418,73 @@ static unsigned int lttng_sessions_count(uid_t uid, gid_t gid)
        return i;
 }
 
+/*
+ * Create a session path used by list_lttng_sessions for the case that the
+ * session consumer is on the network.
+ */
+static int build_network_session_path(char *dst, size_t size,
+               struct ltt_session *session)
+{
+       int ret, kdata_port, udata_port;
+       struct lttng_uri *kuri = NULL, *uuri = NULL, *uri = NULL;
+       char tmp_uurl[PATH_MAX], tmp_urls[PATH_MAX];
+
+       assert(session);
+       assert(dst);
+
+       memset(tmp_urls, 0, sizeof(tmp_urls));
+       memset(tmp_uurl, 0, sizeof(tmp_uurl));
+
+       kdata_port = udata_port = DEFAULT_NETWORK_DATA_PORT;
+
+       if (session->kernel_session && session->kernel_session->consumer) {
+               kuri = &session->kernel_session->consumer->dst.net.control;
+               kdata_port = session->kernel_session->consumer->dst.net.data.port;
+       }
+
+       if (session->ust_session && session->ust_session->consumer) {
+               uuri = &session->ust_session->consumer->dst.net.control;
+               udata_port = session->ust_session->consumer->dst.net.data.port;
+       }
+
+       if (uuri == NULL && kuri == NULL) {
+               uri = &session->consumer->dst.net.control;
+               kdata_port = session->consumer->dst.net.data.port;
+       } else if (kuri && uuri) {
+               ret = uri_compare(kuri, uuri);
+               if (ret) {
+                       /* Not Equal */
+                       uri = kuri;
+                       /* Build uuri URL string */
+                       ret = uri_to_str_url(uuri, tmp_uurl, sizeof(tmp_uurl));
+                       if (ret < 0) {
+                               goto error;
+                       }
+               } else {
+                       uri = kuri;
+               }
+       } else if (kuri && uuri == NULL) {
+               uri = kuri;
+       } else if (uuri && kuri == NULL) {
+               uri = uuri;
+       }
+
+       ret = uri_to_str_url(uri, tmp_urls, sizeof(tmp_urls));
+       if (ret < 0) {
+               goto error;
+       }
+
+       if (strlen(tmp_uurl) > 0) {
+               ret = snprintf(dst, size, "[K]: %s [data: %d] -- [U]: %s [data: %d]",
+                               tmp_urls, kdata_port, tmp_uurl, udata_port);
+       } else {
+               ret = snprintf(dst, size, "%s [data: %d]", tmp_urls, kdata_port);
+       }
+
+error:
+       return ret;
+}
+
 /*
  * Using the session list, filled a lttng_session array to send back to the
  * client for session listing.
@@ -2428,6 +2495,7 @@ static unsigned int lttng_sessions_count(uid_t uid, gid_t gid)
 static void list_lttng_sessions(struct lttng_session *sessions, uid_t uid,
                gid_t gid)
 {
+       int ret;
        unsigned int i = 0;
        struct ltt_session *session;
 
@@ -2444,8 +2512,20 @@ static void list_lttng_sessions(struct lttng_session *sessions, uid_t uid,
                if (!session_access_ok(session, uid, gid)) {
                        continue;
                }
-               strncpy(sessions[i].path, session->path, PATH_MAX);
-               sessions[i].path[PATH_MAX - 1] = '\0';
+
+               if (session->consumer->type == CONSUMER_DST_LOCAL &&
+                               (!session->kernel_session && !session->ust_session)) {
+                       ret = snprintf(sessions[i].path, sizeof(session[i].path), "%s",
+                                       session->consumer->dst.trace_path);
+               } else {
+                       ret = build_network_session_path(sessions[i].path,
+                                       sizeof(session[i].path), session);
+               }
+               if (ret < 0) {
+                       PERROR("snprintf session path");
+                       continue;
+               }
+
                strncpy(sessions[i].name, session->name, NAME_MAX);
                sessions[i].name[NAME_MAX - 1] = '\0';
                sessions[i].enabled = session->enabled;
@@ -2706,6 +2786,12 @@ static int add_uri_to_consumer(struct consumer_output *consumer,
                if (ret < 0) {
                        ret = LTTCOMM_FATAL;
                        goto error;
+               } else if (ret == 1) {
+                       /*
+                        * URI was the same in the consumer so we do not append the subdir
+                        * again so to not duplicate output dir.
+                        */
+                       goto error;
                }
 
                if (uri->stype == LTTNG_STREAM_CONTROL && strlen(uri->subdir) == 0) {
@@ -3687,8 +3773,6 @@ static int cmd_create_session_uri(char *name, struct lttng_uri *uris,
        int ret;
        char *path = NULL;
        struct ltt_session *session;
-       //struct consumer_output *consumer = NULL;
-       //struct lttng_uri *ctrl_uri, *data_uri = NULL;
 
        assert(name);
 
index e686f7c5d788b2676a49c9b4746c846a63fc5aba..ec5d426630b9300e925df81fa8d794b2ed282c94 100644 (file)
@@ -137,6 +137,40 @@ error:
        return -1;
 }
 
+/*
+ * Build a string URL from a lttng_uri object.
+ */
+int uri_to_str_url(struct lttng_uri *uri, char *dst, size_t size)
+{
+       int ipver, ret;
+       const char *addr;
+       char proto[4], port[7];
+
+       assert(uri);
+       assert(dst);
+
+       if (uri->dtype == LTTNG_DST_PATH) {
+               ipver = 0;
+               addr = uri->dst.path;
+               (void) snprintf(proto, sizeof(proto), "file");
+               (void) snprintf(port, sizeof(port), "%s", "");
+       } else {
+               ipver = (uri->dtype == LTTNG_DST_IPV4) ? 4 : 6;
+               addr = (ipver == 4) ?  uri->dst.ipv4 : uri->dst.ipv6;
+               (void) snprintf(proto, sizeof(proto), "net%d", ipver);
+               (void) snprintf(port, sizeof(port), ":%d", uri->port);
+       }
+
+       ret = snprintf(dst, size, "%s://%s%s%s%s/%s", proto,
+                       (ipver == 6) ? "[" : "", addr, (ipver == 6) ? "]" : "",
+                       port, uri->subdir);
+       if (ret < 0) {
+               PERROR("snprintf uri to url");
+       }
+
+       return ret;
+}
+
 /*
  * Compare two URIs.
  *
index d768e8724670d80759c8002a60b2c4acb81efde8..347b639b0008dcd8991c7a468aafcee6ecfce56f 100644 (file)
@@ -77,5 +77,6 @@ struct lttng_uri {
 int uri_compare(struct lttng_uri *uri1, struct lttng_uri *uri2);
 void uri_free(struct lttng_uri *uri);
 ssize_t uri_parse(const char *str_uri, struct lttng_uri **uris);
+int uri_to_str_url(struct lttng_uri *uri, char *dst, size_t size);
 
 #endif /* _LTT_URI_H */
index f18e8ca07358050f58926faece98fb5a500ce910..3bef3b6d71a1e46c22883428382dbd247910b6d2 100644 (file)
@@ -1549,7 +1549,7 @@ int _lttng_create_session_ext(const char *name, const char *url,
        lsm.u.uri.size = size;
 
        if (uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
-               ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "/%s-%s", name,
+               ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s-%s", name,
                                datetime);
                if (ret < 0) {
                        PERROR("snprintf uri subdir");
This page took 0.032769 seconds and 4 git commands to generate.