[PATCH 07/11] coredump: add COREDUMP_SPARSE to the coredump socket protocol

Christian Brauner <[email protected]>
Newsgroups org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kvack.linux-mm
Message-ID <[email protected]>
A coredump with a lot of unpopulated mappings sends endless 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_HEADER framed the zeroes but it didn't get rid of them.

Add a COREDUMP_SPARSE feature bit and a COREDUMP_FRAME_ZERO frame type.
A zero frame is a bare header that tells userspace how many zero bytes
where skipped.

So a hole crosses the socket as one header no matter how long it is. The
coredump server can recreate this sparsely. Zero frames only exist
inside a framed stream. So COREDUMP_SPARSE requires COREDUMP_HEADER.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 include/uapi/linux/coredump.h | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/coredump.h b/include/uapi/linux/coredump.h
index 5252480d3eec..312bafabb467 100644
--- a/include/uapi/linux/coredump.h
+++ b/include/uapi/linux/coredump.h
@@ -14,6 +14,8 @@
  * @COREDUMP_HEADER: send the coredump as a sequence of frames instead of
  *                   as a plain byte stream, see struct coredump_frame_header;
  *                   requires COREDUMP_KERNEL
+ * @COREDUMP_SPARSE: describe the holes in the coredump as zero frames
+ *                   instead of transferring them; requires COREDUMP_HEADER
  */
 enum {
 	COREDUMP_KERNEL		= (1ULL << 0),
@@ -21,6 +23,7 @@ enum {
 	COREDUMP_REJECT		= (1ULL << 2),
 	COREDUMP_WAIT		= (1ULL << 3),
 	COREDUMP_HEADER		= (1ULL << 4),
+	COREDUMP_SPARSE		= (1ULL << 5),
 };
 
 /**
@@ -109,10 +112,13 @@ enum coredump_mark {
  * enum coredump_frame_type - Type of a coredump frame
  *
  * @COREDUMP_FRAME_DATA: the header is followed by ->len bytes of data
+ * @COREDUMP_FRAME_ZERO: the header stands for ->len zero bytes and is not
+ *                       followed by any data
  * @__COREDUMP_FRAME_MAX: the maximum coredump frame type value
  */
 enum coredump_frame_type {
 	COREDUMP_FRAME_DATA	= 0U,
+	COREDUMP_FRAME_ZERO	= 1U,
 	__COREDUMP_FRAME_MAX	= (1U << 31),
 };
 
@@ -126,8 +132,10 @@ enum coredump_frame_type {
  *
  * If the coredump server raises COREDUMP_HEADER in coredump_ack->mask the
  * kernel doesn't send the coredump as a plain byte stream. It sends a
- * sequence of frames instead. A struct coredump_frame_header is followed by
- * @len bytes of actual coredump data.
+ * sequence of frames instead. A COREDUMP_FRAME_DATA frame is followed by
+ * @len bytes of actual coredump data. A COREDUMP_FRAME_ZERO frame is
+ * followed by nothing and stands for @len zero bytes. A server that didn't
+ * raise COREDUMP_SPARSE never sees a zero frame.
  *
  * The @size member is set to the size of struct coredump_frame_header the
  * kernel knows and lets the header grow later. It comes first so it can be
@@ -139,7 +147,8 @@ enum coredump_frame_type {
  * interpreted. No flags are defined yet. Userspace must refuse a frame
  * carrying a flag it doesn't know.
  *
- * COREDUMP_HEADER must be combined with COREDUMP_KERNEL.
+ * COREDUMP_HEADER must be combined with COREDUMP_KERNEL, and
+ * COREDUMP_SPARSE with COREDUMP_HEADER.
  */
 struct coredump_frame_header {
 	__u32 size;

-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.