4

I have seen posts like this on StackOverflow which talk about using uname() to get the current Kernel version number (stored in utsname.release). However that returns a string.

Is there a way to return the or check the Kernel version as a numerical value so that one can simply use if (version >= min_req_ver) { ... } ?

The only method I have seen is to include linux/version.h and check LINUX_VERSION_CODE however in CentOS for example, this version number is not updated when one runs a newer Kernel than the default. The uname() function however does report the correct current Kernel version across Linux distros (on the ones I have tested) including in scenario such as using CentOS with a newer Kernel.

jwbensley
  • 10,534
  • 19
  • 75
  • 93
  • 1
    you can try to parse it with sscanf, but be aware, that there may be non-numeric extensions to the release (i.e. "3.16.0-4-amd64" etc.). More accurate is probably utsname.version, but there is even more foo in it making parsing difficult (i.e. "#1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04)"). Unfortunately, the rigid scheme "major.minor.patchlevel" doesn't hold in practice – Ctx Sep 18 '17 at 13:36
  • 1
    you can't simply compare the version as you mentioned (version >= min_req), because It included kernel version, Major, Minor and patch number. Use 'uname' function, get the each version using sscanf and compare. – Rajeshkumar Sep 18 '17 at 14:21

1 Answers1

6

Use below function to get Kernel, Major, Minor and Patch version and compare individual version.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <sys/utsname.h>

int main(void) {

    struct utsname buffer;
    char *p;
    long ver[16];
    int i=0;

    errno = 0;
    if (uname(&buffer) != 0) {
        perror("uname");
        exit(EXIT_FAILURE);
    }

    printf("system name = %s\n", buffer.sysname);
    printf("node name   = %s\n", buffer.nodename);
    printf("release     = %s\n", buffer.release);
    printf("version     = %s\n", buffer.version);
    printf("machine     = %s\n", buffer.machine);

#ifdef _GNU_SOURCE
    printf("domain name = %s\n", buffer.domainname);
#endif

    p = buffer.release;

    while (*p) {
        if (isdigit(*p)) {
            ver[i] = strtol(p, &p, 10);
            i++;
        } else {
            p++;
        }
    }

    printf("Kernel %d Major %d Minor %d Patch %d\n", ver[0], ver[1], ver[2], ver[3]);

    return EXIT_SUCCESS;
}
Rajeshkumar
  • 739
  • 5
  • 16