Backport: Fix: tracker: ensure consistency of tracker states
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 4 Jul 2018 21:51:47 +0000 (17:51 -0400)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Fri, 21 Sep 2018 04:00:52 +0000 (00:00 -0400)
On error when adding/removing from either UST or kernel trackers,
we need to roll back the state of our internal lists.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/trace-ust.c

index ea0e75d7ff1910fa7d916941bb8befc93c400077..a72fe7f5c977ac76cd351555ec170b5781977191 100644 (file)
@@ -412,6 +412,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
 {
        int ret, value;
        struct lttng_tracker_list *tracker_list;
+       struct lttng_tracker_id *saved_ids;
+       ssize_t saved_ids_count, i;
 
        ret = lttng_tracker_id_lookup_string(tracker_type,
                        id, &value);
@@ -419,14 +421,19 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                return ret;
        }
 
-       /* Add to list. */
        tracker_list = get_id_tracker_list(session, tracker_type);
        if (!tracker_list) {
                return LTTNG_ERR_INVALID;
        }
+       /* Save list for restore on error. */
+       saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+       if (saved_ids_count < 0) {
+               return LTTNG_ERR_INVALID;
+       }
+       /* Add to list. */
        ret = lttng_tracker_list_add(tracker_list, id);
        if (ret != LTTNG_OK) {
-               return ret;
+               goto end;
        }
 
        switch (tracker_type) {
@@ -435,7 +442,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_pid(session->fd, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VPID:
@@ -443,7 +451,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VPID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_UID:
@@ -451,7 +460,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_id(session->fd, LTTNG_TRACKER_UID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_GID:
@@ -459,7 +469,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_id(session->fd, LTTNG_TRACKER_GID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VUID:
@@ -467,7 +478,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VUID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VGID:
@@ -475,22 +487,38 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VGID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        default:
-               return LTTNG_ERR_INVALID;
+               ret = -EINVAL;
+               break;
        }
+       /* Error handling. */
        switch (-ret) {
        case EINVAL:
-               return LTTNG_ERR_INVALID;
+               ret = LTTNG_ERR_INVALID;
+               break;
        case ENOMEM:
-               return LTTNG_ERR_NOMEM;
+               ret = LTTNG_ERR_NOMEM;
+               break;
        case EEXIST:
-               return LTTNG_ERR_ID_TRACKED;
+               ret = LTTNG_ERR_ID_TRACKED;
+               break;
        default:
-               return LTTNG_ERR_UNK;
+               ret = LTTNG_ERR_UNK;
+               break;
+       }
+       if (lttng_tracker_id_set_list(tracker_list, saved_ids, saved_ids_count) != LTTNG_OK) {
+               ERR("Error on tracker add error handling.\n");
+       }
+end:
+       for (i = 0; i < saved_ids_count; i++) {
+               free(saved_ids[i].string);
        }
+       free(saved_ids);
+       return ret;
 }
 
 int kernel_untrack_id(enum lttng_tracker_type tracker_type,
@@ -499,6 +527,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
 {
        int ret, value;
        struct lttng_tracker_list *tracker_list;
+       struct lttng_tracker_id *saved_ids;
+       ssize_t saved_ids_count, i;
 
        ret = lttng_tracker_id_lookup_string(tracker_type,
                        id, &value);
@@ -506,14 +536,19 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                return ret;
        }
 
-       /* Remove from list. */
        tracker_list = get_id_tracker_list(session, tracker_type);
        if (!tracker_list) {
                return LTTNG_ERR_INVALID;
        }
+       /* Save list for restore on error. */
+       saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+       if (saved_ids_count < 0) {
+               return LTTNG_ERR_INVALID;
+       }
+       /* Remove from list. */
        ret = lttng_tracker_list_remove(tracker_list, id);
        if (ret != LTTNG_OK) {
-               return ret;
+               goto end;
        }
 
        switch (tracker_type) {
@@ -522,7 +557,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_pid(session->fd, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VPID:
@@ -530,7 +566,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VPID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_UID:
@@ -538,7 +575,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_UID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_GID:
@@ -546,7 +584,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_GID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VUID:
@@ -554,7 +593,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VUID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        case LTTNG_TRACKER_VGID:
@@ -562,23 +602,40 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                                value, session->id);
                ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VGID, value);
                if (!ret) {
-                       return LTTNG_OK;
+                       ret = LTTNG_OK;
+                       goto end;
                }
                break;
        default:
-               return LTTNG_ERR_INVALID;
+               ret = -EINVAL;
+               break;
        }
 
+       /* Error handling. */
        switch (-ret) {
        case EINVAL:
-               return LTTNG_ERR_INVALID;
+               ret = LTTNG_ERR_INVALID;
+               break;
        case ENOMEM:
-               return LTTNG_ERR_NOMEM;
-       case ENOENT:
-               return LTTNG_ERR_ID_NOT_TRACKED;
+               ret = LTTNG_ERR_NOMEM;
+               break;
+       case EEXIST:
+               ret = LTTNG_ERR_ID_TRACKED;
+               break;
        default:
-               return LTTNG_ERR_UNK;
+               ret = LTTNG_ERR_UNK;
+               break;
+       }
+
+       if (lttng_tracker_id_set_list(tracker_list, saved_ids, saved_ids_count) != LTTNG_OK) {
+               ERR("Error on tracker remove error handling.\n");
        }
+end:
+       for (i = 0; i < saved_ids_count; i++) {
+               free(saved_ids[i].string);
+       }
+       free(saved_ids);
+       return ret;
 }
 
 /*
index 10af67e371406feda5ed6e14e0dc15af286b3b57..29263e7c8a3195e539b04e21d95bf1fa99a35671 100644 (file)
@@ -874,6 +874,8 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
        struct ust_id_tracker *id_tracker;
        struct lttng_tracker_list *tracker_list;
        int value;
+       struct lttng_tracker_id *saved_ids;
+       ssize_t saved_ids_count, i;
 
        if (tracker_type == LTTNG_TRACKER_PID) {
                DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
@@ -885,15 +887,19 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
        if (retval != LTTNG_OK) {
                return retval;
        }
-
-       /* Add to list. */
        tracker_list = get_id_tracker_list(session, tracker_type);
        if (!tracker_list) {
                return LTTNG_ERR_INVALID;
        }
+       /* Save list for restore on error. */
+       saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+       if (saved_ids_count < 0) {
+               return LTTNG_ERR_INVALID;
+       }
+       /* Add to list. */
        retval = lttng_tracker_list_add(tracker_list, id);
        if (retval != LTTNG_OK) {
-               return retval;
+               goto end;
        }
 
        id_tracker = get_id_tracker(session, tracker_type);
@@ -913,12 +919,12 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
                        retval = init_id_tracker(id_tracker);
                        if (retval != LTTNG_OK) {
                                ERR("Error initializing ID tracker");
-                               goto end;
+                               goto end_restore;
                        }
                        retval = id_tracker_add_id(id_tracker, value);
                        if (retval != LTTNG_OK) {
                                fini_id_tracker(id_tracker);
-                               goto end;
+                               goto end_restore;
                        }
                        /* Keep only apps matching ID. */
                        ust_app_global_update_all(session);
@@ -927,7 +933,7 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
 
                        retval = id_tracker_add_id(id_tracker, value);
                        if (retval != LTTNG_OK) {
-                               goto end;
+                               goto end_restore;
                        }
                        /* Add session to application */
                        switch (tracker_type) {
@@ -943,7 +949,17 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
                        }
                }
        }
