As more complicated capsule kernel format occurs like zboot, where the compressed kernel is stored as a payload. The straight forward decompression can not meet the demand. So introducing a new image probe interface -- probe2, which reads in the kernel file and decides how to unfold the content by the method itself. The interface probe and probe2 can not coexist Signed-off-by: Pingfan Liu <piliu@xxxxxxxxxx> To: kexec@xxxxxxxxxxxxxxxxxxx Cc: horms@xxxxxxxxxxxx Cc: ardb@xxxxxxxxxx Cc: jeremy.linton@xxxxxxx --- kexec/kexec.c | 31 +++++++++++++++++++++++-------- kexec/kexec.h | 9 +++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/kexec/kexec.c b/kexec/kexec.c index d5e6dc0..5f75179 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -702,6 +702,9 @@ static int initialze_probe(const char *kern_fname, if (probe_type >= 0) return probe_type; + if (!file_type[0].probe) + goto type_probe2; + *kernel_fd = open(kern_fname, O_RDONLY); if (*kernel_fd == -1) { die("Failed to open file %s:%s\n", kern_fname, @@ -712,27 +715,39 @@ static int initialze_probe(const char *kern_fname, /* slurp in the input kernel */ *kernel_buf = slurp_decompress_file(kern_fname, kernel_size); probe_type = 0; + return probe_type; +type_probe2: + probe_type = 1; return probe_type; } static int probe(struct file_type *ft, const char *kern_fname, char **kernel_buf, off_t *kernel_size, int *kernel_fd) { + struct parsed_info info; int ret; - initialze_probe(kern_fname, kernel_buf, kernel_size, kernel_fd); + ret = initialze_probe(kern_fname, kernel_buf, kernel_size, kernel_fd); + if (ret == 0) { #ifdef __aarch64__ - /* handle Image.gz like cases */ - if (is_zlib_file(kern_fname, &kernel_size)) { - if ((ret = ft->probe(kern_fname, *kernel_size)) >= 0) - *kernel_fd = ret; - } else { - ret = ft->probe(*kernel_buf, *kernel_size); - } + /* handle Image.gz like cases */ + if (is_zlib_file(kern_fname, &kernel_size)) { + if ((ret = ft->probe(kern_fname, *kernel_size)) >= 0) + *kernel_fd = ret; + } else { + ret = ft->probe(*kernel_buf, *kernel_size); + } #else ret = ft->probe(*kernel_buf, *kernel_size); #endif + } else if (ret == 1) { + ret = ft->probe2(kern_fname, &info); + *kernel_buf = info.kernel_buf; + *kernel_size = info.kernel_size; + *kernel_fd = info.fd; + } + return ret; } diff --git a/kexec/kexec.h b/kexec/kexec.h index 0d820ad..fbeee3d 100644 --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -176,6 +176,12 @@ struct arch_map_entry { unsigned long arch; }; +struct parsed_info { + char *kernel_buf; + off_t kernel_size; + int fd; +}; + extern const struct arch_map_entry arches[]; long physical_arch(void); @@ -192,6 +198,7 @@ unsigned long locate_hole(struct kexec_info *info, int hole_end); typedef int (probe_t)(const char *kernel_buf, off_t kernel_size); +typedef int (probe2_t)(const char *kern_fname, struct parsed_info *info); typedef int (load_t )(int argc, char **argv, const char *kernel_buf, off_t kernel_size, struct kexec_info *info); @@ -201,6 +208,8 @@ struct file_type { probe_t *probe; load_t *load; usage_t *usage; + /* Keep it as the last one so that by default it is NULL */ + probe2_t *probe2; }; extern struct file_type file_type[]; -- 2.31.1 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec