diff options
-rw-r--r-- | kexec/arch/ppc64/fs2dt.c | 51 | ||||
-rw-r--r-- | kexec/arch/ppc64/kexec-elf-ppc64.c | 2 |
2 files changed, 41 insertions, 12 deletions
diff --git a/kexec/arch/ppc64/fs2dt.c b/kexec/arch/ppc64/fs2dt.c index 5256bc0..00a4c82 100644 --- a/kexec/arch/ppc64/fs2dt.c +++ b/kexec/arch/ppc64/fs2dt.c @@ -192,13 +192,18 @@ void add_usable_mem_property(int fd, int len) } /* put all properties (files) in the property structure */ -void putprops(char *fn, DIR *dir) +void putprops(char *fn, struct dirent **nlist, int numlist) { struct dirent *dp; + int i = 0; - while ((dp = readdir(dir)) != NULL) { + for (i = 0; i < numlist; i++) { + dp = nlist[i]; strcpy(fn, dp->d_name); + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + if (lstat(pathname, statbuf)) err(pathname, ERR_STAT); @@ -239,6 +244,7 @@ void putprops(char *fn, DIR *dir) fd = open(pathname, O_RDONLY); if (fd == -1) err(pathname, ERR_OPEN); + if (read(fd, dt, len) != len) err(pathname, ERR_READ); @@ -255,7 +261,6 @@ void putprops(char *fn, DIR *dir) "crashkernel="); if (param) crash_param = 1; - param = NULL; param = strstr(local_cmdline, "root="); } if (!param) { @@ -293,15 +298,38 @@ void putprops(char *fn, DIR *dir) } /* + * Compare function used to sort the device-tree directories + * This function will be passed to scandir. + */ +int comparefunc(const void *dentry1, const void *dentry2) +{ + char *str1 = (*(struct dirent **)dentry1)->d_name; + char *str2 = (*(struct dirent **)dentry2)->d_name; + + /* + * strcmp scans from left to right and fails to idetify for some + * strings such as memory@10000000 and memory@f000000. + * Therefore, we get the wrong sorted order like memory@10000000 and + * memory@f000000. + */ + if (strchr(str1, '@') && strchr(str2, '@') && + (strlen(str1) > strlen(str2))) + return 1; + + return strcmp(str1, str2); +} + +/* * put a node (directory) in the property structure. first properties * then children. */ void putnode(void) { - DIR *dir; char *dn; struct dirent *dp; char *basename; + struct dirent **namelist; + int numlist, i; *dt++ = 1; strcpy((void *)dt, *pathstart ? pathstart : "/"); @@ -310,9 +338,8 @@ void putnode(void) if (dt[-1] & 0xff) dt++; - dir = opendir(pathname); - - if (!dir) + numlist = scandir(pathname, &namelist, 0, comparefunc); + if (numlist == 0) err(pathname, ERR_OPENDIR); basename = strrchr(pathname,'/'); @@ -320,7 +347,7 @@ void putnode(void) strcat(pathname, "/"); dn = pathname + strlen(pathname); - putprops(dn, dir); + putprops(dn, namelist, numlist); /* Add initrd entries to the second kernel if first kernel does not * have and second kernel needs. @@ -353,10 +380,10 @@ void putnode(void) reserve(initrd_base, initrd_size); } - rewinddir(dir); - - while ((dp = readdir(dir)) != NULL) { + for (i=0; i < numlist; i++) { + dp = namelist[i]; strcpy(dn, dp->d_name); + free(namelist[i]); if (!strcmp(dn, ".") || !strcmp(dn, "..")) continue; @@ -371,8 +398,8 @@ void putnode(void) err(pathname, ERR_READDIR); *dt++ = 2; - closedir(dir); dn[-1] = '\0'; + free(namelist); } int create_flatten_tree(struct kexec_info *info, unsigned char **bufp, diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c index 7a22683..cfdd76a 100644 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c @@ -144,6 +144,8 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, cmdline_len = 0; if (cmdline) cmdline_len = strlen(cmdline) + 1; + else + fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n"); setup_memory_ranges(info->kexec_flags); |