Page MenuHomeFreeBSD

D31993.id95477.diff
No OneTemporary

D31993.id95477.diff

Index: sys/kern/kern_dump.c
===================================================================
--- sys/kern/kern_dump.c
+++ sys/kern/kern_dump.c
@@ -31,8 +31,10 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/cons.h>
+#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/kerneldump.h>
+#include <sys/malloc.h>
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/watchdog.h>
@@ -295,7 +297,7 @@
#if MINIDUMP_PAGE_TRACKING == 1
if (do_minidump)
- return (minidumpsys(di));
+ return (minidumpsys(di, false));
#endif
bzero(&ehdr, sizeof(ehdr));
@@ -461,15 +463,72 @@
}
int
-minidumpsys(struct dumperinfo *di)
+minidumpsys(struct dumperinfo *di, bool livedump)
{
struct minidumpstate state;
+ struct msgbuf mb_copy;
+ char *msg_ptr;
+ size_t sz;
int error;
- state.msgbufp = msgbufp;
- state.dump_bitset = vm_page_dump;
+ if (livedump) {
+ KASSERT(!dumping, ("live dump invoked from incorrect context"));
+
+ /*
+ * Before invoking cpu_minidumpsys() on the live system, we
+ * must snapshot some required global state: the message
+ * buffer, and the page dump bitset. They may be modified at
+ * any moment, so for the sake of the live dump it is best to
+ * have an unchanging snapshot to work with. Both are included
+ * as part of the dump and consumed by userspace tools.
+ *
+ * Other global state important to the minidump code is the
+ * dump_avail array and the kernel's page tables, but snapshots
+ * are not taken of these. For one, dump_avail[] is expected
+ * not to change after boot. Snapshotting the kernel page
+ * tables would involve an additional walk, so this is avoided
+ * too.
+ *
+ * This means live dumps are best effort, and the result may or
+ * may not be usable; there are no guarantees about the
+ * consistency of the dump's contents. Any of the following
+ * (and likely more) may affect the live dump:
+ *
+ * - Data may be modified, freed, or remapped during the
+ * course of the dump, such that the contents written out
+ * are partially or entirely unrecognizable. This means
+ * valid references may point to destroyed/mangled objects,
+ * and vice versa.
+ *
+ * - The dumped context of any threads that ran during the
+ * dump process may be unreliable.
+ *
+ * - The set of kernel page tables included in the dump likely
+ * won't correspond exactly to the copy of the dump bitset.
+ * This means some pages will be dumped without any way to
+ * locate them, and some pages may not have been dumped
+ * despite appearing as if they should.
+ */
+ msg_ptr = malloc(msgbufsize, M_TEMP, M_WAITOK);
+ msgbuf_duplicate(msgbufp, &mb_copy, msg_ptr);
+ state.msgbufp = &mb_copy;
+
+ sz = BITSET_SIZE(vm_page_dump_pages);
+ state.dump_bitset = malloc(sz, M_TEMP, M_WAITOK);
+ BIT_COPY_STORE_REL(sz, vm_page_dump, state.dump_bitset);
+ } else {
+ KASSERT(dumping, ("minidump invoked outside of doadump()"));
+
+ /* Use the globals. */
+ state.msgbufp = msgbufp;
+ state.dump_bitset = vm_page_dump;
+ }
error = cpu_minidumpsys(di, &state);
+ if (livedump) {
+ free(msg_ptr, M_TEMP);
+ free(state.dump_bitset, M_TEMP);
+ }
return (error);
}
Index: sys/kern/subr_msgbuf.c
===================================================================
--- sys/kern/subr_msgbuf.c
+++ sys/kern/subr_msgbuf.c
@@ -414,3 +414,18 @@
while ((c = msgbuf_getchar(src)) >= 0)
msgbuf_addchar(dst, c);
}
+
+/*
+ * Get a snapshot of the message buffer, without modifying its internal state
+ * (i.e. don't mark any new characters as read).
+ */
+void
+msgbuf_duplicate(struct msgbuf *src, struct msgbuf *dst, char *dst_msgptr)
+{
+
+ mtx_lock_spin(&src->msg_lock);
+ bcopy(src, dst, sizeof(struct msgbuf));
+ dst->msg_ptr = dst_msgptr;
+ bcopy(src->msg_ptr, dst->msg_ptr, src->msg_size);
+ mtx_unlock_spin(&src->msg_lock);
+}
Index: sys/sys/kerneldump.h
===================================================================
--- sys/sys/kerneldump.h
+++ sys/sys/kerneldump.h
@@ -140,7 +140,7 @@
struct bitset *dump_bitset;
};
-int minidumpsys(struct dumperinfo *);
+int minidumpsys(struct dumperinfo *, bool);
int dumpsys_generic(struct dumperinfo *);
void dumpsys_map_chunk(vm_paddr_t, size_t, void **);
Index: sys/sys/msgbuf.h
===================================================================
--- sys/sys/msgbuf.h
+++ sys/sys/msgbuf.h
@@ -78,6 +78,7 @@
int msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen,
u_int *seqp);
void msgbuf_reinit(struct msgbuf *mbp, void *ptr, int size);
+void msgbuf_duplicate(struct msgbuf *src, struct msgbuf *dst, char *msgptr);
#ifndef MSGBUF_SIZE
#define MSGBUF_SIZE (32768 * 3)

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 1:05 AM (13 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31740703
Default Alt Text
D31993.id95477.diff (4 KB)

Event Timeline