Nvidia-installer no longer builds - <sys/sysctl.h> removed from glibc

Now that glibc has finally removed the deprecated sys/sysctl.h, the nvidia-installer source no longer builds. I have a “workaround” for it, but I am wondering if this is really the right solution. Here is the patch I came up with (works with both 460.32.03 and 390.141):

--- kernel.c.orig	2021-01-23 09:52:07.411460973 -0500
+++ kernel.c	2021-01-23 10:08:09.817000455 -0500
@@ -23,7 +23,7 @@
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/sysctl.h>
+#include <linux/sysctl.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <dirent.h>
@@ -1084,12 +1084,8 @@
         size_t len = sizeof(int);
         int name[] = { CTL_KERN, KERN_PRINTK };
 
-        if (!old_level ||
-            sysctl(name, ARRAY_LEN(name), old_level, &len, NULL, 0) == 0) {
-            if (sysctl(name, ARRAY_LEN(name), NULL, 0, &level, len) == 0) {
-                loglevel_set = TRUE;
-            }
-        }
+        if (!old_level)
+        loglevel_set = TRUE;
     }
 
     return loglevel_set;

Any suggestions?

Thanks for reporting this. I filed internal issue number 3240511 to track this.

Here is a much more complete patch I came up with. It works with Slackware, but I cannot vouch for any of the other distros.

diff -Naur nvidia-installer-460.67.orig/kernel.c nvidia-installer-460.67/kernel.c
--- nvidia-installer-460.67.orig/kernel.c	2021-03-10 19:24:00.000000000 -0500
+++ nvidia-installer-460.67/kernel.c	2021-04-16 17:59:48.828574898 -0400
@@ -23,7 +23,10 @@
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/sysctl.h>
+#include <gnu/libc-version.h>
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 30
+  #include <sys/sysctl.h>
+#endif
 #include <ctype.h>
 #include <stdlib.h>
 #include <dirent.h>
@@ -1076,7 +1079,8 @@
     }
 
     if (!loglevel_set) {
-        /*
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 30
+         /*
          * Explicitly initialize the value of len, even though it looks like the
          * syscall should do that, since in practice it doesn't always actually
          * set the value of the pointed-to length parameter.
@@ -1090,6 +1094,10 @@
                 loglevel_set = TRUE;
             }
         }
+#else   /* sys/sysctl.h has been removed from glibc 2.32 and later */
+        if (!old_level)
+        loglevel_set = TRUE;
+#endif
     }
 
     return loglevel_set;

Hope this helps.