+       goto end;
+
+end_restore:
+       if (lttng_tracker_id_set_list(tracker_list, saved_ids, saved_ids_count) != LTTNG_OK) {
+               ERR("Error on tracker add error handling.\n");
+       }
 end:
+       for (i = 0; i < saved_ids_count; i++) {
+               free(saved_ids[i].string);
+       }
+       free(saved_ids);
        return retval;
 }
 
@@ -957,6 +973,8 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
        struct ust_id_tracker *id_tracker;
        struct lttng_tracker_list *tracker_list;
        int value;
+       struct lttng_tracker_id *saved_ids;
+       ssize_t saved_ids_count, i;
 
        if (tracker_type == LTTNG_TRACKER_PID) {
                DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
@@ -969,14 +987,19 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
                return retval;
        }
 
-       /* Remove from list. */
        tracker_list = get_id_tracker_list(session, tracker_type);
        if (!tracker_list) {
                return LTTNG_ERR_INVALID;
        }
+       /* Save list for restore on error. */
+       saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+       if (saved_ids_count < 0) {
+               return LTTNG_ERR_INVALID;
+       }
+       /* Remove from list. */
        retval = lttng_tracker_list_remove(tracker_list, id);
        if (retval != LTTNG_OK) {
-               return retval;
+               goto end;
        }
 
        id_tracker = get_id_tracker(session, tracker_type);
@@ -994,7 +1017,7 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
                        ERR("Error initializing ID tracker");
                        /* Rollback operation. */
                        *id_tracker = tmp_tracker;
-                       goto end;
+                       goto end_restore;
                }
                fini_id_tracker(&tmp_tracker);
 
@@ -1006,12 +1029,12 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
                if (!id_tracker->ht) {
                        /* No ID being tracked. */
                        retval = LTTNG_ERR_ID_NOT_TRACKED;
-                       goto end;
+                       goto end_restore;
                }
                /* Remove ID from tracker */
                retval = id_tracker_del_id(id_tracker, value);
                if (retval != LTTNG_OK) {
-                       goto end;
+                       goto end_restore;
                }
                switch (tracker_type) {
                case LTTNG_TRACKER_VPID:
@@ -1026,7 +1049,17 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
                        ust_app_global_update_all(session);
                }
        }
+       goto end;
+
+end_restore:
+       if (lttng_tracker_id_set_list(tracker_list, saved_ids, saved_ids_count) != LTTNG_OK) {
+               ERR("Error on tracker remove error handling.\n");
+       }
 end:
+       for (i = 0; i < saved_ids_count; i++) {
+               free(saved_ids[i].string);
+       }
+       free(saved_ids);
        return retval;
 }
 
This page took 0.034316 seconds and 5 git commands to generate.