~ubuntu-branches/ubuntu/natty/makedumpfile/natty

« back to all changes in this revision

Viewing changes to makedumpfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2009-06-22 16:19:42 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090622161942-h4wjy49slsyp7xh5
Tags: 1.3.3-0ubuntu1
* New upstream release
* depends on latest libdw-dev (the previous version does
  not ship the required static lib)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * makedumpfile.c
3
3
 *
4
 
 * Copyright (C) 2006, 2007  NEC Corporation
 
4
 * Copyright (C) 2006, 2007, 2008, 2009  NEC Corporation
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
13
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
14
 * GNU General Public License for more details.
15
15
 */
16
 
#include <stdlib.h>
17
16
#include "makedumpfile.h"
18
17
 
19
18
struct symbol_table     symbol_table;
27
26
struct vm_table         vt = { 0 };
28
27
struct DumpInfo         *info = NULL;
29
28
 
 
29
char filename_stdout[] = FILENAME_STDOUT;
30
30
int message_level;
31
31
 
32
32
/*
202
202
/*
203
203
 * Get the number of the page descriptors from the ELF info.
204
204
 */
205
 
unsigned long long
 
205
int
206
206
get_max_mapnr(void)
207
207
{
208
208
        int i;
214
214
                if (max_paddr < pls->phys_end)
215
215
                        max_paddr = pls->phys_end;
216
216
        }
217
 
        return max_paddr / info->page_size;
 
217
        info->max_mapnr = max_paddr / info->page_size;
 
218
 
 
219
        DEBUG_MSG("\n");
 
220
        DEBUG_MSG("max_mapnr    : %llx\n", info->max_mapnr);
 
221
 
 
222
        return TRUE;
 
223
}
 
224
 
 
225
int
 
226
is_in_same_page(unsigned long vaddr1, unsigned long vaddr2)
 
227
{
 
228
        if (round(vaddr1, info->page_size) == round(vaddr2, info->page_size))
 
229
                return TRUE;
 
230
 
 
231
        return FALSE;
218
232
}
219
233
 
220
234
int
221
235
readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
222
236
{
 
237
        size_t read_size, next_size;
223
238
        off_t offset = 0;
 
239
        unsigned long long next_addr;
224
240
        unsigned long long paddr;
 
241
        char *next_ptr;
225
242
        const off_t failed = (off_t)-1;
226
243
 
227
244
        switch (type_addr) {
228
245
        case VADDR:
229
 
                /*
230
 
                 * Convert Virtual Address to File Offset.
231
 
                 */
232
246
                if ((paddr = vaddr_to_paddr(addr)) == NOT_PADDR) {
233
247
                        ERRMSG("Can't convert a virtual address(%llx) to physical address.\n",
234
248
                            addr);
235
 
                        return FALSE;
 
249
                        goto error;
236
250
                }
237
251
                break;
238
252
        case PADDR:
239
253
                paddr = addr;
240
254
                break;
241
255
        case VADDR_XEN:
242
 
                if (!(paddr = kvtop_xen(addr)))
243
 
                        return FALSE;
 
256
                if ((paddr = kvtop_xen(addr)) == NOT_PADDR) {
 
257
                        ERRMSG("Can't convert a virtual address(%llx) to machine address.\n",
 
258
                            addr);
 
259
                        goto error;
 
260
                }
244
261
                break;
 
262
        case MADDR_XEN:
 
263
                paddr = addr;
 
264
                break;
245
265
        default:
246
266
                ERRMSG("Invalid address type (%d).\n", type_addr);
247
 
                return FALSE;
 
267
                goto error;
 
268
        }
 
269
 
 
270
        read_size = size;
 
271
 
 
272
        /*
 
273
         * Read each page, because pages are not necessarily continuous.
 
274
         * Ex) pages in vmalloc area
 
275
         */
 
276
        if (!is_in_same_page(addr, addr + size - 1)) {
 
277
                read_size = info->page_size - (addr % info->page_size);
 
278
                next_addr = roundup(addr + 1, info->page_size);
 
279
                next_size = size - read_size;
 
280
                next_ptr  = (char *)bufptr + read_size;
 
281
 
 
282
                if (!readmem(type_addr, next_addr, next_ptr, next_size))
 
283
                        goto error;
248
284
        }
249
285
 
250
286
        if (!(offset = paddr_to_offset(paddr))) {
251
287
                ERRMSG("Can't convert a physical address(%llx) to offset.\n",
252
288
                    paddr);
253
 
                return FALSE;
 
289
                goto error;
254
290
        }
255
291
 
256
292
        if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
257
293
                ERRMSG("Can't seek the dump memory(%s). %s\n",
258
294
                    info->name_memory, strerror(errno));
259
 
                return FALSE;
 
295
                goto error;
260
296
        }
261
297
 
262
 
        if (read(info->fd_memory, bufptr, size) != size) {
 
298
        if (read(info->fd_memory, bufptr, read_size) != read_size) {
263
299
                ERRMSG("Can't read the dump memory(%s). %s\n",
264
300
                    info->name_memory, strerror(errno));
265
 
                return FALSE;
 
301
                goto error;
266
302
        }
267
303
 
268
304
        return size;
 
305
error:
 
306
        ERRMSG("type_addr: %d, addr:%llx, size:%zd\n", type_addr, addr, size);
 
307
        return FALSE;
269
308
}
270
309
 
271
310
int32_t
315
354
}
316
355
 
317
356
int
 
357
set_page_size(long page_size)
 
358
{
 
359
        if (!is_page_size(page_size)) {
 
360
                ERRMSG("Invalid page_size: %ld", page_size);
 
361
                return FALSE;
 
362
        }
 
363
        info->page_size = page_size;
 
364
        info->page_shift = ffs(info->page_size) - 1;
 
365
        DEBUG_MSG("page_size    : %ld\n", info->page_size);
 
366
 
 
367
        return TRUE;
 
368
}
 
369
 
 
370
int
 
371
fallback_to_current_page_size(void)
 
372
{
 
373
 
 
374
        if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
 
375
                return FALSE;
 
376
 
 
377
        DEBUG_MSG("WARNING: Cannot determine page size (no vmcoreinfo).\n");
 
378
        DEBUG_MSG("Using the dump kernel page size: %ld\n",
 
379
            info->page_size);
 
380
 
 
381
        return TRUE;
 
382
}
 
