diff options
author | Anton Blanchard <anton@samba.org> | 2014-11-13 11:34:18 +1100 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2014-11-13 09:59:39 +0900 |
commit | bd2cfb7791d47ba697ec51edfc18bedc85252fe2 (patch) | |
tree | 111466607850158f9a50cf7fdc730846747228de | |
parent | fc231094d9c0b84802f195fc436bcb24b7b251d7 (diff) | |
download | kexec-tools-bd2cfb7791d47ba697ec51edfc18bedc85252fe2.tar.gz |
kexec/fs2dt: Fix sorting of device tree
Commit b02d735bf252 ('ppc64 kdump device_tree sort') added code to
sort device tree properties, but it had a few issues.
A compare routine needs to return -1 and 1. The special case for
sorting properties with unit addresses only returned 1 and ignored
the opposite case, which screwed up the sorting.
We were missing a few more things:
- Need to check both basenames are the same length
- Need to check both basenames match
I noticed this when looking at the NUMA topology after a kexec, and
it had shifted.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | kexec/fs2dt.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c index 1e5f074..304f6cb 100644 --- a/kexec/fs2dt.c +++ b/kexec/fs2dt.c @@ -479,6 +479,8 @@ static int comparefunc(const struct dirent **dentry1, { char *str1 = (*(struct dirent **)dentry1)->d_name; char *str2 = (*(struct dirent **)dentry2)->d_name; + char *sep1 = strchr(str1, '@'); + char *sep2 = strchr(str2, '@'); /* * strcmp scans from left to right and fails to idetify for some @@ -486,9 +488,20 @@ static int comparefunc(const struct dirent **dentry1, * Therefore, we get the wrong sorted order like memory@10000000 and * memory@f000000. */ - if (strchr(str1, '@') && strchr(str2, '@') && - (strlen(str1) > strlen(str2))) - return 1; + if (sep1 && sep2) { + int baselen1 = sep1 - str1; + int baselen2 = sep2 - str2; + int len1 = strlen(str1); + int len2 = strlen(str2); + + /* + * Check the base name matches, and the properties are + * different lengths. + */ + if ((baselen1 == baselen2) && (len1 != len2) && + !strncmp(str1, str2, baselen2)) + return (len1 > len2) - (len1 < len2); + } return strcmp(str1, str2); } |