tools/ttysnoop: Add ITER_UBUF support
Since kernel commit fcb14cb1bdac("new iov_iter flavour - ITER_UBUF"),
tty_write() will use ITER_UBUF. And introduce iov_iter->ubuf field, so
we should use CO-RE way.
#
# 15-Oct-2016 Brendan Gregg Created this.
# 13-Dec-2022 Rong Tao Detect whether kfunc is supported.
+# 07-Jan-2023 Rong Tao Support ITER_UBUF(CO-RE way)
from __future__ import print_function
from bcc import BPF
@@ -147,18 +148,29 @@ PROBE_TTY_WRITE
if (from->type != (ITER_IOVEC + WRITE))
return 0;
#else
- if (from->iter_type != ITER_IOVEC)
+ if (ADD_FILTER_ITER_UBUF from->iter_type != ITER_IOVEC)
return 0;
if (from->data_source != WRITE)
return 0;
#endif
-
+ /* Support 'type' and 'iter_type' field name */
+ switch (from->IOV_ITER_TYPE_NAME) {
+ /**
+ * < 5.14.0: case ITER_IOVEC + WRITE
+ * >= 5.14.0: case ITER_IOVEC
+ */
+ case CASE_ITER_IOVEC_NAME:
kvec = from->kvec;
buf = kvec->iov_base;
count = kvec->iov_len;
-
- return do_tty_write(ctx, kvec->iov_base, kvec->iov_len);
+ break;
+ CASE_ITER_UBUF_TEXT
+ /* TODO: Support more type */
+ default:
+ break;
+ }
+ return do_tty_write(ctx, buf, count);
}
#endif
"""
@@ -178,6 +190,27 @@ if is_support_kfunc:
else:
bpf_text = bpf_text.replace('PROBE_TTY_WRITE', probe_tty_write_kprobe)
+if BPF.kernel_struct_has_field(b'iov_iter', b'iter_type') == 1:
+ bpf_text = bpf_text.replace('IOV_ITER_TYPE_NAME', 'iter_type')
+ bpf_text = bpf_text.replace('CASE_ITER_IOVEC_NAME', 'ITER_IOVEC')
+else:
+ bpf_text = bpf_text.replace('IOV_ITER_TYPE_NAME', 'type')
+ bpf_text = bpf_text.replace('CASE_ITER_IOVEC_NAME', 'ITER_IOVEC + WRITE')
+
+case_iter_ubuf_text = """
+ case ITER_UBUF:
+ buf = from->ubuf;
+ count = from->count;
+ break;
+"""
+
+if BPF.kernel_struct_has_field(b'iov_iter', b'ubuf') == 1:
+ bpf_text = bpf_text.replace('CASE_ITER_UBUF_TEXT', case_iter_ubuf_text)
+ bpf_text = bpf_text.replace('ADD_FILTER_ITER_UBUF', 'from->iter_type != ITER_UBUF &&')
+else:
+ bpf_text = bpf_text.replace('CASE_ITER_UBUF_TEXT', '')
+ bpf_text = bpf_text.replace('ADD_FILTER_ITER_UBUF', '')
+
if BPF.kernel_struct_has_field(b'bpf_ringbuf', b'waitq') == 1:
PERF_MODE = "USE_BPF_RING_BUF"
bpf_text = bpf_text.replace('PERF_TABLE',