383
 
 
384
int
318
385
check_release(void)
319
386
{
320
387
        struct utsname system_utsname;
570
637
open_dump_file(void)
571
638
{
572
639
        int fd;
573
 
        int open_flags = O_RDWR|O_CREAT;
 
640
        int open_flags = O_RDWR|O_CREAT|O_TRUNC;
574
641
 
575
642
        if (!info->flag_force)
576
643
                open_flags |= O_EXCL;
577
644
 
578
645
        if (info->flag_flatten) {
579
 
                if ((info->name_dumpfile
580
 
                    = (char *)malloc(sizeof(FILENAME_STDOUT))) == NULL) {
581
 
                        ERRMSG("Can't allocate memory for the filename. %s\n",
582
 
                            strerror(errno));
583
 
                        return FALSE;
584
 
                }
585
646
                fd = STDOUT_FILENO;
586
 
                strcpy(info->name_dumpfile, FILENAME_STDOUT);
587
 
 
 
647
                info->name_dumpfile = filename_stdout;
588
648
        } else if ((fd = open(info->name_dumpfile, open_flags,
589
649
            S_IRUSR|S_IWUSR)) < 0) {
590
650
                ERRMSG("Can't open the dump file(%s). %s\n",
598
658
int
599
659
open_dump_bitmap(void)
600
660
{
601
 
        int fd;
 
661
        int i, fd;
602
662
 
603
663
        if ((info->name_bitmap
604
664
            = (char *)malloc(sizeof(FILENAME_BITMAP))) == NULL) {
612
672
                    info->name_bitmap, strerror(errno));
613
673
                return FALSE;
614
674
        }
 
675
        info->fd_bitmap = fd;
 
676
 
 
677
        if (info->flag_split) {
 
678
                /*
 
679
                 * Reserve file descriptors of bitmap for creating split
 
680
                 * dumpfiles by multiple processes, because a bitmap file will
 
681
                 * be unlinked just after this and it is not possible to open
 
682
                 * a bitmap file later.
 
683
                 */
 
684
                for (i = 0; i < info->num_dumpfile; i++) {
 
685
                        if ((fd = open(info->name_bitmap, O_RDONLY)) < 0) {
 
686
                                ERRMSG("Can't open the bitmap file(%s). %s\n",
 
687
                                    info->name_bitmap, strerror(errno));
 
688
                                return FALSE;
 
689
                        }
 
690
                        SPLITTING_FD_BITMAP(i) = fd;
 
691
                }
 
692
        }
615
693
        unlink(info->name_bitmap);
616
 
        info->fd_bitmap = fd;
 
694
 
617
695
        return TRUE;
618
696
}
619
697
 
878
956
{
879
957
        int i, j, phnum, num_load, elf_format;
880
958
        off_t offset_note;
881
 
        unsigned long tmp, size_note;
 
959
        unsigned long size_note;
882
960
        Elf64_Phdr phdr;
883
961
 
884
962
        /*
942
1020
                return FALSE;
943
1021
        }
944
1022
 
945
 
        /*
946
 
         * FIXME
947
 
         *   If the page_size of 1st kernel is different from the one of
948
 
         *   capture(2nd) kernel, the problem will happen.
949
 
         */
950
 
        info->page_size = sysconf(_SC_PAGE_SIZE);
951
 
        info->page_shift = ffs(info->page_size) - 1;
952
 
 
953
 
        info->max_mapnr = get_max_mapnr();
954
 
 
955
 
        DEBUG_MSG("\n");
956
 
        DEBUG_MSG("max_mapnr    : %llx\n", info->max_mapnr);
957
 
 
958
 
        /*
959
 
         * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size boundary.
960
 
         * The crash utility requires both of them to be aligned to block_size
961
 
         * boundary.
962
 
         */
963
 
        tmp = divideup(divideup(info->max_mapnr, BITPERBYTE), info->page_size);
964
 
        info->len_bitmap = tmp*info->page_size*2;
965
 
 
966
1023
        return TRUE;
967
1024
}
968
1025
 
1803
1860
        SYMBOL_INIT(_stext, "_stext");
1804
1861
        SYMBOL_INIT(swapper_pg_dir, "swapper_pg_dir");
1805
1862
        SYMBOL_INIT(init_level4_pgt, "init_level4_pgt");
 
1863
        SYMBOL_INIT(vmlist, "vmlist");
1806
1864
        SYMBOL_INIT(phys_base, "phys_base");
1807
1865
        SYMBOL_INIT(node_online_map, "node_online_map");
1808
1866
        SYMBOL_INIT(node_states, "node_states");
1810
1868
        SYMBOL_INIT(node_data, "node_data");
1811
1869
        SYMBOL_INIT(pgdat_list, "pgdat_list");
1812
1870
        SYMBOL_INIT(contig_page_data, "contig_page_data");
 
1871
        SYMBOL_INIT(log_buf, "log_buf");
 
1872
        SYMBOL_INIT(log_buf_len, "log_buf_len");
 
1873
        SYMBOL_INIT(log_end, "log_end");
1813
1874
 
1814
1875
        if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
1815
1876
                SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
1910
1971
        OFFSET_INIT(node_memblk_s.size, "node_memblk_s", "size");
1911
1972
        OFFSET_INIT(node_memblk_s.nid, "node_memblk_s", "nid");
1912
1973
 
 
1974
        OFFSET_INIT(vm_struct.addr, "vm_struct", "addr");
 
1975
 
1913
1976
        ENUM_NUMBER_INIT(NR_FREE_PAGES, "NR_FREE_PAGES");
1914
1977
        ENUM_NUMBER_INIT(N_ONLINE, "N_ONLINE");
1915
1978
 
2038
2101
int
2039
2102
generate_vmcoreinfo(void)
2040
2103
{
2041
 
        if ((info->page_size = sysconf(_SC_PAGE_SIZE)) <= 0) {
2042
 
                ERRMSG("Can't get the size of page.\n");
 
2104
        if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
2043
2105
                return FALSE;
2044
 
        }
 
2106
 
2045
2107
        dwarf_info.fd_debuginfo   = info->fd_vmlinux;
2046
2108
        dwarf_info.name_debuginfo = info->name_vmlinux;
2047
2109
 
2095
2157
        WRITE_SYMBOL("_stext", _stext);
2096
2158
        WRITE_SYMBOL("swapper_pg_dir", swapper_pg_dir);
2097
2159
        WRITE_SYMBOL("init_level4_pgt", init_level4_pgt);
 
2160
        WRITE_SYMBOL("vmlist", vmlist);
2098
2161
        WRITE_SYMBOL("phys_base", phys_base);
2099
2162
        WRITE_SYMBOL("node_online_map", node_online_map);
2100
2163
        WRITE_SYMBOL("node_states", node_states);
2101
2164
        WRITE_SYMBOL("node_data", node_data);
2102
2165
        WRITE_SYMBOL("pgdat_list", pgdat_list);
2103
2166
        WRITE_SYMBOL("contig_page_data", contig_page_data);
 
2167
        WRITE_SYMBOL("log_buf", log_buf);
 
2168
        WRITE_SYMBOL("log_buf_len", log_buf_len);
 
2169
        WRITE_SYMBOL("log_end", log_end);
2104
2170
 
2105
2171
        /*
2106
2172
         * write the structure size of 1st kernel
2142
2208
        WRITE_MEMBER_OFFSET("node_memblk_s.start_paddr", node_memblk_s.start_paddr);
2143
2209
        WRITE_MEMBER_OFFSET("node_memblk_s.size", node_memblk_s.size);
2144
2210
        WRITE_MEMBER_OFFSET("node_memblk_s.nid", node_memblk_s.nid);
 
2211
        WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr);
2145
2212
 
2146
2213
        if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
2147
2214
                WRITE_ARRAY_LENGTH("node_data", node_data);
2173
2240
int
2174
2241
read_vmcoreinfo_basic_info(void)
2175
2242
{
 
2243
        time_t tv_sec = 0;
2176
2244
        long page_size = FALSE;
2177
2245
        char buf[BUFSIZE_FGETS], *endp;
2178
2246
        unsigned int get_release = FALSE, i;
2204
2272
                                    info->name_vmcoreinfo, buf);
2205
2273
                                return FALSE;
2206
2274
                        }
2207
 
                        if (!is_page_size(page_size)) {
2208
 
                                ERRMSG("Invalid data in %s: %s",
2209
 
                                    info->name_vmcoreinfo, buf);
2210
 
                                return FALSE;
2211
 
                        }
 
2275
                        if (!set_page_size(page_size)) {
 
2276
                                ERRMSG("Invalid data in %s: %s",
 
2277
                                    info->name_vmcoreinfo, buf);
 
2278
                                return FALSE;
 
2279
                        }
 
2280
                }
 
2281
                if (strncmp(buf, STR_CRASHTIME, strlen(STR_CRASHTIME)) == 0) {
 
2282
                        tv_sec = strtol(buf+strlen(STR_CRASHTIME),&endp,10);
 
2283
                        if ((!tv_sec || tv_sec == LONG_MAX)
 
2284
                            || strlen(endp) != 0) {
 
2285
                                ERRMSG("Invalid data in %s: %s",
 
2286
                                    info->name_vmcoreinfo, buf);
 
2287
                                return FALSE;
 
2288
                        }
 
2289
                        info->timestamp.tv_sec = tv_sec;
2212
2290
                }
2213
2291
                if (strncmp(buf, STR_CONFIG_X86_PAE,
2214
2292
                    strlen(STR_CONFIG_X86_PAE)) == 0)
2222
2300
                    strlen(STR_CONFIG_PGTABLE_4)) == 0)
2223
2301
                        vt.mem_flags |= MEMORY_PAGETABLE_4L;
2224
2302
        }
2225
 
        info->page_size = page_size;
2226
 
        info->page_shift = ffs(info->page_size) - 1;
2227
 
 
2228
2303
        if (!get_release || !info->page_size) {
2229
2304
                ERRMSG("Invalid format in %s", info->name_vmcoreinfo);
2230
2305
                return FALSE;
2339
2414
        READ_SYMBOL("_stext", _stext);
2340
2415
        READ_SYMBOL("swapper_pg_dir", swapper_pg_dir);
2341
2416
        READ_SYMBOL("init_level4_pgt", init_level4_pgt);
 
2417
        READ_SYMBOL("vmlist", vmlist);
2342
2418
        READ_SYMBOL("phys_base", phys_base);
2343
2419
        READ_SYMBOL("node_online_map", node_online_map);
2344
2420
        READ_SYMBOL("node_states", node_states);
2345
2421
        READ_SYMBOL("node_data", node_data);
2346
2422
        READ_SYMBOL("pgdat_list", pgdat_list);
2347
2423
        READ_SYMBOL("contig_page_data", contig_page_data);
 
2424
        READ_SYMBOL("log_buf", log_buf);
 
2425
        READ_SYMBOL("log_buf_len", log_buf_len);
 
2426
        READ_SYMBOL("log_end", log_end);
2348
2427
 
2349
2428
        READ_STRUCTURE_SIZE("page", page);
2350
2429
        READ_STRUCTURE_SIZE("mem_section", mem_section);
2379
2458
        READ_MEMBER_OFFSET("node_memblk_s.start_paddr", node_memblk_s.start_paddr);
2380
2459
        READ_MEMBER_OFFSET("node_memblk_s.size", node_memblk_s.size);
2381
2460
        READ_MEMBER_OFFSET("node_memblk_s.nid", node_memblk_s.nid);
 
2461
        READ_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr);
2382
2462
 
2383
2463
        READ_ARRAY_LENGTH("node_data", node_data);
2384
2464
        READ_ARRAY_LENGTH("pgdat_list", pgdat_list);
2551
2631
        return TRUE;
2552
2632
}
2553
2633
 
 
2634
int
 
2635
read_vmcoreinfo_from_vmcore(off_t offset, unsigned long size, int flag_xen_hv)
 
2636
{
 
2637
        int ret = FALSE;
 
2638
 
 
2639
        /*
 
2640
         * Copy vmcoreinfo to /tmp/vmcoreinfoXXXXXX.
 
2641
         */
 
2642
        if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) {
 
2643
                MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO);
 
2644
                return FALSE;
 
2645
        }
 
2646
        if (!copy_vmcoreinfo(offset, size))
 
2647
                goto out;
 
2648
 
 
2649
        /*
 
2650
         * Read vmcoreinfo from /tmp/vmcoreinfoXXXXXX.
 
2651
         */
 
2652
        if (!open_vmcoreinfo("r"))
 
2653
                goto out;
 
2654
 
 
2655
        unlink(info->name_vmcoreinfo);
 
2656
 
 
2657
        if (flag_xen_hv) {
 
2658
                if (!read_vmcoreinfo_xen())
 
2659
                        goto out;
 
2660
        } else {
 
2661
                if (!read_vmcoreinfo())
 
2662
                        goto out;
 
2663
        }
 
2664
        close_vmcoreinfo();
 
2665
 
 
2666
        ret = TRUE;
 
2667
out:
 
2668
        free(info->name_vmcoreinfo);
 
2669
        info->name_vmcoreinfo = NULL;
 
2670
 
 
2671
        return ret;
 
2672
}
 
2673
 
2554
2674
/*
2555
2675
 * Get the number of online nodes.
2556
2676
 */
3258
3378
int
3259
3379
initial(void)
3260
3380
{
 
3381
        int flag_need_debuginfo;
 
3382
 
3261
3383
        if (!(vt.mem_flags & MEMORY_XEN) && info->flag_exclude_xen_dom) {
3262
3384
                MSG("'-X' option is disable,");
3263
3385
                MSG("because %s is not Xen's memory core image.\n", info->name_memory);
3275
3397
        if (info->flag_read_vmcoreinfo) {
3276
3398
                if (!read_vmcoreinfo())
3277
3399
                        return FALSE;
 
3400
                close_vmcoreinfo();
3278
3401
        /*
3279
3402
         * Get the debug information for analysis from the kernel file
3280
3403
         */
3296
3419
                 * and get both the offset and the size.
3297
3420
                 */
3298
3421
                if (!info->offset_vmcoreinfo || !info->size_vmcoreinfo) {
3299
 
                        if (info->dump_level <= DL_EXCLUDE_ZERO)
 
3422
                        if (info->max_dump_level <= DL_EXCLUDE_ZERO)
3300
3423
                                goto out;
3301
3424
 
3302
3425
                        MSG("%s doesn't contain vmcoreinfo.\n",
3312
3435
         * Get the debug information from /proc/vmcore
3313
3436
         */
3314
3437
        if (info->offset_vmcoreinfo && info->size_vmcoreinfo) {
3315
 
                /*
3316
 
                 * Copy vmcoreinfo to /tmp/vmcoreinfoXXXXXX.
3317
 
                 */
3318
 
                if ((info->name_vmcoreinfo
3319
 
                    = malloc(sizeof(FILENAME_VMCOREINFO))) == NULL) {
3320
 
                        ERRMSG("Can't allocate memory for the name(%s). %s\n",
3321
 
                            FILENAME_VMCOREINFO, strerror(errno));
3322
 
                        return FALSE;
3323
 
                }
3324
 
                strcpy(info->name_vmcoreinfo, FILENAME_VMCOREINFO);
3325
 
                if (!copy_vmcoreinfo(info->offset_vmcoreinfo,
3326
 
                    info->size_vmcoreinfo))
3327
 
                        return FALSE;
3328
 
                /*
3329
 
                 * Read vmcoreinfo from /tmp/vmcoreinfoXXXXXX.
3330
 
                 */
3331
 
                if (!open_vmcoreinfo("r"))
3332
 
                        return FALSE;
3333
 
                if (!read_vmcoreinfo())
3334
 
                        return FALSE;
3335
 
                unlink(info->name_vmcoreinfo);
 
3438
                if (!read_vmcoreinfo_from_vmcore(info->offset_vmcoreinfo,
 
3439
                    info->size_vmcoreinfo, FALSE))
 
3440
                        return FALSE;
3336
3441
        }
3337
3442
 
3338
3443
        if (!get_value_for_old_linux())
3339
3444
                return FALSE;
3340
3445
out:
3341
 
        if (info->dump_level <= DL_EXCLUDE_ZERO) {
 
3446
        if (!info->page_size) {
 
3447
                /*
 
3448
                 * If we cannot get page_size from a vmcoreinfo file,
 
3449
                 * fall back to the current kernel page size.
 
3450
                 */
 
3451
                if (!fallback_to_current_page_size())
 
3452
                        return FALSE;
 
3453
        }
 
3454
        if (!get_max_mapnr())
 
3455
                return FALSE;
 
3456
 
 
3457
        if ((info->max_dump_level <= DL_EXCLUDE_ZERO) && !info->flag_dmesg)
 
3458
                flag_need_debuginfo = FALSE;
 
3459
        else 
 
3460
                flag_need_debuginfo = TRUE;
 
3461
 
 
3462
        if (!flag_need_debuginfo) {
3342
3463
                if (!get_mem_map_without_mm())
3343
3464
                        return FALSE;
3344
3465
                else
3363
3484
        return TRUE;
3364
3485
}
3365
3486
 
 
3487
void
 
3488
initialize_bitmap(struct dump_bitmap *bitmap)
 
3489
{
 
3490
        bitmap->fd        = info->fd_bitmap;
 
3491
        bitmap->file_name = info->name_bitmap;
 
3492
        bitmap->no_block  = -1;
 
3493
        memset(bitmap->buf, 0, BUFSIZE_BITMAP);
 
3494
}
 
3495
 
 
3496
void
 
3497
initialize_1st_bitmap(struct dump_bitmap *bitmap)
 
3498
{
 
3499
        initialize_bitmap(bitmap);
 
3500
        bitmap->offset = 0;
 
3501
}
 
3502
 
 
3503
void
 
3504
initialize_2nd_bitmap(struct dump_bitmap *bitmap)
 
3505
{
 
3506
        initialize_bitmap(bitmap);
 
3507
        bitmap->offset = info->len_bitmap / 2;
 
3508
}
 
3509
 
3366
3510
int
3367
3511
set_bitmap(struct dump_bitmap *bitmap, unsigned long long pfn,
3368
3512
    int val)
3458
3602
}
3459
3603
 
3460
3604
int
3461
 
set_bit_on_2nd_bitmap(unsigned long long pfn)
3462
 
{
3463
 
        return set_bitmap(info->bitmap2, pfn, 1);
3464
 
}
3465
 
 
3466
 
int
3467
 
clear_bit_on_1st_bitmap(unsigned long long pfn)
3468
 
{
3469
 
        return set_bitmap(info->bitmap1, pfn, 0);
3470
 
}
3471
 
 
3472
 
int
3473
3605
clear_bit_on_2nd_bitmap(unsigned long long pfn)
3474
3606
{
3475
3607
        return set_bitmap(info->bitmap2, pfn, 0);
3498
3630
}
3499
3631
 
3500
3632
static inline int
3501
 
is_memory_hole(struct dump_bitmap *bitmap, unsigned long long pfn)
3502
 
{
3503
 
        return !is_dumpable(bitmap, pfn);
3504
 
}
3505
 
 
3506
 
static inline int
3507
3633
is_in_segs(unsigned long long paddr)
3508
3634
{
3509
3635
        if (paddr_to_offset(paddr))
3554
3680
}
3555
3681
 
3556
3682
int
 
3683
write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
 
3684
{
 
3685
        int status, written_size = 0;
 
3686
 
 
3687
        while (written_size < buf_size) {
 
3688
                status = write(fd, buf + written_size,
 
3689
                                   buf_size - written_size);
 
3690
                if (0 < status) {
 
3691
                        written_size += status;
 
3692
                        continue;
 
3693
                }
 
3694
                if (errno == ENOSPC)
 
3695
                        info->flag_nospace = TRUE;
 
3696
                MSG("\nCan't write the dump file(%s). %s\n",
 
3697
                    file_name, strerror(errno));
 
3698
                return FALSE;
 
3699
        }
 
3700
        return TRUE;
 
3701
}
 
3702
 
 
3703
int
3557
3704
write_buffer(int fd, off_t offset, void *buf, size_t buf_size, char *file_name)
3558
3705
{
3559
3706
        struct makedumpfile_data_header fdh;
3572
3719
                        fdh.offset   = bswap_64(offset);
3573
3720
                        fdh.buf_size = bswap_64(buf_size);
3574
3721
                }
3575
 
                if (write(fd, &fdh, sizeof(fdh)) != sizeof(fdh)) {
3576
 
                        ERRMSG("Can't write the dump file(%s). %s\n",
3577
 
                            file_name, strerror(errno));
 
3722
                if (!write_and_check_space(fd, &fdh, sizeof(fdh), file_name))
3578
3723
                        return FALSE;
3579
 
                }
3580
3724
        } else {
3581
3725
                if (lseek(fd, offset, SEEK_SET) == failed) {
3582
3726
                        ERRMSG("Can't seek the dump file(%s). %s\n",
3584
3728
                        return FALSE;
3585
3729
                }
3586
3730
        }
3587
 
        if (write(fd, buf, buf_size) != buf_size) {
3588
 
                ERRMSG("Can't write the dump file(%s). %s\n",
3589
 
                    file_name, strerror(errno));
 
3731
        if (!write_and_check_space(fd, buf, buf_size, file_name))
3590
3732
                return FALSE;
3591
 
        }
 
3733
 
3592
3734
        return TRUE;
3593
3735
}
3594
3736
 
3924
4066
}
3925
4067
 
3926
4068
int
 
4069
dump_dmesg()
 
4070
{
 
4071
        int log_buf_len, length_log, length_oldlog, ret = FALSE;
 
4072
        unsigned long log_buf, log_end, index;
 
4073
        char *log_buffer = NULL;
 
4074
 
 
4075
        if (!open_files_for_creating_dumpfile())
 
4076
                return FALSE;
 
4077
 
 
4078
        if (!get_elf_info())
 
4079
                return FALSE;
 
4080
 
 
4081
        if (!initial())
 
4082
                return FALSE;
 
4083
 
 
4084
        if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL)
 
4085
            || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL)
 
4086
            || (SYMBOL(log_end) == NOT_FOUND_SYMBOL)) {
 
4087
                ERRMSG("Can't find some symbols for log_buf.\n");
 
4088
                return FALSE;
 
4089
        }
 
4090
        if (!readmem(VADDR, SYMBOL(log_buf), &log_buf, sizeof(log_buf))) {
 
4091
                ERRMSG("Can't get log_buf.\n");
 
4092
                return FALSE;
 
4093
        }
 
4094
        if (!readmem(VADDR, SYMBOL(log_end), &log_end, sizeof(log_end))) {
 
4095
                ERRMSG("Can't to get log_end.\n");
 
4096
                return FALSE;
 
4097
        }
 
4098
        if (!readmem(VADDR, SYMBOL(log_buf_len), &log_buf_len,
 
4099
            sizeof(log_buf_len))) {
 
4100
                ERRMSG("Can't get log_buf_len.\n");
 
4101
                return FALSE;
 
4102
        }
 
4103
        DEBUG_MSG("\n");
 
4104
        DEBUG_MSG("log_buf      : %lx\n", log_buf);
 
4105
        DEBUG_MSG("log_end      : %lx\n", log_end);
 
4106
        DEBUG_MSG("log_buf_len  : %d\n", log_buf_len);
 
4107
 
 
4108
        if ((log_buffer = malloc(log_buf_len)) == NULL) {
 
4109
                ERRMSG("Can't allocate memory for log_buf. %s\n",
 
4110
                    strerror(errno));
 
4111
                return FALSE;
 
4112
        }
 
4113
 
 
4114
        if (log_end < log_buf_len) {
 
4115
                length_log = log_end;
 
4116
                if(!readmem(VADDR, log_buf, log_buffer, length_log)) {
 
4117
                        ERRMSG("Can't read dmesg log.\n");
 
4118
                        goto out;
 
4119
                }
 
4120
        } else {
 
4121
                index = log_end & (log_buf_len - 1);
 
4122
                DEBUG_MSG("index        : %lx\n", index);
 
4123
                length_log = log_buf_len;
 
4124
                length_oldlog = log_buf_len - index;
 
4125
                if(!readmem(VADDR, log_buf + index, log_buffer, length_oldlog)) {
 
4126
                        ERRMSG("Can't read old dmesg log.\n");
 
4127
                        goto out;
 
4128
                }
 
4129
                if(!readmem(VADDR, log_buf, log_buffer + length_oldlog, index)) {
 
4130
                        ERRMSG("Can't read new dmesg log.\n");
 
4131
                        goto out;
 
4132
                }
 
4133
        }
 
4134
        DEBUG_MSG("length_log   : %d\n", length_log);
 
4135
 
 
4136
        if (!open_dump_file()) {
 
4137
                ERRMSG("Can't open output file.\n");
 
4138
                goto out;
 
4139
        }
 
4140
        if (write(info->fd_dumpfile, log_buffer, length_log) < 0)
 
4141
                goto out;
 
4142
 
 
4143
        if (!close_files_for_creating_dumpfile())
 
4144
                goto out;
 
4145
 
 
4146
        ret = TRUE;
 
4147
out:
 
4148
        if (log_buffer)
 
4149
                free(log_buffer);
 
4150
 
 
4151
        return ret;
 
4152
}
 
4153
 
 
4154
 
 
4155
int
3927
4156
_exclude_free_page(void)
3928
4157
{
3929
4158
        int i, nr_zones, num_nodes, node;
4093
4322
        struct dump_bitmap bitmap2;
4094
4323
        unsigned char buf[info->page_size];
4095
4324
 
4096
 
        bitmap2.fd        = info->fd_bitmap;
4097
 
        bitmap2.file_name = info->name_bitmap;
4098
 
        bitmap2.no_block  = -1;
4099
 
        bitmap2.offset    = info->len_bitmap/2;
4100
 
        memset(bitmap2.buf, 0, sizeof(bitmap2.buf));
 
4325
        initialize_2nd_bitmap(&bitmap2);
4101
4326
 
4102
4327
        for (pfn = paddr = 0; pfn < info->max_mapnr;
4103
4328
            pfn++, paddr += info->page_size) {
4110
4335
                if (!is_dumpable(&bitmap2, pfn))
4111
4336
                        continue;
4112
4337
 
4113
 
                if (!readmem(PADDR, paddr, buf, info->page_size))
4114
 
                        return FALSE;
4115
 
 
 
4338
                if (vt.mem_flags & MEMORY_XEN) {
 
4339
                        if (!readmem(MADDR_XEN, paddr, buf, info->page_size)) {
 
4340
                                ERRMSG("Can't get the page data(pfn:%llx, max_mapnr:%llx).\n",
 
4341
                                    pfn, info->max_mapnr);
 
4342
                                return FALSE;
 
4343
                        }
 
4344
                } else {
 
4345
                        if (!readmem(PADDR, paddr, buf, info->page_size)) {
 
4346
                                ERRMSG("Can't get the page data(pfn:%llx, max_mapnr:%llx).\n",
 
4347
                                    pfn, info->max_mapnr);
 
4348
                                return FALSE;
 
4349
                        }
 
4350
                }
4116
4351
                if (is_zero_page(buf, info->page_size)) {
4117
4352
                        clear_bit_on_2nd_bitmap(pfn);
4118
4353
                        pfn_zero++;
4133
4368
        unsigned int mm;
4134
4369
        unsigned long mem_map;
4135
4370
        unsigned long long pfn, paddr, pfn_mm;
 
4371
        unsigned long long pfn_read_start, pfn_read_end, index_pg;
4136
4372
        unsigned char *page_cache = NULL, *pcache;
4137
4373
        unsigned int _count;
4138
4374
        unsigned long flags, mapping;
4156
4392
                if (mem_map == NOT_MEMMAP_ADDR)
4157
4393
                        continue;
4158
4394
 
 
4395
                /*
 
4396
                 * Refresh the buffer of struct page, when changing mem_map.
 
4397
                 */
 
4398
                pfn_read_start = ULONGLONG_MAX;
 
4399
                pfn_read_end   = 0;
 
4400
 
4159
4401
                for (; pfn < mmd->pfn_end;
4160
4402
                    pfn++, mem_map += SIZE(page),
4161
4403
                    paddr += info->page_size) {
4166
4408
                        if (!is_in_segs(paddr))
4167
4409
                                continue;
4168
4410
 
4169
 
                        if ((pfn % PGMM_CACHED) == 0) {
4170
 
                                if (pfn + PGMM_CACHED < mmd->pfn_end)
4171
 
                                        pfn_mm = PGMM_CACHED;
 
4411
                        index_pg = pfn % PGMM_CACHED;
 
4412
                        if (pfn < pfn_read_start || pfn_read_end < pfn) {
 
4413
                                if (roundup(pfn + 1, PGMM_CACHED) < mmd->pfn_end)
 
4414
                                        pfn_mm = PGMM_CACHED - index_pg;
4172
4415
                                else
4173
4416
                                        pfn_mm = mmd->pfn_end - pfn;
4174
 
                                if (!readmem(VADDR, mem_map, page_cache,
4175
 
                                    SIZE(page) * pfn_mm))
 
4417
 
 
4418
                                if (!readmem(VADDR, mem_map,
 
4419
                                    page_cache + (index_pg * SIZE(page)),
 
4420
                                    SIZE(page) * pfn_mm)) {
 
4421
                                        ERRMSG("Can't read the buffer of struct page.\n");
4176
4422
                                        goto out;
 
4423
                                }
 
4424
                                pfn_read_start = pfn;
 
4425
                                pfn_read_end   = pfn + pfn_mm - 1;
4177
4426
                        }
4178
 
                        pcache  = page_cache + ((pfn%PGMM_CACHED) * SIZE(page));
 
4427
                        pcache  = page_cache + (index_pg * SIZE(page));
 
4428
 
4179
4429
                        flags   = ULONG(pcache + OFFSET(page.flags));
4180
4430
                        _count  = UINT(pcache + OFFSET(page._count));
4181
4431
                        mapping = ULONG(pcache + OFFSET(page.mapping));
4315
4565
                        return FALSE;
4316
4566
 
4317
4567
                if (!exclude_zero_pages()) {
4318
 
                        ERRMSG("Can't exclude pages filled with zero");
4319
 
                        ERRMSG("for creating an ELF dumpfile.\n");
 
4568
                        ERRMSG("Can't exclude pages filled with zero for creating an ELF dumpfile.\n");
4320
4569
                        return FALSE;
4321
4570
                }
4322
4571
        }
4328
4577
}
4329
4578
 
4330
4579
int
4331
 
prepare_dump_bitmap(void)
 
4580
prepare_bitmap_buffer(void)
4332
4581
{
 
4582
        unsigned long tmp;
 
4583
 
 
4584
        /*
 
4585
         * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size boundary.
 
4586
         * The crash utility requires both of them to be aligned to block_size
 
4587
         * boundary.
 
4588
         */
 
4589
        tmp = divideup(divideup(info->max_mapnr, BITPERBYTE), info->page_size);
 
4590
        info->len_bitmap = tmp*info->page_size*2;
 
4591
 
 
4592
        /*
 
4593
         * Prepare bitmap buffers for creating dump bitmap.
 
4594
         */
4333
4595
        if ((info->bitmap1 = malloc(sizeof(struct dump_bitmap))) == NULL) {
4334
4596
                ERRMSG("Can't allocate memory for the 1st-bitmap. %s\n",
4335
4597
                    strerror(errno));
4340
4602
                    strerror(errno));
4341
4603
                return FALSE;
4342
4604
        }
4343
 
        info->bitmap1->fd        = info->fd_bitmap;
4344
 
        info->bitmap1->file_name = info->name_bitmap;
4345
 
        info->bitmap1->no_block  = -1;
4346
 
        info->bitmap1->offset    = 0;
4347
 
        memset(info->bitmap1->buf, 0, sizeof(info->bitmap1->buf));
4348
 
 
4349
 
        info->bitmap2->fd        = info->fd_bitmap;
4350
 
        info->bitmap2->file_name = info->name_bitmap;
4351
 
        info->bitmap2->no_block  = -1;
4352
 
        info->bitmap2->offset    = info->len_bitmap/2;
4353
 
        memset(info->bitmap2->buf, 0, sizeof(info->bitmap2->buf));
 
4605
        initialize_1st_bitmap(info->bitmap1);
 
4606
        initialize_2nd_bitmap(info->bitmap2);
4354
4607
 
4355
4608
        return TRUE;
4356
4609
}
4357
4610
 
 
4611
void
 
4612
free_bitmap_buffer(void)
 
4613
{
 
4614
        free(info->bitmap1);
 
4615
        free(info->bitmap2);
 
4616
 
 
4617
        info->bitmap1 = NULL;
 
4618
        info->bitmap2 = NULL;
 
4619
}
 
4620
 
4358
4621
int
4359
4622
create_dump_bitmap(void)
4360
4623
{
4361
 
        if (!prepare_dump_bitmap())
 
4624
        int ret = FALSE;
 
4625
 
 
4626
        if (!prepare_bitmap_buffer())
4362
4627
                return FALSE;
4363
4628
 
4364
4629
        if (!create_1st_bitmap())
4365
 
                return FALSE;
 
4630
                goto out;
4366
4631
 
4367
4632
        if (!create_2nd_bitmap())
4368
 
                return FALSE;
4369
 
 
4370
 
        return TRUE;
 
4633
                goto out;
 
4634
 
 
4635
        ret = TRUE;
 
4636
out:
 
4637
        free_bitmap_buffer();
 
4638
 
 
4639
        return ret;
4371
4640
}
4372
4641
 
4373
4642
int
4402
4671
        unsigned long long pfn, pfn_start, pfn_end, num_excluded;
4403
4672
        unsigned long frac_head, frac_tail;
4404
4673
        Elf64_Phdr load;
 
4674
        struct dump_bitmap bitmap2;
 
4675
 
 
4676
        initialize_2nd_bitmap(&bitmap2);
4405
4677
 
4406
4678
        if (!(phnum = get_phnum_memory()))
4407
4679
                return FALSE;
4426
4698
                        pfn_end++;
4427
4699
 
4428
4700
                for (pfn = pfn_start; pfn < pfn_end; pfn++) {
4429
 
                        if (!is_dumpable(info->bitmap2, pfn)) {
 
4701
                        if (!is_dumpable(&bitmap2, pfn)) {
4430
4702
                                num_excluded++;
4431
4703
                                continue;
4432
4704
                        }
4466
4738
free_cache_data(struct cache_data *cd)
4467
4739
{
4468
4740
        free(cd->buf);
 
4741
        cd->buf = NULL;
4469
4742
}
4470
4743
 
4471
4744
int
4494
4767
        memset(buf, 0, sizeof(buf));
4495
4768
        memcpy(buf, &fh, sizeof(fh));
4496
4769
 
4497
 
        if (write(info->fd_dumpfile, buf, MAX_SIZE_MDF_HEADER)
4498
 
            != MAX_SIZE_MDF_HEADER) {
4499
 
                ERRMSG("Can't write the dump file(%s). %s\n",
4500
 
                    info->name_dumpfile, strerror(errno));
 
4770
        if (!write_and_check_space(info->fd_dumpfile, buf, MAX_SIZE_MDF_HEADER,
 
4771
            info->name_dumpfile))
4501
4772
                return FALSE;
4502
 
        }
4503
4773
 
4504
4774
        return TRUE;
4505
4775
}
4515
4785
        fdh.offset   = END_FLAG_FLAT_HEADER;
4516
4786
        fdh.buf_size = END_FLAG_FLAT_HEADER;
4517
4787
 
4518
 
        if (write(info->fd_dumpfile, &fdh, sizeof(fdh)) != sizeof(fdh)) {
4519
 
                ERRMSG("Can't write the dump file(%s). %s\n",
4520
 
                    info->name_dumpfile, strerror(errno));
 
4788
        if (!write_and_check_space(info->fd_dumpfile, &fdh, sizeof(fdh),
 
4789
            info->name_dumpfile))
4521
4790
                return FALSE;
4522
 
        }
 
4791
 
4523
4792
        return TRUE;
4524
4793
}
4525
4794
 
4692
4961
         * Write common header
4693
4962
         */
4694
4963
        strcpy(dh->signature, KDUMP_SIGNATURE);
4695
 
        dh->header_version = 1;
 
4964
        dh->header_version = 2;
4696
4965
        dh->block_size   = info->page_size;
4697
4966
        dh->sub_hdr_size = 1;
4698
4967
        dh->max_mapnr    = info->max_mapnr;
4699
4968
        dh->nr_cpus      = 1;
4700
4969
        dh->bitmap_blocks
4701
4970
            = divideup(info->len_bitmap, dh->block_size);
 
4971
        memcpy(&dh->timestamp, &info->timestamp, sizeof(dh->timestamp));
4702
4972
 
4703
4973
        size = sizeof(struct disk_dump_header);
4704
4974
        if (!write_buffer(info->fd_dumpfile, 0, dh, size, info->name_dumpfile))
4707
4977
        /*
4708
4978
         * Write sub header
4709
4979
         */
 
4980
        size = sizeof(struct kdump_sub_header);
 
4981
        memset(&sub_dump_header, 0, size);
4710
4982
        sub_dump_header.phys_base  = info->phys_base;
4711
4983
        sub_dump_header.dump_level = info->dump_level;
4712
 
        size = sizeof(struct kdump_sub_header);
 
4984
        if (info->flag_split) {
 
4985
                sub_dump_header.split = 1;
 
4986
                sub_dump_header.start_pfn = info->split_start_pfn;
 
4987
                sub_dump_header.end_pfn   = info->split_end_pfn;
 
4988
        }
4713
4989
        if (!write_buffer(info->fd_dumpfile, dh->block_size, &sub_dump_header,
4714
4990
            size, info->name_dumpfile))
4715
4991
                return FALSE;
4741
5017
}
4742
5018
 
4743
5019
unsigned long long
4744
 
get_num_dumpable(struct dump_bitmap *bitmap2)
 
5020
get_num_dumpable(void)
4745
5021
{
4746
5022
        unsigned long long pfn, num_dumpable;
 
5023
        struct dump_bitmap bitmap2;
 
5024
 
 
5025
        initialize_2nd_bitmap(&bitmap2);
4747
5026
 
4748
5027
        for (pfn = 0, num_dumpable = 0; pfn < info->max_mapnr; pfn++) {
4749
 
                if (is_dumpable(bitmap2, pfn))
 
5028
                if (is_dumpable(&bitmap2, pfn))
4750
5029
                        num_dumpable++;
4751
5030
        }
4752
5031
        return num_dumpable;
4797
5076
        int i, phnum;
4798
5077
        long page_size = info->page_size;
4799
5078
        unsigned long long pfn, pfn_start, pfn_end, paddr, num_excluded;
4800
 
        unsigned long long num_dumpable = 0, num_dumped = 0, per;
 
5079
        unsigned long long num_dumpable, num_dumped = 0, per;
4801
5080
        unsigned long long memsz, filesz;
4802
5081
        unsigned long frac_head, frac_tail;
4803
5082
        off_t off_seg_load, off_memory;
4807
5086
        if (!info->flag_elf_dumpfile)
4808
5087
                return FALSE;
4809
5088
 
4810
 
        bitmap2.fd        = info->fd_bitmap;
4811
 
        bitmap2.file_name = info->name_bitmap;
4812
 
        bitmap2.no_block  = -1;
4813
 
        bitmap2.offset    = info->len_bitmap / 2;
4814
 
        memset(bitmap2.buf, 0, sizeof(bitmap2.buf));
 
5089
        initialize_2nd_bitmap(&bitmap2);
4815
5090
 
4816
 
        num_dumpable = get_num_dumpable(&bitmap2);
 
5091
        num_dumpable = get_num_dumpable();
4817
5092
        per = num_dumpable / 100;
4818
5093
 
4819
5094
        off_seg_load    = info->offset_load_dumpfile;
5032
5307
int
5033
5308
write_kdump_pages(struct cache_data *cd_header, struct cache_data *cd_page)
5034
5309
{
5035
 
        unsigned long long pfn, per, num_dumpable = 0, num_dumped = 0;
 
5310
        unsigned long long pfn, per, num_dumpable, num_dumped = 0;
 
5311
        unsigned long long start_pfn, end_pfn;
5036
5312
        unsigned long size_out;
5037
5313
        struct page_desc pd, pd_zero;
5038
5314
        off_t offset_data = 0;
5039
5315
        struct disk_dump_header *dh = info->dump_header;
5040
5316
        unsigned char buf[info->page_size], *buf_out = NULL;
5041
5317
        unsigned long len_buf_out;
5042
 
        struct dump_bitmap bitmap1, bitmap2;
 
5318
        struct dump_bitmap bitmap2;
5043
5319
        const off_t failed = (off_t)-1;
5044
5320
 
5045
5321
        int ret = FALSE;
5047
5323
        if (info->flag_elf_dumpfile)
5048
5324
                return FALSE;
5049
5325
 
5050
 
        bitmap1.fd        = info->fd_bitmap;
5051
 
        bitmap1.file_name = info->name_bitmap;
5052
 
        bitmap1.no_block  = -1;
5053
 
        bitmap1.offset    = 0;
5054
 
        memset(bitmap1.buf, 0, sizeof(bitmap1.buf));
5055
 
 
5056
 
        bitmap2.fd        = info->fd_bitmap;
5057
 
        bitmap2.file_name = info->name_bitmap;
5058
 
        bitmap2.no_block  = -1;
5059
 
        bitmap2.offset    = info->len_bitmap/2;
5060
 
        memset(bitmap2.buf, 0, sizeof(bitmap2.buf));
 
5326
        initialize_2nd_bitmap(&bitmap2);
5061
5327
 
5062
5328
        len_buf_out = compressBound(info->page_size);
5063
5329
        if ((buf_out = malloc(len_buf_out)) == NULL) {
5066
5332
                goto out;
5067
5333
        }
5068
5334
 
5069
 
        num_dumpable = get_num_dumpable(&bitmap2);
 
5335
        num_dumpable = get_num_dumpable();
5070
5336
        per = num_dumpable / 100;
5071
5337
 
5072
5338
        /*
5100
5366
                        goto out;
5101
5367
                offset_data  += pd_zero.size;
5102
5368
        }
5103
 
        for (pfn = 0; pfn < info->max_mapnr; pfn++) {
 
5369
        if (info->flag_split) {
 
5370
                start_pfn = info->split_start_pfn;
 
5371
                end_pfn   = info->split_end_pfn;
 
5372
        }
 
5373
        else {
 
5374
                start_pfn = 0;
 
5375
                end_pfn   = info->max_mapnr;
 
5376
        }
 
5377
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
5104
5378
 
5105
5379
                if ((num_dumped % per) == 0)
5106
5380
                        print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
5107
5381
 
5108
5382
                /*
5109
 
                 * Check the memory hole.
5110
 
                 */
5111
 
                if (is_memory_hole(&bitmap1, pfn))
5112
 
                        continue;
5113
 
                /*
5114
5383
                 * Check the excluded page.
5115
5384
                 */
5116
5385
                if (!is_dumpable(&bitmap2, pfn))
5327
5596
int
5328
5597
close_files_for_creating_dumpfile(void)
5329
5598
{
5330
 
        if (info->flag_read_vmcoreinfo)
5331
 
                close_vmcoreinfo();
5332
 
        else if (info->dump_level > DL_EXCLUDE_ZERO)
 
5599
        if (info->max_dump_level > DL_EXCLUDE_ZERO)
5333
5600
                close_kernel_file();
5334
5601
 
 
5602
        /* free name for vmcoreinfo */
 
5603
        if (info->offset_vmcoreinfo && info->size_vmcoreinfo) {
 
5604
                free(info->name_vmcoreinfo);
 
5605
                info->name_vmcoreinfo = NULL;
 
5606
        }
5335
5607
        close_dump_memory();
5336
5608
 
5337
 
        close_dump_file();
5338
 
 
5339
5609
        close_dump_bitmap();
5340
5610
 
5341
5611
        return TRUE;
5680
5950
                                    info->name_vmcoreinfo, buf);
5681
5951
                                return FALSE;
5682
5952
                        }
5683
 
                        if (!is_page_size(page_size)) {
 
5953
                        if (!set_page_size(page_size)) {
5684
5954
                                ERRMSG("Invalid data in %s: %s",
5685
5955
                                    info->name_vmcoreinfo, buf);
5686
5956
                                return FALSE;
5688
5958
                        break;
5689
5959
                }
5690
5960
        }
5691
 
        info->page_size = page_size;
5692
 
 
5693
5961
        if (!info->page_size) {
5694
5962
                ERRMSG("Invalid format in %s", info->name_vmcoreinfo);
5695
5963
                return FALSE;
5849
6117
                MSG("Try `makedumpfile --help' for more information.\n");
5850
6118
                return FALSE;
5851
6119
        }
5852
 
        if (DL_EXCLUDE_ZERO < info->dump_level) {
 
6120
        if (DL_EXCLUDE_ZERO < info->max_dump_level) {
5853
6121
                MSG("Dump_level is invalid. It should be 0 or 1.\n");
5854
6122
                MSG("Commandline parameter is invalid.\n");
5855
6123
                MSG("Try `makedumpfile --help' for more information.\n");
5856
6124
                return FALSE;
5857
6125
        }
5858
6126
 
 
6127
        if (!fallback_to_current_page_size())
 
6128
                return FALSE;
5859
6129
        /*
5860
6130
         * Get the debug information for analysis from the vmcoreinfo file
5861
6131
         */
5862
6132
        if (info->flag_read_vmcoreinfo) {
5863
6133
                if (!read_vmcoreinfo_xen())
5864
6134
                        return FALSE;
 
6135
                close_vmcoreinfo();
5865
6136
        /*
5866
6137
         * Get the debug information for analysis from the xen-syms file
5867
6138
         */
5883
6154
                 */
5884
6155
                if (!info->offset_vmcoreinfo_xen || !info->size_vmcoreinfo_xen){
5885
6156
                        if (!info->flag_exclude_xen_dom)
5886
 
                                return TRUE;
 
6157
                                goto out;
5887
6158
 
5888
6159
                        MSG("%s doesn't contain a vmcoreinfo for Xen.\n",
5889
6160
                            info->name_memory);
5892
6163
                        MSG("Try `makedumpfile --help' for more information.\n");
5893
6164
                        return FALSE;
5894
6165
                }
5895
 
 
5896
 
                /*
5897
 
                 * Copy vmcoreinfo to /tmp/vmcoreinfoXXXXXX.
5898
 
                 */
5899
 
                if ((info->name_vmcoreinfo
5900
 
                    = malloc(sizeof(FILENAME_VMCOREINFO))) == NULL) {
5901
 
                        ERRMSG("Can't allocate memory for the name(%s). %s\n",
5902
 
                            FILENAME_VMCOREINFO, strerror(errno));
5903
 
                        return FALSE;
5904
 
                }
5905
 
                strcpy(info->name_vmcoreinfo, FILENAME_VMCOREINFO);
5906
 
                if (!copy_vmcoreinfo(info->offset_vmcoreinfo_xen,
5907
 
                    info->size_vmcoreinfo_xen))
5908
 
                        return FALSE;
5909
 
                /*
5910
 
                 * Read vmcoreinfo from /tmp/vmcoreinfoXXXXXX.
5911
 
                 */
5912
 
                if (!open_vmcoreinfo("r"))
5913
 
                        return FALSE;
5914
 
                if (!read_vmcoreinfo_xen())
5915
 
                        return FALSE;
5916
 
                unlink(info->name_vmcoreinfo);
 
6166
                /*
 
6167
                 * Get the debug information from /proc/vmcore
 
6168
                 */
 
6169
                if (!read_vmcoreinfo_from_vmcore(info->offset_vmcoreinfo_xen,
 
6170
                    info->size_vmcoreinfo_xen, TRUE))
 
6171
                        return FALSE;
5917
6172
        }
5918
6173
        if (!get_xen_phys_start())
5919
6174
                return FALSE;
5922
6177
 
5923
6178
        if (message_level & ML_PRINT_DEBUG_MSG)
5924
6179
                show_data_xen();
 
6180
out:
 
6181
        if (!get_max_mapnr())
 
6182
                return FALSE;
5925
6183
 
5926
6184
        return TRUE;
5927
6185
#endif
5983
6241
}
5984
6242
 
5985
6243
int
5986
 
create_dumpfile(void)
 
6244
writeout_dumpfile(void)
5987
6245
{
 
6246
        int ret = FALSE;
5988
6247
        struct cache_data cd_header, cd_page;
5989
6248
 
5990
 
        if (!open_files_for_creating_dumpfile())
5991
 
                return FALSE;
5992
 
 
5993
 
        if (!get_elf_info())
5994
 
                return FALSE;
5995
 
 
5996
 
        if (vt.mem_flags & MEMORY_XEN) {
5997
 
                if (!initial_xen())
5998
 
                        return FALSE;
5999
 
        } else {
6000
 
                if (!initial())
6001
 
                        return FALSE;
6002
 
        }
6003
 
        print_vtop();
6004
 
 
6005
 
        if (!create_dump_bitmap())
6006
 
                return FALSE;
 
6249
        info->flag_nospace = FALSE;
6007
6250
 
6008
6251
        if (!open_dump_file())
6009
6252
                return FALSE;
6015
6258
        if (!prepare_cache_data(&cd_header))
6016
6259
                return FALSE;
6017
6260
 
6018
 
        if (!prepare_cache_data(&cd_page))
 
6261
        if (!prepare_cache_data(&cd_page)) {
 
6262
                free_cache_data(&cd_header);
6019
6263
                return FALSE;
6020
 
 
 
6264
        }
6021
6265
        if (info->flag_elf_dumpfile) {
6022
6266
                if (!write_elf_header(&cd_header))
6023
 
                        return FALSE;
 
6267
                        goto out;
6024
6268
                if (!write_elf_pages(&cd_header, &cd_page))
6025
 
                        return FALSE;
 
6269
                        goto out;
6026
6270
        } else {
6027
6271
                if (!write_kdump_header())
6028
 
                        return FALSE;
 
6272
                        goto out;
6029
6273
                if (!write_kdump_pages(&cd_header, &cd_page))
6030
 
                        return FALSE;
 
6274
                        goto out;
6031
6275
                if (!write_kdump_bitmap())
6032
 
                        return FALSE;
 
6276
                        goto out;
6033
6277
        }
6034
6278
        if (info->flag_flatten) {
6035
6279
                if (!write_end_flat_header())
6036
 
                        return FALSE;
 
6280
                        goto out;
6037
6281
        }
 
6282
 
 
6283
        ret = TRUE;
 
6284
out:
6038
6285
        free_cache_data(&cd_header);
6039
6286
        free_cache_data(&cd_page);
6040
6287
 
6041
 
        if (!close_files_for_creating_dumpfile())
6042
 
                return FALSE;
6043
 
 
 
6288
        close_dump_file();
 
6289
 
 
6290
        if ((ret == FALSE) && info->flag_nospace)
 
6291
                return NOSPACE;
 
6292
        else
 
6293
                return ret;
 
6294
}
 
6295
 
 
6296
int
 
6297
setup_splitting(void)
 
6298
{
 
6299
        int i;
 
6300
        unsigned long long j, pfn_per_dumpfile;
 
6301
        unsigned long long start_pfn, end_pfn;
 
6302
        unsigned long long num_dumpable = get_num_dumpable();
 
6303
        struct dump_bitmap bitmap2;
 
6304
 
 
6305
        if (info->num_dumpfile <= 1)
 
6306
                return FALSE;
 
6307
 
 
6308
        initialize_2nd_bitmap(&bitmap2);
 
6309
 
 
6310
        pfn_per_dumpfile = num_dumpable / info->num_dumpfile;
 
6311
        start_pfn = end_pfn = 0;
 
6312
        for (i = 0; i < info->num_dumpfile; i++) {
 
6313
                start_pfn = end_pfn;
 
6314
                if (i == (info->num_dumpfile - 1)) {
 
6315
                        end_pfn  = info->max_mapnr;
 
6316
                } else {
 
6317
                        for (j = 0; j < pfn_per_dumpfile; end_pfn++) {
 
6318
                                if (is_dumpable(&bitmap2, end_pfn))
 
6319
                                        j++;
 
6320
                        }
 
6321
                }
 
6322
                SPLITTING_START_PFN(i) = start_pfn;
 
6323
                SPLITTING_END_PFN(i)   = end_pfn;
 
6324
        }
 
6325
 
 
6326
        return TRUE;
 
6327
}
 
6328
 
 
6329
/*
 
6330
 * This function is for creating split dumpfiles by multiple
 
6331
 * processes. Each child process should re-open a /proc/vmcore
 
6332
 * file, because it prevents each other from affectting the file
 
6333
 * offset due to read(2) call.
 
6334
 */
 
6335
int
 
6336
reopen_dump_memory()
 
6337
{
 
6338
        close_dump_memory();
 
6339
 
 
6340
        if ((info->fd_memory = open(info->name_memory, O_RDONLY)) < 0) {
 
6341
                ERRMSG("Can't open the dump memory(%s). %s\n",
 
6342
                    info->name_memory, strerror(errno));
 
6343
                return FALSE;
 
6344
        }
 
6345
        return TRUE;
 
6346
}
 
6347
 
 
6348
int
 
6349
get_next_dump_level(int index)
 
6350
{
 
6351
        if (info->num_dump_level <= index)
 
6352
                return -1;
 
6353
 
 
6354
        return info->array_dump_level[index];
 
6355
}
 
6356
 
 
6357
int
 
6358
delete_dumpfile(void)
 
6359
{
 
6360
        int i;
 
6361
 
 
6362
        if (info->flag_flatten)
 
6363
                return TRUE;
 
6364
 
 
6365
        if (info->flag_split) {
 
6366
                for (i = 0; i < info->num_dumpfile; i++)
 
6367
                        unlink(SPLITTING_DUMPFILE(i));
 
6368
        } else {
 
6369
                unlink(info->name_dumpfile);
 
6370
        }
 
6371
        return TRUE;
 
6372
}
 
6373
 
 
6374
int
 
6375
writeout_multiple_dumpfiles(void)
 
6376
{
 
6377
        int i, status, ret = TRUE;
 
6378
        pid_t pid;
 
6379
        pid_t array_pid[info->num_dumpfile];
 
6380
 
 
6381
        if (!setup_splitting())
 
6382
                return FALSE;
 
6383
 
 
6384
        for (i = 0; i < info->num_dumpfile; i++) {
 
6385
                if ((pid = fork()) < 0) {
 
6386
                        return FALSE;
 
6387
 
 
6388
                } else if (pid == 0) { /* Child */
 
6389
                        info->name_dumpfile   = SPLITTING_DUMPFILE(i);
 
6390
                        info->fd_bitmap       = SPLITTING_FD_BITMAP(i);
 
6391
                        info->split_start_pfn = SPLITTING_START_PFN(i);
 
6392
                        info->split_end_pfn   = SPLITTING_END_PFN(i);
 
6393
 
 
6394
                        if (!reopen_dump_memory())
 
6395
                                exit(1);
 
6396
                        if ((status = writeout_dumpfile()) == FALSE)
 
6397
                                exit(1);
 
6398
                        else if (status == NOSPACE)
 
6399
                                exit(2);
 
6400
                        exit(0);
 
6401
                }
 
6402
                array_pid[i] = pid;
 
6403
        }
 
6404
        for (i = 0; i < info->num_dumpfile; i++) {
 
6405
                waitpid(array_pid[i], &status, WUNTRACED);
 
6406
                if (!WIFEXITED(status) || WEXITSTATUS(status) == 1) {
 
6407
                        ERRMSG("Child process(%d) finished imcompletely.(%d)\n",
 
6408
                            array_pid[i], status);
 
6409
                        ret = FALSE;
 
6410
                } else if ((ret == TRUE) && (WEXITSTATUS(status) == 2))
 
6411
                        ret = NOSPACE;
 
6412
        }
 
6413
        return ret;
 
6414
}
 
6415
 
 
6416
int
 
6417
create_dumpfile(void)
 
6418
{
 
6419
        int num_retry, status;
 
6420
 
 
6421
        if (!open_files_for_creating_dumpfile())
 
6422
                return FALSE;
 
6423
 
 
6424
        if (!get_elf_info())
 
6425
                return FALSE;
 
6426
 
 
6427
        if (vt.mem_flags & MEMORY_XEN) {
 
6428
                if (!initial_xen())
 
6429
                        return FALSE;
 
6430
        } else {
 
6431
                if (!initial())
 
6432
                        return FALSE;
 
6433
        }
 
6434
        print_vtop();
 
6435
 
 
6436
        num_retry = 0;
 
6437
retry:
 
6438
        if (!create_dump_bitmap())
 
6439
                return FALSE;
 
6440
 
 
6441
        if (info->flag_split) {
 
6442
                if ((status = writeout_multiple_dumpfiles()) == FALSE)
 
6443
                        return FALSE;
 
6444
        } else {
 
6445
                if ((status = writeout_dumpfile()) == FALSE)
 
6446
                        return FALSE;
 
6447
        }
 
6448
        if (status == NOSPACE) {
 
6449
                /*
 
6450
                 * If specifying the other dump_level, makedumpfile tries
 
6451
                 * to create a dumpfile with it again.
 
6452
                 */
 
6453
                num_retry++;
 
6454
                if ((info->dump_level = get_next_dump_level(num_retry)) < 0)
 
6455
                        return FALSE;
 
6456
                MSG("Retry to create a dumpfile by dump_level(%d).\n",
 
6457
                    info->dump_level);
 
6458
                if (!delete_dumpfile())
 
6459
                        return FALSE;
 
6460
                goto retry;
 
6461
        }
6044
6462
        print_report();
6045
6463
 
 
6464
        if (!close_files_for_creating_dumpfile())
 
6465
                return FALSE;
 
6466
 
 
6467
        return TRUE;
 
6468
}
 
6469
 
 
6470
int
 
6471
read_disk_dump_header(struct disk_dump_header *dh, char *filename)
 
6472
{
 
6473
        int fd, ret = FALSE;
 
6474
 
 
6475
        if ((fd = open(filename, O_RDONLY)) < 0) {
 
6476
                ERRMSG("Can't open a file(%s). %s\n",
 
6477
                    filename, strerror(errno));
 
6478
                return FALSE;
 
6479
        }
 
6480
        if (lseek(fd, 0x0, SEEK_SET) < 0) {
 
6481
                ERRMSG("Can't seek a file(%s). %s\n",
 
6482
                    filename, strerror(errno));
 
6483
                goto out;
 
6484
        }
 
6485
        if (read(fd, dh, sizeof(struct disk_dump_header))
 
6486
            != sizeof(struct disk_dump_header)) {
 
6487
                ERRMSG("Can't read a file(%s). %s\n",
 
6488
                    filename, strerror(errno));
 
6489
                goto out;
 
6490
        }
 
6491
        if (strncmp(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE))) {
 
6492
                ERRMSG("%s is not the kdump-compressed format.\n",
 
6493
                    filename);
 
6494
                goto out;
 
6495
        }
 
6496
        ret = TRUE;
 
6497
out:
 
6498
        close(fd);
 
6499
 
 
6500
        return ret;
 
6501
}
 
6502
 
 
6503
int
 
6504
read_kdump_sub_header(struct kdump_sub_header *ksh, char *filename)
 
6505
{
 
6506
        int fd, ret = FALSE;
 
6507
 
 
6508
        if (!info->page_size)
 
6509
                return FALSE;
 
6510
 
 
6511
        if ((fd = open(filename, O_RDONLY)) < 0) {
 
6512
                ERRMSG("Can't open a file(%s). %s\n",
 
6513
                    filename, strerror(errno));
 
6514
                return FALSE;
 
6515
        }
 
6516
        if (lseek(fd, info->page_size, SEEK_SET) < 0) {
 
6517
                ERRMSG("Can't seek a file(%s). %s\n",
 
6518
                    filename, strerror(errno));
 
6519
                goto out;
 
6520
        }
 
6521
        if (read(fd, ksh, sizeof(struct kdump_sub_header))
 
6522
             != sizeof(struct kdump_sub_header)) {
 
6523
                ERRMSG("Can't read a file(%s). %s\n",
 
6524
                    filename, strerror(errno));
 
6525
                goto out;
 
6526
        }
 
6527
        ret = TRUE;
 
6528
out:
 
6529
        close(fd);
 
6530
 
 
6531
        return ret;
 
6532
}
 
6533
 
 
6534
int
 
6535
store_splitting_info(void)
 
6536
{
 
6537
        int i;
 
6538
        struct disk_dump_header dh, tmp_dh;
 
6539
        struct kdump_sub_header ksh;
 
6540
 
 
6541
        for (i = 0; i < info->num_dumpfile; i++) {
 
6542
                if (!read_disk_dump_header(&tmp_dh, SPLITTING_DUMPFILE(i)))
 
6543
                        return FALSE;
 
6544
 
 
6545
                if (i == 0) {
 
6546
                        memcpy(&dh, &tmp_dh, sizeof(tmp_dh));
 
6547
                        info->max_mapnr = dh.max_mapnr;
 
6548
                        if (!set_page_size(dh.block_size))
 
6549
                                return FALSE;
 
6550
                        DEBUG_MSG("max_mapnr    : %llx\n", info->max_mapnr);
 
6551
                        DEBUG_MSG("page_size    : %ld\n", info->page_size);
 
6552
                }
 
6553
 
 
6554
                /*
 
6555
                 * Check whether multiple dumpfiles are parts of
 
6556
                 * the same /proc/vmcore.
 
6557
                 */
 
6558
                if (memcmp(&dh, &tmp_dh, sizeof(tmp_dh))) {
 
6559
                        ERRMSG("Invalid dumpfile(%s).\n",
 
6560
                            SPLITTING_DUMPFILE(i));
 
6561
                        return FALSE;
 
6562
                }
 
6563
                if (!read_kdump_sub_header(&ksh, SPLITTING_DUMPFILE(i)))
 
6564
                        return FALSE;
 
6565
 
 
6566
                if (i == 0) {
 
6567
                        info->dump_level = ksh.dump_level;
 
6568
                        DEBUG_MSG("dump_level   : %d\n", info->dump_level);
 
6569
                }
 
6570
                SPLITTING_START_PFN(i) = ksh.start_pfn;
 
6571
                SPLITTING_END_PFN(i)   = ksh.end_pfn;
 
6572
        }
 
6573
        return TRUE;
 
6574
}
 
6575
 
 
6576
void
 
6577
sort_splitting_info(void)
 
6578
{
 
6579
        int i, j;
 
6580
        unsigned long long start_pfn, end_pfn;
 
6581
        char *name_dumpfile;
 
6582
 
 
6583
        /*
 
6584
         * Sort splitting_info by start_pfn.
 
6585
         */
 
6586
        for (i = 0; i < (info->num_dumpfile - 1); i++) {
 
6587
                for (j = i; j < info->num_dumpfile; j++) {
 
6588
                        if (SPLITTING_START_PFN(i) < SPLITTING_START_PFN(j))
 
6589
                                continue;
 
6590
                        start_pfn     = SPLITTING_START_PFN(i);
 
6591
                        end_pfn       = SPLITTING_END_PFN(i);
 
6592
                        name_dumpfile = SPLITTING_DUMPFILE(i);
 
6593
 
 
6594
                        SPLITTING_START_PFN(i) = SPLITTING_START_PFN(j);
 
6595
                        SPLITTING_END_PFN(i)   = SPLITTING_END_PFN(j);
 
6596
                        SPLITTING_DUMPFILE(i)  = SPLITTING_DUMPFILE(j);
 
6597
 
 
6598
                        SPLITTING_START_PFN(j) = start_pfn;
 
6599
                        SPLITTING_END_PFN(j)   = end_pfn;
 
6600
                        SPLITTING_DUMPFILE(j)  = name_dumpfile;
 
6601
                }
 
6602
        }
 
6603
 
 
6604
        DEBUG_MSG("num_dumpfile : %d\n", info->num_dumpfile);
 
6605
        for (i = 0; i < info->num_dumpfile; i++) {
 
6606
                DEBUG_MSG("dumpfile (%s)\n", SPLITTING_DUMPFILE(i));
 
6607
                DEBUG_MSG("  start_pfn  : %llx\n", SPLITTING_START_PFN(i));
 
6608
                DEBUG_MSG("  end_pfn    : %llx\n", SPLITTING_END_PFN(i));
 
6609
        }
 
6610
}
 
6611
 
 
6612
int
 
6613
check_splitting_info(void)
 
6614
{
 
6615
        int i;
 
6616
        unsigned long long end_pfn;
 
6617
 
 
6618
        /*
 
6619
         * Check whether there are not lack of /proc/vmcore.
 
6620
         */
 
6621
        if (SPLITTING_START_PFN(0) != 0) {
 
6622
                ERRMSG("There is not dumpfile corresponding to pfn 0x%x - 0x%llx.\n",
 
6623
                    0x0, SPLITTING_START_PFN(0));
 
6624
                return FALSE;
 
6625
        }
 
6626
        end_pfn = SPLITTING_END_PFN(0);
 
6627
 
 
6628
        for (i = 1; i < info->num_dumpfile; i++) {
 
6629
                if (end_pfn != SPLITTING_START_PFN(i)) {
 
6630
                        ERRMSG("There is not dumpfile corresponding to pfn 0x%llx - 0x%llx.\n",
 
6631
                            end_pfn, SPLITTING_START_PFN(i));
 
6632
                        return FALSE;
 
6633
                }
 
6634
                end_pfn = SPLITTING_END_PFN(i);
 
6635
        }
 
6636
        if (end_pfn != info->max_mapnr) {
 
6637
                ERRMSG("There is not dumpfile corresponding to pfn 0x%llx - 0x%llx.\n",
 
6638
                    end_pfn, info->max_mapnr);
 
6639
                return FALSE;
 
6640
        }
 
6641
 
 
6642
        return TRUE;
 
6643
}
 
6644
 
 
6645
int
 
6646
get_splitting_info(void)
 
6647
{
 
6648
        if (!store_splitting_info())
 
6649
                return FALSE;
 
6650
 
 
6651
        sort_splitting_info();
 
6652
 
 
6653
        if (!check_splitting_info())
 
6654
                return FALSE;
 
6655
 
 
6656
        return TRUE;
 
6657
}
 
6658
 
 
6659
int
 
6660
reassemble_kdump_header(void)
 
6661
{
 
6662
        int fd, ret = FALSE;
 
6663
        off_t offset_bitmap;
 
6664
        struct disk_dump_header dh;
 
6665
        struct kdump_sub_header ksh;
 
6666
        char *buf_bitmap;
 
6667
 
 
6668
        /*
 
6669
         * Write common header.
 
6670
         */
 
6671
        if (!read_disk_dump_header(&dh, SPLITTING_DUMPFILE(0)))
 
6672
                return FALSE;
 
6673
 
 
6674
        if (lseek(info->fd_dumpfile, 0x0, SEEK_SET) < 0) {
 
6675
                ERRMSG("Can't seek a file(%s). %s\n",
 
6676
                    info->name_dumpfile, strerror(errno));
 
6677
                return FALSE;
 
6678
        }
 
6679
        if (write(info->fd_dumpfile, &dh, sizeof(dh)) != sizeof(dh)) {
 
6680
                ERRMSG("Can't write a file(%s). %s\n",
 
6681
                    info->name_dumpfile, strerror(errno));
 
6682
                return FALSE;
 
6683
        }
 
6684
 
 
6685
        /*
 
6686
         * Write sub header.
 
6687
         */
 
6688
        if (!read_kdump_sub_header(&ksh, SPLITTING_DUMPFILE(0)))
 
6689
                return FALSE;
 
6690
 
 
6691
        ksh.split = 0;
 
6692
        ksh.start_pfn = 0;
 
6693
        ksh.end_pfn   = 0;
 
6694
 
 
6695
        if (lseek(info->fd_dumpfile, info->page_size, SEEK_SET) < 0) {
 
6696
                ERRMSG("Can't seek a file(%s). %s\n",
 
6697
                    info->name_dumpfile, strerror(errno));
 
6698
                return FALSE;
 
6699
        }
 
6700
        if (write(info->fd_dumpfile, &ksh, sizeof(ksh)) != sizeof(ksh)) {
 
6701
                ERRMSG("Can't write a file(%s). %s\n",
 
6702
                    info->name_dumpfile, strerror(errno));
 
6703
                return FALSE;
 
6704
        }
 
6705
 
 
6706
        /*
 
6707
         * Write dump bitmap to both a dumpfile and a bitmap file.
 
6708
         */
 
6709
        offset_bitmap    = info->page_size * (1 + dh.sub_hdr_size);
 
6710
        info->len_bitmap = info->page_size * dh.bitmap_blocks;
 
6711
        if ((buf_bitmap = malloc(info->len_bitmap)) == NULL) {
 
6712
                ERRMSG("Can't allcate memory for bitmap.\n");
 
6713
                return FALSE;
 
6714
        }
 
6715
 
 
6716
        if ((fd = open(SPLITTING_DUMPFILE(0), O_RDONLY)) < 0) {
 
6717
                ERRMSG("Can't open a file(%s). %s\n",
 
6718
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
6719
                return FALSE;
 
6720
        }
 
6721
        if (lseek(fd, offset_bitmap, SEEK_SET) < 0) {
 
6722
                ERRMSG("Can't seek a file(%s). %s\n",
 
6723
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
6724
                goto out;
 
6725
        }
 
6726
        if (read(fd, buf_bitmap, info->len_bitmap) != info->len_bitmap) {
 
6727
                ERRMSG("Can't read a file(%s). %s\n",
 
6728
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
6729
                goto out;
 
6730
        }
 
6731
 
 
6732
        if (lseek(info->fd_dumpfile, offset_bitmap, SEEK_SET) < 0) {
 
6733
                ERRMSG("Can't seek a file(%s). %s\n",
 
6734
                    info->name_dumpfile, strerror(errno));
 
6735
                goto out;
 
6736
        }
 
6737
        if (write(info->fd_dumpfile, buf_bitmap, info->len_bitmap)
 
6738
            != info->len_bitmap) {
 
6739
                ERRMSG("Can't write a file(%s). %s\n",
 
6740
                    info->name_dumpfile, strerror(errno));
 
6741
                goto out;
 
6742
        }
 
6743
 
 
6744
        if (lseek(info->fd_bitmap, 0x0, SEEK_SET) < 0) {
 
6745
                ERRMSG("Can't seek a file(%s). %s\n",
 
6746
                    info->name_bitmap, strerror(errno));
 
6747
                goto out;
 
6748
        }
 
6749
        if (write(info->fd_bitmap, buf_bitmap, info->len_bitmap)
 
6750
            != info->len_bitmap) {
 
6751
                ERRMSG("Can't write a file(%s). %s\n",
 
6752
                    info->name_bitmap, strerror(errno));
 
6753
                goto out;
 
6754
        }
 
6755
 
 
6756
        ret = TRUE;
 
6757
out:
 
6758
        close(fd);
 
6759
 
 
6760
        return ret;
 
6761
}
 
6762
 
 
6763
int
 
6764
reassemble_kdump_pages(void)
 
6765
{
 
6766
        int i, fd = 0, ret = FALSE;
 
6767
        off_t offset_first_ph, offset_ph_org;
 
6768
        off_t offset_data_new, offset_zero_page = 0;
 
6769
        unsigned long long pfn, start_pfn, end_pfn;
 
6770
        unsigned long long num_dumpable, num_dumped;
 
6771
        struct dump_bitmap bitmap2;
 
6772
        struct disk_dump_header dh;
 
6773
        struct page_desc pd, pd_zero;
 
6774
        struct cache_data cd_pd, cd_data;
 
6775
        char *data = NULL;
 
6776
 
 
6777
        initialize_2nd_bitmap(&bitmap2);
 
6778
 
 
6779
        if (!read_disk_dump_header(&dh, SPLITTING_DUMPFILE(0)))
 
6780
                return FALSE;
 
6781
 
 
6782
        if (!prepare_cache_data(&cd_pd))
 
6783
                return FALSE;
 
6784
 
 
6785
        if (!prepare_cache_data(&cd_data)) {
 
6786
                free_cache_data(&cd_pd);
 
6787
                return FALSE;
 
6788
        }
 
6789
        if ((data = malloc(info->page_size)) == NULL) {
 
6790
                ERRMSG("Can't allcate memory for page data.\n");
 
6791
                free_cache_data(&cd_pd);
 
6792
                free_cache_data(&cd_data);
 
6793
                return FALSE;
 
6794
        }
 
6795
        num_dumpable = get_num_dumpable();
 
6796
        num_dumped = 0;
 
6797
 
 
6798
        offset_first_ph = (1 + dh.sub_hdr_size + dh.bitmap_blocks)
 
6799
             * dh.block_size;
 
6800
        cd_pd.offset    = offset_first_ph;
 
6801
        offset_data_new = offset_first_ph + sizeof(page_desc_t) * num_dumpable;
 
6802
        cd_data.offset  = offset_data_new;
 
6803
 
 
6804
        /*
 
6805
         * Write page header of zero-filled page.
 
6806
         */
 
6807
        if (info->dump_level & DL_EXCLUDE_ZERO) {
 
6808
                /*
 
6809
                 * makedumpfile outputs the data of zero-filled page at first
 
6810
                 * if excluding zero-filled page, so the offset of first data
 
6811
                 * is for zero-filled page in all dumpfiles.
 
6812
                 */
 
6813
                offset_zero_page = offset_data_new;
 
6814
 
 
6815
                pd_zero.size = info->page_size;
 
6816
                pd_zero.flags = 0;
 
6817
                pd_zero.offset = offset_data_new;
 
6818
                pd_zero.page_flags = 0;
 
6819
                memset(data, 0, pd_zero.size);
 
6820
                if (!write_cache(&cd_data, data, pd_zero.size))
 
6821
                        goto out;
 
6822
                offset_data_new  += pd_zero.size;
 
6823
        }
 
6824
        for (i = 0; i < info->num_dumpfile; i++) {
 
6825
                if ((fd = open(SPLITTING_DUMPFILE(i), O_RDONLY)) < 0) {
 
6826
                        ERRMSG("Can't open a file(%s). %s\n",
 
6827
                            SPLITTING_DUMPFILE(i), strerror(errno));
 
6828
                        goto out;
 
6829
                }
 
6830
                start_pfn = SPLITTING_START_PFN(i);
 
6831
                end_pfn   = SPLITTING_END_PFN(i);
 
6832
 
 
6833
                offset_ph_org = offset_first_ph;
 
6834
                for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 
6835
                        if (!is_dumpable(&bitmap2, pfn))
 
6836
                                continue;
 
6837
 
 
6838
                        num_dumped++;
 
6839
 
 
6840
                        print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
 
6841
 
 
6842
                        if (lseek(fd, offset_ph_org, SEEK_SET) < 0) {
 
6843
                                ERRMSG("Can't seek a file(%s). %s\n",
 
6844
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
6845
                                goto out;
 
6846
                        }
 
6847
                        if (read(fd, &pd, sizeof(pd)) != sizeof(pd)) {
 
6848
                                ERRMSG("Can't read a file(%s). %s\n",
 
6849
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
6850
                                goto out;
 
6851
                        }
 
6852
                        if (lseek(fd, pd.offset, SEEK_SET) < 0) {
 
6853
                                ERRMSG("Can't seek a file(%s). %s\n",
 
6854
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
6855
                                goto out;
 
6856
                        }
 
6857
                        if (read(fd, data, pd.size) != pd.size) {
 
6858
                                ERRMSG("Can't read a file(%s). %s\n",
 
6859
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
6860
                                goto out;
 
6861
                        }
 
6862
                        if ((info->dump_level & DL_EXCLUDE_ZERO)
 
6863
                            && (pd.offset == offset_zero_page)) {
 
6864
                                /*
 
6865
                                 * Handle the data of zero-filled page.
 
6866
                                 */
 
6867
                                if (!write_cache(&cd_pd, &pd_zero,
 
6868
                                    sizeof(pd_zero)))
 
6869
                                        goto out;
 
6870
                                offset_ph_org += sizeof(pd);
 
6871
                                continue;
 
6872
                        }
 
6873
                        pd.offset = offset_data_new;
 
6874
                        if (!write_cache(&cd_pd, &pd, sizeof(pd)))
 
6875
                                goto out;
 
6876
                        offset_ph_org += sizeof(pd);
 
6877
 
 
6878
                        if (!write_cache(&cd_data, data, pd.size))
 
6879
                                goto out;
 
6880
 
 
6881
                        offset_data_new += pd.size;
 
6882
                }
 
6883
                close(fd);
 
6884
                fd = 0;
 
6885
        }
 
6886
        if (!write_cache_bufsz(&cd_pd))
 
6887
                goto out;
 
6888
        if (!write_cache_bufsz(&cd_data))
 
6889
                goto out;
 
6890
 
 
6891
        print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
 
6892
        ret = TRUE;
 
6893
out:
 
6894
        free_cache_data(&cd_pd);
 
6895
        free_cache_data(&cd_data);
 
6896
 
 
6897
        if (data)
 
6898
                free(data);
 
6899
        if (fd > 0)
 
6900
                close(fd);
 
6901
 
 
6902
        return ret;
 
6903
}
 
6904
 
 
6905
int
 
6906
reassemble_dumpfile(void)
 
6907
{
 
6908
        if (!get_splitting_info())
 
6909
                return FALSE;
 
6910
 
 
6911
        if (!open_dump_bitmap())
 
6912
                return FALSE;
 
6913
 
 
6914
        if (!open_dump_file())
 
6915
                return FALSE;
 
6916
 
 
6917
        if (!reassemble_kdump_header())
 
6918
                return FALSE;
 
6919
 
 
6920
        if (!reassemble_kdump_pages())
 
6921
                return FALSE;
 
6922
 
 
6923
        close_dump_file();
 
6924
        close_dump_bitmap();
 
6925
 
6046
6926
        return TRUE;
6047
6927
}
6048
6928
 
6085
6965
}
6086
6966
 
6087
6967
/*
 
6968
 * Parameters for reassembling multiple dumpfiles into one dumpfile.
 
6969
 */
 
6970
int
 
6971
check_param_for_reassembling_dumpfile(int argc, char *argv[])
 
6972
{
 
6973
        int i;
 
6974
 
 
6975
        info->num_dumpfile  = argc - optind - 1;
 
6976
        info->name_dumpfile = argv[argc - 1];
 
6977
 
 
6978
        DEBUG_MSG("num_dumpfile : %d\n", info->num_dumpfile);
 
6979
 
 
6980
        if (info->flag_compress        || info->dump_level
 
6981
            || info->flag_elf_dumpfile || info->flag_read_vmcoreinfo
 
6982
            || info->name_vmlinux      || info->name_xen_syms
 
6983
            || info->flag_flatten      || info->flag_generate_vmcoreinfo
 
6984
            || info->flag_exclude_xen_dom || info->flag_split)
 
6985
                return FALSE;
 
6986
 
 
6987
        if ((info->splitting_info
 
6988
            = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
 
6989
            == NULL) {
 
6990
                MSG("Can't allocate memory for splitting_info.\n");
 
6991
                return FALSE;
 
6992
        }
 
6993
        for (i = 0; i < info->num_dumpfile; i++)
 
6994
                SPLITTING_DUMPFILE(i) = argv[optind + i];
 
6995
 
 
6996
        return TRUE;
 
6997
}
 
6998
 
 
6999
/*
6088
7000
 * Check parameters to create the dump file.
6089
7001
 */
6090
7002
int
6091
7003
check_param_for_creating_dumpfile(int argc, char *argv[])
6092
7004
{
6093
 
        if (argc > optind + 2)
6094
 
                return FALSE;
 
7005
        int i;
6095
7006
 
6096
7007
        if (info->flag_generate_vmcoreinfo || info->flag_rearrange)
6097
7008
                return FALSE;
6098
7009
 
6099
 
        if ((info->dump_level < MIN_DUMP_LEVEL)
6100
 
            || (MAX_DUMP_LEVEL < info->dump_level)) {
6101
 
                MSG("Dump_level is invalid.\n");
6102
 
                return FALSE;
6103
 
        }
6104
7010
        if ((message_level < MIN_MSG_LEVEL)
6105
7011
            || (MAX_MSG_LEVEL < message_level)) {
6106
7012
                message_level = DEFAULT_MSG_LEVEL;
6112
7018
            || (info->flag_read_vmcoreinfo && info->name_xen_syms))
6113
7019
                return FALSE;
6114
7020
 
6115
 
        if ((argc == optind + 2) && !info->flag_flatten) {
 
7021
        if (info->flag_flatten && info->flag_split)
 
7022
                return FALSE;
 
7023
 
 
7024
        if ((argc == optind + 2) && !info->flag_flatten
 
7025
                                 && !info->flag_split) {
6116
7026
                /*
6117
7027
                 * Parameters for creating the dumpfile from vmcore.
6118
7028
                 */
6119
7029
                info->name_memory   = argv[optind];
6120
7030
                info->name_dumpfile = argv[optind+1];
6121
7031
 
 
7032
        } else if ((argc > optind + 2) && info->flag_split) {
 
7033
                /*
 
7034
                 * Parameters for creating multiple dumpfiles from vmcore.
 
7035
                 */
 
7036
                info->num_dumpfile = argc - optind - 1;
 
7037
                info->name_memory  = argv[optind];
 
7038
 
 
7039
                if (info->flag_elf_dumpfile) {
 
7040
                        MSG("Options for splitting dumpfile cannot be used with Elf format.\n");
 
7041
                        return FALSE;
 
7042
                }
 
7043
                if ((info->splitting_info
 
7044
                    = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
 
7045
                    == NULL) {
 
7046
                        MSG("Can't allocate memory for splitting_info.\n");
 
7047
                        return FALSE;
 
7048
                }
 
7049
                for (i = 0; i < info->num_dumpfile; i++)
 
7050
                        SPLITTING_DUMPFILE(i) = argv[optind + 1 + i];
 
7051
 
6122
7052
        } else if ((argc == optind + 1) && info->flag_flatten) {
6123
7053
                /*
6124
7054
                 * Parameters for outputting the dump data of the
6132
7062
        return TRUE;
6133
7063
}
6134
7064
 
 
7065
int
 
7066
parse_dump_level(char *str_dump_level)
 
7067
{
 
7068
        int i, ret = FALSE;
 
7069
        char *buf, *ptr;
 
7070
 
 
7071
        if (!(buf = strdup(str_dump_level))) {
 
7072
                MSG("Can't duplicate strings(%s).\n", str_dump_level);
 
7073
                return FALSE;
 
7074
        }
 
7075
        info->max_dump_level = 0;
 
7076
        info->num_dump_level = 0;
 
7077
        ptr = buf;
 
7078
        while(TRUE) {
 
7079
                ptr = strtok(ptr, ",");
 
7080
                if (!ptr)
 
7081
                        break;
 
7082
 
 
7083
                i = atoi(ptr);
 
7084
                if ((i < MIN_DUMP_LEVEL) || (MAX_DUMP_LEVEL < i)) {
 
7085
                        MSG("Dump_level(%d) is invalid.\n", i);
 
7086
                        goto out;
 
7087
                }
 
7088
                if (NUM_ARRAY_DUMP_LEVEL <= info->num_dump_level) {
 
7089
                        MSG("Dump_level is invalid.\n");
 
7090
                        goto out;
 
7091
                }
 
7092
                if (info->max_dump_level < i)
 
7093
                        info->max_dump_level = i;
 
7094
                if (info->num_dump_level == 0)
 
7095
                        info->dump_level = i;
 
7096
                info->array_dump_level[info->num_dump_level] = i;
 
7097
                info->num_dump_level++;
 
7098
                ptr = NULL;
 
7099
        }
 
7100
        ret = TRUE;
 
7101
out:
 
7102
        free(buf);
 
7103
 
 
7104
        return ret;
 
7105
}
 
7106
 
6135
7107
static struct option longopts[] = {
 
7108
        {"split", no_argument, NULL, 's'}, 
 
7109
        {"reassemble", no_argument, NULL, 'r'},
6136
7110
        {"xen-syms", required_argument, NULL, 'y'},
6137
7111
        {"xen-vmcoreinfo", required_argument, NULL, 'z'},
6138
7112
        {"xen_phys_start", required_argument, NULL, 'P'},
6139
7113
        {"message-level", required_argument, NULL, 'm'},
6140
7114
        {"vtop", required_argument, NULL, 'V'},
 
7115
        {"dump-dmesg", no_argument, NULL, 'M'}, 
6141
7116
        {"help", no_argument, NULL, 'h'},
6142
7117
        {0, 0, 0, 0}
6143
7118
};
6145
7120
int
6146
7121
main(int argc, char *argv[])
6147
7122
{
6148
 
        int opt, flag_debug = FALSE;
 
7123
        int i, opt, flag_debug = FALSE;
6149
7124
 
6150
7125
        if ((info = calloc(1, sizeof(struct DumpInfo))) == NULL) {
6151
7126
                ERRMSG("Can't allocate memory for the pagedesc cache. %s.\n",
6162
7137
 
6163
7138
        info->block_order = DEFAULT_ORDER;
6164
7139
        message_level = DEFAULT_MSG_LEVEL;
6165
 
        while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:RVvXx:", longopts,
 
7140
        while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:MRrsVvXx:", longopts,
6166
7141
            NULL)) != -1) {
6167
7142
                switch (opt) {
6168
7143
                case 'b':
6175
7150
                        flag_debug = TRUE;
6176
7151
                        break;
6177
7152
                case 'd':
6178
 
                        info->dump_level = atoi(optarg);
 
7153
                        if (!parse_dump_level(optarg))
 
7154
                                goto out;
6179
7155
                        break;
6180
7156
                case 'E':
6181
7157
                        info->flag_elf_dumpfile = 1;
6200
7176
                case 'm':
6201
7177
                        message_level = atoi(optarg);
6202
7178
                        break;
 
7179
                case 'M':
 
7180
                        info->flag_dmesg = 1;
 
7181
                        break;
6203
7182
                case 'P':
6204
7183
                        info->xen_phys_start = strtoul(optarg, NULL, 0);
6205
7184
                        break;
6206
7185
                case 'R':
6207
7186
                        info->flag_rearrange = 1;
6208
7187
                        break;
 
7188
                case 's':
 
7189
                        info->flag_split = 1;
 
7190
                        break;
 
7191
                case 'r':
 
7192
                        info->flag_reassemble = 1;
 
7193
                        break;
6209
7194
                case 'V':
6210
7195
                        info->vaddr_for_vtop = strtoul(optarg, NULL, 0);
6211
7196
                        break;
6290
7275
 
6291
7276
                MSG("\n");
6292
7277
                MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7278
        } else if (info->flag_reassemble) {
 
7279
                if (!check_param_for_reassembling_dumpfile(argc, argv)) {
 
7280
                        MSG("Commandline parameter is invalid.\n");
 
7281
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7282
                        goto out;
 
7283
                }
 
7284
                if (!reassemble_dumpfile())
 
7285
                        goto out;
 
7286
 
 
7287
                MSG("\n");
 
7288
                MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7289
        } else if (info->flag_dmesg) {
 
7290
                if (!check_param_for_creating_dumpfile(argc, argv)) {
 
7291
                        MSG("Commandline parameter is invalid.\n");
 
7292
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7293
                        goto out;
 
7294
                }
 
7295
                if (!dump_dmesg())
 
7296
                        goto out;
 
7297
 
 
7298
                MSG("\n");
 
7299
                MSG("The dmesg log is saved to %s.\n", info->name_dumpfile);
6293
7300
        } else {
6294
7301
                if (!check_param_for_creating_dumpfile(argc, argv)) {
6295
7302
                        MSG("Commandline parameter is invalid.\n");
6300
7307
                        goto out;
6301
7308
 
6302
7309
                MSG("\n");
6303
 
                MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7310
                if (info->flag_split) {
 
7311
                        MSG("The dumpfiles are saved to ");
 
7312
                        for (i = 0; i < info->num_dumpfile; i++) {
 
7313
                                if (i != (info->num_dumpfile - 1))
 
7314
                                        MSG("%s, ", SPLITTING_DUMPFILE(i));
 
7315
                                else
 
7316
                                        MSG("and %s.\n", SPLITTING_DUMPFILE(i));
 
7317
                        }
 
7318
                } else {
 
7319
                        MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7320
                }
6304
7321
        }
6305
7322
        retcd = COMPLETED;
6306
7323
out:
6318
7335
                close(info->fd_bitmap);
6319
7336
        if (info->pt_load_segments != NULL)
6320
7337
                free(info->pt_load_segments);
 
7338
        if (vt.node_online_map != NULL)
 
7339
                free(vt.node_online_map);
6321
7340
        if (info->mem_map_data != NULL)
6322
7341
                free(info->mem_map_data);
6323
7342
        if (info->dump_header != NULL)
6324
7343
                free(info->dump_header);
 
7344
        if (info->splitting_info != NULL)
 
7345
                free(info->splitting_info);
6325
7346
        if (info != NULL)
6326
7347
                free(info);
6327
7348