aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_shutdown.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2017-08-18 03:52:35 +0000
committerMark Johnston <markj@FreeBSD.org>2017-08-18 03:52:35 +0000
commit50ef60dabeb9edd3e6cd17f39ffa8b15f3f19c69 (patch)
tree0c2745a71919dd6481f4d99e4dcf4c73c7c73355 /sys/kern/kern_shutdown.c
parent9a61faf67d9eb2200999d653728aafe6121db1e3 (diff)
downloadsrc-50ef60dabeb9edd3e6cd17f39ffa8b15f3f19c69.tar.gz
src-50ef60dabeb9edd3e6cd17f39ffa8b15f3f19c69.zip
Factor out duplicated kernel dump code into dump_{start,finish}().
dump_start() and dump_finish() are responsible for writing kernel dump headers, optionally writing the key when encryption is enabled, and initializing the initial offset into the dump device. Also remove the unused dump_pad(), and make some functions static now that they're only called from kern_shutdown.c. No functional change intended. Reviewed by: cem, def Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D11584
Notes
Notes: svn path=/head/; revision=322644
Diffstat (limited to 'sys/kern/kern_shutdown.c')
-rw-r--r--sys/kern/kern_shutdown.c78
1 files changed, 61 insertions, 17 deletions
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index d87b63461de5..5d225ce55949 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -897,7 +897,7 @@ failed:
}
#endif /* EKCD */
-int
+static int
kerneldumpcrypto_init(struct kerneldumpcrypto *kdc)
{
#ifndef EKCD
@@ -1180,21 +1180,7 @@ dump_raw_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
return (dump_raw_write(di, buf, physical, offset, *size));
}
-int
-dump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
- off_t offset, size_t length, size_t *size)
-{
- void *buf;
- int error;
-
- error = dump_pad(di, virtual, length, &buf, size);
- if (error != 0)
- return (error);
-
- return (dump_write(di, buf, physical, offset, *size));
-}
-
-int
+static int
dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
vm_offset_t physical, off_t offset)
{
@@ -1208,7 +1194,7 @@ dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
return (ret);
}
-int
+static int
dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset)
{
#ifndef EKCD
@@ -1225,6 +1211,64 @@ dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset)
#endif /* !EKCD */
}
+/*
+ * Don't touch the first SIZEOF_METADATA bytes on the dump device. This is to
+ * protect us from metadata and metadata from us.
+ */
+#define SIZEOF_METADATA (64 * 1024)
+
+/*
+ * Do some preliminary setup for a kernel dump: verify that we have enough space
+ * on the dump device, write the leading header, and optionally write the crypto
+ * key.
+ */
+int
+dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t *dumplop)
+{
+ uint64_t dumpsize;
+ int error;
+
+ error = kerneldumpcrypto_init(di->kdc);
+ if (error != 0)
+ return (error);
+
+ dumpsize = dtoh64(kdh->dumplength) + 2 * di->blocksize +
+ kerneldumpcrypto_dumpkeysize(di->kdc);
+ if (di->mediasize < SIZEOF_METADATA + dumpsize)
+ return (E2BIG);
+
+ *dumplop = di->mediaoffset + di->mediasize - dumpsize;
+
+ error = dump_write_header(di, kdh, 0, *dumplop);
+ if (error != 0)
+ return (error);
+ *dumplop += di->blocksize;
+
+ error = dump_write_key(di, 0, *dumplop);
+ if (error != 0)
+ return (error);
+ *dumplop += kerneldumpcrypto_dumpkeysize(di->kdc);
+
+ return (0);
+}
+
+/*
+ * Write the trailing kernel dump header and signal to the lower layers that the
+ * dump has completed.
+ */
+int
+dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t dumplo)
+{
+ int error;
+
+ error = dump_write_header(di, kdh, 0, dumplo);
+ if (error != 0)
+ return (error);
+
+ (void)dump_write(di, NULL, 0, 0, 0);
+ return (0);
+}
+
void
mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
uint64_t dumplen, uint32_t dumpkeysize, uint32_t blksz)