kexec-tools ppc64: add --reuseinitrd option
Subsystems (2)
PATCH 1/1 kexec-tools ppc64: add --reuseinitrd option
Add a --reuseinitrd option so that initrds saved using the retain_initrd kernel option can be reused on the kexec boot.
---
Horms: applies on top of my recent cleanup patch
kexec/arch/ppc64/fs2dt.c | 23 +++++++++++++++++------ kexec/arch/ppc64/kexec-elf-ppc64.c | 6 ++++++ kexec/arch/ppc64/kexec-ppc64.c | 1 + kexec/arch/ppc64/kexec-ppc64.h | 1 + 4 files changed, 25 insertions(+), 6 deletions(-)
kexec/arch/ppc64/fs2dt.c +17 -6
@@ -68,9 +68,9 @@ void reserve(unsigned long long where, u/* look for properties we need to reserve memory space for */ static void checkprop (char *name,unsigned *data) { -static unsigned long long base, size; +static unsigned long long base, size, end; -if ((data ==NULL ) && (base || size)) +if ((data ==NULL ) && (base || size || end))die ("unrecoverable error: no property data" );else if (!strcmp (name,"linux,rtas-base" )) base = *data;
@@ -79,11 +79,21 @@ static void checkprop(char *name, unsignelse if (!strcmp (name,"rtas-size" ) || !strcmp (name,"linux,tce-size" )) size = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-start" )) + base = *(unsigned long long *) data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-end" )) + end = *(unsigned long long *) data; +if (size && end) +die ("unrecoverable error: size and end set at same time\n" );if (base && size) {reserve (base, size); base = size =0 ; } +if (base && end) { +reserve (base, end-base); + base = end =0 ; + } }/*
@@ -213,10 +223,11 @@ static void putprops(char *fn, struct dicontinue ;/* This property will be created/modified later in putnode() -* So ignore it. +* So ignore it, unless we are reusing the initrd. */ -if (!strcmp (dp->d_name,"linux,initrd-start" ) || - !strcmp (dp->d_name,"linux,initrd-end" )) +if ((!strcmp (dp->d_name,"linux,initrd-start" ) || + !strcmp (dp->d_name,"linux,initrd-end" )) && + !reuse_initrd)continue ;if (!S_ISREG (statbuf.st_mode))
@@ -343,7 +354,7 @@ static void putnode(void)putprops (dn, namelist, numlist);/* Add initrd entries to the second kernel */ -if (initrd_base && !strcmp (basename,"/chosen/" )) { +if (initrd_base && !strcmp (basename,"/chosen/" ) && !reuse_initrd) {int len =8 ;unsigned long long initrd_end; *dt++ =3 ;
kexec/arch/ppc64/kexec-elf-ppc64.c +6 -0
@@ -43,6 +43,7 @@#define BOOTLOADER_VERSION VERSIONunsigned long initrd_base, initrd_size; +unsigned char reuse_initrd =0 ;int create_flatten_tree (struct kexec_info *,unsigned char **,unsigned long *,char *);
@@ -95,6 +96,7 @@ int elf_ppc64_load(int argc, char **argv#define OPT_RAMDISK (OPT_ARCH_MAX+1)#define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2)#define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) +#define OPT_REUSE_INITRD (OPT_ARCH_MAX+4)static const struct option options[] = {KEXEC_ARCH_OPTIONS
@@ -104,6 +106,7 @@ int elf_ppc64_load(int argc, char **argv { "initrd", 1, NULL, OPT_RAMDISK }, { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, + { "reuseinitrd", 0, NULL, OPT_REUSE_INITRD }, { 0, 0, NULL, 0 }, };
@@ -139,6 +142,9 @@ int elf_ppc64_load(int argc, char **argvbreak ;case OPT_ARGS_IGNORE :break ; +case OPT_REUSE_INITRD : + reuse_initrd =1 ; +break ; } }
kexec/arch/ppc64/kexec-ppc64.c +1 -0
@@ -635,6 +635,7 @@ void arch_usage(void)fprintf (stderr," --ramdisk=<filename> Initial RAM disk.\n" );fprintf (stderr," --initrd=<filename> same as --ramdisk.\n" );fprintf (stderr," --devicetreeblob=<filename> Specify device tree blob file.\n" ); +fprintf (stderr," --reuseinitrd Reuse the current initrd in memory.\n" );fprintf (stderr," --elf64-core-headers Prepare core headers in ELF64 format\n" ); }
kexec/arch/ppc64/kexec-ppc64.h +1 -0
@@ -16,6 +16,7 @@ void reserve(unsigned long long where, uextern unsigned long initrd_base, initrd_size;extern int max_memory_ranges; +extern unsigned char reuse_initrd;/* boot block version 2 as defined by the linux kernel */ struct bootblock {
PATCH 1/1 kexec-tools ppc64: add --reuseinitrd option
Add a --reuseinitrd option so that initrds saved using the retain_initrd kernel option can be reused on the kexec boot.
---
Horms: This fixes comments from Milton. Also adds sanity checks to make sure the old initrd was retained, and that another initrd/ramdisk is not being specified at the same time.
fastboot is dead... love live kexec! Yay :-)
kexec/arch/ppc64/fs2dt.c | 36 +++++++++++++++++++++++++++--------- kexec/arch/ppc64/kexec-elf-ppc64.c | 9 +++++++++ kexec/arch/ppc64/kexec-ppc64.c | 1 + kexec/arch/ppc64/kexec-ppc64.h | 1 + 4 files changed, 38 insertions(+), 9 deletions(-)
kexec/arch/ppc64/fs2dt.c +27 -9
@@ -66,11 +66,11 @@ void reserve(unsigned long long where, u }/* look for properties we need to reserve memory space for */ -static void checkprop (char *name,unsigned *data) +static void checkprop (char *name,unsigned *data,int len) { -static unsigned long long base, size; +static unsigned long long base, size, end; -if ((data ==NULL ) && (base || size)) +if ((data ==NULL ) && (base || size || end))die ("unrecoverable error: no property data" );else if (!strcmp (name,"linux,rtas-base" )) base = *data;
@@ -79,11 +79,24 @@ static void checkprop(char *name, unsignelse if (!strcmp (name,"rtas-size" ) || !strcmp (name,"linux,tce-size" )) size = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-start" )) +if (len ==8 ) + base = *(unsigned long long *) data; +else + base = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-end" )) + end = *(unsigned long long *) data; +if (size && end) +die ("unrecoverable error: size and end set at same time\n" );if (base && size) {reserve (base, size); base = size =0 ; } +if (base && end) { +reserve (base, end-base); + base = end =0 ; + } }/*
@@ -213,10 +226,11 @@ static void putprops(char *fn, struct dicontinue ;/* This property will be created/modified later in putnode() -* So ignore it. +* So ignore it, unless we are reusing the initrd. */ -if (!strcmp (dp->d_name,"linux,initrd-start" ) || - !strcmp (dp->d_name,"linux,initrd-end" )) +if ((!strcmp (dp->d_name,"linux,initrd-start" ) || + !strcmp (dp->d_name,"linux,initrd-end" )) && + !reuse_initrd)continue ;if (!S_ISREG (statbuf.st_mode))
@@ -241,7 +255,7 @@ static void putprops(char *fn, struct didie ("unrecoverable error: could not read \"%s\": %s\n" , pathname,strerror (errno)); -checkprop (fn, dt); +checkprop (fn, dt, len);/* Get the cmdline from the device-tree and modify it */ if (!strcmp (dp->d_name,"bootargs" )) {
@@ -249,6 +263,10 @@ static void putprops(char *fn, struct dichar temp_cmdline[COMMAND_LINE_SIZE ] = {"" };char *param =NULL ; cmd_len =strlen (local_cmdline); +if (reuse_initrd && + (strstr ((char *)dt,"retain_initrd" ) ==NULL )) +die ("unrecoverable error: current boot didn't " +"retain the initrd for reuse.\n" );if (cmd_len !=0 ) { param =strstr (local_cmdline,"crashkernel=" );if (param)
@@ -282,7 +300,7 @@ static void putprops(char *fn, struct di } fn[0 ] ='\0' ; -checkprop (pathname,NULL ); +checkprop (pathname,NULL ,0 ); }/*
@@ -343,7 +361,7 @@ static void putnode(void)putprops (dn, namelist, numlist);/* Add initrd entries to the second kernel */ -if (initrd_base && !strcmp (basename,"/chosen/" )) { +if (initrd_base && !strcmp (basename,"/chosen/" ) && !reuse_initrd) {int len =8 ;unsigned long long initrd_end; *dt++ =3 ;
kexec/arch/ppc64/kexec-elf-ppc64.c +9 -0
@@ -43,6 +43,7 @@#define BOOTLOADER_VERSION VERSIONunsigned long initrd_base, initrd_size; +unsigned char reuse_initrd =0 ;int create_flatten_tree (struct kexec_info *,unsigned char **,unsigned long *,char *);
@@ -95,6 +96,7 @@ int elf_ppc64_load(int argc, char **argv#define OPT_RAMDISK (OPT_ARCH_MAX+1)#define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2)#define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) +#define OPT_REUSE_INITRD (OPT_ARCH_MAX+4)static const struct option options[] = {KEXEC_ARCH_OPTIONS
@@ -104,6 +106,7 @@ int elf_ppc64_load(int argc, char **argv { "initrd", 1, NULL, OPT_RAMDISK }, { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, + { "reuseinitrd", 0, NULL, OPT_REUSE_INITRD }, { 0, 0, NULL, 0 }, };
@@ -139,6 +142,9 @@ int elf_ppc64_load(int argc, char **argvbreak ;case OPT_ARGS_IGNORE :break ; +case OPT_REUSE_INITRD : + reuse_initrd =1 ; +break ; } }
@@ -148,6 +154,9 @@ int elf_ppc64_load(int argc, char **argvelse fprintf (stdout,"Warning: append= option is not passed. Using the first kernel root partition\n" ); +if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with --reuseinitrd\n" ); +setup_memory_ranges (info->kexec_flags);/* Need to append some command line parameters internally in case of
kexec/arch/ppc64/kexec-ppc64.c +1 -0
@@ -635,6 +635,7 @@ void arch_usage(void)fprintf (stderr," --ramdisk=<filename> Initial RAM disk.\n" );fprintf (stderr," --initrd=<filename> same as --ramdisk.\n" );fprintf (stderr," --devicetreeblob=<filename> Specify device tree blob file.\n" ); +fprintf (stderr," --reuseinitrd Reuse the current initrd in memory.\n" );fprintf (stderr," --elf64-core-headers Prepare core headers in ELF64 format\n" ); }
kexec/arch/ppc64/kexec-ppc64.h +1 -0
@@ -16,6 +16,7 @@ void reserve(unsigned long long where, uextern unsigned long initrd_base, initrd_size;extern int max_memory_ranges; +extern unsigned char reuse_initrd;/* boot block version 2 as defined by the linux kernel */ struct bootblock {
Quoted 20 lines · Michael Neuling
Add a --reuseinitrd option so that initrds saved using the
retain_initrdkernel option can be reused on the kexec boot.Signed-off-by Michael Neuling <[email protected]>---
Horms: This fixes comments from Milton. Also adds sanity checks to make
sure the old initrd was retained, and that another initrd/ramdisk is not
being specified at the same time.fastboot is dead... love live kexec! Yay :-)
kexec/arch/ppc64/fs2dt.c +1
-1-checkprop (fn, dt); +checkprop (fn, dt, len);/* Get the cmdline from the device-tree and modify it */ if (!strcmp (dp->d_name,"bootargs" )) {
kexec/arch/ppc64/fs2dt.c static void putprops(char *fn, struct di · line 269
Quoted 7 lines
kexec/arch/ppc64/fs2dt.c +4
-0@@ -249,6 +263,10 @@ static void putprops(char *fn, struct dichar temp_cmdline[COMMAND_LINE_SIZE ] = {"" };char *param =NULL ; cmd_len =strlen (local_cmdline); +if (reuse_initrd && + (strstr ((char *)dt,"retain_initrd" ) ==NULL )) +die ("unrecoverable error: current boot didn't " +"retain the initrd for reuse.\n" );
Although this seems efficent to look at what was in the device tree, I'd prefer we actually looked at /proc/cmdline when we parse the arg, so that we are sure to find what the kernel is actually using for the command line.
Besides it will be eaiser for other archs to copy the check.
Quoted 13 lines
kexec/arch/ppc64/fs2dt.c +1
-1if (cmd_len !=0 ) { param =strstr (local_cmdline,"crashkernel=" );if (param)@@ -282,7 +300,7 @@ static void putprops(char *fn, struct di } fn[0 ] ='\0' ; -checkprop (pathname,NULL ); +checkprop (pathname,NULL ,0 ); }/*
kexec/arch/ppc64/fs2dt.c static void putnode(void) · line 364
Quoted 5 lines
kexec/arch/ppc64/fs2dt.c +1
-1@@ -343,7 +361,7 @@ static void putnode(void)putprops (dn, namelist, numlist);/* Add initrd entries to the second kernel */ -if (initrd_base && !strcmp (basename,"/chosen/" )) { +if (initrd_base && !strcmp (basename,"/chosen/" ) && !reuse_initrd) {
How does initrd_base get set if you disallow --initrd= ?
kexec/arch/ppc64/kexec-elf-ppc64.c int elf_ppc64_load(int argc, char **argv · line 160
Quoted 9 lines
kexec/arch/ppc64/kexec-elf-ppc64.c +3
-0@@ -148,6 +154,9 @@ int elf_ppc64_load(int argc, char **argv else fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n"); + if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with --reuseinitrd\n" ); +
This check is generic, not elf specific, so it should be where we pass the args. Hmm, maybe this is that place and it just wants abstracting, I don't have the tree in front of me.
Quoted 4 lines
kexec/arch/ppc64/kexec-elf-ppc64.c +0
-0setup_memory_ranges (info->kexec_flags);/* Need to append some command line parameters internally in case of
milton
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Quoted 36 lines · In message <[email protected]> you wrote:
Quoted 20 lines · Michael Neuling
Add a --reuseinitrd option so that initrds saved using the
retain_initrdkernel option can be reused on the kexec boot.Signed-off-by Michael Neuling <[email protected]>---
Horms: This fixes comments from Milton. Also adds sanity checks to make
sure the old initrd was retained, and that another initrd/ramdisk is not
being specified at the same time.fastboot is dead... love live kexec! Yay :-)
kexec/arch/ppc64/fs2dt.c +1
-1-checkprop (fn, dt); +checkprop (fn, dt, len);/* Get the cmdline from the device-tree and modify it */ if (!strcmp (dp->d_name,"bootargs" )) {kexec/arch/ppc64/fs2dt.c static void putprops(char *fn, struct di · line 269
Quoted 7 lines
kexec/arch/ppc64/fs2dt.c +4
-0@@ -249,6 +263,10 @@ static void putprops(char *fn, struct dichar temp_cmdline[COMMAND_LINE_SIZE ] = {"" };char *param =NULL ; cmd_len =strlen (local_cmdline); +if (reuse_initrd && + (strstr ((char *)dt,"retain_initrd" ) ==NULL )) +die ("unrecoverable error: current boot didn't " +"retain the initrd for reuse.\n" );Although this seems efficent to look at what was in the device tree, I'd prefer we actually looked at
/proc/cmdlinewhen we parse the arg, so that we are sure to find what the kernel is actually using for the command line.
Quoted 1 line
Besides it will be eaiser for other archs to copy the check.
Looks like we should make it a generic option. If we do, this should probably be two patches. One to introduce the option, and one for the ppc64 specific parts.
Do any of the other architectures allow you to see where the initrd is located for the current boot from user space? If not, the option will need to take two parameters saying where the retained initrd is. This will make the option less generic (if not, we'll need to change the other archs to export these values to user space).
Quoted 5 lines
kexec/arch/ppc64/fs2dt.c static void putnode(void) · line 364
Quoted 3 lines
kexec/arch/ppc64/fs2dt.c +1
-1/* Add initrd entries to the second kernel */ -if (initrd_base && !strcmp (basename,"/chosen/" )) { +if (initrd_base && !strcmp (basename,"/chosen/" ) && !reuse_initrd) {How does
initrd_baseget set if you disallow --initrd= ?
Oops, that's left over crud. Thanks.
When using this option, the initrd entries get imported from the first kernel, rather than being generated here.
Quoted 5 lines
Review int elf_ppc64_load(int argc, char **argv · line 155
Quoted 5 lines
(quoted diff) +0
-0@@ -148,6 +154,9 @@ int elf_ppc64_load(int argc, char **argv else fprintf(stdout, "Warning: append= option is not passed. Using t
he
Quoted 4 lines
kexec/arch/ppc64/kexec-elf-ppc64.c int elf_ppc64_load(int argc, char **argv
Quoted 4 lines
kexec/arch/ppc64/kexec-elf-ppc64.c +2
-0first kernel root partition\n"); +if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with --reuseinitrd\n" )
;
Quoted 5 lines
kexec/arch/ppc64/kexec-elf-ppc64.c int elf_ppc64_load(int argc, char **argv · line 159
Quoted 1 line
kexec/arch/ppc64/kexec-elf-ppc64.c +1
-0+This check is generic, not elf specific, so it should be where we pass the args. Hmm, maybe this is that place and it just wants abstracting, I don't have the tree in front of me.
I put it here so the error's caught independent of the arg parsing order. Otherwise, we'd need to duplicate the check.
I think it's the right place, unless we move it to an arch generic option.
Mikey
Quoted 16 lines · Michael Neuling
Quoted 10 lines · In message <[email protected]> you wrote:
Quoted 2 lines · Michael Neuling
Add a --reuseinitrd option so that initrds saved using the
retain_initrdkernel option can be reused on the kexec boot.Although this seems efficent to look at what was in the device tree, I'd prefer we actually looked at
/proc/cmdlinewhen we parse the arg, so that we are sure to find what the kernel is actually using for the command line.Besides it will be eaiser for other archs to copy the check.
Looks like we should make it a generic option. If we do, this should probably be two patches. One to introduce the option, and one for the ppc64 specific parts.
Quoted 5 lines
Do any of the other architectures allow you to see where the initrd is located for the current boot from user space? If not, the option will need to take two parameters saying where the retained initrd is. This will make the option less generic (if not, we'll need to change the other archs to export these values to user space).
Since we just added the option to the kernel, I'm guessing not. Most of them use /proc/iomem with resources for finding system ram, the kernel text and crash kernel region, so they should probably add a resource there when the initrd is retained. We (powerpc) export our bootloader data aka device tree instead, and make kexec-tools parse it. I don't know how sparc passes an initrd to the kernel.
Quoted 15 lines
Quoted 3 lines
Review int elf_ppc64_load(int argc, char **argv · line 155
Quoted 3 lines
(quoted diff) +0
-0@@ -148,6 +154,9 @@ int elf_ppc64_load(int argc, char **argv else fprintf(stdout, "Warning: append= option is not passed. Using the
Quoted 4 lines
kexec/arch/ppc64/kexec-elf-ppc64.c int elf_ppc64_load(int argc, char **argv
Quoted 4 lines
kexec/arch/ppc64/kexec-elf-ppc64.c +2
-0first kernel root partition\n"); +if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with --reuseinitrd\n" );
Quoted 5 lines
kexec/arch/ppc64/kexec-elf-ppc64.c int elf_ppc64_load(int argc, char **argv · line 159
Quoted 1 line
kexec/arch/ppc64/kexec-elf-ppc64.c +1
-0+This check is generic, not elf specific, so it should be where we pass the args. Hmm, maybe this is that place and it just wants abstracting, I don't have the tree in front of me.
Quoted 5 lines
I put it here so the error's caught independent of the arg parsing order. Otherwise, we'd need to duplicate the check.
I think it's the right place, unless we move it to an arch generic option.
I didn't mean as we parse the option, but is there not something
that gets called after we parse all the options? Maybe that is
just the load function. I was just thinking it should be in asanity_check_args() function that looks for exclusive options like these rather than in "load a kernel like elf file", although that is the only current option for ppc64, so it might be ok here.
milton
PATCH 1/2 kexec: Added generic --reuseinitrd option
In reply to Michael NeulingAdds a generic --reuseinitrd option and performs some sanity checks on it. Can be used with the retain_initrd kernel option.
---
This series attempts to address some of Milton's concerns.
kexec/kexec.c | 33 +++++++++++++++++++++++++++++++++ kexec/kexec.h | 2 ++ 2 files changed, 35 insertions(+)
kexec/kexec.c +33 -0
@@ -748,6 +748,7 @@ void usage(void)" load code into.\n" " --mem-max=<addr> Specify the highest memory address to\n" " load code into.\n" +" --reuseinird Reuse initrd from first boot.\n" "\n" "Supported kernel file types and options: \n");for (i =0 ; i < file_types; i++) {
@@ -772,6 +773,29 @@ static int kexec_loaded(void)return ret; } +/* check we retained the initrd */ +void check_reuse_initrd (void ) +{ +FILE * fp; +char * line =NULL ; +size_t len =0 ; +ssize_t read; + + fp =fopen ("/proc/cmdline" ,"r" ); +if (fp ==NULL ) +die ("unable to open /proc/cmdline\n" ); + read =getline (&line, &len, fp); +if (strstr (line,"retain_initrd" ) ==NULL ) +die ("unrecoverable error: current boot didn't " +"retain the initrd for reuse.\n" ); +} + +/* Arch hook for reuse_initrd */ +void __attribute__((weak))arch_reuse_initrd (void ) +{ +die ("--reuseinitrd not implemented on this architecture\n" ); +} +int main (int argc,char *argv[]) {int do_load =1 ;
@@ -780,6 +804,7 @@ int main(int argc, char *argv[])int do_sync =1 ;int do_ifdown =0 ;int do_unload =0 ; +int do_reuse_initrd =0 ;unsigned long kexec_flags =0 ;char *type =0 ;char *endptr;
@@ -860,6 +885,9 @@ int main(int argc, char *argv[])return 1 ; }break ; +case OPT_REUSE_INITRD : + do_reuse_initrd =1 ; +break ;default :break ; }
@@ -890,6 +918,11 @@ int main(int argc, char *argv[]) } } +if (do_reuse_initrd){ +check_reuse_initrd (); +arch_reuse_initrd (); + } +if (do_unload) { result =k_unload (kexec_flags); }
kexec/kexec.h +2 -0
@@ -163,6 +163,7 @@ extern int file_types;#define OPT_MEM_MIN 256#define OPT_MEM_MAX 257#define OPT_MAX 258 +#define OPT_REUSE_INITRD 259#define KEXEC_OPTIONS \ { "help", 0, 0, OPT_HELP }, \ { "version", 0, 0, OPT_VERSION }, \
@@ -175,6 +176,7 @@ extern int file_types; { "load-panic", 0, 0, OPT_PANIC }, \ { "mem-min", 1, 0, OPT_MEM_MIN }, \ { "mem-max", 1, 0, OPT_MEM_MAX }, \ + { "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \ #define KEXEC_OPT_STR "hvdfxluet:p"
PATCH 1/2 kexec: Added generic --reuseinitrd option
Adds a generic --reuseinitrd option and performs some sanity checks on it. Can be used with the retain_initrd kernel option.
---
This series reserves the memory region so kexec doesn't attempt to use it for something else. Noticed by Milton.
---
kexec/kexec.c | 33 +++++++++++++++++++++++++++++++++ kexec/kexec.h | 2 ++ 2 files changed, 35 insertions(+)
kexec/kexec.c +33 -0
@@ -748,6 +748,7 @@ void usage(void)" load code into.\n" " --mem-max=<addr> Specify the highest memory address to\n" " load code into.\n" +" --reuseinird Reuse initrd from first boot.\n" "\n" "Supported kernel file types and options: \n");for (i =0 ; i < file_types; i++) {
@@ -772,6 +773,29 @@ static int kexec_loaded(void)return ret; } +/* check we retained the initrd */ +void check_reuse_initrd (void ) +{ +FILE * fp; +char * line =NULL ; +size_t len =0 ; +ssize_t read; + + fp =fopen ("/proc/cmdline" ,"r" ); +if (fp ==NULL ) +die ("unable to open /proc/cmdline\n" ); + read =getline (&line, &len, fp); +if (strstr (line,"retain_initrd" ) ==NULL ) +die ("unrecoverable error: current boot didn't " +"retain the initrd for reuse.\n" ); +} + +/* Arch hook for reuse_initrd */ +void __attribute__((weak))arch_reuse_initrd (void ) +{ +die ("--reuseinitrd not implemented on this architecture\n" ); +} +int main (int argc,char *argv[]) {int do_load =1 ;
@@ -780,6 +804,7 @@ int main(int argc, char *argv[])int do_sync =1 ;int do_ifdown =0 ;int do_unload =0 ; +int do_reuse_initrd =0 ;unsigned long kexec_flags =0 ;char *type =0 ;char *endptr;
@@ -860,6 +885,9 @@ int main(int argc, char *argv[])return 1 ; }break ; +case OPT_REUSE_INITRD : + do_reuse_initrd =1 ; +break ;default :break ; }
@@ -890,6 +918,11 @@ int main(int argc, char *argv[]) } } +if (do_reuse_initrd){ +check_reuse_initrd (); +arch_reuse_initrd (); + } +if (do_unload) { result =k_unload (kexec_flags); }
kexec/kexec.h +2 -0
@@ -163,6 +163,7 @@ extern int file_types;#define OPT_MEM_MIN 256#define OPT_MEM_MAX 257#define OPT_MAX 258 +#define OPT_REUSE_INITRD 259#define KEXEC_OPTIONS \ { "help", 0, 0, OPT_HELP }, \ { "version", 0, 0, OPT_VERSION }, \
@@ -175,6 +176,7 @@ extern int file_types; { "load-panic", 0, 0, OPT_PANIC }, \ { "mem-min", 1, 0, OPT_MEM_MIN }, \ { "mem-max", 1, 0, OPT_MEM_MAX }, \ + { "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \ #define KEXEC_OPT_STR "hvdfxluet:p"
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
PATCH 2/2 kexec ppc64: Add arch specific --reuseinitrd hooks
Adds ppc64 specific hooks for the --reuseinitrd option.
---
kexec/arch/ppc64/fs2dt.c | 30 +++++++++++----- kexec/arch/ppc64/kexec-elf-ppc64.c | 12 +++++- kexec/arch/ppc64/kexec-ppc64.c | 69 +++++++++++++++++++++++++++++++++++++ kexec/arch/ppc64/kexec-ppc64.h | 1 4 files changed, 103 insertions(+), 9 deletions(-)
kexec/arch/ppc64/fs2dt.c +22 -8
@@ -66,11 +66,11 @@ void reserve(unsigned long long where, u }/* look for properties we need to reserve memory space for */ -static void checkprop (char *name,unsigned *data) +static void checkprop (char *name,unsigned *data,int len) { -static unsigned long long base, size; +static unsigned long long base, size, end; -if ((data ==NULL ) && (base || size)) +if ((data ==NULL ) && (base || size || end))die ("unrecoverable error: no property data" );else if (!strcmp (name,"linux,rtas-base" )) base = *data;
@@ -79,11 +79,24 @@ static void checkprop(char *name, unsignelse if (!strcmp (name,"rtas-size" ) || !strcmp (name,"linux,tce-size" )) size = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-start" )) +if (len ==8 ) + base = *(unsigned long long *) data; +else + base = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-end" )) + end = *(unsigned long long *) data; +if (size && end) +die ("unrecoverable error: size and end set at same time\n" );if (base && size) {reserve (base, size); base = size =0 ; } +if (base && end) { +reserve (base, end-base); + base = end =0 ; + } }/*
@@ -213,10 +226,11 @@ static void putprops(char *fn, struct dicontinue ;/* This property will be created/modified later in putnode() -* So ignore it. +* So ignore it, unless we are reusing the initrd. */ -if (!strcmp (dp->d_name,"linux,initrd-start" ) || - !strcmp (dp->d_name,"linux,initrd-end" )) +if ((!strcmp (dp->d_name,"linux,initrd-start" ) || + !strcmp (dp->d_name,"linux,initrd-end" )) && + !reuse_initrd)continue ;if (!S_ISREG (statbuf.st_mode))
@@ -241,7 +255,7 @@ static void putprops(char *fn, struct didie ("unrecoverable error: could not read \"%s\": %s\n" , pathname,strerror (errno)); -checkprop (fn, dt); +checkprop (fn, dt, len);/* Get the cmdline from the device-tree and modify it */ if (!strcmp (dp->d_name,"bootargs" )) {
@@ -282,7 +296,7 @@ static void putprops(char *fn, struct di } fn[0 ] ='\0' ; -checkprop (pathname,NULL ); +checkprop (pathname,NULL ,0 ); }/*
kexec/arch/ppc64/kexec-elf-ppc64.c +11 -1
@@ -43,6 +43,8 @@#define BOOTLOADER_VERSION VERSIONunsigned long initrd_base, initrd_size; +unsigned char reuse_initrd =0 ; +const char *ramdisk;int create_flatten_tree (struct kexec_info *,unsigned char **,unsigned long *,char *);
@@ -69,12 +71,17 @@ int elf_ppc64_probe(const char *buf, offreturn result; } +void arch_reuse_initrd (void ) +{ + reuse_initrd =1 ; +} +int elf_ppc64_load (int argc,char **argv,const char *buf,off_t len,struct kexec_info *info) {struct mem_ehdr ehdr;char *cmdline, *modified_cmdline; -const char *ramdisk, *devicetreeblob; +const char *devicetreeblob;int cmdline_len, modified_cmdline_len;unsigned long long max_addr, hole_addr;unsigned char *seg_buf =NULL ;
@@ -148,6 +155,9 @@ int elf_ppc64_load(int argc, char **argvelse fprintf (stdout,"Warning: append= option is not passed. Using the first kernel root partition\n" ); +if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with --reuseinitrd\n" ); +setup_memory_ranges (info->kexec_flags);/* Need to append some command line parameters internally in case of
kexec/arch/ppc64/kexec-ppc64.c +69 -0
93 lines not on this page · raw message
kexec/arch/ppc64/kexec-ppc64.h +1 -0
@@ -16,6 +16,7 @@ void reserve(unsigned long long where, uextern unsigned long initrd_base, initrd_size;extern int max_memory_ranges; +extern unsigned char reuse_initrd;/* boot block version 2 as defined by the linux kernel */ struct bootblock {
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH 1/2] kexec: Added generic --reuseinitrd option
In reply to Michael NeulingQuoted 2 lines · Michael Neuling
Adds a generic --reuseinitrd option and performs some sanity checks on it. Can be used with the
retain_initrdkernel option.
Thanks, I've applied both this and the following patch.
Signature · 9 lines
Horms H: http://www.vergenet.net/~horms/ W: http://www.valinux.co.jp/en/ _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH 2/2 kexec ppc64: Add arch specific --reuseinitrd hooks
In reply to Michael NeulingAdds ppc64 specific hooks for the --reuseinitrd option. --
kexec/arch/ppc64/fs2dt.c | 30 ++++++++++++++++++++++-------- kexec/arch/ppc64/kexec-elf-ppc64.c | 13 ++++++++++++- kexec/arch/ppc64/kexec-ppc64.h | 1 + 3 files changed, 35 insertions(+), 9 deletions(-)
kexec/arch/ppc64/fs2dt.c +22 -8
@@ -66,11 +66,11 @@ void reserve(unsigned long long where, u }/* look for properties we need to reserve memory space for */ -static void checkprop (char *name,unsigned *data) +static void checkprop (char *name,unsigned *data,int len) { -static unsigned long long base, size; +static unsigned long long base, size, end; -if ((data ==NULL ) && (base || size)) +if ((data ==NULL ) && (base || size || end))die ("unrecoverable error: no property data" );else if (!strcmp (name,"linux,rtas-base" )) base = *data;
@@ -79,11 +79,24 @@ static void checkprop(char *name, unsignelse if (!strcmp (name,"rtas-size" ) || !strcmp (name,"linux,tce-size" )) size = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-start" )) +if (len ==8 ) + base = *(unsigned long long *) data; +else + base = *data; +else if (reuse_initrd && !strcmp (name,"linux,initrd-end" )) + end = *(unsigned long long *) data; +if (size && end) +die ("unrecoverable error: size and end set at same time\n" );if (base && size) {reserve (base, size); base = size =0 ; } +if (base && end) { +reserve (base, end-base); + base = end =0 ; + } }/*
@@ -213,10 +226,11 @@ static void putprops(char *fn, struct dicontinue ;/* This property will be created/modified later in putnode() -* So ignore it. +* So ignore it, unless we are reusing the initrd. */ -if (!strcmp (dp->d_name,"linux,initrd-start" ) || - !strcmp (dp->d_name,"linux,initrd-end" )) +if ((!strcmp (dp->d_name,"linux,initrd-start" ) || + !strcmp (dp->d_name,"linux,initrd-end" )) && + !reuse_initrd)continue ;if (!S_ISREG (statbuf.st_mode))
@@ -241,7 +255,7 @@ static void putprops(char *fn, struct didie ("unrecoverable error: could not read \"%s\": %s\n" , pathname,strerror (errno)); -checkprop (fn, dt); +checkprop (fn, dt, len);/* Get the cmdline from the device-tree and modify it */ if (!strcmp (dp->d_name,"bootargs" )) {
@@ -282,7 +296,7 @@ static void putprops(char *fn, struct di } fn[0 ] ='\0' ; -checkprop (pathname,NULL ); +checkprop (pathname,NULL ,0 ); }/*
kexec/arch/ppc64/kexec-elf-ppc64.c +12 -1
@@ -43,6 +43,8 @@#define BOOTLOADER_VERSION VERSIONunsigned long initrd_base, initrd_size; +unsigned char reuse_initrd =0 ; +const char *ramdisk;int create_flatten_tree (struct kexec_info *,unsigned char **,unsigned long *,char *);
@@ -69,12 +71,17 @@ int elf_ppc64_probe(const char *buf, offreturn result; } +void arch_reuse_initrd (void ) +{ + reuse_initrd =1 ; +} +int elf_ppc64_load (int argc,char **argv,const char *buf,off_t len,struct kexec_info *info) {struct mem_ehdr ehdr;char *cmdline, *modified_cmdline; -const char *ramdisk, *devicetreeblob; +const char *devicetreeblob;int cmdline_len, modified_cmdline_len;unsigned long long max_addr, hole_addr;unsigned char *seg_buf =NULL ;
@@ -148,6 +155,10 @@ int elf_ppc64_load(int argc, char **argvelse fprintf (stdout,"Warning: append= option is not passed. Using the first kernel root partition\n" ); +if (ramdisk && reuse_initrd) +die ("Can't specify --ramdisk or --initrd with " +"--reuseinitrd\n" ); +setup_memory_ranges (info->kexec_flags);/* Need to append some command line parameters internally in case of
kexec/arch/ppc64/kexec-ppc64.h +1 -0
@@ -16,6 +16,7 @@ void reserve(unsigned long long where, uextern unsigned long initrd_base, initrd_size;extern int max_memory_ranges; +extern unsigned char reuse_initrd;/* boot block version 2 as defined by the linux kernel */ struct bootblock {