----- "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