Mi enable-channel command: support and validation
authorJonathan Rajotte Julien <jonathan.r.julien@gmail.com>
Wed, 18 Jun 2014 19:49:15 +0000 (15:49 -0400)
committerJonathan Rajotte Julien <jonathan.r.julien@gmail.com>
Tue, 22 Jul 2014 20:14:57 +0000 (16:14 -0400)
Signed-off-by: Jonathan Rajotte Julien <jonathan.r.julien@gmail.com>
src/bin/lttng/commands/create.c
src/bin/lttng/commands/enable_channels.c
src/common/mi-lttng.c
src/common/mi-lttng.h
src/common/mi_lttng.xsd

index 1d02a1f0a86021d50c3ad53e5581181b96bc3563..4145e14d85e88e15b5d1b025d38881dfa61e856c 100644 (file)
@@ -594,7 +594,7 @@ int cmd_create(int argc, const char **argv)
        }
 
 
-       /* MI initilisation */
+       /* MI initialization */
        if (lttng_opt_mi) {
                writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
                if (!writer) {
@@ -656,7 +656,7 @@ end:
                ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
        }
 
-       /* Overwrite ret if an error occured in create_session() */
+       /* Overwrite ret if an error occurred in create_session() */
        ret = command_ret ? command_ret : ret;
 
        poptFreeContext(pc);
index 1fdaada99f625a9418683b3e24ecd763a5437da1..a58ebe0f7847a653147654c53345b0ddb500c016 100644 (file)
 #include <assert.h>
 #include <ctype.h>
 
+#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/utils.h>
+#include <common/mi-lttng.h>
+
 #include "../command.h"
 #include "../utils.h"
 
-#include <src/common/sessiond-comm/sessiond-comm.h>
-#include <src/common/utils.h>
 
 static char *opt_channels;
 static int opt_kernel;
@@ -43,6 +45,8 @@ static int opt_buffer_uid;
 static int opt_buffer_pid;
 static int opt_buffer_global;
 
+static struct mi_writer *writer;
+
 enum {
        OPT_HELP = 1,
        OPT_DISCARD,
@@ -187,7 +191,7 @@ static void set_default_attr(struct lttng_domain *dom)
  */
 static int enable_channel(char *session_name)
 {
-       int ret = CMD_SUCCESS, warn = 0;
+       int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0;
        char *channel_name;
        struct lttng_domain dom;
 
@@ -257,6 +261,16 @@ static int enable_channel(char *session_name)
                goto error;
        }
 
+       /* Mi open channels element */
+       if (lttng_opt_mi) {
+               assert(writer);
+               ret = mi_lttng_channels_open(writer);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto error;
+               }
+       }
+
        /* Strip channel list (format: chan1,chan2,...) */
        channel_name = strtok(opt_channels, ",");
        while (channel_name != NULL) {
@@ -268,34 +282,75 @@ static int enable_channel(char *session_name)
 
                ret = lttng_enable_channel(handle, &chan);
                if (ret < 0) {
+                       success = 0;
                        switch (-ret) {
                        case LTTNG_ERR_KERN_CHAN_EXIST:
                        case LTTNG_ERR_UST_CHAN_EXIST:
                        case LTTNG_ERR_CHAN_EXIST:
                                WARN("Channel %s: %s (session %s)", channel_name,
                                                lttng_strerror(ret), session_name);
-                               goto error;
+                               warn = 1;
+                               break;
                        default:
                                ERR("Channel %s: %s (session %s)", channel_name,
                                                lttng_strerror(ret), session_name);
+                               error = 1;
                                break;
                        }
-                       warn = 1;
                } else {
                        MSG("%s channel %s enabled for session %s",
                                        get_domain_str(dom.type), channel_name, session_name);
+                       success = 1;
+               }
+
+               if (lttng_opt_mi) {
+                       /* Mi print the channel element and leave it open */
+                       ret = mi_lttng_channel(writer, &chan, 1);
+                       if (ret) {
+                               ret = CMD_ERROR;
+                               goto error;
+                       }
+
+                       /* Individual Success ? */
+                       ret = mi_lttng_writer_write_element_bool(writer,
+                                       mi_lttng_element_command_success, success);
+                       if (ret) {
+                               ret = CMD_ERROR;
+                               goto error;
+                       }
+
+                       /* Close channel element */
+                       ret = mi_lttng_writer_close_element(writer);
+                       if (ret) {
+                               ret = CMD_ERROR;
+                               goto error;
+                       }
                }
 
-               /* Next event */
+               /* Next channel */
                channel_name = strtok(NULL, ",");
        }
 
+       if (lttng_opt_mi) {
+               /* Close channels element */
+               ret = mi_lttng_writer_close_element(writer);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto error;
+               }
+       }
+
        ret = CMD_SUCCESS;
 
 error:
-       if (warn) {
+       /* If more important error happen bypass the warning */
+       if (!ret && warn) {
                ret = CMD_WARNING;
        }
+       /* If more important error happen bypass the warning */
+       if (!ret && error) {
+               ret = CMD_ERROR;
+       }
 
        lttng_destroy_handle(handle);
 
@@ -319,7 +374,7 @@ static void init_channel_config(void)
  */
 int cmd_enable_channels(int argc, const char **argv)
 {
-       int opt, ret = CMD_SUCCESS;
+       int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
        static poptContext pc;
        char *session_name = NULL;
        char *opt_arg = NULL;
@@ -329,13 +384,6 @@ int cmd_enable_channels(int argc, const char **argv)
        pc = poptGetContext(NULL, argc, argv, long_options, 0);
        poptReadDefaultConfig(pc, 0);
 
-       /* TODO: mi support */
-       if (lttng_opt_mi) {
-               ret = -LTTNG_ERR_MI_NOT_IMPLEMENTED;
-               ERR("mi option not supported");
-               goto end;
-       }
-
        while ((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case OPT_HELP:
@@ -507,30 +555,92 @@ int cmd_enable_channels(int argc, const char **argv)
                }
        }
 
+       /* Mi check */
+       if (lttng_opt_mi) {
+               writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
+               if (!writer) {
+                       ret = -LTTNG_ERR_NOMEM;
+                       goto end;
+               }
+
+               /* Open command element */
+               ret = mi_lttng_writer_command_open(writer,
+                               mi_lttng_element_command_enable_channels);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+
+               /* Open output element */
+               ret = mi_lttng_writer_open_element(writer,
+                               mi_lttng_element_command_output);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+       }
+
        opt_channels = (char*) poptGetArg(pc);
        if (opt_channels == NULL) {
                ERR("Missing channel name.\n");
                usage(stderr);
                ret = CMD_ERROR;
-               goto end;
+               success = 0;
+               goto mi_closing;
        }
 
        if (!opt_session_name) {
                session_name = get_session_name();
                if (session_name == NULL) {
-                       ret = CMD_ERROR;
-                       goto end;
+                       command_ret = CMD_ERROR;
+                       success = 0;
+                       goto mi_closing;
                }
        } else {
                session_name = opt_session_name;
        }
 
-       ret = enable_channel(session_name);
+       command_ret = enable_channel(session_name);
+       if (command_ret) {
+               success = 0;
+       }
+
+mi_closing:
+       /* Mi closing */
+       if (lttng_opt_mi) {
+               /* Close  output element */
+               ret = mi_lttng_writer_close_element(writer);
+               if (ret) {
+                       goto end;
+               }
+
+               /* Success ? */
+               ret = mi_lttng_writer_write_element_bool(writer,
+                               mi_lttng_element_command_success, success);
+               if (ret) {
+                       goto end;
+               }
+
+               /* Command element close */
+               ret = mi_lttng_writer_command_close(writer);
+               if (ret) {
+                       goto end;
+               }
+       }
 
 end:
+       /* Mi clean-up */
+       if (writer && mi_lttng_writer_destroy(writer)) {
+               /* Preserve original error code */
+               ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
+       }
+
        if (!opt_session_name && session_name) {
                free(session_name);
        }
+
+       /* Overwrite ret if an error occurred when enable_channel */
+       ret = command_ret ? command_ret : ret;
        poptFreeContext(pc);
        return ret;
 }
index 515f16941b52cb881ad2644991b8b592d4eb4766..d13c2a6f7eeb70255d1d584c6be84aaebe294af1 100644 (file)
@@ -36,6 +36,7 @@ const char * const mi_lttng_element_command_create = "create";
 const char * const mi_lttng_element_command_destroy = "destroy";
 const char * const mi_lttng_element_command_calibrate = "calibrate";
 const char * const mi_lttng_element_command_add_context = "add-context";
+const char * const mi_lttng_element_command_enable_channels = "enable-channel";
 const char * const mi_lttng_element_command_output = "output";
 const char * const mi_lttng_element_command_success = "success";
 
index a3a087036a310a48a8aeb368863deefb74b78a1c..4b2b035e04a66d1d55c9036103975e3ce90a3612 100644 (file)
@@ -58,6 +58,7 @@ const char * const mi_lttng_element_command_create;
 const char * const mi_lttng_element_command_destroy;
 const char * const mi_lttng_element_command_calibrate;
 const char * const mi_lttng_element_command_add_context;
+const char * const mi_lttng_element_command_enable_channels;
 const char * const mi_lttng_element_command_output;
 const char * const mi_lttng_element_command_success;
 
index ebf20854bf4162a42907ce9707d061e466353d71..08184aca687057f4e1ae174ed9c3b2b3584b6ab9 100644 (file)
@@ -258,7 +258,7 @@ THE SOFTWARE.
                        <xs:element name="name" type="name_type"/>
                        <xs:element name="enabled" type="xs:boolean" default="true" minOccurs="0"/>
                        <xs:element name="attributes" type="channel_attributes_type" minOccurs="0"/>
-                       <xs:element name="events" type="event_list_type"/>
+                       <xs:element name="events" type="event_list_type" minOccurs="0" />
                </xs:all>
        </xs:complexType>
 
@@ -379,6 +379,7 @@ THE SOFTWARE.
                        <xs:element name="load" type="load_type" minOccurs="0" />
                        <xs:element name="calibrate" type="calibrate_type" minOccurs="0" />
                        <xs:element name="contexts" type="contexts_type" minOccurs="0" />
+                       <xs:element name="channels" type="channels_type" minOccurs="0" />
                </xs:choice>
        </xs:complexType>
 
@@ -395,6 +396,7 @@ THE SOFTWARE.
                        <xs:enumeration value="destroy" />
                        <xs:enumeration value="calibrate" />
                        <xs:enumeration value="add-context" />
+                       <xs:enumeration value="enable-channel" />
                </xs:restriction>
        </xs:simpleType>
 
This page took 0.030087 seconds and 4 git commands to generate.