Backport: Fix: tracker: ensure consistency of tracker states
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.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;
 }
 
 /*
This page took 0.027293 seconds and 5 git commands to generate.