What is the difference between /lib/modules/version and /lib/modules/version+ (plus sign)? - linux

Please help, who know between /lib/modules/version and /lib/modules/version+ (plus sign)
e.g. /lib/modules/3.4.61 and /lib/modules/3.4.61+.
Sorry my weak English and weak Linux (I am newbie).

First, you need to understand the difference between version and release.
Version is a three fields value, like v5.0.1. We can have alternatives for the same version, especially on development.
As real example: Linus is now working to publish Linux v6.0.0. Before pushing it, he is making many 6.0.0 testing versions, we call it release candidates.
He releases each release candidate as v6.0.0rc2, then v6.0.0rc3, and it keeps increasing. The version prefix keeps the same, it only changes the release suffix (rcN). When its good enough, we releases the 'official' v6.0.0.
So, release is kind of 'version of a version'. Its a very specific moment/commit.
We can check version and release strings using make -s kernelversion and make -s kernelrelease.
kernelrelease is just kernelversion concatenated with a release suffix.
Kernelversion is extracted from the file ./Makefile, from its first lines:
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 0
SUBLEVEL = 0
EXTRAVERSION =
Kernelversion is just these three first values separated by '.'.
Lets see ./scripts/setlocalversion algorithm, he is the guy who tells its release suffix:
if [ -z "$(git describe --exact-match 2>/dev/null)" ]; then
...
if $short; then
echo "+"
return
fi
...
fi
Note that he checks git describe, if it doesn't return an annoted tag, it will return "+". That means, if the version is '6.0.0', it will become '6.0.0+'.
TUTORIAL
First thing we need, is to asure we have a git annoted tag, to avoid the '+'.
Use
git tag -a mytag -m 'Commenting about this tag'
Now ./scripts/setlocalversion may return nothing (empty).
Enable auto complement on .config.
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
Make a file .scmversion with the suffix you want (if you want any).
echo 'mysuffix' > .scmversion
Now check it again with make -s kernelrelease. Its expected to be solved :)

Related

Execute p4 aliased command result in messed wrong order of lines in output

I have the following content inside my p4aliases.txt.
diff-cl $(target-cl) = diff -dl //...#$(EQ)$(target-cl)
Basically it diffs against your files in current workspace toward the target shelved files of changelist.
It is fine. I can execute it. But when I compare the result coming from above aliased command against the direct raw (non-aliased) command as follows
p4 diff -dl //...#=<target-cl>
the output lines of text from aliased command is in wrong order e.g. changes according to a certain file shows up first before a line of file shown, line orders are messed up. This is not the case if you execute with a non-aliased command.
Example
Expected result
==== //depot/common.h#none - x:\mydir\project\src\common.h ====
==== //depot/file.cpp#none - x:\mydir\project\src\file.cpp ====
3a4
> added line 1
==== //depot/file.h#none - x:\mydir\project\src\file.h ====
Actual result
3a4
> added line 1
==== //depot/common.h#none - x:\mydir\project\src\common.h ====
==== //depot/file.cpp#none - x:\mydir\project\src\file.cpp ====
==== //depot/file.h#none - x:\mydir\project\src\file.h ====
I have p4 version as of Rev. P4/NTX64/2021.1/2126753 (2021/05/12).
Perforce server version (got from p4 info) is Server version: P4D/LINUX26X86_64/2017.1/1574018 (2017/10/02).
How can I solve this issue?
Could this be a version too far away between client and server
Update
I have tested p4 client all the way down from 2016-2020 version by downloading old binaries from ftp.perforce.com (in directory perforce). No luck. Output still messed the same. So it's not the problem about version mismatch.
This looks like a bug in the p4 client. When the client does a diff, it's written by the ClientUser::Diff() method, which defaults to writing to stdout (i.e. it does not route the output through ClientUser::OutputText()):
https://workshop.perforce.com/projects/perforce_software-p4/files/2018-2/client/clientuser.cc#436
https://workshop.perforce.com/projects/perforce_software-p4/files/2018-2/client/clientuser.cc#573
Output from commands run as part of an alias go through the ClientUserStrBuf subclass, which buffers all of its output. The file headers, for example, are buffered by ClientUserStrBuf::OutputInfo():
https://workshop.perforce.com/projects/perforce_software-p4/files/2018-2/client/clientaliases.cc#1647
There isn't a ClientUserStrBuf::Diff() implementation, though, so that diff output goes straight to stdout while the headers are buffered and printed at the end (presumably after some post-processing) -- hence the diff output showing up first in the console.
The fix I'd make would be to have the base ClientUser::Diff() implementation route the output through OutputText() when no output file is provided, which seems like the least-surprise behavior; that'd fix the aliases behavior and might even make life a little easier for other client developers who would otherwise hit the same issue. If you have a support contract with Perforce you can file this as a bug report, or since the client is open source you can take a crack at fixing and building it yourself. I don't think there's a workaround that doesn't involve modifying the client source code.
Samwise has the correct approach to truly fix the problem at hands although it might take some effort to understand the code, and conduct the fix itself.
At any rate, if we took such approach we won't be able to take benefits of bug fixes and future updates as we will be stuck with 2018-2 version of p4 as it's the latest as it can be in which we can grab the source.
I would recommend to use WSL then interact with p4.exe (yes, a Windows-based binary) for Windows-based project, and p4 for Linux-based binary. If you didn't use WSL, please find the .bash_aliases-like solution as I have below to seamlessly solve aliases diff operation.
Put the following code into your ~/.bash_aliases
# p4 - fix of aliases diff operation
# platform independent, it will choose a correct binary path to execute properly
p4() { cmd="p4.exe" # default is Windows-based
# get the last argument value, if "-lx" passed in then we know it's linux
if [[ "${#: -1}" == "-lx" ]]; then
cmd="/usr/local/bin/p4"
fi
if [[ $1 == "diff-cl" ]]; then
if [ -z "$2" ]; then
echo "usage: p4 diff-cl <CL>"
return 1
fi
$cmd diff -dl //...#=$2 | diffp4 | less -r
elif [[ $1 == "diff-cl-fonly" ]]; then
if [ -z "$2" ]; then
echo "usage: p4 diff-cl-fonly <CL>"
return 1
fi
$cmd diff -Od -dl -ds //...#=$2 | diffp4 | grep ==== | less -r
else
$cmd "$#"
fi
}
then source ~/.bash_aliases.
What it does is to allow you to still use p4 with all of its original commands & arguments normally with exceptions of diff-cl (which is the same name of alias I've put into p4aliases.txt for Windows or ~/.p4aliases for Linux). You can safely remove diff-cl entry from p4's alias file, or just leave it there. What we have in ~/.bash_aliases file will intercept whenever such argument matches then execute the raw command, just that we don't have to type long command ourselves.
We can later remove such section in our ~/.bash_aliases file when upstream p4 has been fixed.
In else section, we just relay the the whole arguments, and it will be performed just as normally done.
Extra: diff-cl-fonly to list out only files (its depot path, and local workspace path) which have changes.

How to prevent git from committing two files with names differing only in case?

We develop in a mixed environment - some people work on Macs and some work on Linux. This has proven to be a bit of a challenge at times, as those people who work on Linux are used to having their filesystems be case sensitive, so there's no issue committing (accidentally or otherwise) multiple files differing just by case. (e.g. FileName.ext versus filename.ext)
However, when the people on Macs go to check out the repository, having a case-insensitive filesystem means that the two files - differing only in case - overwrite each other and cause general havoc.
I know that there are various git settings to help people on case-insensitive filesystems work better with case changes (e.g. core.ignorecase), but these don't solve the issue where there's two different files in the repository, only differing by case.
I realize that the only way to fix it is to make sure the Linux people don't commit the two files differing only in case in the first place. -- Is there some setting in git which will pop up a warning or error if a user on a case-sensitive filesystem attempts to commit file(s) which would be confused with each other on a case-insensitive filesystem?
There's nothing built in (although there should be, no doubt). What you can do is provide a pre-commit hook that verifies that all names are OK and prevents the commit if not.
This hook only needs to be run on the Linux box (although making it work on Linux and Mac is easy, it's just Windows with its default impoverished toolbox that is problematic). You might want to add it to a side branch and give the Linux folks instructions on setting it up.
You may want to check branch names as well, as in git pre-commit or update hook for stopping commit with branch names having Case Insensitive match. (Interesting: the answer on this question is my own; I had forgotten it.)
First, let's write a "check for case conflict" function. This is just a matter of sorting with case-folding (so that "helloworld" and "helloWorld" are placed adjacent to each other), then using uniq -di to print any duplicate (after case-folding) strings, but no non-duplicates:
sort -f | uniq -di
If this produces any output, these are the "bad names". Let's capture the output in a temporary file and check its size, so we can print them to standard output as well:
#! /bin/sh
TF=$(mktemp)
trap "rm -f $TF" 0 1 2 3 15
checkstdin() {
sort -f | uniq -di > $TF
test -s $TF || return 0 # if $TF is empty, we are good
echo "non-unique (after case folding) names found!" 1>&2
cat $TF 1>&2
return 1
}
Now we just need to use it on files that will be committed, and perhaps on branch names as well. The former are listed with git ls-files, so:
git ls-files | checkstdin || {
echo "ERROR - file name collision, stopping commit" 1>&2
exit 1
}
You can fancy this up to use git diff-index --cached -r --name-only --diff-filter=A HEAD to check only added files, allowing existing case collisions to continue, and/or try to check things across many branches and/or commits, but that gets difficult.
Combine the above two fragments into one script (and test) and then simply copy it to an executable file named .git/hooks/pre-commit.
Checking branch names is a bit trickier. This really should happen when you create the branch name, rather than when you commit to it, and it's impossible to do a really good job on the client—it has to be done on a centralized server that has a proper global view.
Here is a way to do it on the server in a pre-receive script, in shell script rather than in Python (as in the linked answer). We still need the checkstdin function though, and you might want to do it in an update hook rather than a pre-receive hook, since you don't need to reject the entire push, just the one branch name.
NULLSHA=0000000000000000000000000000000000000000 # 40 0s
# Verify that the given branch name $1 is unique,
# even IF we fold all existing branch names' cases.
# To be used on any proposed branch creation (we won't
# look at existing branches).
check_new_branch_name() {
(echo "$1"; git for-each-ref --format='%(refname:short)' refs/heads) |
checkstdin || {
echo "ERROR: new branch name $1 is not unique after case-folding" 1>&2
exit 1 # or set overall failure status
}
}
while read oldsha newsha refname; do
... any other checks ...
case $oldsha,$refname in
$NULLSHA,refs/heads/*) check_new_branch_name ${refname#refs/heads/};;
esac
... continue with any other checks ...
done

Don't add "+" to linux kernel version

I am building linux kernel, if my kernel under git, then kernel version every time is:
Image Name: Linux-2.6.39+
If I am not using git, then everything is OK without any plus at the end.
I know that this done by scripts/setlocalversion script:
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
# full scm version string
res="$res$(scm_version)"
else
# append a plus sign if the repository is not in a clean
# annotated or signed tagged state (as git describe only
# looks at signed or annotated tags - git tag -a/-s) and
# LOCALVERSION= is not specified
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi
fi
So, it is possible without code changes say to build system that no need to add "+" at the end of version line?
The plus sign at the end of your version string is there as an indicator that the kernel was built from modified sources (that is, there were non-committed changes). This is also indicated by the comments in scripts/setlocalversion.
To avoid the '+' being appended despite having a dirty working directory, simply set LOCALVERSION explicityly when running make:
make LOCALVERSION=
You may also have to change the configuration option CONFIG_LOCALVERSION_AUTO to n in your kernel config (.config) before building:
sed -i "s|CONFIG_LOCALVERSION_AUTO=.*|CONFIG_LOCALVERSION_AUTO=n|" .config
To prevent the script scripts/setlocalversion to append the + to the end of the kernel local version, create an empty .scmversion file in the root of the kernel sources.
touch .scmversion
this way, you'll be able to leave LOCALVERSION as is in the kernel configuration file, in case you want to append a local signature to the kernel name.
Manipulating scripts/setlocalversion seems to be the only way for me.
Force return in scm_version():
scm_version()
{
local short
short=false
**return**
Add this line to your local.conf if you're using yocto and imx soc
SCMVERSION_pn-linux-imx = ""
Tested on imx-4.9.88-2.0.0_ga release
Just comment the line as a workaround/quickfix in scripts/setlocalversion. Then the kernel version should be same as "make kernelversion".
# Check for git and a git repo.
if test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
head=$(git rev-parse --verify HEAD 2>/dev/null); then
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile.
if [ -z "$(git describe --exact-match 2>/dev/null)" ]; then
# If only the short version is requested, don't bother
# running further git commands
if $short; then
#echo "+" #comment this line
return
fi

Linux makefile to check required minimum linux kernel version

I have a linux makefile that needs to compile on 2 different kernel versions. The makefile is not generated from automake/autoconf.
The C code are already conditioned using macros to generate different code for different kernel version, but certain features in the makefile needs to be also conditioned.
Is there a way in a makefile to do:
if (kernel_version > 2.6.30)
newer_kernel = 1
else
newer_kernel = 0
endif
Well, I can think of one quick way to do it with bash:
KERNEL_VERSION=`uname -r`
HIGHER_VERSION=`echo -e "$KERNEL_VERSION\n2.6.30" | sort -g -t '.' | tail --lines=1`
if [ "$HIGHER_VERSION" == "2.6.30" ]
# its an older kernel
else
# its a newer kernel
fi
Basically, you use uname to obtain the version of the current kernel, then compare it to 2.6.30 using sort (the -g flag enables numeric sorting, -t '.' means use dot as a field separator), then use tail to determine which of the two version was higher in the list. Not exactly a beautiful solution, but it will work.
You can put it into a separate script or directly into the makefile recipe

How to check Linux version with Autoconf?

My program requires at least Linux 2.6.26 (I use timerfd and some other Linux-specific features).
I have an general idea how to write this macro but I don't have enough knowledge about writing test macros for Autoconf. Algorithm:
Run "uname --release" and store output
Parse output and subtract Linux version number (MAJOR.MINOR.MICRO)
Compare version
I don't know how to run command, store output and parse it.
Maybe such macro already exists and it's available (I haven't found any)?
I think you'd be better off detecting the specific functions you need using AC_CHECK_FUNC, rather than a specific kernel version.
This will also prevent breakage if you find yourself cross-compiling at some point in the future
There is a macro for steps 2 (parse) and 3 (compare) version, ax_compare_version. For example:
linux_version=$(uname --release)
AX_COMPARE_VERSION($linux_version, [eq3], [2.6.26],
[AC_MSG_NOTICE([Ok])],
[AC_MSG_ERROR([Bad Linux version])])
Here I used eq3 so that if $linux_version contained additional strings, such as -amd64, the comparison still succeeds. There is a plethora of comparison operators available.
I would suggest you not to check the Linux version number, but for the specific type you need or function. Who knows, maybe someone decides to backport timerfd_settime() to 2.4.x? So I think AC_CANONICAL_TARGET and AC_CHECK_LIB or similar are your friends. If you need to check the function arguments or test behaviour, you'd better write a simple program and use AC_LANG_CONFTEST([AC_LANG_PROGRAM(...)])/AC_TRY_RUN to do the job.
Without going too deep and write autoconf macros properly (which would be preferable anyway) don't forget that configure.ac is basically a shell script preprocessed by m4. So you can write shell commands directly.
# prev. part of configure.ac
if test `uname -r |cut -d. -f1` -lt 2 then; echo "major v. error"; exit 1; fi
if test `uname -r |cut -d. -f2` -lt 6 then; echo "minor v. error"; exit 1; fi
if test `uname -r |cut -d. -f3` -lt 26 then; echo "micro error"; exit 1; fi
# ...
This is just an idea if you want to do it avoiding writing macros for autoconf. This choice is not good, but should work...
The best way is the already suggested one: you should check for features; so, say in a future kernel timerfd is no more available... or changed someway your code is broken... you won't catch it since you test for version.
edit
As user foof says in comments (with other words), it is a naive way to check for major.minor.micro. E.g. 3.5.1 will fail because of 5 being lt 6, but 3.5.1 comes after 2.6.26 so (likely) it should be accepted. There are many tricks that can be used in order to transform x.y.z into a representation that puts each version in its "natural" order. E.g. if we expect x, y, or z won't be greather than 999, we can do something like multiplying by 1000000 major, 1000 minor and 1 micro: thus, you can compare the result with 2006026 as Foof suggested in comment(s).

Resources