diff options
author | Mark Johnston <markj@FreeBSD.org> | 2017-08-18 03:52:35 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2017-08-18 03:52:35 +0000 |
commit | 50ef60dabeb9edd3e6cd17f39ffa8b15f3f19c69 (patch) | |
tree | 0c2745a71919dd6481f4d99e4dcf4c73c7c73355 /sys/kern/kern_shutdown.c | |
parent | 9a61faf67d9eb2200999d653728aafe6121db1e3 (diff) | |
download | src-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.c | 78 |
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) |