In some environments, some files in scripts/mod (devicetable-offsets.s
and file2alias.o) are always getting rebuilt, and thus get incorrectly
added to the changed_objs file, resulting in the following error:
strip:/root/.kpatch/3.10.0-115.el7.x86_64/obj2/scripts/mod/devicetable-offsets.s: File format not recognized
The indexes are in order when being read from the
table. Just index directly into the table; a benefit
of using an array for this structure instead of a linked
list.
Removes another hot path during the rela table initialization.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
remove "ughs" by changing macro to start at symbol
index 1. new for_each_symbol_zero will start at zero
for rare cases that need it.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Upon realizing that there is no point in correlating rela entries,
I also realized that tracking the status of rela entries is also
not needed.
Additionally, the rela section correlation path (really misnamed
as it is the rela section _comparison path) is VERY hot. Particularly
on files like fs/ext4/ext4.o (which create-diff-object currently can't
successfully parse entirely):
Samples: 40K of event 'cycles', Event count (approx.): 36516578362
49.49% create-diff-obj create-diff-object [.] rela_equal
31.85% create-diff-obj create-diff-object [.] kpatch_correlate_relas
16.22% create-diff-obj create-diff-object [.] find_symbol_by_index
The refactor does a few things:
- replaces nested for loops with single for loop when comparing rela entries
- removes status field for rela entires
- compares rela and nonrela sections in the same path
- removes unnecessary setting of status fields as the inclusion tree
will include them even if the section status isn't set to CHANGED. This is
even better as unchanged sections won't appear as CHANGED just because
their partner .text or .rela section is CHANGED.
This drastically reduced runtime for larger objects and cooled the rela
comparison path:
87.64% create-diff-obj create-diff-object [.] find_symbol_by_index
6.98% create-diff-obj libc-2.18.so [.] __GI___strcmp_ssse3
1.33% create-diff-obj create-diff-object [.] find_section_by_index
1.16% create-diff-obj create-diff-object [.] kpatch_correlate_symbols
0.61% create-diff-obj create-diff-object [.] kpatch_create_rela_table
0.52% create-diff-obj create-diff-object [.] kpatch_correlate_sections
Signed-off-by: Seth Jennings <sjenning@redhat.com>
I've created a test designed to exercise the ability
of create-diff-object to parse, compare, and return
"no changed functions" for the entire kernel source
tree one file at a time by passing the same file as
both the original and patched file.
Through this process, I realized that excluding every
special case from being bundled it not feasible. There
are many sections in the kernel that don't honor
-ffunction|data-sections, not just __ksymtab_strings and
.init.text.
Plus, excluding situations is not the best way. We are
really only looking for sections that _were_ the result
of -f[function|data]-sections for bundling.
To that end, this commit looks to bundle only symbol/section
pairs that should be bundled ensuringthe .text/.data suffix
and the FUNC/OBJECT symbol name match.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
A local changed function will not appear with a "changed function"
notice if it is a dependency of another changed function and that
function occurs before it in the symbol table.
Rearrange some logic to print the notice regardless of whether or not
the function symbols has already been selected for inclusion.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
When linking function bundles (.text/.rela/section sym/func sym)
ignore __init functions as they do not honor -ffunction-sections
and violate the one-to-one func/section assumption of the
function bundling.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
In some circumstances, the kernel is built outside from the source tree,
thus we should specify the .config file of build path.
This patch changes the basic option parsing by using getopt, and add more
information in usage().
Signed-off-by: Jincheng Miao <jincheng.miao@gmail.com>
Create a new function kpatch_copy_symbols() that copies symbols from
one kelf to another if the "select" function to return true for the
symbol.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
ld drops FUNC syms that appear after the last SECTION
sym in the symbol table.
Make sure we order the FUNC syms before the SECTION syms.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Like in add-patches-section, we should continue to
search the vmlinux symbol table to see if there
is a duplicate global symbol. This normally would
not be possible, however, because create-diff-object
modifies unchanged local functions to be global
as a hack so they can be linked, there is a chance
that these symbols could collide with an existing
global symbol. We should detect this case and error
out.
Hopefully we can figure out a way to avoid this
situation altogether. But for now, this is a
protection against improper linking.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
My apologies for the size of this commit. I combined these two features
(updating API and using a hash table) into a single commit because their
implementations are tightly coupled and I didn't want to have to add
support for the old kpatch_funcs array with the new API just for the
sake of splitting up the commit :-)
- Update the core module API to get a more clear separation between core
module and patch module. This is cleaner and will help our case for
getting the core module merged upstream into the kernel.
- Convert the old kpatch_funcs array into a hash table. This is so much
nicer performance-wise and everything-else-wise than that ugly old
array.
- Do the incremental patching in stop machine. This ensures that the
funcs hash is up to date and we don't miss anything.
- Disable preemption in the ftrace handler when accessing the func hash.
That way we don't get conflicts with the stop_machine handler updating
the hash.
Currently, add-patches-section just blindly looks in vmlinux
for a function symbol matching the name of the patched function
in the input object file. However, for local symbols, they may
appear multiple times in the vmlinux symbol table since the symbol
name may be reused locally in different files.
This commit add support for "file hinting". It tracks what
file the symbol is in and searches for local symbols within
that file in vmlinux first. If it doesn't find one, it then
searches globally like it always has.
Fixes issue #53
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The current solution doesn't work because "$?" will always be 0, even if
there were no "CC" lines in the build log. Instead, just make sure the
changed_objs file isn't empty.
Add a patch testing step before compiling the kernel, so that users
don't have to wait for the kernel to compile before seeing if the patch
applies cleanly.
Also allow the printing of the patch command's stdout/stderr to make it
clear what files are being patched and whether there's any fuzz.
If the patch file fails to apply, it "corrupts" the cache by leaving the
old applied-patch file around. Fix that by always cleaning up after
ourselves.
Allow the user to supply a custom kernel source directory. This copies
the directory to ~/.kpatch/src instead of using it in place. Otherwise
the "make mrproper" (which is needed for compiling objects in a separate
tree) would modify the original source tree and remove its .config file.
There's currently no caching support for this option. If needed, we
could implement that pretty easily by calculating an md5sum of the
original source directory.
kpatch-build is outgrowing the kpatch script and probably is a better
fit as its own utility instead of being wrapped by kpatch. Install
kpatch-build into /usr/local/bin, remove the kpatch wrapper around it,
and update the README accordingly.
For a local object or function symbol, we expect that
the section offset, sym.st_value, be 0 because we used
-ffunction-sections and -fdata-section during compile.
If value != 0, it undermines assumptions we make and
should return an error. Exceptions should be handled
on a case by case basis, like __ksymtab_strings.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
In preparation for adding an automated test framework,
add an ability to create-object-diff that will create
a human readable list of included sections and symbols
with type and bind information so that the test framework
can compare against a known-good reference list with the
expected set of sections and symbols.
The file is created when the -i/--inventory option is
used. The inventory filename is the user supplied output
file name suffixed by .inventory
Signed-off-by: Seth Jennings <sjenning@redhat.com>
I'm tired of setting CFLAGS and people shouldn't have to
recompile to get debug output. This lays the foundations
proper option handling and logging levels.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
- Fixup debug messages
- Remove dead code
- No more DEPENDENCY state
- Reachability test is now the "Inclusion tree" for determining
which syms/sections will be included in the output
- 'reachable' field is now and 'include' and is the sole
consideration in including sections/symbols (no more complex
conditional checks)
- Order LOCAL before GLOBAL in the symbol table. Apparently, after
a FILE sym, all LOCAL symbols should precede GLOBAL syms or readelf
shows <corrupt>
- Handle __ksymtab_strings section and __ksymtab_* syms
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The kernel Makefile look for localversion in the source tree,
not the object tree. The absense from the source tree results
in a patch module that will not load because the kernel versions
don't match.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Setting KCFLAGS="-ffunction-sections -fdata-sections" causes make to
invalidate all the kernel objects, resulting in all the objects getting
rebuilt on the next pass, thus no build caching.
To fix that, build the objects in a separate directory (obj) for normal
builds, and another separate directory (obj2) for the builds with added
cflags.