[PATCH v1] kexec-tools/s390: add --reuseinitrd support

Joseph Cathcart <[email protected]>
Newsgroups org.infradead.lists.kexec
Message-ID <[email protected]>
Currently, the --reuseinitrd param is not supported on s390. This
prevents testing kexec in environments such as virtme-ng, which by
default does not store the initrd on disk.

When --reuseinitrd is specified, add retained initrd memory range to
memory_range[] and fill new kernel parmarea directly with retained
initrd base and size, rather than memory range of a new ramdisk.

Add die() cases for trying to use --reuseinitrd flag in addition to
--ramdisk or --initrd, and for using --kexec-file-syscall instead of
--kexec-syscall while trying to use --reuseinitrd.

Signed-off-by: Joseph Cathcart <[email protected]>
---

Depends on: https://lore.kernel.org/linux-s390/[email protected]/T/#u

 kexec/arch/s390/Makefile      |  2 ++
 kexec/arch/s390/kexec-image.c | 11 ++++++++++-
 kexec/arch/s390/kexec-s390.c  | 17 +++++++++++++++--
 kexec/arch/s390/kexec-s390.h  |  2 ++
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/kexec/arch/s390/Makefile b/kexec/arch/s390/Makefile
index fab3e68..17f9dc8 100644
--- a/kexec/arch/s390/Makefile
+++ b/kexec/arch/s390/Makefile
@@ -6,6 +6,8 @@ s390_KEXEC_SRCS += kexec/arch/s390/kexec-image.c
 s390_KEXEC_SRCS += kexec/arch/s390/kexec-elf-rel-s390.c
 s390_KEXEC_SRCS += kexec/arch/s390/crashdump-s390.c
 
+s390_ARCH_REUSE_INITRD =
+
 dist += kexec/arch/s390/Makefile $(s390_KEXEC_SRCS)			\
 	kexec/arch/s390/kexec-s390.h					\
 	kexec/arch/s390/include/arch/options.h
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
index 69aaf96..1a59a32 100644
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -78,6 +78,9 @@ int image_s390_load_file(int argc, char **argv, struct kexec_info *info)
 		}
 	}
 
+	if (reuse_initrd)
+		die("--reuseinitrd not supported with --kexec-file-syscall. Please use --kexec-syscall\n");
+
 	if (ramdisk) {
 		info->initrd_fd = open(ramdisk, O_RDONLY);
 		if (info->initrd_fd == -1) {
@@ -104,7 +107,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
 	char *rd_buffer;
 	const char *ramdisk;
 	off_t ramdisk_len;
-	unsigned int ramdisk_origin;
+	unsigned long long ramdisk_origin;
 	int opt, ret = -1;
 
 	if (info->file_mode)
@@ -137,6 +140,9 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
 		}
 	}
 
+	if (ramdisk && reuse_initrd)
+		die("Can't specify --ramdisk or --initrd with --reuseinitrd\n");
+
 	if (info->kexec_flags & KEXEC_ON_CRASH) {
 		if (parse_iomem_single("Crash kernel\n", &crash_base,
 				       &crash_end))
@@ -165,6 +171,9 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
 		ramdisk_origin = _ALIGN_UP(ramdisk_origin, 0x100000);
 		add_segment_check(info, rd_buffer, ramdisk_len,
 				  ramdisk_origin, ramdisk_len);
+	} else if (reuse_initrd) {
+		ramdisk_origin = retained_initrd_base;
+		ramdisk_len = retained_initrd_size;
 	}
 	if (info->kexec_flags & KEXEC_ON_CRASH) {
 		if (load_crashdump_segments(info, crash_base, crash_end))
diff --git a/kexec/arch/s390/kexec-s390.c b/kexec/arch/s390/kexec-s390.c
index 86c9fb8..4e77fc4 100644
--- a/kexec/arch/s390/kexec-s390.c
+++ b/kexec/arch/s390/kexec-s390.c
@@ -25,6 +25,13 @@
 #include <arch/options.h>
 
 static struct memory_range memory_range[MAX_MEMORY_RANGES];
+unsigned long long retained_initrd_base, retained_initrd_size;
+unsigned int reuse_initrd = 0;
+
+void arch_reuse_initrd(void)
+{
+	reuse_initrd = 1;
+}
 
 /*
  * Read string from file
@@ -151,6 +158,7 @@ int get_memory_ranges_s390(struct memory_range memory_range[], int *ranges,
 {
 	char crash_kernel[] = "Crash kernel\n";
 	char sys_ram[] = "System RAM\n";
+	char kernel_initrd[] = "initrd\n";
 	const char *iomem = proc_iomem();
 	FILE *fp;
 	char line[80];
@@ -174,11 +182,16 @@ int get_memory_ranges_s390(struct memory_range memory_range[], int *ranges,
 		sscanf(line,"%llx-%llx : %n", &start, &end, &cons);
 		str = line+cons;
 		if ((memcmp(str, sys_ram, strlen(sys_ram)) == 0) ||
-		    ((memcmp(str, crash_kernel, strlen(crash_kernel)) == 0) &&
-		     with_crashk)) {
+			((memcmp(str, kernel_initrd, strlen(kernel_initrd)) == 0) && reuse_initrd) ||
+			((memcmp(str, crash_kernel, strlen(crash_kernel)) == 0) && with_crashk)) {
 			memory_range[current_range].start = start;
 			memory_range[current_range].end = end;
 			memory_range[current_range].type = RANGE_RAM;
+			if (memcmp(str, kernel_initrd, strlen(kernel_initrd)) == 0) {
+				retained_initrd_base = start;
+				retained_initrd_size = end - start + 1;
+			}
+
 			current_range++;
 		}
 		else {
diff --git a/kexec/arch/s390/kexec-s390.h b/kexec/arch/s390/kexec-s390.h
index 6a99518..a990739 100644
--- a/kexec/arch/s390/kexec-s390.h
+++ b/kexec/arch/s390/kexec-s390.h
@@ -34,5 +34,7 @@ extern int load_crashdump_segments(struct kexec_info *info,
 extern int get_memory_ranges_s390(struct memory_range range[], int *ranges,
 				  int with_crashk);
 extern int command_line_add(struct kexec_info *info, const char *str);
+extern unsigned long long retained_initrd_base, retained_initrd_size;
+extern unsigned int reuse_initrd;
 
 #endif /* KEXEC_S390_H */
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.