X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Ffd-tracker%2Futils.c;fp=src%2Fcommon%2Ffd-tracker%2Futils.c;h=fe2cdcc4ed4f84f1c629e27c630964d25d10f377;hp=1f71fd49623eda113386fc1dd8ed7471cf318234;hb=dd95933f8371a8c81ffc1dc5b306f2263f1ff808;hpb=9d16b343fb9e781fc8d8fa3c448a3f382306dd33 diff --git a/src/common/fd-tracker/utils.c b/src/common/fd-tracker/utils.c index 1f71fd496..fe2cdcc4e 100644 --- a/src/common/fd-tracker/utils.c +++ b/src/common/fd-tracker/utils.c @@ -5,29 +5,35 @@ * */ +#include #include #include +#include #include #include #include -static int open_pipe_cloexec(void *data, int *fds) +static +int open_pipe_cloexec(void *data, int *fds) { return utils_create_pipe_cloexec(fds); } -static int close_pipe(void *data, int *pipe) +static +int close_pipe(void *data, int *pipe) { utils_close_pipe(pipe); pipe[0] = pipe[1] = -1; return 0; } +LTTNG_HIDDEN int fd_tracker_util_close_fd(void *unused, int *fd) { return close(*fd); } +LTTNG_HIDDEN int fd_tracker_util_pipe_open_cloexec( struct fd_tracker *tracker, const char *name, int *pipe) { @@ -53,8 +59,134 @@ end: return ret; } +LTTNG_HIDDEN int fd_tracker_util_pipe_close(struct fd_tracker *tracker, int *pipe) { return fd_tracker_close_unsuspendable_fd( tracker, pipe, 2, close_pipe, NULL); } + +struct open_directory_handle_args { + const struct lttng_directory_handle *in_handle; + struct lttng_directory_handle *ret_handle; + const char *path; +}; + +static +int open_directory_handle(void *_args, int *out_fds) +{ + int ret = 0; + struct open_directory_handle_args *args = _args; + struct lttng_directory_handle *new_handle = NULL; + + new_handle = args->in_handle ? + lttng_directory_handle_create_from_handle( + args->path, args->in_handle) : + lttng_directory_handle_create(args->path); + if (!new_handle) { + ret = -errno; + goto end; + } + + args->ret_handle = new_handle; + + /* + * Reserved to indicate that the handle does not use a handle; there is + * nothing to track. We want to indicate an error to the fd-tracker so + * that it doesn't attempt to track the file descriptor, but also want + * the caller to retrieve the newly-created handle. + * + * Calling this a hack is a fair assessment. + */ + if (!lttng_directory_handle_uses_fd(new_handle)) { + ret = ENOTSUP; + } else { +#ifdef COMPAT_DIRFD + *out_fds = new_handle->dirfd; +#else + abort(); +#endif + + } +end: + return ret; +} + +#ifdef COMPAT_DIRFD +static +int fd_close(void *unused, int *in_fds) +{ + const int ret = close(in_fds[0]); + + in_fds[0] = -1; + return ret; +} + +static +void directory_handle_destroy( + struct lttng_directory_handle *handle, void *data) +{ + struct fd_tracker *tracker = data; + const int ret = fd_tracker_close_unsuspendable_fd( + tracker, &handle->dirfd, 1, fd_close, NULL); + + if (ret) { + ERR("Failed to untrack directory handle file descriptor"); + } +} +#endif + +LTTNG_HIDDEN +struct lttng_directory_handle *fd_tracker_create_directory_handle( + struct fd_tracker *tracker, const char *path) +{ + return fd_tracker_create_directory_handle_from_handle( + tracker, NULL, path); +} + +LTTNG_HIDDEN +struct lttng_directory_handle *fd_tracker_create_directory_handle_from_handle( + struct fd_tracker *tracker, + struct lttng_directory_handle *in_handle, + const char *path) +{ + int ret; + int dirfd = -1; + char *handle_name = NULL; + char cwd_path[LTTNG_PATH_MAX] = "working directory"; + struct lttng_directory_handle *new_handle = NULL; + struct open_directory_handle_args open_args = { + .in_handle = in_handle, + .path = path, + }; + + if (!path) { + if (!getcwd(cwd_path, sizeof(cwd_path))) { + PERROR("Failed to get current working directory to name directory handle"); + goto end; + } + } + + ret = asprintf(&handle_name, "Directory handle to %s", + path ? path : cwd_path); + if (ret < 0) { + PERROR("Failed to format directory handle name"); + goto end; + } + + ret = fd_tracker_open_unsuspendable_fd(tracker, &dirfd, + (const char **) &handle_name, 1, open_directory_handle, + &open_args); + if (ret && ret != ENOTSUP) { + ERR("Failed to open directory handle to %s through the fd tracker", path ? path : cwd_path); + } + new_handle = open_args.ret_handle; + +#ifdef COMPAT_DIRFD + new_handle->destroy_cb = directory_handle_destroy; + new_handle->destroy_cb_data = tracker; +#endif +end: + free(handle_name); + return new_handle; +}