From: Alan T. DeKok Date: Fri, 24 Apr 2020 15:43:08 +0000 (-0400) Subject: add debug API for armouring FDs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4fd11bb6afa0843c3dcc39728048918fc3a0ca1;p=thirdparty%2Ffreeradius-server.git add debug API for armouring FDs this API is likely short-lived until we discover what is accidentally deleting the FDs --- diff --git a/src/lib/util/event.c b/src/lib/util/event.c index 8562f368bc6..ea7764581f4 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -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 * diff --git a/src/lib/util/event.h b/src/lib/util/event.h index 2b593639dc3..1328946107f 100644 --- a/src/lib/util/event.h +++ b/src/lib/util/event.h @@ -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));