libkmod: dump index files
Provide a function to dump the index files to a certain fd. It could be
more optimized (particularly the functions to dump the index that were
copied and pasted from m-i-t), but it seems like the only user of it is
'modprobe -c', used for debugging purposes. So, keep it as is.
diff --git a/TODO b/TODO
index 2e6987b..d1d553a 100644
--- a/TODO
+++ b/TODO
@@ -11,18 +11,6 @@
* create test-mock library to be LD_PRELOAD'ed before running the binaries
so we're able to create unit tests
-* Add functions to dump configuration. Create a list with the config items
- (blacklist, aliases, etc) or just dump to a fd?
-
-* Add functions to list all modules known by modules.dep
-
-* provide 1:1 compatibility with module-init-tools's modprobe
- - dump modules.alias and modules.symbols
-
-* Add docs to kmod_config_* functions
-
-* Add manpages: copy them from module-init-tools and make the necessary changes
-
* review API, maybe unify all of these setters:
- kmod_module_version_get_symbol()
- kmod_module_version_get_crc()
@@ -63,10 +51,14 @@
===================================================================
* list of currently loaded modules
+ - readdir() in /sys/modules: dirs without a 'initstate' file mean the
+ modules is builtin.
* module's size should be available under /sys
+ - DONE in 3.3: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=cca3e707301862ca9b9327e6a732463982f8cd1b
* kill /proc/modules ?
+ - Unlikely, given other tools might depend on it
Things that are different from module-init-tools on purpose (!TODO)
===================================================================
diff --git a/libkmod/libkmod-index.c b/libkmod/libkmod-index.c
index 15e4898..9d3b939 100644
--- a/libkmod/libkmod-index.c
+++ b/libkmod/libkmod-index.c
@@ -211,6 +211,19 @@
return true;
}
+static unsigned buf_pushchars(struct buffer *buf, const char *str)
+{
+ unsigned i = 0;
+ int ch;
+
+ while ((ch = str[i])) {
+ buf_pushchar(buf, ch);
+ i++;
+ }
+
+ return i;
+}
+
static unsigned buf_freadchars(struct buffer *buf, FILE *in)
{
unsigned i = 0;
@@ -383,6 +396,48 @@
return NULL;
}
+static void index_dump_node(struct index_node_f *node, struct buffer *buf,
+ int fd)
+{
+ struct index_value *v;
+ int ch, pushed;
+
+ pushed = buf_pushchars(buf, node->prefix);
+
+ for (v = node->values; v != NULL; v = v->next) {
+ write_str_safe(fd, buf->bytes, buf->used);
+ write_str_safe(fd, " ", 1);
+ write_str_safe(fd, v->value, strlen(v->value));
+ write_str_safe(fd, "\n", 1);
+ }
+
+ for (ch = node->first; ch <= node->last; ch++) {
+ struct index_node_f *child = index_readchild(node, ch);
+
+ if (!child)
+ continue;
+
+ buf_pushchar(buf, ch);
+ index_dump_node(child, buf, fd);
+ buf_popchar(buf);
+ }
+
+ buf_popchars(buf, pushed);
+ index_close(node);
+}
+
+void index_dump(struct index_file *in, int fd, const char *prefix)
+{
+ struct index_node_f *root;
+ struct buffer buf;
+
+ buf_init(&buf);
+ buf_pushchars(&buf, prefix);
+ root = index_readroot(in);
+ index_dump_node(root, &buf, fd);
+ buf_release(&buf);
+}
+
static char *index_search__node(struct index_node_f *node, const char *key, int i)
{
char *value;
@@ -810,6 +865,50 @@
return NULL;
}
+static void index_mm_dump_node(struct index_mm_node *node, struct buffer *buf,
+ int fd)
+{
+ struct index_mm_value *itr, *itr_end;
+ int ch, pushed;
+
+ pushed = buf_pushchars(buf, node->prefix);
+
+ itr = node->values.values;
+ itr_end = itr + node->values.len;
+ for (; itr < itr_end; itr++) {
+ write_str_safe(fd, buf->bytes, buf->used);
+ write_str_safe(fd, " ", 1);
+ write_str_safe(fd, itr->value, itr->len);
+ write_str_safe(fd, "\n", 1);
+ }
+
+ for (ch = node->first; ch <= node->last; ch++) {
+ struct index_mm_node *child = index_mm_readchild(node, ch);
+
+ if (child == NULL)
+ continue;
+
+ buf_pushchar(buf, ch);
+ index_mm_dump_node(child, buf, fd);
+ buf_popchar(buf);
+ }
+
+ buf_popchars(buf, pushed);
+ index_mm_free_node(node);
+}
+
+void index_mm_dump(struct index_mm *idx, int fd, const char *prefix)
+{
+ struct index_mm_node *root;
+ struct buffer buf;
+
+ buf_init(&buf);
+ buf_pushchars(&buf, prefix);
+ root = index_mm_readroot(idx);
+ index_mm_dump_node(root, &buf, fd);
+ buf_release(&buf);
+}
+
static char *index_mm_search_node(struct index_mm_node *node, const char *key,
int i)
{
diff --git a/libkmod/libkmod-index.h b/libkmod/libkmod-index.h
index e9cd456..0134ac5 100644
--- a/libkmod/libkmod-index.h
+++ b/libkmod/libkmod-index.h
@@ -114,6 +114,7 @@
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, const char *prefix);
struct index_value *index_searchwild(struct index_file *idx, const char *key);
void index_values_free(struct index_value *values);
@@ -125,5 +126,6 @@
void index_mm_close(struct index_mm *index);
char *index_mm_search(struct index_mm *idx, const char *key);
struct index_value *index_mm_searchwild(struct index_mm *idx, const char *key);
+void index_mm_dump(struct index_mm *idx, int fd, const char *prefix);
#endif
diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c
index 8696945..f544c66 100644
--- a/libkmod/libkmod.c
+++ b/libkmod/libkmod.c
@@ -746,6 +746,39 @@
}
}
+KMOD_EXPORT int kmod_dump_index(struct kmod_ctx *ctx, enum kmod_index type,
+ int fd)
+{
+ if (ctx == NULL)
+ return -ENOSYS;
+
+ if (type < 0 || type >= _KMOD_INDEX_MODULES_SIZE)
+ return -ENOENT;
+
+ if (ctx->indexes[type] != NULL) {
+ DBG(ctx, "use mmaped index '%s'\n", index_files[type].fn);
+ index_mm_dump(ctx->indexes[type], fd,
+ index_files[type].prefix);
+ } else {
+ char fn[PATH_MAX];
+ struct index_file *idx;
+
+ snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
+ index_files[type].fn);
+
+ DBG(ctx, "file=%s\n", fn);
+
+ idx = index_file_open(fn);
+ if (idx == NULL)
+ return -ENOSYS;
+
+ index_dump(idx, fd, index_files[type].prefix);
+ index_file_close(idx);
+ }
+
+ return 0;
+}
+
const struct kmod_list *kmod_get_blacklists(const struct kmod_ctx *ctx)
{
return ctx->config->blacklists;
diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h
index a3939d3..64fe064 100644
--- a/libkmod/libkmod.h
+++ b/libkmod/libkmod.h
@@ -69,6 +69,8 @@
_KMOD_INDEX_PAD = (1 << 31),
};
+int kmod_dump_index(struct kmod_ctx *ctx, enum kmod_index idx, int fd);
+
/*
* kmod_list
*
diff --git a/libkmod/libkmod.sym b/libkmod/libkmod.sym
index 500af4e..f2d704d 100644
--- a/libkmod/libkmod.sym
+++ b/libkmod/libkmod.sym
@@ -94,4 +94,5 @@
kmod_config_iter_get_value;
kmod_config_iter_next;
kmod_config_iter_free_iter;
+ kmod_dump_index;
} LIBKMOD_3;