Re: [patch] crash on a KVM-generated dump

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



----- "Dave Anderson" <anderson@xxxxxxxxxx> wrote:

> ----- "Sami Liedes" <sliedes@xxxxxxxxx> wrote:
> 
> > On Fri, Oct 08, 2010 at 02:48:11PM -0400, Dave Anderson wrote:
> > > Can you send me the -d1 output from that dumpfile session with
> > > your slirp-patch applied?  Like this:
> > >
> > >   # crash -d1 vmlinux dumpfile > /tmp/junk
> > >   q
> > >   #
> >
> > Of course. Attached.
> 
> OK, I was hoping that perhaps it would show up after the cpu and cpu_common
> devices, because if that were the case, we could just bail out on reading
> any more devices.
> 
> As far as the slirp device handling, I got this response from Paolo:
> 
> > slirp is not supported on RHEL, so I never encountered it.
> >
> > Looking at QEMU's source code, SLIRP savevm/loadvm is a mess, and 131 is
> > definitely not ok in general because there are several variable-length
> > fields.  Looking at it later.
> >
> > Paolo

Hi Sami,

Can you try the attached patch on your dumpfile containing the "slirp" device?

Given that the crash utility really only cares about the "ram", "cpu" and
"cpu_common" devices, when the patch encounters a device like "slirp" that's
not in the existing devices table, it just skips it and searches for the next
"known" device.

Dave
--- crash-5.0.8/qemu-load.c.orig
+++ crash-5.0.8/qemu-load.c
@@ -819,6 +819,8 @@ struct libvirt_header {
 	uint32_t	padding[16];
 };
 
+static long device_search(const struct qemu_device_loader *, FILE *);
+
 static struct qemu_device *
 device_get (const struct qemu_device_loader *devices,
 	    struct qemu_device_list *dl, enum qemu_save_section sec, FILE *fp)
@@ -826,7 +828,11 @@ device_get (const struct qemu_device_loa
 	char name[257];
 	uint32_t section_id, instance_id, version_id;
 //	bool live;
+	const struct qemu_device_loader *devp;
+	long next_device_offset;
 
+next_device:
+	devp = devices;
 	section_id = get_be32 (fp);
 	if (sec != QEMU_VM_SECTION_START &&
 	    sec != QEMU_VM_SECTION_FULL)
@@ -837,12 +843,21 @@ device_get (const struct qemu_device_loa
 	instance_id = get_be32 (fp);
 	version_id = get_be32 (fp);
 
-	while (devices->name && strcmp (devices->name, name))
-		devices++;
-	if (!devices->name)
+	while (devp->name && strcmp (devp->name, name))
+		devp++;
+	if (!devp->name) {
+		dprintf("device_get: unknown/unsupported: \"%s\"\n", name);
+		if ((next_device_offset = device_search(devices, fp))) {
+			fseek(fp, next_device_offset, SEEK_CUR);
+			sec = getc(fp);
+			if (sec == QEMU_VM_EOF)
+				return NULL;
+			goto next_device;
+		}
 		return NULL;
+	}
 
-	return devices->init_load (dl, section_id, instance_id, version_id,
+	return devp->init_load (dl, section_id, instance_id, version_id,
 				   sec == QEMU_VM_SECTION_START, fp);
 }
 
@@ -1026,3 +1041,40 @@ dump_qemu_header(FILE *out)
 	fprintf(out, "\n");
 }
 
+static long
+device_search(const struct qemu_device_loader *devices, FILE *fp)
+{
+	uint sz;
+	char *p1, *p2;
+	long next_device_offset;
+	long remaining;
+	char buf[4096];
+	off_t current;
+
+	BZERO(buf, 4096);
+
+	current = ftello(fp);
+	if (fread(buf, sizeof(char), 4096, fp) != 4096) {
+		fseeko(fp, current, SEEK_SET);
+		return 0;
+	}
+	fseeko(fp, current, SEEK_SET);
+
+        while (devices->name) {
+		for (p1 = buf, remaining = 4096; 
+	     	    (p2 = memchr(p1, devices->name[0], remaining));
+	     	     p1 = p2+1, remaining = 4096 - (p1-buf)) {
+			sz = *((unsigned char *)p2-1);
+			if (STRNEQ(p2, devices->name) && 
+			    (strlen(devices->name) == sz)) {
+				*(p2+sz) = '\0';
+				dprintf("device_search: %s\n", p2);
+				next_device_offset = (p2-buf) - 6;
+				return next_device_offset;
+			}
+		}
+		devices++;
+	}
+
+	return 0;
+}
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux