Applying patch folder to a linux kernel - patch

I have folder of patches(patchfile1.patch,patchfile2.patch and patchfile3.patch).How can I patch linux kernel from the patches given in this folder via single command.Or do i have to apply the patch one at a time from the folder
cd /kernel-directory
patch -p1 < patchfile1.patch
patch -p1 < patchfile2.patch
patch -p1 < patchfile3.patch
etc

In theory, it would be possible to concatenate all the patch fiels and apply them at once.
However, you should apply them one at a time so that it is possible to detect which one, if any, has an error or is outdated.

You could apply them all in a loop:
$ for p in `ls -v /path/to/patches/*.patch`; do patch -p1 < $p; done
Note that for many patch sets, the order in which they're applied matters. I used the -v switch to GNU ls above to get the natural sort. Otherwise, once you hit patchfile10.patch, the order from ls would look like:
patchfile1.patch
patchfile10.patch
patchfile2.patch
...
Which may be fine, but not always.

Related

Is it possible to use diff and patch tools to achieve the desired result?

I have a dir D-1.0.3 and D-1.0.5 with files A and B (and other subdirectories and files within D-x.x.x) with the following version tree of file A and B (alike in terms of versioning, also the other subdirs and files)
1.0.3 - 1.0.5
|
1.0.3.1 (head)
I would like to apply changes from 1.0.5 to 1.0.3.1 using diff and patch tool as i don't have access to git or svn tools associated to the files.
Is this possible using the unified diff format (or whatever)?How can I achieve that if possible (the command set i need to execute)?
I have checked that there is no adds, deletes or rename of the filename associated to the changes.
Many thanks!
yes, you can use diff to capture the difference between two directory trees. There are a few pitfalls:
in case you have new files (not in the older tree), you should use the -N option
if directories were added or removed, diff will not tell you about the files within those directories. I use a Perl script makepatch (an older version than on CPAN) which works around that problem.
For the simple case (no added/removed directories), you would use
diff -Naur olddirectory newdirectory >myfile.diff
and I would apply it in the top-level of the directory to be patched,
patch -p1 < myfile.diff
to eliminate problems due to the actual name of that directory. The -p1 option discards the name of the top-level directory.
To recap, assuming that these are the names of your directories, all subdirectories of the current directory:
diff -Naur 1.0.3 - 1.0.5 >mydiff.diff
cd 1.0.3.1 && patch -p1 <mydiff.diff

If condition inside the %Files section on a SPEC file

I'm kinda a new to writing spec files and building RPM's. Currently I have one RPM that is supposed to deploy some files in 1 of 2 possible directories that will vary with the OS.
How can I, within the %files section, verify them? I can't use variable...I can't verify both paths because one will for sure fail...I tried to define a macro earlier in the %install section but it will be defined just once and won't be redefined on every RPM installation...
what can I do here?
Thanks
I had a similar situation where additional files were included in the RPM in case of a DEBUG build over and above all files in the RELEASE build.
The trick is to pass a list of files to %files alongwith a regular list of files below it:
%install
# Create a temporary file containing the list of files
EXTRA_FILES=$RPM_BUILD_ROOT/ExtraFiles.list
touch %{EXTRA_FILES}
# If building in DEBUG mode, then include additional test binaries in the package
%if %{build_mode} == "DEBUG"
# %{build_mode} is a variable that is passed to the spec file when invoked by the build script
# Like: rpmbuild --define "build_mode DEBUG"
echo path/to/file1 > %{EXTRA_FILES}
echo path/to/file2 >> %{EXTRA_FILES}
%endif
%files -f %{EXTRA_FILES}
path/to/release/file1
path/to/release/file2
In your case, you can leverage the %if conditional in the %install section, use the OS as a spec variable passed to rpmbuild (or detect it in the RPM spec itself) and then pass the file containing the list to %files
The %files section can have variables in it, but usually this would be something like your path that is defined so you don't have to repeat it a bunch. so %{long_path}/file_name, where long_path was defined earlier in the spec file. the %files section is all the information that goes into the RPM database, and is created when you build the RPM so you won't be able to change those values based on machine information when installed.
If you really want to do this, you could include a tar file inside of the main tarball that gets extracted depending on certain conditions (since the spec file is just bash). Now keep in mind this is an awful idea. The files won't be tracked by the RPM database, so when you remove the RPM these files will still exist.
In reality you should build two RPMs, this will allow for better support going forward into the future in the event you have to hand this off to someone, as well as preserving your own sanity a year from now when you need to update the RPM.
This is how I solved my problem
step 1 :
In Build section .. somewhere I wrote :
%build
.....
#check my condition here & if true define some macro
%define is_valid %( if [ -f /usr/bin/myfile ]; then echo "1" ; else echo "0"; fi )
#after his normal continuation
.....
...
Step 2: in install section
%install
......
#do something in that condition
if %is_valid
install -m 0644 <file>
%endif
#rest all your stuff
................
Step 3:in files section
%files
%if %is_valid
%{_dir}/<file>
%endif
That's it
It works.
PS : I cannot give you full code hence giving all useful snippet
Forrest suggests the best solution, but if that is not possible practical you can detect the OS version at runtime in the post-install section, move the script to the appropriate location, and then delete it post-uninstall, eg:
# rpm spec snippets
%define OS_version %(hacky os detection)
...
Source2: script.sh
...
%install
install %{_sourcedir}/script.sh %{buildroot}/some/known/location
...
%post
%if %{OS_version} == "..."
mv /some/known/location/script.sh /distro/specific/script.sh
%elif %{OS_version} == "..."
...
%preun
rm -rf /all/script/locations
Much more error prone than building different RPMs on different OSes, but will scale a little better if you need to support many different OSes.

