]> git.ipfire.org Git - thirdparty/kmod.git/blobdiff - libkmod/libkmod-index.c
improve logging to mention context.
[thirdparty/kmod.git] / libkmod / libkmod-index.c
index e4e0786f11469e0915f710ffd346054fcc827a72..07f3b8c71eb90c0676cab34134105e767c3f9907 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libkmod - interface to kernel module operations
  *
- * Copyright (C) 2011  ProFUSION embedded systems
+ * Copyright (C) 2011-2012  ProFUSION embedded systems
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -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;
@@ -336,18 +349,22 @@ struct index_file *index_file_open(const char *filename)
        uint32_t magic, version;
        struct index_file *new;
 
-       file = fopen(filename, "r");
+       file = fopen(filename, "re");
        if (!file)
                return NULL;
        errno = EINVAL;
 
        magic = read_long(file);
-       if (magic != INDEX_MAGIC)
+       if (magic != INDEX_MAGIC) {
+               fclose(file);
                return NULL;
+       }
 
        version = read_long(file);
-       if (version >> 16 != INDEX_VERSION_MAJOR)
+       if (version >> 16 != INDEX_VERSION_MAJOR) {
+               fclose(file);
                return NULL;
+       }
 
        new = NOFAIL(malloc(sizeof(struct index_file)));
        new->file = file;
@@ -379,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;
@@ -669,7 +728,7 @@ static struct index_mm_node *index_mm_read_node(struct index_mm *idx,
                child_count = 0;
        }
 
-       children_padding = (offsetof(struct index_mm_node, children) +
+       children_padding = (sizeof(struct index_mm_node) +
                            (sizeof(uint32_t) * child_count)) % sizeof(void *);
 
        if (offset & INDEX_NODE_VALUES)
@@ -712,7 +771,7 @@ static void index_mm_free_node(struct index_mm_node *node)
 }
 
 struct index_mm *index_mm_open(struct kmod_ctx *ctx, const char *filename,
-                                                               bool populate)
+                               bool populate, unsigned long long *stamp)
 {
        int fd;
        int flags;
@@ -727,26 +786,26 @@ struct index_mm *index_mm_open(struct kmod_ctx *ctx, const char *filename,
 
        DBG(ctx, "file=%s\n", filename);
 
-       if ((fd = open(filename, O_RDONLY)) < 0) {
-               ERR(ctx, "%m\n");
+       idx = malloc(sizeof(*idx));
+       if (idx == NULL) {
+               ERR(ctx, "malloc: %m\n");
                return NULL;
        }
 
-       fstat(fd, &st);
-
-       idx = malloc(sizeof(*idx));
-       if (idx == NULL) {
-               ERR(ctx, "%m\n");
-               goto fail;
+       if ((fd = open(filename, O_RDONLY|O_CLOEXEC)) < 0) {
+               ERR(ctx, "open(%s, O_RDONLY|O_CLOEXEC): %m\n", filename);
+               goto fail_open;
        }
 
+       fstat(fd, &st);
        flags = MAP_PRIVATE;
        if (populate)
                flags |= MAP_POPULATE;
 
        if ((idx->mm = mmap(0, st.st_size, PROT_READ, flags, fd, 0))
                                                        == MAP_FAILED) {
-               ERR(ctx, "%m\n");
+               ERR(ctx, "mmap(0, %zd, PROT_READ, %d, %d, 0): %m\n",
+                   (size_t)st.st_size, flags, fd);
                goto fail;
        }
 
@@ -772,12 +831,15 @@ struct index_mm *index_mm_open(struct kmod_ctx *ctx, const char *filename,
        idx->ctx = ctx;
        close(fd);
 
+       *stamp = stat_mstamp(&st);
+
        return idx;
 
 fail:
        close(fd);
-       if (idx->mm)
+       if (idx->mm != MAP_FAILED)
                munmap(idx->mm, st.st_size);
+fail_open:
        free(idx);
        return NULL;
 }
@@ -804,6 +866,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)
 {