From 758428a75f569600b3c649eedc7c8c02e40628f1 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Mon, 16 Jan 2012 15:56:17 -0200 Subject: [PATCH] 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. --- TODO | 16 ++------ libkmod/libkmod-index.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ libkmod/libkmod-index.h | 2 + libkmod/libkmod.c | 33 +++++++++++++++++ libkmod/libkmod.h | 2 + libkmod/libkmod.sym | 1 + 6 files changed, 141 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 2e6987b..d1d553a 100644 --- a/TODO +++ b/TODO @@ -11,18 +11,6 @@ Features: * 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 @@ Things to be added/removed in kernel (check what is really needed): =================================================================== * 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 @@ static bool buf_pushchar(struct buffer *buf, char ch) 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 @@ static struct index_node_f *index_readchild(const struct index_node_f *parent, 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 @@ static struct index_mm_node *index_mm_readchild(const struct index_mm_node *pare 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; 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 @@ struct index_mm *index_mm_open(struct kmod_ctx *ctx, const char *filename, 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 void kmod_unload_resources(struct kmod_ctx *ctx) } } +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 @@ enum kmod_index { _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 @@ global: kmod_config_iter_get_value; kmod_config_iter_next; kmod_config_iter_free_iter; + kmod_dump_index; } LIBKMOD_3; -- 2.7.4