init: introduce ro.kernel.version property

This property will hold the major.minor part of the kernel version (e.g. "5.4"), allowing init scripts to act depending on that version, enabling and disabling certain features.

Bug: 194156700
Test: manual on a Pixel device
Signed-off-by: Alexander Potapenko <glider@google.com>
Merged-In: Icec640b8a7150b344d9aa3bc0bdbcdae050c7c45
Change-Id: I5af411e39da600e5e0f6703f3a2a4930d509e29d
(cherry picked from commit 1c496e94e0b7fb4425d05b6b9764700842723dfd)
Merged-In:I5af411e39da600e5e0f6703f3a2a4930d509e29d
diff --git a/init/init.cpp b/init/init.cpp
index a7325ca..942feb9 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -27,6 +27,7 @@
 #include <sys/mount.h>
 #include <sys/signalfd.h>
 #include <sys/types.h>
+#include <sys/utsname.h>
 #include <unistd.h>
 
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -554,6 +555,19 @@
     }
 }
 
+/// Set ro.kernel.version property to contain the major.minor pair as returned
+/// by uname(2).
+static void SetKernelVersion() {
+    struct utsname uts;
+    unsigned int major, minor;
+
+    if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
+        LOG(ERROR) << "Could not parse the kernel version from uname";
+        return;
+    }
+    SetProperty("ro.kernel.version", android::base::StringPrintf("%u.%u", major, minor));
+}
+
 static void HandleSigtermSignal(const signalfd_siginfo& siginfo) {
     if (siginfo.ssi_pid != 0) {
         // Drop any userspace SIGTERM requests.
@@ -824,6 +838,7 @@
     export_oem_lock_status();
     MountHandler mount_handler(&epoll);
     SetUsbController();
+    SetKernelVersion();
 
     const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
     Action::set_function_map(&function_map);