SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / bin / lttng / commands / track-untrack.c
index 25b4461f696a7e96beab3265da9f437eb1fda9d5..24e2d02aeb50e1f6ffb9c5eb3864913b84547715 100644 (file)
@@ -1,24 +1,15 @@
 /*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
- * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define _LGPL_SOURCE
 #include <ctype.h>
 #include <popt.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -56,7 +47,7 @@ struct opt_type {
 
 struct id_list {
        size_t nr;
-       struct lttng_tracker_id *array;
+       struct lttng_tracker_id **array;
 };
 
 static char *opt_session_name;
@@ -100,7 +91,7 @@ static struct poptOption long_options[] = {
 static struct id_list *alloc_id_list(size_t nr_items)
 {
        struct id_list *id_list;
-       struct lttng_tracker_id *items;
+       struct lttng_tracker_id **items;
 
        id_list = zmalloc(sizeof(*id_list));
        if (!id_list) {
@@ -128,15 +119,16 @@ static void free_id_list(struct id_list *list)
        }
        nr_items = list->nr;
        for (i = 0; i < nr_items; i++) {
-               struct lttng_tracker_id *item = &list->array[i];
-
-               free(item->string);
+               struct lttng_tracker_id *item = list->array[i];
+               lttng_tracker_id_destroy(item);
        }
        free(list);
 }
 
-static int parse_id_string(
-               const char *_id_string, int all, struct id_list **_id_list)
+static int parse_id_string(const char *_id_string,
+               int all,
+               struct id_list **_id_list,
+               enum lttng_tracker_type tracker_type)
 {
        const char *one_id_str;
        char *iter;
@@ -157,14 +149,28 @@ static int parse_id_string(
                goto error;
        }
        if (all) {
-               /* Empty ID string means all IDs */
+               enum lttng_tracker_id_status status;
+               /* Empty `ID string means all IDs */
                id_list = alloc_id_list(1);
                if (!id_list) {
                        ERR("Out of memory");
                        retval = CMD_ERROR;
                        goto error;
                }
-               id_list->array[0].type = LTTNG_ID_ALL;
+
+               id_list->array[0] = lttng_tracker_id_create();
+               if (id_list->array[0] == NULL) {
+                       ERR("Out of memory");
+                       retval = CMD_ERROR;
+                       goto error;
+               }
+
+               status = lttng_tracker_id_set_all(id_list->array[0]);
+               if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+                       ERR("Invalid value for tracker id");
+                       retval = CMD_ERROR;
+                       goto error;
+               }
                goto assign;
        }
 
