TRACE_EVENT(lttng_statedump_file_descriptor,
TP_PROTO(struct lttng_session *session,
- struct task_struct *p, int fd, const char *filename),
- TP_ARGS(session, p, fd, filename),
+ struct task_struct *p, int fd, const char *filename,
+ unsigned int flags, fmode_t fmode),
+ TP_ARGS(session, p, fd, filename, flags, fmode),
TP_STRUCT__entry(
__field(pid_t, pid)
__field(int, fd)
+ __field_oct(unsigned int, flags)
+ __field_hex(fmode_t, fmode)
__string(filename, filename)
),
TP_fast_assign(
tp_assign(pid, p->tgid)
tp_assign(fd, fd)
+ tp_assign(flags, flags)
+ tp_assign(fmode, fmode)
tp_strcpy(filename, filename)
),
TP_printk("")
char *page;
struct lttng_session *session;
struct task_struct *p;
+ struct fdtable *fdt;
};
/*
{
const struct lttng_fd_ctx *ctx = p;
const char *s = d_path(&file->f_path, ctx->page, PAGE_SIZE);
+ unsigned int flags = file->f_flags;
+ /*
+ * We don't expose kernel internal flags, only userspace-visible
+ * flags.
+ */
+ flags &= ~FMODE_NONOTIFY;
+ if (test_bit(fd, ctx->fdt->close_on_exec))
+ flags |= O_CLOEXEC;
if (IS_ERR(s)) {
struct dentry *dentry = file->f_path.dentry;
/* Make sure we give at least some info */
spin_lock(&dentry->d_lock);
trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd,
- dentry->d_name.name);
+ dentry->d_name.name, flags, file->f_mode);
spin_unlock(&dentry->d_lock);
goto end;
}
- trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd, s);
+ trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd, s,
+ flags, file->f_mode);
end:
return 0;
}
struct lttng_fd_ctx ctx = { .page = tmp, .session = session, .p = p };
task_lock(p);
+ ctx.fdt = files_fdtable(p->files);
lttng_iterate_fd(p->files, 0, lttng_dump_one_fd, &ctx);
task_unlock(p);
}
#define __field_hex(_type, _item) \
__field_full(_type, _item, __BYTE_ORDER, 16)
+#undef __field_oct
+#define __field_oct(_type, _item) \
+ __field_full(_type, _item, __BYTE_ORDER, 8)
+
#undef __field_network
#define __field_network(_type, _item) \
__field_full(_type, _item, __BIG_ENDIAN, 10)