LINUX_VERSION_CODE where the value from?
I just make a mistake about the macro LINUX_VERSION_CODE. Here is what I want to do,when execute the code,the code run different branch due to the machine ,which is running. I just realized,the result is not change,since I compile my code always in the same server.For example I compile the belw code in kernel version of 2.6.18,then the LINUX_VERSION_CODE marco is always 132626 . If there is any way ,let the run different branch due to the version of which it runs?
What happens? Can you paraphrase that, I don’t understand you at all. You have 4 machines with different operating systems installed — centos5.5, redhat5.5, centos7.0 and centos6.5. On the first three of them, that is cnetos5.5, redhat5.5 and centos7.0 the value of the macro defined in linux/version.h named «LINUX_VERSION_CODE» is the same (in comparison to each other). On the machine centos6.5 the macro is different. Can you post the source of llinux/version.h on your centos6.5 machine ? Did I understood you correctly?
The simplest answer would be: the linux headers installed on your machine do not match the kernel version installed. Reinstall them then. As to your question : the value of LINUX_VERSION_CODE comes from /usr/include/linux/version.h as a standard location.
1 Answer 1
So you want to run a different code depending on kernel version. But you don’t want to decide on that using a compile time constant — you want that at runtime.
Nothing simpler, but a call to uname:
#include #include #include #include int main() < struct utsname name; if (uname(&name)) < fprintf(stderr, "Uname failed!\n"); exit(-1); >printf("%s\n", name.release); if (!memcmp(&name.release, "4.18.9-", sizeof("4.18.9-") - 1)) < printf("Och, kernel 4.18.9 found!\n"); >else < printf("Och, you've got a different kernel. \n"); >>
$ cat 1.c | gcc -xc - && ./a.out 4.18.9-arch1-1-ARCH Och, kernel 4.18.9 found!
cat 1.c | ssh friend 'gcc -xc - && ./a.out' 4.12.14-lp150.11-default Och, you've got a different kernel.
I will leave it to the OP, to call strtoll or sscanf(&name.release, «%d.%d.%d-«, &major, &minor, &release) to get the kernel version as integer number.
But you can get way more hardcore than that. On runtime, you can just do anything, so just read the content of /usr/include/linux/version.h file:
#define _GNU_SOURCE 1 #include #include #include #include #include #include int main() < FILE *f; f = fopen("/usr/include/linux/version.h", "r"); if (f == NULL) return -__LINE__; char *line = NULL; size_t linelen = 0; char *found = NULL; while (getline(&line, &linelen, f) >0) < if ((found = strstr(line, "LINUX_VERSION_CODE")) != NULL) < break; >> if (found == NULL) return -__LINE__; fclose(f); found += sizeof("LINUX_VERSION_CODE") - 1; errno = 0; const long long kv = strtoll(found, NULL, 10); if (errno) return -__LINE__; free(line); printf("%ld.%ld.%ld\n", kv>>16&0xff, kv>>8&0xff, kv&0xff); if (kv > KERNEL_VERSION(4,17,0)) < printf("Och, kernel api greater then 4.17.0 found!\n"); >else < printf("Och, kernel api below 4.17.0 found!\n"); >>
And on my machine this outputs:
$ cat 1.c | gcc -xc - && ./a.out 4.17.11 Och, kernel api greater then 4.17.0 found!
$ cat 1.c | ssh friend 'gcc -xc - && ./a.out' 4.15.0 Och, kernel api below 4.17.0 found!
We can also see, that uname -a != grep «LINUX_VERSION_CODE» /usr/include/linux/version.h .
[KERNEL] Где определена LINUX_VERSION_CODE ?
Доброе утро.
Собственно сабж.
Где определена LINUX_VERSION_CODE?
[ megabaks@desktop ] ~ $ grep -RH "LINUX_VERSION_CODE" /usr/src/linux /usr/src/linux/arch/sh/kernel/vsyscall/vsyscall-note.S: .long LINUX_VERSION_CODE /usr/src/linux/arch/arm/include/asm/stackprotector.h: canary ^= LINUX_VERSION_CODE; /usr/src/linux/arch/x86/vdso/vdso-note.S: .long LINUX_VERSION_CODE /usr/src/linux/arch/x86/vdso/vdso32/note.S: .long LINUX_VERSION_CODE /usr/src/linux/arch/s390/kernel/vdso32/note.S: .long LINUX_VERSION_CODE /usr/src/linux/arch/s390/kernel/vdso64/note.S: .long LINUX_VERSION_CODE /usr/src/linux/arch/sparc/boot/piggyback.c: /* skip HdrS + LINUX_VERSION_CODE + HdrS version */ /usr/src/linux/arch/sparc/kernel/head_32.S: .word LINUX_VERSION_CODE /usr/src/linux/arch/sparc/kernel/head_64.S: .word LINUX_VERSION_CODE /usr/src/linux/arch/powerpc/kernel/vdso32/note.S: .long LINUX_VERSION_CODE /usr/src/linux/init/version.c:extern int version_string(LINUX_VERSION_CODE); /usr/src/linux/init/version.c:int version_string(LINUX_VERSION_CODE); /usr/src/linux/Makefile: (echo \#define LINUX_VERSION_CODE $(shell \ /usr/src/linux/scripts/checkpatch.pl: if ($line =~ /\bLINUX_VERSION_CODE\b/) < /usr/src/linux/scripts/checkpatch.pl: WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); /usr/src/linux/scripts/checkversion.pl:# checkversion find uses of LINUX_VERSION_CODE or KERNEL_VERSION /usr/src/linux/scripts/checkversion.pl: # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE /usr/src/linux/scripts/checkversion.pl: if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) < /usr/src/linux/drivers/net/wan/farsync.c: info->kernelVersion = LINUX_VERSION_CODE; /usr/src/linux/drivers/usb/core/hcd.c:#define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) /usr/src/linux/drivers/usb/core/hcd.c:#define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) /usr/src/linux/drivers/s390/char/sclp_cpi.c: LINUX_VERSION_CODE); /usr/src/linux/drivers/scsi/gdth.c: osv.version = (u8)(LINUX_VERSION_CODE >> 16); /usr/src/linux/drivers/scsi/gdth.c: osv.subversion = (u8)(LINUX_VERSION_CODE >> 8); /usr/src/linux/drivers/scsi/gdth.c: osv.revision = (u16)(LINUX_VERSION_CODE & 0xff); /usr/src/linux/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c:#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) /usr/src/linux/kernel/power/snapshot.c: info->version_code = LINUX_VERSION_CODE; /usr/src/linux/kernel/power/snapshot.c: if (info->version_code != LINUX_VERSION_CODE) /usr/src/linux/Documentation/scsi/ChangeLog.lpfc: * Moved #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) to include /usr/src/linux/Documentation/bus-virt-phys-mapping.txt: #if LINUX_VERSION_CODE < 0x020100 /usr/src/linux/include/linux/version.h:#define LINUX_VERSION_CODE 196609 [ megabaks@desktop ] ~ $
Чем мне заменить такую конструкцию?
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) /* Подключение файлов для ядра 2.6.9 */ #endif
Shell find out which linux version code example
Check out the difference between the part and the part in (the first version number in -a) Solution 2: you have some way to know linux kernel version : good way bad way to see kernel version ( you should see version of vmlinu* initrd files if they have version number of kernel ) you can try this way to know all of kernel versions on your machine : On Ubuntu and some other OS' you can run or read /etc/lsb_release Debian stores the version in /etc/debian_version find linux version
How do I know what linux kernel version does a distribution use?
Try man uname and find -v for the kernel version used. 😉
So it is uname -v or uname -a if you just dont care about specifics and want to see it all. :p
$ uname -v #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) $ uname -a Linux Phobos 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
Check out the difference between the uname -r part and the uname -v part in uname -a (the first version number in -a)
you have some way to know linux kernel version :
uname -r is the easiest way.
though there are utilities like screenfetch or neofetch that give you more information in a clear and pretty manner.
Just run screenfetch and it'll display details. (screenfetch is usually pre-installed on most distros these days).
If it is not installed, just run sudo apt install screenfetch (on debian based distros like ubuntu) or sudo pacman -S screenfetch ( on Arch based distros.
How can I check for software versions in a shell script?, That will find git version within git version 1.8.5.2 (Apple Git-48). Second you are missing a $ in your [[ "GIT_VERSION" == "git version" ]] test. So, …
How do I find out what version of Linux is running?
Don't try and make assumptions based on the distro as to what you can and cannot do, for that way lies madness (see also "User Agent detection"). Instead, detect whether what it is that you want to do is supported, and how it's done by whatever command or file location you want to use.
For example, if you wanted to install a package, you can detect whether you're on a Debian-like system or a RedHat-like system by checking for the existence of dpkg or rpm (check for dpkg first, because Debian machines can have the rpm command on them. ). Make your decision as to what to do based on that, not just on whether it's a Debian or RedHat system. That way you'll automatically support any derivative distros that you didn't explicitly program in. Oh, and if your package requires specific dependencies, then test for those too and let the user know what they're missing.
Another example is fiddling with network interfaces. Work out what to do based on whether there's an /etc/network/interfaces file or an /etc/sysconfig/network-scripts directory, and go from there.
Yes, it's more work, but unless you want to remake all the mistakes that web developers have made over the past decade or more, you'll do it the smart way right from the start.
There is no cross-distribution way. However:
- Redhat and friends: Test for /etc/redhat-release , check contents
- Debian: Test for /etc/debian_version , check contents
- Mandriva and friends: Test for /etc/version , check contents
- Slackware: Test for /etc/slackware-version , check contents
Etc. Generally speaking, check for /etc/*-release and /etc/*-version .
Edit: Found an old (1+ years) bash script of mine lying around that I must have cobbled together over the years (it has an impressive CVS log going back 6 years.) It might not work properly anymore as-is and I can't be bothered to find installed distros to test against, but it should provide you with a good starting point. It works fine on CentOS, Fedora and Gentoo. gyaresu tested it successfully on Debian Lenny.
#!/bin/bash get_distribution_type() < local dtype # Assume unknown dtype="unknown" # First test against Fedora / RHEL / CentOS / generic Redhat derivative if [ -r /etc/rc.d/init.d/functions ]; then source /etc/rc.d/init.d/functions [ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat" # Then test against SUSE (must be after Redhat, # I've seen rc.status on Ubuntu I think? TODO: Recheck that) elif [ -r /etc/rc.status ]; then source /etc/rc.status [ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse" # Then test against Debian, Ubuntu and friends elif [ -r /lib/lsb/init-functions ]; then source /lib/lsb/init-functions [ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian" # Then test against Gentoo elif [ -r /etc/init.d/functions.sh ]; then source /etc/init.d/functions.sh [ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo" # For Slackware we currently just test if /etc/slackware-version exists # and isn't empty (TODO: Find a better way :) elif [ -s /etc/slackware-version ]; then dtype="slackware" fi echo $dtype >
Note that this will probably only work correctly in Bash. You could rewrite it for other shells.
That being said, you might want to test for features, not for distributions. I'm not using this anymore simply because it became a maintenance burden. It's easier to rely on cross-distribution tools and solutions.
Conceptually, what it does is, in order:
- Pull in a known, "common init script function" type of file. Those are distribution-specific. If it doesn't exist, skip to next distribution check.
- Check the existence of a specific, known-to-exist, often-used and unlikely to be renamed function from that core script. We do that using the type Bash builtin. type -t returns function if that symbol is a function. We prepend zz to the output from type -t 2>/dev/null because if the name isn't defined the output string would be empty and we'd get a syntax error about a missing left hand to the == operator. If the name we just checked isn't a function, skip to next distribution check, otherwise we found the distribution type.
- Finally, echo the distribution type so the function output can be easily used in a case .. esac block.
Edit in case you're trying to run this as a straight script: This script is supposed to get sourced or included from other scripts. It does not output anything on its own if you run it as-is. To test it, source it and then invoke the function, e.g.:
source /path/to/this/script.sh get_distribution_type
Edit: Please note that this script does not require root privileges. I urge you not to run it as root. Shouldn't harm anything, but there's no need.
Found a link to a relevant mailing list post in the CVS log. Should be useful in unwrapping init script spaghetti.
You can find the kernel version by running uname -a , finding the distro version is dependant on the distro.
On Ubuntu and some other OS' you can run lsb_release -a or read /etc/lsb_release
Debian stores the version in /etc/debian_version