These functions are used to parse /proc/iomem code and get memory
ranges of specific type. They are implemented in kexec-tools and
borrowed here to get the crashkernel memory range. Since crashkernel
memory range should be excluded from dumpable memory ranges.

Signed-off-by: Baoquan He <b...@redhat.com>
---
 makedumpfile.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |  7 +++++
 2 files changed, 89 insertions(+)

diff --git a/makedumpfile.c b/makedumpfile.c
index 760bfd1..220570e 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -8980,6 +8980,88 @@ calculate_cyclic_buffer_size(void) {
        return TRUE;
 }
 
+
+
+//#define CRASH_RESERVED_MEM_NR   8
+struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
+int crash_reserved_mem_nr;
+
+/*
+ * iomem_for_each_line()
+ *
+ * Iterate over each line in the file returned by proc_iomem(). If match is
+ * NULL or if the line matches with our match-pattern then call the
+ * callback if non-NULL.
+ *
+ * Return the number of lines matched.
+ */
+int iomem_for_each_line(char *match,
+                             int (*callback)(void *data,
+                                             int nr,
+                                             char *str,
+                                             unsigned long base,
+                                             unsigned long length),
+                             void *data)
+{
+       const char iomem[] = "/proc/iomem";
+       char line[BUFSIZE_FGETS];
+       FILE *fp;
+       unsigned long long start, end, size;
+       char *str;
+       int consumed;
+       int count;
+       int nr = 0;
+
+       fp = fopen(iomem, "r");
+       if (!fp) {
+               ERRMSG("Cannot open %s\n", iomem);
+               exit(1);
+       }
+
+       while(fgets(line, sizeof(line), fp) != 0) {
+               count = sscanf(line, "%Lx-%Lx : %n", &start, &end, &consumed);
+               if (count != 2)
+                       continue;
+               str = line + consumed;
+               size = end - start + 1;
+               if (!match || memcmp(str, match, strlen(match)) == 0) {
+                       if (callback
+                           && callback(data, nr, str, start, size) < 0) {
+                               break;
+                       }
+                       nr++;
+               }
+       }
+
+       fclose(fp);
+
+       return nr;
+}
+
+static int crashkernel_mem_callback(void *data, int nr,
+                                          char *str,
+                                          unsigned long base,
+                                          unsigned long length)
+{
+        if (nr >= CRASH_RESERVED_MEM_NR)
+                return 1;
+
+        crash_reserved_mem[nr].start = base;
+        crash_reserved_mem[nr].end   = base + length - 1;
+        return 0;
+}
+
+int is_crashkernel_mem_reserved(void)
+{
+        int ret;
+
+        ret = iomem_for_each_line("Crash kernel\n",
+                                        crashkernel_mem_callback, NULL);
+        crash_reserved_mem_nr = ret;
+
+        return !!crash_reserved_mem_nr;
+}
+
 static struct option longopts[] = {
        {"split", no_argument, NULL, OPT_SPLIT},
        {"reassemble", no_argument, NULL, OPT_REASSEMBLE},
diff --git a/makedumpfile.h b/makedumpfile.h
index 9402f05..7ffa1ee 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1452,6 +1452,13 @@ extern struct array_table        array_table;
 extern struct number_table     number_table;
 extern struct srcfile_table    srcfile_table;
 
+struct memory_range {
+        unsigned long long start, end;
+};
+
+#define CRASH_RESERVED_MEM_NR   8
+struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
+int crash_reserved_mem_nr;
 
 int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size);
 int get_str_osrelease_from_vmlinux(void);
-- 
1.8.4.2


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to