----- "Dave Anderson" <[email protected]> wrote:
> ----- "Sami Liedes" <[email protected]> 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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility