about summary refs log tree commit diff
path: root/nixpkgs/pkgs/os-specific/linux/kmod
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/os-specific/linux/kmod')
-rw-r--r--nixpkgs/pkgs/os-specific/linux/kmod/aggregator.nix35
-rw-r--r--nixpkgs/pkgs/os-specific/linux/kmod/darwin.patch123
-rw-r--r--nixpkgs/pkgs/os-specific/linux/kmod/default.nix44
-rw-r--r--nixpkgs/pkgs/os-specific/linux/kmod/module-dir.patch157
4 files changed, 359 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/os-specific/linux/kmod/aggregator.nix b/nixpkgs/pkgs/os-specific/linux/kmod/aggregator.nix
new file mode 100644
index 000000000000..7d46a13f3562
--- /dev/null
+++ b/nixpkgs/pkgs/os-specific/linux/kmod/aggregator.nix
@@ -0,0 +1,35 @@
+{ stdenv, kmod, modules, buildEnv }:
+
+buildEnv {
+  name = "kernel-modules";
+
+  paths = modules;
+
+  postBuild =
+    ''
+      source ${stdenv}/setup
+
+      if ! test -d "$out/lib/modules"; then
+        echo "No modules found."
+        # To support a kernel without modules
+        exit 0
+      fi
+
+      kernelVersion=$(cd $out/lib/modules && ls -d *)
+      if test "$(echo $kernelVersion | wc -w)" != 1; then
+         echo "inconsistent kernel versions: $kernelVersion"
+         exit 1
+      fi
+
+      echo "kernel version is $kernelVersion"
+
+      shopt -s extglob
+
+      # Regenerate the depmod map files.  Be sure to pass an explicit
+      # kernel version number, otherwise depmod will use `uname -r'.
+      if test -w $out/lib/modules/$kernelVersion; then
+          rm -f $out/lib/modules/$kernelVersion/modules.!(builtin*|order*)
+          ${kmod}/bin/depmod -b $out -a $kernelVersion
+      fi
+    '';
+}
diff --git a/nixpkgs/pkgs/os-specific/linux/kmod/darwin.patch b/nixpkgs/pkgs/os-specific/linux/kmod/darwin.patch
new file mode 100644
index 000000000000..69dbf479f9f1
--- /dev/null
+++ b/nixpkgs/pkgs/os-specific/linux/kmod/darwin.patch
@@ -0,0 +1,123 @@
+diff --git a/Makefile.am b/Makefile.am
+index 194e111..0a095b5 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -80,8 +80,7 @@ EXTRA_DIST += libkmod/README \
+ 	libkmod/COPYING testsuite/COPYING tools/COPYING COPYING
+ 
+ libkmod_libkmod_la_LDFLAGS = $(AM_LDFLAGS) \
+-	-version-info $(LIBKMOD_CURRENT):$(LIBKMOD_REVISION):$(LIBKMOD_AGE) \
+-	-Wl,--version-script=$(top_srcdir)/libkmod/libkmod.sym
++	-version-info $(LIBKMOD_CURRENT):$(LIBKMOD_REVISION):$(LIBKMOD_AGE)
+ libkmod_libkmod_la_DEPENDENCIES = \
+ 	shared/libshared.la \
+ 	${top_srcdir}/libkmod/libkmod.sym
+@@ -91,8 +90,7 @@ libkmod_libkmod_la_LIBADD = \
+ 
+ noinst_LTLIBRARIES += libkmod/libkmod-internal.la
+ libkmod_libkmod_internal_la_SOURCES = $(libkmod_libkmod_la_SOURCES)
+-libkmod_libkmod_internal_la_LDFLAGS = $(AM_LDFLAGS) \
+-	-Wl,--version-script=$(top_srcdir)/libkmod/libkmod.sym
++libkmod_libkmod_internal_la_LDFLAGS = $(AM_LDFLAGS)
+ libkmod_libkmod_internal_la_DEPENDENCIES  = $(libkmod_libkmod_la_DEPENDENCIES)
+ libkmod_libkmod_internal_la_LIBADD = $(libkmod_libkmod_la_LIBADD)
+ 
+diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
+index 889f264..6f0a285 100644
+--- a/libkmod/libkmod-module.c
++++ b/libkmod/libkmod-module.c
+@@ -787,7 +787,11 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
+ 	flags &= KMOD_REMOVE_FORCE;
+ 	flags |= KMOD_REMOVE_NOWAIT;
+ 
++#if defined(__linux__)
+ 	err = delete_module(mod->name, flags);
++#else
++	err = -1;
++#endif
+ 	if (err != 0) {
+ 		err = -errno;
+ 		ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
+@@ -879,7 +883,11 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
+ 	}
+ 	size = kmod_file_get_size(mod->file);
+ 
++#if defined(__linux__)
+ 	err = init_module(mem, size, args);
++#else
++	err = -1;
++#endif
+ init_finished:
+ 	if (err < 0) {
+ 		err = -errno;
+diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
+index 429ffbd..17a3b9c 100644
+--- a/libkmod/libkmod-signature.c
++++ b/libkmod/libkmod-signature.c
+@@ -17,7 +17,10 @@
+  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+  */
+ 
++#if defined(__linux__)
+ #include <endian.h>
++#endif
++
+ #include <inttypes.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+diff --git a/shared/macro.h b/shared/macro.h
+index 4fc5405..b5a2702 100644
+--- a/shared/macro.h
++++ b/shared/macro.h
+@@ -71,3 +71,7 @@
+ #endif
+ 
+ #define UNIQ __COUNTER__
++
++ #if !defined(__linux__)
++#define program_invocation_short_name getprogname()
++#endif
+diff --git a/shared/missing.h b/shared/missing.h
+index 4c0d136..ad8ec0f 100644
+--- a/shared/missing.h
++++ b/shared/missing.h
+@@ -45,6 +45,9 @@ static inline int finit_module(int fd, const char *uargs, int flags)
+ #endif
+ 
+ #if !HAVE_DECL_BE32TOH
++
++#if defined(__linux__)
++
+ #include <endian.h>
+ #include <byteswap.h>
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
+@@ -52,4 +55,16 @@ static inline int finit_module(int fd, const char *uargs, int flags)
+ #else
+ #define be32toh(x) (x)
+ #endif
++
++#elif defined(__APPLE__)
++
++#include <libkern/OSByteOrder.h>
++#define be32toh(x) OSSwapBigToHostInt32(x)
++
++#else
++
++#error No be32toh known for platform
++
++#endif
++
+ #endif
+diff --git a/shared/util.c b/shared/util.c
+index fd2028d..ecb0141 100644
+--- a/shared/util.c
++++ b/shared/util.c
+@@ -367,7 +367,7 @@ char *path_make_absolute_cwd(const char *p)
+ 	if (path_is_absolute(p))
+ 		return strdup(p);
+ 
+-	cwd = get_current_dir_name();
++	cwd = getcwd(NULL, 0);
+ 	if (!cwd)
+ 		return NULL;
+ 
diff --git a/nixpkgs/pkgs/os-specific/linux/kmod/default.nix b/nixpkgs/pkgs/os-specific/linux/kmod/default.nix
new file mode 100644
index 000000000000..8a09d7fea093
--- /dev/null
+++ b/nixpkgs/pkgs/os-specific/linux/kmod/default.nix
@@ -0,0 +1,44 @@
+{ stdenv, buildPackages, lib, fetchurl, autoreconfHook, pkgconfig
+, libxslt, xz, elf-header }:
+
+let
+  systems = [ "/run/current-system/kernel-modules" "/run/booted-system/kernel-modules" "" ];
+  modulesDirs = lib.concatMapStringsSep ":" (x: "${x}/lib/modules") systems;
+
+in stdenv.mkDerivation rec {
+  name = "kmod-${version}";
+  version = "25";
+
+  src = fetchurl {
+    url = "mirror://kernel/linux/utils/kernel/kmod/${name}.tar.xz";
+    sha256 = "1kgixs4m3jvwk7fb3d18n6j77qhgi9qfv4csj35rs5ancr4ycrbi";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkgconfig libxslt ];
+  buildInputs = [ xz ] ++ lib.optional stdenv.isDarwin elf-header;
+
+  configureFlags = [
+    "--sysconfdir=/etc"
+    "--with-xz"
+    "--with-modulesdirs=${modulesDirs}"
+  ];
+
+  patches = [ ./module-dir.patch ]
+    ++ lib.optional stdenv.isDarwin ./darwin.patch;
+
+  postInstall = ''
+    for prog in rmmod insmod lsmod modinfo modprobe depmod; do
+      ln -sv $out/bin/kmod $out/bin/$prog
+    done
+
+    # Backwards compatibility
+    ln -s bin $out/sbin
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = https://www.kernel.org/pub/linux/utils/kernel/kmod/;
+    description = "Tools for loading and managing Linux kernel modules";
+    license = licenses.lgpl21;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/os-specific/linux/kmod/module-dir.patch b/nixpkgs/pkgs/os-specific/linux/kmod/module-dir.patch
new file mode 100644
index 000000000000..f7432e3756e9
--- /dev/null
+++ b/nixpkgs/pkgs/os-specific/linux/kmod/module-dir.patch
@@ -0,0 +1,157 @@
+diff --git a/Makefile.am b/Makefile.am
+index d4eeb7e..5c9f603 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -19,6 +19,7 @@ AM_CPPFLAGS = \
+ 	-include $(top_builddir)/config.h \
+ 	-I$(top_srcdir) \
+ 	-DSYSCONFDIR=\""$(sysconfdir)"\" \
++	-DMODULESDIRS=\""$(shell echo $(modulesdirs) | $(SED) 's|:|\\",\\"|g')"\" \
+ 	${zlib_CFLAGS}
+ 
+ AM_CFLAGS = $(OUR_CFLAGS)
+diff --git a/configure.ac b/configure.ac
+index 23510c8..66490cf 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -202,6 +202,12 @@ GTK_DOC_CHECK([1.14],[--flavour no-tmpl-flat])
+ ], [
+ AM_CONDITIONAL([ENABLE_GTK_DOC], false)])
+ 
++AC_ARG_WITH([modulesdirs],
++	AS_HELP_STRING([--with-modulesdirs=DIRS], [Kernel modules directories, separated by :]),
++	[],
++	[with_modulesdirs=/lib/modules])
++AC_SUBST([modulesdirs], [$with_modulesdirs])
++
+ 
+ #####################################################################
+ # Default CFLAGS and LDFLAGS
+diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c
+index 69fe431..d37da32 100644
+--- a/libkmod/libkmod.c
++++ b/libkmod/libkmod.c
+@@ -206,12 +206,15 @@ static int log_priority(const char *priority)
+ 	return 0;
+ }
+ 
+-static const char *dirname_default_prefix = "/lib/modules";
++static const char *dirname_default_prefixes[] = {
++	MODULESDIRS,
++	NULL
++};
+ 
+ static char *get_kernel_release(const char *dirname)
+ {
+ 	struct utsname u;
+-	char *p;
++	char *p, *dirname_prefix;
+ 
+ 	if (dirname != NULL)
+ 		return path_make_absolute_cwd(dirname);
+@@ -219,8 +222,42 @@ static char *get_kernel_release(const char *dirname)
+ 	if (uname(&u) < 0)
+ 		return NULL;
+ 
+-	if (asprintf(&p, "%s/%s", dirname_default_prefix, u.release) < 0)
+-		return NULL;
++	if ((dirname_prefix = getenv("MODULE_DIR")) != NULL) {
++		if(asprintf(&p, "%s/%s", dirname_prefix, u.release) < 0)
++			return NULL;
++	} else {
++		size_t i;
++		char buf[PATH_MAX];
++
++		for (i = 0; dirname_default_prefixes[i] != NULL; i++) {
++			int plen;
++			struct stat dirstat;
++
++			plen = snprintf(buf, sizeof(buf), "%s/%s", dirname_default_prefixes[i], u.release);
++			if (plen < 0)
++				return NULL;
++			else if (plen >= PATH_MAX)
++				continue;
++
++			if (dirname_default_prefixes[i + 1] != NULL) {
++				if (stat(buf, &dirstat) < 0) {
++					if (errno == ENOENT)
++						continue;
++					else
++						return NULL;
++				}
++
++				if (!S_ISDIR(dirstat.st_mode))
++					continue;
++			}
++
++			p = malloc(plen + 1);
++			if (p == NULL)
++				return NULL;
++			memcpy(p, buf, plen + 1);
++			break;
++		}
++	}
+ 
+ 	return p;
+ }
+diff --git a/tools/static-nodes.c b/tools/static-nodes.c
+index 8d2356d..2ed306d 100644
+--- a/tools/static-nodes.c
++++ b/tools/static-nodes.c
+@@ -29,10 +29,11 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+-#include <sys/utsname.h>
+ 
+ #include <shared/util.h>
+ 
++#include <libkmod/libkmod.h>
++
+ #include "kmod.h"
+ 
+ struct static_nodes_format {
+@@ -154,8 +155,8 @@ static void help(void)
+ 
+ static int do_static_nodes(int argc, char *argv[])
+ {
+-	struct utsname kernel;
+ 	char modules[PATH_MAX], buf[4096];
++	struct kmod_ctx *ctx;
+ 	const char *output = "/dev/stdout";
+ 	FILE *in = NULL, *out = NULL;
+ 	const struct static_nodes_format *format = &static_nodes_format_human;
+@@ -206,22 +207,25 @@ static int do_static_nodes(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	if (uname(&kernel) < 0) {
+-		fputs("Error: uname failed!\n", stderr);
++	ctx = kmod_new(NULL, NULL);
++	if (ctx == NULL) {
++		fprintf(stderr, "Error: failed to create kmod context\n");
+ 		ret = EXIT_FAILURE;
+ 		goto finish;
+ 	}
+-
+-	snprintf(modules, sizeof(modules), "/lib/modules/%s/modules.devname", kernel.release);
++	if (snprintf(modules, sizeof(modules), "%s/modules.devname", kmod_get_dirname(ctx)) < 0) {
++		fprintf(stderr, "Error: path to modules.devname is too long\n");
++		ret = EXIT_FAILURE;
++		goto finish;
++	}
++	kmod_unref(ctx);
+ 	in = fopen(modules, "re");
+ 	if (in == NULL) {
+ 		if (errno == ENOENT) {
+-			fprintf(stderr, "Warning: /lib/modules/%s/modules.devname not found - ignoring\n",
+-				kernel.release);
++			fprintf(stderr, "Warning: %s not found - ignoring\n", modules);
+ 			ret = EXIT_SUCCESS;
+ 		} else {
+-			fprintf(stderr, "Error: could not open /lib/modules/%s/modules.devname - %m\n",
+-				kernel.release);
++			fprintf(stderr, "Error: could not open %s - %m\n", modules);
+ 			ret = EXIT_FAILURE;
+ 		}
+ 		goto finish;