diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-08-20 01:09:31 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-09-22 13:25:01 +0200 |
| commit | ac3a5a750ee5aa225eab27c2964c81028e5c888a (patch) | |
| tree | 5a98c6739db366ecb3a6082580eeb1ccae13991a | |
| parent | a769e2e7114266e40a62b483360c73d83da82e11 (diff) | |
coredump: add COREDUMP_SPARSE to the coredump socket protocol
A coredump with a lot of unpopulated mappings sends useless amounts of
zero data to userspace. This is nonsensical. While __dump_skip() can
seek over them when the target is a regular file a socket cannot do
this. COREDUMP_RECORDS put the zeroes in records but it didn't get rid
of them.
Add a COREDUMP_SPARSE feature bit and a COREDUMP_RECORD_ZERO record
type. A zero record is a bare header that tells userspace how many zero
bytes were skipped.
So a hole crosses the socket as one header no matter how long it is. The
coredump server can recreate this sparsely. Zero records only exist
inside a record stream. COREDUMP_SPARSE requires COREDUMP_RECORDS.
Link: https://patch.msgid.link/20260820-work-coredump-sparse-v2-14-ba32dd718c51@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
| -rw-r--r-- | include/uapi/linux/coredump.h | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/include/uapi/linux/coredump.h b/include/uapi/linux/coredump.h index 0bd5c8662ebe..f3771861ca48 100644 --- a/include/uapi/linux/coredump.h +++ b/include/uapi/linux/coredump.h @@ -14,6 +14,8 @@ * @COREDUMP_RECORDS: send the coredump as a sequence of records instead of * as a plain byte stream, see struct coredump_record_header; * requires COREDUMP_KERNEL + * @COREDUMP_SPARSE: describe the holes in the coredump as zero records + * instead of transferring them; requires COREDUMP_RECORDS */ enum { COREDUMP_KERNEL = (1ULL << 0), @@ -21,6 +23,7 @@ enum { COREDUMP_REJECT = (1ULL << 2), COREDUMP_WAIT = (1ULL << 3), COREDUMP_RECORDS = (1ULL << 4), + COREDUMP_SPARSE = (1ULL << 5), }; /** @@ -111,11 +114,14 @@ enum coredump_mark { * @COREDUMP_RECORD_DATA: the header is followed by ->len bytes of data * @COREDUMP_RECORD_END: the coredump ends here, the header is not followed * by any data and no further record is sent + * @COREDUMP_RECORD_ZERO: the header stands for ->len zero bytes and is not + * followed by any data * @__COREDUMP_RECORD_TYPE_MAX: the maximum coredump record type value */ enum coredump_record_type { COREDUMP_RECORD_DATA = 0U, COREDUMP_RECORD_END = 1U, + COREDUMP_RECORD_ZERO = 2U, __COREDUMP_RECORD_TYPE_MAX = (1U << 31), }; @@ -130,9 +136,11 @@ enum coredump_record_type { * If the coredump server raises COREDUMP_RECORDS in coredump_ack->mask * the kernel doesn't send the coredump as a plain byte stream. It sends * a sequence of records instead. A COREDUMP_RECORD_DATA record is - * followed by @len bytes of actual coredump data. Records arrive in - * order and leave no gaps. So @offset is the sum of the @len of all - * records before it. + * followed by @len bytes of actual coredump data. A + * COREDUMP_RECORD_ZERO record is followed by nothing and stands for + * @len zero bytes. A server that didn't raise COREDUMP_SPARSE never + * sees a zero record. Records arrive in order and leave no gaps. So + * @offset is the sum of the @len of all records before it. * * The last record is a COREDUMP_RECORD_END record. It is followed by * nothing. Its @len is zero. Its @offset is the size of the coredump. @@ -153,7 +161,8 @@ enum coredump_record_type { * type is raised in coredump_req->mask as a feature of its own. A * server only ever sees the types it asked for. * - * COREDUMP_RECORDS must be combined with COREDUMP_KERNEL. + * COREDUMP_RECORDS must be combined with COREDUMP_KERNEL, and + * COREDUMP_SPARSE with COREDUMP_RECORDS. */ struct coredump_record_header { __u32 size; |