How can I check syntax for Make but be sure I am not executing?

We work with Make files and want to create a precommit check in HG to check Makefile syntax. Originally, our check was just going to be
make -n FOO.mk
However, we realized that if a Makefile were syntactically correct but required some environment variable to be set, the test could fail.
Any ideas? Our default is to resort to writing our own python scripts to check for a limited subset of common Makefile mistakes.
We are using GNUmake.
$ make --dry-run > /dev/null
$ echo $?
0
The output is of no value to me so I always redirect to /dev/null (often stderr too) and rely on exit code. The man page https://linux.die.net/man/1/make explains:
-n, --just-print, --dry-run, --recon
Print the commands that would be executed, but do not execute them.
A syntax error would result in the sample output:
$ make --dry-run > /dev/null
Makefile:11: *** unterminated variable reference. Stop.
It is not a good idea to have makefiles depend on environment variables. Precisely because of the issue you mentioned.
Variables from the Environment:
... use of variables from the environment is not recommended. It is not wise for makefiles to depend for their functioning on environment variables set up outside their control, since this would cause different users to get different results from the same makefile. This is against the whole purpose of most makefiles.
References to an environment variable in the recipe need a $$ prefix so it is not that hard to find references to the pattern '[$][$][{] or the pattern [$][$][A-Z] which will find the direct references. A pretty simple perl filter (sed script) finds them all.
To find the indirect ones I would try the recipe with only PATH set and HOME set to /dev/null, and SHELL set to /bin/false. Make's macro SHELL is not the environment $SHELL, so you can get the recipes to run, you'll have to set SHELL=/bin/sh in the recipe file to run the command from the recipe. That should shake out enough data to help you find the depends.
What you do about the results is another issue.

Have rsync only report files which were updated

When rsync prints out the details of what it did for each file (using one of the verbose flags) it seems to include both files that were updated and files that were not updated. For example a snippet of my output using the -v flag looks like this:
rforms.php is uptodate
robots.txt is uptodate
sorry.html
thankyou.html is uptodate
I'm only interested about the files that were updated. In the above case that's sorry.html. It also prints out directory names as it enters them even if there is no file in that directory that is updated. Is there a way to filter out uptodate files and directories with no updated files from this output?
You can pipe it through grep:
rsync -vv (your other rsync options here) | grep -v 'uptodate'
Rsync's output can be extensively customized, take a look at rsync --info=help; -v is a fairly coarse way to get information from a modern rsync.
In your case, I'm not sure exactly what you consider "updated" to mean. For example, deleted on the receiver too? Only files/dirs, but also pipes and symlinks too? Mod/access times or only content?
As a simple test I suggest you look at: rsync --info=name1 <other opts>.
Here's my take... (work-proven and very happy with it.)
rsync -arzihv --stats --progress \
/media/frank/foo/ \
/mnt/backup_drive/ | grep -E '^[^.]|^$'
The important bit is the -i for itemize.
The grep lets all output lines pass (also any summary as in -h --stats, also empty ones before that, which benefits legibility) except those starting with a dot: These are the ones, that describe unchanged files:
A . means that the item is not being updated (though it
might have attributes that are being modified).

Can 'make' check if mtime of a dependency is *different* between runs, not just if it's newer than target?

If foo_user.cpp depends on foo.h, then foo_user.cpp is built, and then foo.h's modification time is set to further in the past, make will not rebuild foo_user.cpp (because foo.cpp is 'newer'). I'd prefer it if make recorded the modification times of dependencies, and if they changed at all (newer or older), to consider targets of that dependency to be out of date. Can GNU make do this? If not, is there an easy alternative?
In case you're curious how this situation arises: foo.h resides in a symlinked folder. The symlink may point to the foolib-1.0 folder, the foolib-2.0 folder, etc. When the symlink points at a different version of the library, even an older version, foo_user.cpp should be rebuilt. If I simply specifiy symlinkfolder/foo.h as a dependency of foo_user.cpp, make only pays attention to the timestamp of foo.h, not the timestamp of the symlink'd directory through which foo.h is accessed. I can't add the symlink itself as a dependency, because the make rule is generated by the compiler (GCC has a special flag that when given causes it to output a make rule for all the headers a source file depends on).
I'm trying to understand why you can't just add the symlink as a dependency. I imagine your automatic dependencies are on one line, but you can have as many as you want.
x.o: a.h b.h
x.o: c.h
x.o: d.h
But having said that, it seems likely that make will stat the symlink's target, and not the symlink itself, so that may not DTRT. I suppose you could just touch a file somewhere whenever you make the symlink, but I also suppose you've already thought of that...
You could have a rule that runs ls -id link/. > test, which will put the inode number of the link target directory in test. You could then cmp test save, where save is from the last run. You could then have that make rule do make clean && make target if they are different.
targetwrapper:
ls -id link/. > test
cmp test save || make clean
make realtarget
cp test save
clean:
echo cleaned
realtarget:
echo made
No, Make does not support this. You may wish to consider using another build system such as SCons, which does not rely solely on the timestamp but actually computes the MD5 hash of source files and bases its decisions on the hashes.
From "What makes SCons better?" on its web site:
Reliable detection of build changes using MD5 signatures; optional, configurable support for traditional timestamps.
While make doesn't support it out of the box, you can program it.
include more_deps
ifneq ($(MAKE_RESTARTS),)
more_deps:
if (foolink.old differs from what foolink points to) ; then \
readlink foolink > foolink.old ; \
echo "foo_user: foolink_trigger" > more_deps ; \
touch foolink_trigger ; \
else \
echo "" > more_deps ;\
fi
endif
foo_user: foo_user.cpp
g++ $^ -o $#
Here you include makefile more_deps which sometimes will include the dependency on the symlink's trigger. Trigger is a special intermediate flie, all the meaningful informaion in which is its timestamp. When the symlink changes, the timestamp of the trigger is updated to current time (see touch), thus making foo_user outdated and it is the rebuilt.
include and MAKE_RESTARTS are needed to restart make after calculating the dependency described above. If the makefile being included is a target itself, the target is considered to be rebuilt, is rebuilt and then make restarts and re-reads makefile. But when it reads makefile for the second time, it doesn't see more_deps as a target, because MAKE_RESTARTS variable expands to non-empty string.
In fact, the line with if can sound like this:
more_deps:
if (any condition you want with $(VARIABLES) possible!) ; then \
update a file that holds the previous state ;\
...
Through which process do you change the symlink? You could add a make clean type of action to the script that changes the symlink.
You could also set up a "header working folder" in with you let make copy your header files, where the copied header files are dependent on their original and the symlink. The dependencies generated by GCC only take the working headers into account and won't clash with your copy headers into the working folder part of your Makefile.

Resources