Skip to content

Incremental depmod #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7c7afc6
libkmod: add helper functions for walking indices
mwilck Jan 15, 2022
8bfd8cc
libkmod: only use first value when looking up symbols
mwilck Sep 19, 2021
e8cb779
depmod: write crcsum to modules.symbols.bin
mwilck Sep 19, 2021
2d8074e
depmod: add option -I/--incremental
mwilck Sep 13, 2021
0400d6f
depmod -I: read current depmod data base from index files
mwilck Sep 15, 2021
14f4455
depmod: track reverse dependencies
mwilck Sep 19, 2021
9e11a74
depmod_modules_search_file(): factor out depmod_must_replace()
mwilck Sep 20, 2021
224919b
depmod_load_modules(): factor out depmod_load_module()
mwilck Sep 20, 2021
260f99e
depmod_module_is_higher_priority: check for identical paths
mwilck Nov 20, 2021
3313918
depmod: remove symbols and dependencies in depmod_module_del()
mwilck Sep 20, 2021
4b4782c
depmod: implement incremental module addition
mwilck Sep 17, 2021
d399eed
depmod: implement "--incremental --all"
mwilck Nov 20, 2021
d82bcc0
depmod -I: support module removal
mwilck Nov 21, 2021
176adc7
depmod: add option -x/--errexit
mwilck Jul 28, 2022
589acde
testsuite: add a test for generating dependencies with depmod
mwilck Jan 14, 2022
4cf740e
testsuite: add tests for demonstrating dependency order changes
mwilck Jan 14, 2022
3c7fccf
testsuite/module-playground: add script for non-trivial depmod example
mwilck Jan 17, 2022
c6f3133
testsuite: add "big" depmod test using the module generation script
mwilck Jan 18, 2022
ba1ebf2
depmod: deterministic module sort order in depmod_calculate_dependenc…
mwilck Sep 17, 2021
9db7df2
testsuite: add unit test for incremental module addition
mwilck Nov 14, 2024
5bd88f5
testsuite: add unit test for incremental module deletion
mwilck Nov 14, 2024
76c8e73
testsuite: create a second module playground
mwilck Nov 14, 2024
2078128
testsuite: add unit test for module replacement
mwilck Nov 15, 2024
3a3f7cd
testsuite: add unit test for module overriding
mwilck Nov 15, 2024
ea3c038
testsuite: add generic test script for incremental depmod
mwilck Jul 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@
.*.swp
cscope.out
tags
__pycache__
testsuite/module-playground/ex-*.c
testsuite/module-playground/gen_mod.mak
testsuite/module-playground/symvers

70 changes: 46 additions & 24 deletions libkmod/libkmod-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,20 +395,18 @@
return NULL;
}

static void index_dump_node(struct index_node_f *node, struct strbuf *buf,
struct wrtbuf *wbuf)
static void index_walk_node(struct index_node_f *node, struct strbuf *buf,
index_walk_cb *callback, void *arg)
{
struct index_value *v;
size_t pushed;
const char *key;

pushed = strbuf_pushchars(buf, node->prefix);
key = strbuf_str(buf);

for (v = node->values; v != NULL; v = v->next) {
wrtbuf_write(wbuf, buf->bytes, strbuf_used(buf));
wrtbuf_write(wbuf, " ", 1);
wrtbuf_write(wbuf, v->value, strlen(v->value));
wrtbuf_write(wbuf, "\n", 1);
}
for (v = node->values; v != NULL; v = v->next)
callback(key, v->value, v->len, v->priority, arg);

for (uint8_t ch = node->first; ch <= node->last; ch++) {
struct index_node_f *child = index_readchild(node, ch);
Expand All @@ -417,7 +415,7 @@
continue;

if (strbuf_pushchar(buf, ch)) {
index_dump_node(child, buf, wbuf);
index_walk_node(child, buf, callback, arg);
strbuf_popchar(buf);
}
}
Expand All @@ -426,19 +424,37 @@
index_close(node);
}

void index_dump(struct index_file *in, int fd, bool alias_prefix)
void index_walk(struct index_file *in, bool alias_prefix, index_walk_cb *callback,
void *arg)
{
DECLARE_STRBUF_WITH_STACK(buf, 128);
struct index_node_f *root;
struct wrtbuf wbuf;

root = index_readroot(in);
if (root == NULL)
return;

wrtbuf_init(&wbuf, fd);
if (!alias_prefix || strbuf_pushchars(&buf, "alias "))
index_dump_node(root, &buf, &wbuf);
index_walk_node(root, &buf, callback, arg);
}

static void index_dump_cb(const char *key, const char *str, unsigned int len,
unsigned int priority, void *arg)
{
struct wrtbuf *wbuf = arg;

wrtbuf_write(wbuf, key, strlen(key));
wrtbuf_write(wbuf, " ", 1);
wrtbuf_write(wbuf, str, len - 1);
wrtbuf_write(wbuf, "\n", 1);
}

void index_dump(struct index_file *in, int fd, bool alias_prefix)
{
struct wrtbuf wbuf;

wrtbuf_init(&wbuf, fd);
index_walk(in, alias_prefix, index_dump_cb, &wbuf);
wrtbuf_flush(&wbuf);
}

Expand Down Expand Up @@ -852,22 +868,21 @@
return NULL;
}

static void index_mm_dump_node(struct index_mm_node *node, struct strbuf *buf,
struct wrtbuf *wbuf)
static void index_mm_walk_node(const struct index_mm_node *node, struct strbuf *buf,
index_walk_cb *callback, void *arg)
{
const void *p;
size_t i, pushed;
const char *key;

pushed = strbuf_pushchars(buf, node->prefix);
key = strbuf_str(buf);

for (i = 0, p = node->values; i < node->value_count; i++) {
struct index_mm_value v;

read_value_mm(&p, &v);
wrtbuf_write(wbuf, buf->bytes, strbuf_used(buf));
wrtbuf_write(wbuf, " ", 1);
wrtbuf_write(wbuf, v.value, v.len);
wrtbuf_write(wbuf, "\n", 1);
callback(key, v.value, v.len, v.priority, arg);
}

for (uint8_t ch = node->first; ch <= node->last; ch++) {
Expand All @@ -878,27 +893,34 @@
continue;

if (strbuf_pushchar(buf, ch)) {
index_mm_dump_node(child, buf, wbuf);
index_mm_walk_node(child, buf, callback, arg);
strbuf_popchar(buf);
}
}

strbuf_popchars(buf, pushed);
}

void index_mm_dump(const struct index_mm *idx, int fd, bool alias_prefix)
void index_mm_walk(const struct index_mm *idx, bool alias_prefix, index_walk_cb *callback,
void *arg)
{
DECLARE_STRBUF_WITH_STACK(buf, 128);
struct index_mm_node nbuf, *root;
struct wrtbuf wbuf;

root = index_mm_readroot(idx, &nbuf);
if (root == NULL)
return;

wrtbuf_init(&wbuf, fd);
if (!alias_prefix || strbuf_pushchars(&buf, "alias "))
index_mm_dump_node(root, &buf, &wbuf);
index_mm_walk_node(root, &buf, callback, arg);
}

void index_mm_dump(const struct index_mm *idx, int fd, bool alias_prefix)

Check warning on line 918 in libkmod/libkmod-index.c

View check run for this annotation

Codecov / codecov/patch

libkmod/libkmod-index.c#L918

Added line #L918 was not covered by tests
{
struct wrtbuf wbuf;

Check warning on line 920 in libkmod/libkmod-index.c

View check run for this annotation

Codecov / codecov/patch

libkmod/libkmod-index.c#L920

Added line #L920 was not covered by tests

wrtbuf_init(&wbuf, fd);
index_mm_walk(idx, alias_prefix, index_dump_cb, &wbuf);

Check warning on line 923 in libkmod/libkmod-index.c

View check run for this annotation

Codecov / codecov/patch

libkmod/libkmod-index.c#L922-L923

Added lines #L922 - L923 were not covered by tests
wrtbuf_flush(&wbuf);
}

Expand Down
6 changes: 6 additions & 0 deletions libkmod/libkmod-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ struct index_value {

/* In-memory index (depmod only) */
struct index_file;
typedef void(index_walk_cb)(const char *key, const char *value, unsigned int len,
unsigned int prio, void *arg);
struct index_file *index_file_open(const char *filename);
void index_file_close(struct index_file *idx);
char *index_search(struct index_file *idx, const char *key);
void index_dump(struct index_file *in, int fd, bool alias_prefix);
void index_walk(struct index_file *in, bool alias_prefix, index_walk_cb *callback,
void *arg);
struct index_value *index_searchwild(struct index_file *idx, const char *key);

void index_values_free(struct index_value *values);
Expand All @@ -31,4 +35,6 @@ int index_mm_open(const struct kmod_ctx *ctx, const char *filename,
void index_mm_close(struct index_mm *index);
char *index_mm_search(const struct index_mm *idx, const char *key);
struct index_value *index_mm_searchwild(const struct index_mm *idx, const char *key);
void index_mm_walk(const struct index_mm *idx, bool alias_prefix, index_walk_cb *callback,
void *arg);
void index_mm_dump(const struct index_mm *idx, int fd, bool alias_prefix);
1 change: 1 addition & 0 deletions libkmod/libkmod-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ _nonnull_(1)void kmod_module_set_visited(struct kmod_module *mod, bool visited);
_nonnull_(1) void kmod_module_set_builtin(struct kmod_module *mod, bool builtin);
_nonnull_(1) void kmod_module_set_required(struct kmod_module *mod, bool required);
_nonnull_all_ bool kmod_module_is_builtin(struct kmod_module *mod);
_nonnull_(1, 2) struct kmod_list *kmod_module_info_append(struct kmod_list **list, const char *key, size_t keylen, const char *value, size_t valuelen);

/* libkmod-file.c */
struct kmod_file;
Expand Down
6 changes: 3 additions & 3 deletions libkmod/libkmod-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1777,9 +1777,9 @@ static void kmod_module_info_free(struct kmod_module_info *info)
free(info);
}

static struct kmod_list *kmod_module_info_append(struct kmod_list **list, const char *key,
size_t keylen, const char *value,
size_t valuelen)
struct kmod_list *kmod_module_info_append(struct kmod_list **list, const char *key,
size_t keylen, const char *value,
size_t valuelen)
{
struct kmod_module_info *info;
struct kmod_list *n;
Expand Down
22 changes: 16 additions & 6 deletions libkmod/libkmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,13 @@
hash_del(ctx->modules_by_name, key);
}

static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,
enum kmod_index index_number,
const char *name, struct kmod_list **list)
static int kmod_lookup_alias_from_alias_bin_n(struct kmod_ctx *ctx,
enum kmod_index index_number,
const char *name, struct kmod_list **list,
unsigned int max_match)
{
int err, nmatch = 0;
unsigned int n;
struct index_file *idx;
struct index_value *realnames, *realname;

Expand All @@ -378,7 +380,8 @@
index_file_close(idx);
}

for (realname = realnames; realname; realname = realname->next) {
for (realname = realnames, n = 0; realname && n < max_match;
realname = realname->next, n++) {

Check warning on line 384 in libkmod/libkmod.c

View check run for this annotation

Codecov / codecov/patch

libkmod/libkmod.c#L384

Added line #L384 was not covered by tests
struct kmod_module *mod;
struct kmod_list *node;

Expand Down Expand Up @@ -409,14 +412,21 @@
return err;
}

static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,
enum kmod_index index_number,
const char *name, struct kmod_list **list)
{
return kmod_lookup_alias_from_alias_bin_n(ctx, index_number, name, list, UINT_MAX);
}

int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name,
struct kmod_list **list)
{
if (!strstartswith(name, "symbol:"))
return 0;

return kmod_lookup_alias_from_alias_bin(ctx, KMOD_INDEX_MODULES_SYMBOL, name,
list);
return kmod_lookup_alias_from_alias_bin_n(ctx, KMOD_INDEX_MODULES_SYMBOL, name,

Check warning on line 428 in libkmod/libkmod.c

View check run for this annotation

Codecov / codecov/patch

libkmod/libkmod.c#L428

Added line #L428 was not covered by tests
list, 1);
}

int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name,
Expand Down
19 changes: 16 additions & 3 deletions man/depmod.8.scd
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ depmod - Generate modules.dep and map files.
# SYNOPSIS

*depmod* [*-b* _basedir_] [*-m* _moduledir_] [*-o* _outdir_] [*-e*] [*-E* _Module.symvers_]
\ \ \ \ \ \ \ \[*-F* _System.map_] [*-n*] [*-v*] [*-A*] [*-P* _prefix_] [*-w*] [_version_]
\ \ \ \ \ \ \ \[*-F* _System.map_] [*-n*] [*-v*] [*-A*] [*-P* _prefix_] [*-w*] [*-x*] [*-I*] [_version_]

*depmod* [*-e*] [*-E* _Module.symvers_] [*-F* _System.map_] [*-n*] [*-v*] [*-P* _prefix_]
\ \ \ \ \ \ \ \[*-w*] [_version_] [_filename_...]
\ \ \ \ \ \ \ \[*-w*] [*-x*] [*-I*] [_version_] [_filename_...]

# DESCRIPTION

Expand All @@ -25,7 +25,7 @@ and <BASEDIR> is empty. See options below to override when needed. It determines
what symbols each module exports and needs. This list is written to
*modules.dep*, and a binary hashed version named modules.dep.bin, in the same
directory. If filenames are given on the command line, only those modules are
examined (which is rarely useful unless all modules are listed). *depmod* also
examined (which is rarely useful unless incremental mode is used). *depmod* also
creates a list of symbols provided by modules in the file named modules.symbols
and its binary hashed version, modules.symbols.bin. Finally, *depmod* will
output a file named modules.devname if modules supply special device names
Expand Down Expand Up @@ -136,6 +136,13 @@ depmod -b /tmp/build -m kernel-modules
*-h*, *--help*
Print the help message and exit.

*-I*, *--incremental*
Run in incremental mode. This mode preserves previous module dependencies
and adds the dependencies of the modules given on the command line. If no
modules are given or *--all* is set, the module directory is scanned for
added or deleted modules, and the *modules.dep* file and other outputs
are updated accordingly.

*-n*, *--show*, *--dry-run*
This sends the resulting *modules.dep* and the various map files to
standard output rather than writing them into the module directory.
Expand All @@ -155,6 +162,12 @@ depmod -b /tmp/build -m kernel-modules
*-w*
Warn on duplicate dependencies, aliases, symbol versions, etc.

*-x*, *--errexit*
Exit with an error status if any condition occurs that would create
a warning with *-e*, i.e. if some module requires an unknown symbol,
or if a symbol with a symbol version that doesn't match the version
provided by the kernel or other modules.

# COPYRIGHT

This manual page originally Copyright 2002, Rusty Russell, IBM Corporation.
Expand Down
2 changes: 1 addition & 1 deletion scripts/setup-modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ if test "$SRCDIR" != "$BUILDDIR"; then
fi

export MAKEFLAGS=${MAKEFLAGS-"-j$(nproc)"}
"${MAKE-make}" -C "$PWD/$MODULE_PLAYGROUND" modules
"${MAKE-make}" -C "$PWD/$MODULE_PLAYGROUND"
Loading
Loading