@@ -230,20 +236,30 @@ static int parse_id_string(
        count = 0;
        one_id_str = strtok_r(id_string, ",", &iter);
        while (one_id_str != NULL) {
+               enum lttng_tracker_id_status status;
                struct lttng_tracker_id *item;
+               item = lttng_tracker_id_create();
+               if (item == NULL) {
+                       ERR("Out of memory");
+                       retval = CMD_ERROR;
+                       goto error;
+               }
 
-               item = &id_list->array[count++];
+               id_list->array[count++] = item;
                if (isdigit(one_id_str[0])) {
                        unsigned long v;
 
                        v = strtoul(one_id_str, NULL, 10);
-                       item->type = LTTNG_ID_VALUE;
-                       item->value = (int) v;
+                       status = lttng_tracker_id_set_value(item, (int) v);
+                       if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+                               ERR("Invalid value");
+                               retval = CMD_ERROR;
+                               goto error;
+                       }
                } else {
-                       item->type = LTTNG_ID_STRING;
-                       item->string = strdup(one_id_str);
-                       if (!item->string) {
-                               PERROR("Failed to allocate ID string");
+                       status = lttng_tracker_id_set_string(item, one_id_str);
+                       if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+                               ERR("Failed to set ID string");
                                retval = CMD_ERROR;
                                goto error;
                        }
@@ -254,11 +270,12 @@ static int parse_id_string(
        }
 
 assign:
+       /* SUCCESS */
        *_id_list = id_list;
-       goto end;       /* SUCCESS */
+       goto end;
 
-       /* ERROR */
 error:
+       /* ERROR */
        free_id_list(id_list);
 end:
        free(id_string);
@@ -365,7 +382,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                retval = CMD_ERROR;
                goto end;
        }
-       ret = parse_id_string(id_string, all, &id_list);
+       ret = parse_id_string(id_string, all, &id_list, tracker_type);
        if (ret != CMD_SUCCESS) {
                ERR("Error parsing %s string", tracker_str);
                retval = CMD_ERROR;
@@ -387,25 +404,54 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
        }
 
        for (i = 0; i < id_list->nr; i++) {
-               struct lttng_tracker_id *item = &id_list->array[i];
+               struct lttng_tracker_id *item = id_list->array[i];
+               enum lttng_tracker_id_type type =
+                               lttng_tracker_id_get_type(item);
+               enum lttng_tracker_id_status status =
+                               LTTNG_TRACKER_ID_STATUS_OK;
+               int value;
+               const char *value_string;
+
+               switch (type) {
+               case LTTNG_ID_ALL:
+                       /* Nothing to check */
+                       break;
+               case LTTNG_ID_VALUE:
+                       status = lttng_tracker_id_get_value(item, &value);
+                       break;
+               case LTTNG_ID_STRING:
+                       status = lttng_tracker_id_get_string(
+                                       item, &value_string);
+                       break;
+               default:
+                       retval = CMD_ERROR;
+                       goto end;
+               }
 
-               switch (item->type) {
+               if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+                       ERR("Tracker id object is in an invalid state");
+                       retval = CMD_ERROR;
+                       goto end;
+               }
+
+               switch (type) {
                case LTTNG_ID_ALL:
                        DBG("%s all IDs", cmd_str);
                        break;
                case LTTNG_ID_VALUE:
-                       DBG("%s ID %d", cmd_str, item->value);
+                       DBG("%s ID %d", cmd_str, value);
                        break;
                case LTTNG_ID_STRING:
-                       DBG("%s ID '%s'", cmd_str, item->string);
+                       DBG("%s ID '%s'", cmd_str, value_string);
                        break;
                default:
                        retval = CMD_ERROR;
                        goto end;
                }
+
                ret = cmd_func(handle, tracker_type, item);
                if (ret) {
-                       char *msg = NULL;
+                       const char *msg = NULL;
 
                        switch (-ret) {
                        case LTTNG_ERR_ID_TRACKED:
@@ -425,7 +471,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                break;
                        }
                        if (msg) {
-                               switch (item->type) {
+                               switch (type) {
                                case LTTNG_ID_ALL:
                                        WARN("All %ss %s in session %s",
                                                        tracker_str, msg,
@@ -433,14 +479,13 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                        break;
                                case LTTNG_ID_VALUE:
                                        WARN("%s %i %s in session %s",
-                                                       tracker_str,
-                                                       item->value, msg,
+                                                       tracker_str, value, msg,
                                                        session_name);
                                        break;
                                case LTTNG_ID_STRING:
                                        WARN("%s '%s' %s in session %s",
                                                        tracker_str,
-                                                       item->string, msg,
+                                                       value_string, msg,
                                                        session_name);
                                        break;
                                default:
@@ -449,19 +494,18 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                }
                        }
                } else {
-                       switch (item->type) {
+                       switch (type) {
                        case LTTNG_ID_ALL:
                                MSG("All %ss %sed in session %s", tracker_str,
                                                cmd_str, session_name);
                                break;
                        case LTTNG_ID_VALUE:
                                MSG("%s %i %sed in session %s", tracker_str,
-                                               item->value, cmd_str,
-                                               session_name);
+                                               value, cmd_str, session_name);
                                break;
                        case LTTNG_ID_STRING:
                                MSG("%s '%s' %sed in session %s", tracker_str,
-                                               item->string, cmd_str,
+                                               value_string, cmd_str,
                                                session_name);
                                break;
                        default:
@@ -537,11 +581,12 @@ static
 int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                int argc, const char **argv, const char *help_msg)
 {
-       int opt, ret = 0;
+       int opt, ret = 0, success = 1;
+       bool opt_all_present = false;
        enum cmd_error_code command_ret = CMD_SUCCESS;
-       int success = 1;
        static poptContext pc;
        char *session_name = NULL;
+       const char *leftover = NULL;
        struct mi_writer *writer = NULL;
 
        if (argc < 1) {
@@ -617,29 +662,7 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                        type_state = STATE_VGID;
                        break;
                case OPT_ALL:
-                       switch (type_state) {
-                       case STATE_PID:
-                               opt_pid.all = 1;
-                               break;
-                       case STATE_VPID:
-                               opt_vpid.all = 1;
-                               break;
-                       case STATE_UID:
-                               opt_uid.all = 1;
-                               break;
-                       case STATE_VUID:
-                               opt_vuid.all = 1;
-                               break;
-                       case STATE_GID:
-                               opt_gid.all = 1;
-                               break;
-                       case STATE_VGID:
-                               opt_vgid.all = 1;
-                               break;
-                       default:
-                               command_ret = CMD_ERROR;
-                               goto end;
-                       }
+                       opt_all_present = true;
                        break;
                default:
                        command_ret = CMD_UNDEFINED;
@@ -653,6 +676,36 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                goto end;
        }
 
+       /*
+        * If the `--all` option is present set the appropriate tracker's `all`
+        * field.
+        */
+       if (opt_all_present) {
+               switch (type_state) {
+               case STATE_PID:
+                       opt_pid.all = 1;
+                       break;
+               case STATE_VPID:
+                       opt_vpid.all = 1;
+                       break;
+               case STATE_UID:
+                       opt_uid.all = 1;
+                       break;
+               case STATE_VUID:
+                       opt_vuid.all = 1;
+                       break;
+               case STATE_GID:
+                       opt_gid.all = 1;
+                       break;
+               case STATE_VGID:
+                       opt_vgid.all = 1;
+                       break;
+               default:
+                       command_ret = CMD_ERROR;
+                       goto end;
+               }
+       }
+
        if (!opt_session_name) {
                session_name = get_session_name();
                if (session_name == NULL) {
@@ -663,6 +716,13 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                session_name = opt_session_name;
        }
 
+       leftover = poptGetArg(pc);
+       if (leftover) {
+               ERR("Unknown argument: %s", leftover);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
        /* Mi check */
        if (lttng_opt_mi) {
                writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
This page took 0.029248 seconds and 5 git commands to generate.