|
|
d2cad3 |
From e91ce48303e37b92f123a91acfa9cbda17035d7c Mon Sep 17 00:00:00 2001
|
|
|
d2cad3 |
From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Thu, 17 Aug 2017 15:09:06 +0300
|
|
|
d2cad3 |
Subject: [PATCH] depmod: backport external directories support
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Requires to backport scratchbuf implementation
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Squashed commit of the following:
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 92ab2321a4b761eb2822d77dc235dd543b021c69
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Thu Jul 20 17:09:52 2017 +0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
man/depmod.d: add external keyword description
|
|
|
d2cad3 |
|
|
|
d2cad3 |
The commit 'depmod: implement external directories support' added
|
|
|
d2cad3 |
external directories support (see
|
|
|
d2cad3 |
7da6884e7357ac05772e90f6d7e63b1948103fc4).
|
|
|
d2cad3 |
|
|
|
d2cad3 |
This patch documents the extention in the manpage.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 01673c9b8dbe580634604808f831b735aa7fe298
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Tue May 9 22:09:23 2017 +0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
depmod: implement external directories support
|
|
|
d2cad3 |
|
|
|
d2cad3 |
The idea is to add a configuration keyword, external, which
|
|
|
d2cad3 |
will list directories for scanning for particular kernel version
|
|
|
d2cad3 |
mask:
|
|
|
d2cad3 |
|
|
|
d2cad3 |
external 4.10 /the/modules/dir /second/modules/dir
|
|
|
d2cad3 |
|
|
|
d2cad3 |
And extend "search" keyword to set it's priority with pseudo dir
|
|
|
d2cad3 |
"external" (as it's done for built-in):
|
|
|
d2cad3 |
|
|
|
d2cad3 |
search subdir external subdir2 built-in subdir3
|
|
|
d2cad3 |
|
|
|
d2cad3 |
(actually, the version is the same as for override keyword: * or
|
|
|
d2cad3 |
posix regexp, so example above is a bit incorrect).
|
|
|
d2cad3 |
|
|
|
d2cad3 |
All other logic left the same: if there are duplicates, only one
|
|
|
d2cad3 |
is under consideration and it is unloadable if it is bad.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
The resulting modules.dep will contain entries a-la:
|
|
|
d2cad3 |
|
|
|
d2cad3 |
/the/modules/dir/module1.ko:
|
|
|
d2cad3 |
kernel/module2.ko: /the/modules/dir/module1.ko
|
|
|
d2cad3 |
|
|
|
d2cad3 |
(here /lib/modules/$(uname -r)/kernel/module2.ko depends of
|
|
|
d2cad3 |
symbols, provided by /the/modules/dir/module1.ko and external has
|
|
|
d2cad3 |
higher priority).
|
|
|
d2cad3 |
|
|
|
d2cad3 |
modprobe and modinfo understand it out of box.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
This is a pretty simple extention of existing logic, since now
|
|
|
d2cad3 |
depmod already is able to:
|
|
|
d2cad3 |
|
|
|
d2cad3 |
a) scan modules with full path from command line without -a
|
|
|
d2cad3 |
switch;
|
|
|
d2cad3 |
b) detects broken symbol dependencies and broken modversions,
|
|
|
d2cad3 |
what assumes, that modules are already are not built for the
|
|
|
d2cad3 |
existing kernel.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 5274ad44377ad5998b9f4b3c5c180d407ed68fb9
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Tue May 9 22:09:22 2017 +0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
depmod: rewrite depmod modules search with scratchbuf
|
|
|
d2cad3 |
|
|
|
d2cad3 |
The recursive search code used used pretty big, PATH_MAX,
|
|
|
d2cad3 |
automatic storage buffer for the module directory scanning. Some
|
|
|
d2cad3 |
time ago there was scratchbuf implemented, which dynamically
|
|
|
d2cad3 |
reallocates its buffer on demand. The patch takes it in use for
|
|
|
d2cad3 |
the scanning code also. The initial size is hardcoded to 256
|
|
|
d2cad3 |
bytes which sounds good enough for most usecases so there should
|
|
|
d2cad3 |
be not many reallocations.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
(add #include <shared/scratchbuf.h> which in upstream
|
|
|
d2cad3 |
comes from 3b4c684c125d depmod: fix string overflow)
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 88f47f04df80dd80065d2811f3a7bae25dd98a79
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Tue May 9 22:09:21 2017 +0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
depmod: create depmod dir independent search function
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Prepare to implement external directories support.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
The patch splits depmod_modules_search() function to two
|
|
|
d2cad3 |
functions: depmod_modules_search(), called by the high level with
|
|
|
d2cad3 |
intention to search all possible modules, and
|
|
|
d2cad3 |
depmod_module_search_path(), which takes path as a parameter and
|
|
|
d2cad3 |
scans modules under the path only. Initially it is used to scan
|
|
|
d2cad3 |
the same depmod->cfg->dirname path only.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 6488110e07ad49a0dc4da7bbf79dd00a50bd9cc5
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Wed Nov 23 17:23:38 2016 +0200
|
|
|
d2cad3 |
|
|
|
d2cad3 |
depmod: search key: move builtin detection under the add function
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Prepare to implement external directories support.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
It's better to isolate behaviour difference under the
|
|
|
d2cad3 |
cfg_search_add() call, then make the client code aware of it.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
In case of external modules/directories support, there will be
|
|
|
d2cad3 |
one more keyword added, so making the clients aware of it makes
|
|
|
d2cad3 |
even less sense.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 183465f82e0157b7facba9e100d0e822163ca951
|
|
|
d2cad3 |
Author: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
Date: Wed Nov 9 08:52:26 2016 +0200
|
|
|
d2cad3 |
|
|
|
d2cad3 |
shared: make scratchbuf_str static
|
|
|
d2cad3 |
|
|
|
d2cad3 |
It fixes linking problem
|
|
|
d2cad3 |
|
|
|
d2cad3 |
tools/depmod.o: In function `output_symbols_bin':
|
|
|
d2cad3 |
depmod.c:(.text.output_symbols_bin+0x135): undefined reference to `scratchbuf_str'
|
|
|
d2cad3 |
|
|
|
d2cad3 |
for -O0 build, where gcc doesn't actually inline it.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit 4d202380a16b273a641b3c9e85a6d80d9f367c68
|
|
|
d2cad3 |
Author: Lucas De Marchi <lucas.demarchi@intel.com>
|
|
|
d2cad3 |
Date: Wed Aug 10 14:51:57 2016 -0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
testsuite: include stdio.h
|
|
|
d2cad3 |
|
|
|
d2cad3 |
It's used in the log macros so include it.
|
|
|
d2cad3 |
|
|
|
d2cad3 |
commit c226d66c43c7550247c76e7285aeb338dce2ea34
|
|
|
d2cad3 |
Author: Lucas De Marchi <lucas.demarchi@intel.com>
|
|
|
d2cad3 |
Date: Wed Aug 10 14:20:32 2016 -0300
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Add scratchbuf implementation
|
|
|
d2cad3 |
|
|
|
d2cad3 |
This should fill the requirements for "we need to loop over a lot of
|
|
|
d2cad3 |
strings that usually are small enough to remain on stack, but we want to
|
|
|
d2cad3 |
protect ourselves against huge strings not fitting in the static
|
|
|
d2cad3 |
buffer we estimated as sufficient"
|
|
|
d2cad3 |
|
|
|
d2cad3 |
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
|
|
|
d2cad3 |
---
|
|
|
d2cad3 |
Makefile.am | 5 +
|
|
|
d2cad3 |
man/depmod.d.xml | 20 ++++
|
|
|
d2cad3 |
shared/scratchbuf.c | 60 +++++++++++
|
|
|
d2cad3 |
shared/scratchbuf.h | 31 ++++++
|
|
|
d2cad3 |
testsuite/.gitignore | 3 +
|
|
|
d2cad3 |
testsuite/test-scratchbuf.c | 89 +++++++++++++++++
|
|
|
d2cad3 |
testsuite/testsuite.h | 1 +
|
|
|
d2cad3 |
tools/depmod.c | 239 ++++++++++++++++++++++++++++++++++++--------
|
|
|
d2cad3 |
8 files changed, 404 insertions(+), 44 deletions(-)
|
|
|
d2cad3 |
create mode 100644 shared/scratchbuf.c
|
|
|
d2cad3 |
create mode 100644 shared/scratchbuf.h
|
|
|
d2cad3 |
create mode 100644 testsuite/test-scratchbuf.c
|
|
|
d2cad3 |
|
|
|
d2cad3 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
d2cad3 |
index 896ae6366f45..407efe3f93c2 100644
|
|
|
d2cad3 |
--- a/Makefile.am
|
|
|
d2cad3 |
+++ b/Makefile.am
|
|
|
d2cad3 |
@@ -51,6 +51,7 @@ shared_libshared_la_SOURCES = \
|
|
|
d2cad3 |
shared/array.h \
|
|
|
d2cad3 |
shared/hash.c \
|
|
|
d2cad3 |
shared/hash.h \
|
|
|
d2cad3 |
+ shared/scratchbuf.c \
|
|
|
d2cad3 |
shared/strbuf.c \
|
|
|
d2cad3 |
shared/strbuf.h \
|
|
|
d2cad3 |
shared/util.c \
|
|
|
d2cad3 |
@@ -307,6 +308,7 @@ testsuite_libtestsuite_la_LIBADD = -lrt
|
|
|
d2cad3 |
TESTSUITE = \
|
|
|
d2cad3 |
testsuite/test-hash \
|
|
|
d2cad3 |
testsuite/test-array \
|
|
|
d2cad3 |
+ testsuite/test-scratchbuf \
|
|
|
d2cad3 |
testsuite/test-strbuf \
|
|
|
d2cad3 |
testsuite/test-init \
|
|
|
d2cad3 |
testsuite/test-initstate \
|
|
|
d2cad3 |
@@ -329,6 +331,9 @@ testsuite_test_hash_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
|
|
|
d2cad3 |
testsuite_test_array_LDADD = $(TESTSUITE_LDADD)
|
|
|
d2cad3 |
testsuite_test_array_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+testsuite_test_scratchbuf_LDADD = $(TESTSUITE_LDADD)
|
|
|
d2cad3 |
+testsuite_test_scratchbuf_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
testsuite_test_strbuf_LDADD = $(TESTSUITE_LDADD)
|
|
|
d2cad3 |
testsuite_test_strbuf_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
|
|
|
d2cad3 |
|
|
|
d2cad3 |
diff --git a/man/depmod.d.xml b/man/depmod.d.xml
|
|
|
d2cad3 |
index c30c06c5b605..4341a568e8a0 100644
|
|
|
d2cad3 |
--- a/man/depmod.d.xml
|
|
|
d2cad3 |
+++ b/man/depmod.d.xml
|
|
|
d2cad3 |
@@ -75,6 +75,9 @@
|
|
|
d2cad3 |
first listed directory and the lowest priority given to the last
|
|
|
d2cad3 |
directory listed. The special keyword <command>built-in</command>
|
|
|
d2cad3 |
refers to the standard module directories installed by the kernel.
|
|
|
d2cad3 |
+ Another special keyword <command>external</command> refers to the
|
|
|
d2cad3 |
+ list of external directories, defined by the
|
|
|
d2cad3 |
+ <command>external</command> command.
|
|
|
d2cad3 |
</para>
|
|
|
d2cad3 |
<para>
|
|
|
d2cad3 |
By default, depmod will give a higher priority to
|
|
|
d2cad3 |
@@ -110,6 +113,23 @@
|
|
|
d2cad3 |
</para>
|
|
|
d2cad3 |
</listitem>
|
|
|
d2cad3 |
</varlistentry>
|
|
|
d2cad3 |
+ <varlistentry>
|
|
|
d2cad3 |
+ <term>external <replaceable>kernelversion</replaceable>
|
|
|
d2cad3 |
+ <replaceable>absolutemodulesdirectory...</replaceable>
|
|
|
d2cad3 |
+ </term>
|
|
|
d2cad3 |
+ <listitem>
|
|
|
d2cad3 |
+ <para>
|
|
|
d2cad3 |
+ This specifies a list of directories, which will be checked
|
|
|
d2cad3 |
+ according to the priorities in the <command>search</command>
|
|
|
d2cad3 |
+ command. The order matters also, the first directory has the higher
|
|
|
d2cad3 |
+ priority.
|
|
|
d2cad3 |
+ </para>
|
|
|
d2cad3 |
+ <para>
|
|
|
d2cad3 |
+ The <replaceable>kernelversion</replaceable> is a POSIX regular
|
|
|
d2cad3 |
+ expression or * wildcard, like in the <command>override</command>.
|
|
|
d2cad3 |
+ </para>
|
|
|
d2cad3 |
+ </listitem>
|
|
|
d2cad3 |
+ </varlistentry>
|
|
|
d2cad3 |
</variablelist>
|
|
|
d2cad3 |
</refsect1>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
diff --git a/shared/scratchbuf.c b/shared/scratchbuf.c
|
|
|
d2cad3 |
new file mode 100644
|
|
|
d2cad3 |
index 000000000000..8d9eb83f30c1
|
|
|
d2cad3 |
--- /dev/null
|
|
|
d2cad3 |
+++ b/shared/scratchbuf.c
|
|
|
d2cad3 |
@@ -0,0 +1,60 @@
|
|
|
d2cad3 |
+/*
|
|
|
d2cad3 |
+ * kmod - interface to kernel module operations
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * This library is free software; you can redistribute it and/or
|
|
|
d2cad3 |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
d2cad3 |
+ * License as published by the Free Software Foundation; either
|
|
|
d2cad3 |
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
d2cad3 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d2cad3 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
d2cad3 |
+ * Lesser General Public License for more details.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
d2cad3 |
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
d2cad3 |
+ */
|
|
|
d2cad3 |
+#include "scratchbuf.h"
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include <errno.h>
|
|
|
d2cad3 |
+#include <string.h>
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+void scratchbuf_init(struct scratchbuf *buf, char *stackbuf, size_t size)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ buf->bytes = stackbuf;
|
|
|
d2cad3 |
+ buf->size = size;
|
|
|
d2cad3 |
+ buf->need_free = false;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+int scratchbuf_alloc(struct scratchbuf *buf, size_t size)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ char *tmp;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (size <= buf->size)
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (buf->need_free) {
|
|
|
d2cad3 |
+ tmp = realloc(buf->bytes, size);
|
|
|
d2cad3 |
+ if (tmp == NULL)
|
|
|
d2cad3 |
+ return -ENOMEM;
|
|
|
d2cad3 |
+ } else {
|
|
|
d2cad3 |
+ tmp = malloc(size);
|
|
|
d2cad3 |
+ if (tmp == NULL)
|
|
|
d2cad3 |
+ return -ENOMEM;
|
|
|
d2cad3 |
+ memcpy(tmp, buf->bytes, buf->size);
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ buf->size = size;
|
|
|
d2cad3 |
+ buf->bytes = tmp;
|
|
|
d2cad3 |
+ buf->need_free = true;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+void scratchbuf_release(struct scratchbuf *buf)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ if (buf->need_free)
|
|
|
d2cad3 |
+ free(buf->bytes);
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
diff --git a/shared/scratchbuf.h b/shared/scratchbuf.h
|
|
|
d2cad3 |
new file mode 100644
|
|
|
d2cad3 |
index 000000000000..27ea9d9f6008
|
|
|
d2cad3 |
--- /dev/null
|
|
|
d2cad3 |
+++ b/shared/scratchbuf.h
|
|
|
d2cad3 |
@@ -0,0 +1,31 @@
|
|
|
d2cad3 |
+#pragma once
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include <stdbool.h>
|
|
|
d2cad3 |
+#include <stdlib.h>
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include <shared/macro.h>
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+/*
|
|
|
d2cad3 |
+ * Buffer abstract data type
|
|
|
d2cad3 |
+ */
|
|
|
d2cad3 |
+struct scratchbuf {
|
|
|
d2cad3 |
+ char *bytes;
|
|
|
d2cad3 |
+ size_t size;
|
|
|
d2cad3 |
+ bool need_free;
|
|
|
d2cad3 |
+};
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+void scratchbuf_init(struct scratchbuf *buf, char *stackbuf, size_t size);
|
|
|
d2cad3 |
+int scratchbuf_alloc(struct scratchbuf *buf, size_t sz);
|
|
|
d2cad3 |
+void scratchbuf_release(struct scratchbuf *buf);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+/* Return a C string */
|
|
|
d2cad3 |
+static inline char *scratchbuf_str(struct scratchbuf *buf)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ return buf->bytes;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#define SCRATCHBUF_INITIALIZER(buf_) { \
|
|
|
d2cad3 |
+ .bytes = buf_, \
|
|
|
d2cad3 |
+ .size = sizeof(buf_) + _array_size_chk(buf_), \
|
|
|
d2cad3 |
+ .need_free = false, \
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
diff --git a/testsuite/test-scratchbuf.c b/testsuite/test-scratchbuf.c
|
|
|
d2cad3 |
new file mode 100644
|
|
|
d2cad3 |
index 000000000000..6d86957cefb8
|
|
|
d2cad3 |
--- /dev/null
|
|
|
d2cad3 |
+++ b/testsuite/test-scratchbuf.c
|
|
|
d2cad3 |
@@ -0,0 +1,89 @@
|
|
|
d2cad3 |
+/*
|
|
|
d2cad3 |
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * This program is free software; you can redistribute it and/or
|
|
|
d2cad3 |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
d2cad3 |
+ * License as published by the Free Software Foundation; either
|
|
|
d2cad3 |
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
d2cad3 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d2cad3 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
d2cad3 |
+ * Lesser General Public License for more details.
|
|
|
d2cad3 |
+ *
|
|
|
d2cad3 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
d2cad3 |
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
d2cad3 |
+ */
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include <errno.h>
|
|
|
d2cad3 |
+#include <string.h>
|
|
|
d2cad3 |
+#include <unistd.h>
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include <shared/scratchbuf.h>
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+#include "testsuite.h"
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+static int test_scratchbuf_onlystack(const struct test *t)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ struct scratchbuf sbuf;
|
|
|
d2cad3 |
+ const char *smallstr = "xyz";
|
|
|
d2cad3 |
+ char buf[3 + 2];
|
|
|
d2cad3 |
+ char buf2[3 + 1];
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ scratchbuf_init(&sbuf, buf, sizeof(buf));
|
|
|
d2cad3 |
+ assert_return(scratchbuf_alloc(&sbuf, strlen(smallstr) + 1) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.need_free == false, EXIT_FAILURE);
|
|
|
d2cad3 |
+ scratchbuf_release(&sbuf);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ scratchbuf_init(&sbuf, buf2, sizeof(buf2));
|
|
|
d2cad3 |
+ assert_return(scratchbuf_alloc(&sbuf, strlen(smallstr) + 1) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.need_free == false, EXIT_FAILURE);
|
|
|
d2cad3 |
+ scratchbuf_release(&sbuf);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ memcpy(scratchbuf_str(&sbuf), smallstr, strlen(smallstr) + 1);
|
|
|
d2cad3 |
+ assert_return(strcmp(scratchbuf_str(&sbuf), smallstr) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+DEFINE_TEST(test_scratchbuf_onlystack,
|
|
|
d2cad3 |
+ .description = "test scratchbuf for buffer on stack only");
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+static int test_scratchbuf_heap(const struct test *t)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ struct scratchbuf sbuf;
|
|
|
d2cad3 |
+ const char *smallstr = "xyz";
|
|
|
d2cad3 |
+ const char *largestr = "xyzxyzxyz";
|
|
|
d2cad3 |
+ const char *largestr2 = "xyzxyzxyzxyzxyz";
|
|
|
d2cad3 |
+ char buf[3 + 1];
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ scratchbuf_init(&sbuf, buf, sizeof(buf));
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ /* Initially only on stack */
|
|
|
d2cad3 |
+ assert_return(scratchbuf_alloc(&sbuf, strlen(smallstr) + 1) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.need_free == false, EXIT_FAILURE);
|
|
|
d2cad3 |
+ memcpy(scratchbuf_str(&sbuf), smallstr, strlen(smallstr) + 1);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ /* Grow once to heap */
|
|
|
d2cad3 |
+ assert_return(scratchbuf_alloc(&sbuf, strlen(largestr) + 1) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.need_free == true, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.size == strlen(largestr) + 1, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(strcmp(scratchbuf_str(&sbuf), smallstr) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ memcpy(scratchbuf_str(&sbuf), largestr, strlen(largestr) + 1);
|
|
|
d2cad3 |
+ assert_return(strcmp(scratchbuf_str(&sbuf), largestr) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ /* Grow again - realloc should take place */
|
|
|
d2cad3 |
+ assert_return(scratchbuf_alloc(&sbuf, strlen(largestr2) + 1) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.need_free == true, EXIT_FAILURE);
|
|
|
d2cad3 |
+ assert_return(sbuf.size == strlen(largestr2) + 1, EXIT_FAILURE);
|
|
|
d2cad3 |
+ memcpy(scratchbuf_str(&sbuf), largestr2, strlen(largestr2) + 1);
|
|
|
d2cad3 |
+ assert_return(strcmp(scratchbuf_str(&sbuf), largestr2) == 0, EXIT_FAILURE);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ scratchbuf_release(&sbuf);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+DEFINE_TEST(test_scratchbuf_heap,
|
|
|
d2cad3 |
+ .description = "test scratchbuf for buffer on that grows to heap");
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+TESTSUITE_MAIN();
|
|
|
d2cad3 |
diff --git a/testsuite/testsuite.h b/testsuite/testsuite.h
|
|
|
d2cad3 |
index 3bd74f34ca7e..bb0eb507ac2f 100644
|
|
|
d2cad3 |
--- a/testsuite/testsuite.h
|
|
|
d2cad3 |
+++ b/testsuite/testsuite.h
|
|
|
d2cad3 |
@@ -19,6 +19,7 @@
|
|
|
d2cad3 |
|
|
|
d2cad3 |
#include <stdbool.h>
|
|
|
d2cad3 |
#include <stdarg.h>
|
|
|
d2cad3 |
+#include <stdio.h>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
#include <shared/macro.h>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
diff --git a/tools/depmod.c b/tools/depmod.c
|
|
|
d2cad3 |
index 7b9583249018..79fd14354266 100644
|
|
|
d2cad3 |
--- a/tools/depmod.c
|
|
|
d2cad3 |
+++ b/tools/depmod.c
|
|
|
d2cad3 |
@@ -35,6 +35,7 @@
|
|
|
d2cad3 |
#include <shared/hash.h>
|
|
|
d2cad3 |
#include <shared/macro.h>
|
|
|
d2cad3 |
#include <shared/util.h>
|
|
|
d2cad3 |
+#include <shared/scratchbuf.h>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
#include <libkmod/libkmod.h>
|
|
|
d2cad3 |
|
|
|
d2cad3 |
@@ -44,6 +45,7 @@
|
|
|
d2cad3 |
static int verbose = DEFAULT_VERBOSE;
|
|
|
d2cad3 |
|
|
|
d2cad3 |
static const char CFG_BUILTIN_KEY[] = "built-in";
|
|
|
d2cad3 |
+static const char CFG_EXTERNAL_KEY[] = "external";
|
|
|
d2cad3 |
static const char *default_cfg_paths[] = {
|
|
|
d2cad3 |
"/run/depmod.d",
|
|
|
d2cad3 |
SYSCONFDIR "/depmod.d",
|
|
|
d2cad3 |
@@ -432,9 +434,21 @@ struct cfg_override {
|
|
|
d2cad3 |
char path[];
|
|
|
d2cad3 |
};
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+enum search_type {
|
|
|
d2cad3 |
+ SEARCH_PATH,
|
|
|
d2cad3 |
+ SEARCH_BUILTIN,
|
|
|
d2cad3 |
+ SEARCH_EXTERNAL
|
|
|
d2cad3 |
+};
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
struct cfg_search {
|
|
|
d2cad3 |
struct cfg_search *next;
|
|
|
d2cad3 |
- uint8_t builtin;
|
|
|
d2cad3 |
+ enum search_type type;
|
|
|
d2cad3 |
+ size_t len;
|
|
|
d2cad3 |
+ char path[];
|
|
|
d2cad3 |
+};
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+struct cfg_external {
|
|
|
d2cad3 |
+ struct cfg_external *next;
|
|
|
d2cad3 |
size_t len;
|
|
|
d2cad3 |
char path[];
|
|
|
d2cad3 |
};
|
|
|
d2cad3 |
@@ -449,14 +463,27 @@ struct cfg {
|
|
|
d2cad3 |
uint8_t warn_dups;
|
|
|
d2cad3 |
struct cfg_override *overrides;
|
|
|
d2cad3 |
struct cfg_search *searches;
|
|
|
d2cad3 |
+ struct cfg_external *externals;
|
|
|
d2cad3 |
};
|
|
|
d2cad3 |
|
|
|
d2cad3 |
-static int cfg_search_add(struct cfg *cfg, const char *path, uint8_t builtin)
|
|
|
d2cad3 |
+static enum search_type cfg_define_search_type(const char *path)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ if (streq(path, CFG_BUILTIN_KEY))
|
|
|
d2cad3 |
+ return SEARCH_BUILTIN;
|
|
|
d2cad3 |
+ if (streq(path, CFG_EXTERNAL_KEY))
|
|
|
d2cad3 |
+ return SEARCH_EXTERNAL;
|
|
|
d2cad3 |
+ return SEARCH_PATH;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+static int cfg_search_add(struct cfg *cfg, const char *path)
|
|
|
d2cad3 |
{
|
|
|
d2cad3 |
struct cfg_search *s;
|
|
|
d2cad3 |
size_t len;
|
|
|
d2cad3 |
+ enum search_type type;
|
|
|
d2cad3 |
|
|
|
d2cad3 |
- if (builtin)
|
|
|
d2cad3 |
+ type = cfg_define_search_type(path);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (type != SEARCH_PATH)
|
|
|
d2cad3 |
len = 0;
|
|
|
d2cad3 |
else
|
|
|
d2cad3 |
len = strlen(path) + 1;
|
|
|
d2cad3 |
@@ -466,15 +493,15 @@ static int cfg_search_add(struct cfg *cfg, const char *path, uint8_t builtin)
|
|
|
d2cad3 |
ERR("search add: out of memory\n");
|
|
|
d2cad3 |
return -ENOMEM;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
- s->builtin = builtin;
|
|
|
d2cad3 |
- if (builtin)
|
|
|
d2cad3 |
+ s->type = type;
|
|
|
d2cad3 |
+ if (type != SEARCH_PATH)
|
|
|
d2cad3 |
s->len = 0;
|
|
|
d2cad3 |
else {
|
|
|
d2cad3 |
s->len = len - 1;
|
|
|
d2cad3 |
memcpy(s->path, path, len);
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
- DBG("search add: %s, builtin=%hhu\n", path, builtin);
|
|
|
d2cad3 |
+ DBG("search add: %s, search type=%hhu\n", path, type);
|
|
|
d2cad3 |
|
|
|
d2cad3 |
s->next = cfg->searches;
|
|
|
d2cad3 |
cfg->searches = s;
|
|
|
d2cad3 |
@@ -522,6 +549,32 @@ static void cfg_override_free(struct cfg_override *o)
|
|
|
d2cad3 |
free(o);
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+static int cfg_external_add(struct cfg *cfg, const char *path)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ struct cfg_external *ext;
|
|
|
d2cad3 |
+ size_t len = strlen(path);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ ext = malloc(sizeof(struct cfg_external) + len + 1);
|
|
|
d2cad3 |
+ if (ext == NULL) {
|
|
|
d2cad3 |
+ ERR("external add: out of memory\n");
|
|
|
d2cad3 |
+ return -ENOMEM;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ strcpy(ext->path, path);
|
|
|
d2cad3 |
+ ext->len = len;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ DBG("external add: %s\n", ext->path);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ ext->next = cfg->externals;
|
|
|
d2cad3 |
+ cfg->externals = ext;
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+static void cfg_external_free(struct cfg_external *ext)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ free(ext);
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
static int cfg_kernel_matches(const struct cfg *cfg, const char *pattern)
|
|
|
d2cad3 |
{
|
|
|
d2cad3 |
regex_t re;
|
|
|
d2cad3 |
@@ -567,8 +620,7 @@ static int cfg_file_parse(struct cfg *cfg, const char *filename)
|
|
|
d2cad3 |
if (streq(cmd, "search")) {
|
|
|
d2cad3 |
const char *sp;
|
|
|
d2cad3 |
while ((sp = strtok_r(NULL, "\t ", &saveptr)) != NULL) {
|
|
|
d2cad3 |
- uint8_t builtin = streq(sp, CFG_BUILTIN_KEY);
|
|
|
d2cad3 |
- cfg_search_add(cfg, sp, builtin);
|
|
|
d2cad3 |
+ cfg_search_add(cfg, sp);
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
} else if (streq(cmd, "override")) {
|
|
|
d2cad3 |
const char *modname = strtok_r(NULL, "\t ", &saveptr);
|
|
|
d2cad3 |
@@ -586,6 +638,20 @@ static int cfg_file_parse(struct cfg *cfg, const char *filename)
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
cfg_override_add(cfg, modname, subdir);
|
|
|
d2cad3 |
+ } else if (streq(cmd, "external")) {
|
|
|
d2cad3 |
+ const char *version = strtok_r(NULL, "\t ", &saveptr);
|
|
|
d2cad3 |
+ const char *dir = strtok_r(NULL, "\t ", &saveptr);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (version == NULL || dir == NULL)
|
|
|
d2cad3 |
+ goto syntax_error;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (!cfg_kernel_matches(cfg, version)) {
|
|
|
d2cad3 |
+ INF("%s:%u: external directory did not match %s\n",
|
|
|
d2cad3 |
+ filename, linenum, version);
|
|
|
d2cad3 |
+ goto done_next;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ cfg_external_add(cfg, dir);
|
|
|
d2cad3 |
} else if (streq(cmd, "include")
|
|
|
d2cad3 |
|| streq(cmd, "make_map_files")) {
|
|
|
d2cad3 |
INF("%s:%u: command %s not implemented yet\n",
|
|
|
d2cad3 |
@@ -762,7 +828,7 @@ static int cfg_load(struct cfg *cfg, const char * const *cfg_paths)
|
|
|
d2cad3 |
* list here. But only if there was no "search" option specified.
|
|
|
d2cad3 |
*/
|
|
|
d2cad3 |
if (cfg->searches == NULL)
|
|
|
d2cad3 |
- cfg_search_add(cfg, "updates", 0);
|
|
|
d2cad3 |
+ cfg_search_add(cfg, "updates");
|
|
|
d2cad3 |
|
|
|
d2cad3 |
return 0;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
@@ -780,6 +846,12 @@ static void cfg_free(struct cfg *cfg)
|
|
|
d2cad3 |
cfg->searches = cfg->searches->next;
|
|
|
d2cad3 |
cfg_search_free(tmp);
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ while (cfg->externals) {
|
|
|
d2cad3 |
+ struct cfg_external *tmp = cfg->externals;
|
|
|
d2cad3 |
+ cfg->externals = cfg->externals->next;
|
|
|
d2cad3 |
+ cfg_external_free(tmp);
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
|
|
|
d2cad3 |
@@ -987,6 +1059,33 @@ static int depmod_module_del(struct depmod *depmod, struct mod *mod)
|
|
|
d2cad3 |
return 0;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+static const char *search_to_string(const struct cfg_search *s)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ switch(s->type) {
|
|
|
d2cad3 |
+ case SEARCH_EXTERNAL:
|
|
|
d2cad3 |
+ return "external";
|
|
|
d2cad3 |
+ case SEARCH_BUILTIN:
|
|
|
d2cad3 |
+ return "built-in";
|
|
|
d2cad3 |
+ default:
|
|
|
d2cad3 |
+ return s->path;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+static bool depmod_is_path_starts_with(const char *path,
|
|
|
d2cad3 |
+ size_t pathlen,
|
|
|
d2cad3 |
+ const char *prefix,
|
|
|
d2cad3 |
+ size_t prefix_len)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ if (pathlen <= prefix_len)
|
|
|
d2cad3 |
+ return false;
|
|
|
d2cad3 |
+ if (path[prefix_len] != '/')
|
|
|
d2cad3 |
+ return false;
|
|
|
d2cad3 |
+ if (memcmp(path, prefix, prefix_len) != 0)
|
|
|
d2cad3 |
+ return false;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ return true;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
/* returns if existing module @mod is higher priority than newpath.
|
|
|
d2cad3 |
* note this is the inverse of module-init-tools is_higher_priority()
|
|
|
d2cad3 |
*/
|
|
|
d2cad3 |
@@ -995,6 +1094,7 @@ static int depmod_module_is_higher_priority(const struct depmod *depmod, const s
|
|
|
d2cad3 |
const struct cfg *cfg = depmod->cfg;
|
|
|
d2cad3 |
const struct cfg_override *ov;
|
|
|
d2cad3 |
const struct cfg_search *se;
|
|
|
d2cad3 |
+ const struct cfg_external *ext;
|
|
|
d2cad3 |
|
|
|
d2cad3 |
/* baselen includes the last '/' and mod->baselen doesn't. So it's
|
|
|
d2cad3 |
* actually correct to use modnamelen in the first and modnamesz in
|
|
|
d2cad3 |
@@ -1003,35 +1103,55 @@ static int depmod_module_is_higher_priority(const struct depmod *depmod, const s
|
|
|
d2cad3 |
size_t oldlen = mod->baselen + mod->modnamesz;
|
|
|
d2cad3 |
const char *oldpath = mod->path;
|
|
|
d2cad3 |
int i, bprio = -1, oldprio = -1, newprio = -1;
|
|
|
d2cad3 |
-
|
|
|
d2cad3 |
- assert(strncmp(newpath, cfg->dirname, cfg->dirnamelen) == 0);
|
|
|
d2cad3 |
- assert(strncmp(oldpath, cfg->dirname, cfg->dirnamelen) == 0);
|
|
|
d2cad3 |
-
|
|
|
d2cad3 |
- newpath += cfg->dirnamelen + 1;
|
|
|
d2cad3 |
- newlen -= cfg->dirnamelen + 1;
|
|
|
d2cad3 |
- oldpath += cfg->dirnamelen + 1;
|
|
|
d2cad3 |
- oldlen -= cfg->dirnamelen + 1;
|
|
|
d2cad3 |
+ size_t relnewlen = 0;
|
|
|
d2cad3 |
+ size_t reloldlen = 0;
|
|
|
d2cad3 |
+ const char *relnewpath = NULL;
|
|
|
d2cad3 |
+ const char *reloldpath = NULL;
|
|
|
d2cad3 |
|
|
|
d2cad3 |
DBG("comparing priorities of %s and %s\n",
|
|
|
d2cad3 |
oldpath, newpath);
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+ if (strncmp(newpath, cfg->dirname, cfg->dirnamelen) == 0) {
|
|
|
d2cad3 |
+ relnewpath = newpath + cfg->dirnamelen + 1;
|
|
|
d2cad3 |
+ relnewlen = newlen - cfg->dirnamelen + 1;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+ if (strncmp(oldpath, cfg->dirname, cfg->dirnamelen) == 0) {
|
|
|
d2cad3 |
+ reloldpath = oldpath + cfg->dirnamelen + 1;
|
|
|
d2cad3 |
+ reloldlen = oldlen - cfg->dirnamelen + 1;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
for (ov = cfg->overrides; ov != NULL; ov = ov->next) {
|
|
|
d2cad3 |
DBG("override %s\n", ov->path);
|
|
|
d2cad3 |
- if (newlen == ov->len && memcmp(ov->path, newpath, newlen) == 0)
|
|
|
d2cad3 |
+ if (relnewlen == ov->len &&
|
|
|
d2cad3 |
+ memcmp(ov->path, relnewpath, relnewlen) == 0)
|
|
|
d2cad3 |
return 0;
|
|
|
d2cad3 |
- if (oldlen == ov->len && memcmp(ov->path, oldpath, oldlen) == 0)
|
|
|
d2cad3 |
+ if (reloldlen == ov->len &&
|
|
|
d2cad3 |
+ memcmp(ov->path, reloldpath, reloldlen) == 0)
|
|
|
d2cad3 |
return 1;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
for (i = 0, se = cfg->searches; se != NULL; se = se->next, i++) {
|
|
|
d2cad3 |
- DBG("search %s\n", se->builtin ? "built-in" : se->path);
|
|
|
d2cad3 |
- if (se->builtin)
|
|
|
d2cad3 |
+ DBG("search %s\n", search_to_string(se));
|
|
|
d2cad3 |
+ if (se->type == SEARCH_BUILTIN)
|
|
|
d2cad3 |
bprio = i;
|
|
|
d2cad3 |
- else if (newlen > se->len && newpath[se->len] == '/' &&
|
|
|
d2cad3 |
- memcmp(se->path, newpath, se->len) == 0)
|
|
|
d2cad3 |
+ else if (se->type == SEARCH_EXTERNAL) {
|
|
|
d2cad3 |
+ for (ext = cfg->externals; ext != NULL; ext = ext->next, i++) {
|
|
|
d2cad3 |
+ if (depmod_is_path_starts_with(newpath,
|
|
|
d2cad3 |
+ newlen,
|
|
|
d2cad3 |
+ ext->path,
|
|
|
d2cad3 |
+ ext->len))
|
|
|
d2cad3 |
+ newprio = i;
|
|
|
d2cad3 |
+ if (depmod_is_path_starts_with(oldpath,
|
|
|
d2cad3 |
+ oldlen,
|
|
|
d2cad3 |
+ ext->path,
|
|
|
d2cad3 |
+ ext->len))
|
|
|
d2cad3 |
+ oldprio = i;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+ } else if (relnewlen > se->len && relnewpath[se->len] == '/' &&
|
|
|
d2cad3 |
+ memcmp(se->path, relnewpath, se->len) == 0)
|
|
|
d2cad3 |
newprio = i;
|
|
|
d2cad3 |
- else if (oldlen > se->len && oldpath[se->len] == '/' &&
|
|
|
d2cad3 |
- memcmp(se->path, oldpath, se->len) == 0)
|
|
|
d2cad3 |
+ else if (reloldlen > se->len && reloldpath[se->len] == '/' &&
|
|
|
d2cad3 |
+ memcmp(se->path, reloldpath, se->len) == 0)
|
|
|
d2cad3 |
oldprio = i;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
@@ -1102,10 +1222,11 @@ add:
|
|
|
d2cad3 |
return 0;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
-static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, char *path)
|
|
|
d2cad3 |
+static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, struct scratchbuf *s_path)
|
|
|
d2cad3 |
{
|
|
|
d2cad3 |
struct dirent *de;
|
|
|
d2cad3 |
int err = 0, dfd = dirfd(d);
|
|
|
d2cad3 |
+ char *path;
|
|
|
d2cad3 |
|
|
|
d2cad3 |
while ((de = readdir(d)) != NULL) {
|
|
|
d2cad3 |
const char *name = de->d_name;
|
|
|
d2cad3 |
@@ -1118,11 +1239,13 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
|
|
|
d2cad3 |
if (streq(name, "build") || streq(name, "source"))
|
|
|
d2cad3 |
continue;
|
|
|
d2cad3 |
namelen = strlen(name);
|
|
|
d2cad3 |
- if (baselen + namelen + 2 >= PATH_MAX) {
|
|
|
d2cad3 |
- path[baselen] = '\0';
|
|
|
d2cad3 |
- ERR("path is too long %s%s\n", path, name);
|
|
|
d2cad3 |
+ if (scratchbuf_alloc(s_path, baselen + namelen + 2) < 0) {
|
|
|
d2cad3 |
+ err = -ENOMEM;
|
|
|
d2cad3 |
+ ERR("No memory\n");
|
|
|
d2cad3 |
continue;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ path = scratchbuf_str(s_path);
|
|
|
d2cad3 |
memcpy(path + baselen, name, namelen + 1);
|
|
|
d2cad3 |
|
|
|
d2cad3 |
if (de->d_type == DT_REG)
|
|
|
d2cad3 |
@@ -1148,10 +1271,6 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
|
|
|
d2cad3 |
if (is_dir) {
|
|
|
d2cad3 |
int fd;
|
|
|
d2cad3 |
DIR *subdir;
|
|
|
d2cad3 |
- if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
|
|
|
d2cad3 |
- ERR("directory path is too long %s\n", path);
|
|
|
d2cad3 |
- continue;
|
|
|
d2cad3 |
- }
|
|
|
d2cad3 |
fd = openat(dfd, name, O_RDONLY);
|
|
|
d2cad3 |
if (fd < 0) {
|
|
|
d2cad3 |
ERR("openat(%d, %s, O_RDONLY): %m\n",
|
|
|
d2cad3 |
@@ -1168,7 +1287,7 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
|
|
|
d2cad3 |
path[baselen + namelen + 1] = '\0';
|
|
|
d2cad3 |
err = depmod_modules_search_dir(depmod, subdir,
|
|
|
d2cad3 |
baselen + namelen + 1,
|
|
|
d2cad3 |
- path);
|
|
|
d2cad3 |
+ s_path);
|
|
|
d2cad3 |
closedir(subdir);
|
|
|
d2cad3 |
} else {
|
|
|
d2cad3 |
err = depmod_modules_search_file(depmod, baselen,
|
|
|
d2cad3 |
@@ -1181,33 +1300,65 @@ static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t basel
|
|
|
d2cad3 |
err = 0; /* ignore errors */
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
-
|
|
|
d2cad3 |
return err;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
-static int depmod_modules_search(struct depmod *depmod)
|
|
|
d2cad3 |
+static int depmod_modules_search_path(struct depmod *depmod,
|
|
|
d2cad3 |
+ const char *path)
|
|
|
d2cad3 |
{
|
|
|
d2cad3 |
- char path[PATH_MAX];
|
|
|
d2cad3 |
- DIR *d = opendir(depmod->cfg->dirname);
|
|
|
d2cad3 |
+ char buf[256];
|
|
|
d2cad3 |
+ _cleanup_(scratchbuf_release) struct scratchbuf s_path_buf =
|
|
|
d2cad3 |
+ SCRATCHBUF_INITIALIZER(buf);
|
|
|
d2cad3 |
+ char *path_buf;
|
|
|
d2cad3 |
+ DIR *d;
|
|
|
d2cad3 |
size_t baselen;
|
|
|
d2cad3 |
int err;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ d = opendir(path);
|
|
|
d2cad3 |
if (d == NULL) {
|
|
|
d2cad3 |
err = -errno;
|
|
|
d2cad3 |
- ERR("could not open directory %s: %m\n", depmod->cfg->dirname);
|
|
|
d2cad3 |
+ ERR("could not open directory %s: %m\n", path);
|
|
|
d2cad3 |
return err;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
- baselen = depmod->cfg->dirnamelen;
|
|
|
d2cad3 |
- memcpy(path, depmod->cfg->dirname, baselen);
|
|
|
d2cad3 |
- path[baselen] = '/';
|
|
|
d2cad3 |
+ baselen = strlen(path);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ if (scratchbuf_alloc(&s_path_buf, baselen + 2) < 0) {
|
|
|
d2cad3 |
+ err = -ENOMEM;
|
|
|
d2cad3 |
+ goto out;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+ path_buf = scratchbuf_str(&s_path_buf);
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ memcpy(path_buf, path, baselen);
|
|
|
d2cad3 |
+ path_buf[baselen] = '/';
|
|
|
d2cad3 |
baselen++;
|
|
|
d2cad3 |
- path[baselen] = '\0';
|
|
|
d2cad3 |
+ path_buf[baselen] = '\0';
|
|
|
d2cad3 |
|
|
|
d2cad3 |
- err = depmod_modules_search_dir(depmod, d, baselen, path);
|
|
|
d2cad3 |
+ err = depmod_modules_search_dir(depmod, d, baselen, &s_path_buf);
|
|
|
d2cad3 |
+out:
|
|
|
d2cad3 |
closedir(d);
|
|
|
d2cad3 |
return err;
|
|
|
d2cad3 |
}
|
|
|
d2cad3 |
|
|
|
d2cad3 |
+static int depmod_modules_search(struct depmod *depmod)
|
|
|
d2cad3 |
+{
|
|
|
d2cad3 |
+ int err;
|
|
|
d2cad3 |
+ struct cfg_external *ext;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ err = depmod_modules_search_path(depmod, depmod->cfg->dirname);
|
|
|
d2cad3 |
+ if (err < 0)
|
|
|
d2cad3 |
+ return err;
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ for (ext = depmod->cfg->externals; ext != NULL; ext = ext->next) {
|
|
|
d2cad3 |
+ err = depmod_modules_search_path(depmod, ext->path);
|
|
|
d2cad3 |
+ if (err < 0 && err == -ENOENT)
|
|
|
d2cad3 |
+ /* ignore external dir absense */
|
|
|
d2cad3 |
+ continue;
|
|
|
d2cad3 |
+ }
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
+ return 0;
|
|
|
d2cad3 |
+}
|
|
|
d2cad3 |
+
|
|
|
d2cad3 |
static int mod_cmp(const void *pa, const void *pb) {
|
|
|
d2cad3 |
const struct mod *a = *(const struct mod **)pa;
|
|
|
d2cad3 |
const struct mod *b = *(const struct mod **)pb;
|
|
|
d2cad3 |
--
|
|
|
d2cad3 |
2.14.1
|
|
|
d2cad3 |
|
|
|
d2cad3 |
--- kmod-20/man/depmod.d.5.orig 2017-08-17 16:01:34.330058135 +0300
|
|
|
d2cad3 |
+++ kmod-20/man/depmod.d.5 2017-08-17 16:01:37.901058086 +0300
|
|
|
d2cad3 |
@@ -1,13 +1,13 @@
|
|
|
d2cad3 |
'\" t
|
|
|
d2cad3 |
.\" Title: depmod.d
|
|
|
d2cad3 |
.\" Author: Jon Masters <jcm@jonmasters.org>
|
|
|
d2cad3 |
-.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
|
|
|
d2cad3 |
-.\" Date: 03/01/2015
|
|
|
d2cad3 |
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
|
|
d2cad3 |
+.\" Date: 08/17/2017
|
|
|
d2cad3 |
.\" Manual: depmod.d
|
|
|
d2cad3 |
.\" Source: kmod
|
|
|
d2cad3 |
.\" Language: English
|
|
|
d2cad3 |
.\"
|
|
|
d2cad3 |
-.TH "DEPMOD\&.D" "5" "03/01/2015" "kmod" "depmod.d"
|
|
|
d2cad3 |
+.TH "DEPMOD\&.D" "5" "08/17/2017" "kmod" "depmod.d"
|
|
|
d2cad3 |
.\" -----------------------------------------------------------------
|
|
|
d2cad3 |
.\" * Define some portability stuff
|
|
|
d2cad3 |
.\" -----------------------------------------------------------------
|
|
|
d2cad3 |
@@ -52,7 +52,11 @@
|
|
|
d2cad3 |
This allows you to specify the order in which /lib/modules (or other configured module location) subdirectories will be processed by
|
|
|
d2cad3 |
\fBdepmod\fR\&. Directories are listed in order, with the highest priority given to the first listed directory and the lowest priority given to the last directory listed\&. The special keyword
|
|
|
d2cad3 |
\fBbuilt\-in\fR
|
|
|
d2cad3 |
-refers to the standard module directories installed by the kernel\&.
|
|
|
d2cad3 |
+refers to the standard module directories installed by the kernel\&. Another special keyword
|
|
|
d2cad3 |
+\fBexternal\fR
|
|
|
d2cad3 |
+refers to the list of external directories, defined by the
|
|
|
d2cad3 |
+\fBexternal\fR
|
|
|
d2cad3 |
+command\&.
|
|
|
d2cad3 |
.sp
|
|
|
d2cad3 |
By default, depmod will give a higher priority to a directory with the name
|
|
|
d2cad3 |
\fBupdates\fR
|
|
|
d2cad3 |
@@ -73,6 +77,18 @@
|
|
|
d2cad3 |
\fBextra\fR
|
|
|
d2cad3 |
subdirectory within /lib/modules (or other module location) will take priority over any likenamed module already provided by the kernel\&.
|
|
|
d2cad3 |
.RE
|
|
|
d2cad3 |
+.PP
|
|
|
d2cad3 |
+external \fIkernelversion\fR \fIabsolutemodulesdirectory\&.\&.\&.\fR
|
|
|
d2cad3 |
+.RS 4
|
|
|
d2cad3 |
+This specifies a list of directories, which will be checked according to the priorities in the
|
|
|
d2cad3 |
+\fBsearch\fR
|
|
|
d2cad3 |
+command\&. The order matters also, the first directory has the higher priority\&.
|
|
|
d2cad3 |
+.sp
|
|
|
d2cad3 |
+The
|
|
|
d2cad3 |
+\fIkernelversion\fR
|
|
|
d2cad3 |
+is a POSIX regular expression or * wildcard, like in the
|
|
|
d2cad3 |
+\fBoverride\fR\&.
|
|
|
d2cad3 |
+.RE
|
|
|
d2cad3 |
.SH "COPYRIGHT"
|
|
|
d2cad3 |
.PP
|
|
|
d2cad3 |
This manual page Copyright 2006\-2010, Jon Masters, Red Hat, Inc\&.
|