]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add debug API for armouring FDs
authorAlan T. DeKok <aland@freeradius.org>
Fri, 24 Apr 2020 15:43:08 +0000 (11:43 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 24 Apr 2020 15:43:08 +0000 (11:43 -0400)
this API is likely short-lived until we discover what is
accidentally deleting the FDs

src/lib/util/event.c
src/lib/util/event.h

index 8562f368bc6fc8d5a2154d8f81c6a8c9ab45071c..ea7764581f4667136ca0b1f5c969af951e89843e 100644 (file)
@@ -257,6 +257,10 @@ struct fr_event_fd {
        TALLOC_CTX              *linked_ctx;            //!< talloc ctx this event was bound to.
 
        fr_event_fd_t           *next;                  //!< item in a list of fr_event_fd (to free).
+
+#ifndef NDEBUG
+       uint32_t                armour;                 //!< protection flag from being deleted.
+#endif
 };
 
 struct fr_event_pid {
@@ -643,6 +647,8 @@ static int _event_fd_delete(fr_event_fd_t *ef)
        if (ef->is_registered) {
                memset(&funcs, 0, sizeof(funcs));
 
+               fr_assert(ef->armour == 0);
+
                /*
                 *      If this fails, it's a pretty catastrophic error.
                 */
@@ -1020,6 +1026,62 @@ int fr_event_fd_insert(TALLOC_CTX *ctx, fr_event_list_t *el, int fd,
        return fr_event_filter_insert(ctx, el, fd, FR_EVENT_FILTER_IO, &funcs, error, uctx);
 }
 
+#ifndef NDEBUG
+/** Armour an FD
+ *
+ * @param[in] el       to remove file descriptor from.
+ * @param[in] fd       to remove.
+ * @param[in] filter   The type of filter to remove.
+ * @param[in] armour   The armour to add.
+ * @return
+ *     - 0 if file descriptor was armoured
+ *     - <0 on error.
+ */
+int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uint32_t armour)
+{
+       fr_event_fd_t   *ef;
+
+       ef = rbtree_finddata(el->fds, &(fr_event_fd_t){ .fd = fd, .filter = filter });
+       if (unlikely(!ef)) {
+               fr_strerror_printf("No events are registered for fd %i", fd);
+               return -1;
+       }
+
+       if (ef->armour != 0) {
+               fr_strerror_printf("FD %i is already armoured", fd);
+               return -1;
+       }
+
+       ef->armour = armour;
+       return 0;
+}
+
+/** Unarmour an FD
+ *
+ * @param[in] el       to remove file descriptor from.
+ * @param[in] fd       to remove.
+ * @param[in] filter   The type of filter to remove.
+ * @param[in] armour   The armour to remove
+ * @return
+ *     - 0 if file descriptor was unarmoured
+ *     - <0 on error.
+ */
+int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uint32_t armour)
+{
+       fr_event_fd_t   *ef;
+
+       ef = rbtree_finddata(el->fds, &(fr_event_fd_t){ .fd = fd, .filter = filter });
+       if (unlikely(!ef)) {
+               fr_strerror_printf("No events are registered for fd %i", fd);
+               return -1;
+       }
+
+       fr_assert(ef->armour == armour);
+
+       ef->armour = 0;
+       return 0;
+}
+#endif
 
 /** Delete a timer event from the event list
  *
index 2b593639dc3730b5c03414496fdb34615df9e676..1328946107f57bb99889a8bf8c2870e7f56208db 100644 (file)
@@ -218,6 +218,12 @@ int                fr_event_fd_insert(TALLOC_CTX *ctx, fr_event_list_t *el, int fd,
                                   fr_event_error_cb_t error,
                                   void *uctx);
 
+#ifndef NDEBUG
+int            fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t, uint32_t armour);
+int            fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uint32_t armour);
+#endif
+
+
 int            fr_event_pid_wait(TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const **ev_p,
                                  pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx) CC_HINT(nonnull(2,5));