blob: ef83e314c574276d35a54e91ae9727f2ba8e95ff [file] [log] [blame]
Lucas De Marchi586fc302011-11-21 14:35:35 -02001/*
2 * libkmod - interface to kernel module operations
3 *
Lucas De Marchie6b0e492013-01-16 11:27:21 -02004 * Copyright (C) 2011-2013 ProFUSION embedded systems
Lucas De Marchi586fc302011-11-21 14:35:35 -02005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
Lucas De Marchicb451f32011-12-12 18:24:35 -02008 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
Lucas De Marchi586fc302011-11-21 14:35:35 -020010 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
Lucas De Marchiee1d1882012-02-27 18:48:02 -030021#include <assert.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020022#include <stdio.h>
23#include <stdlib.h>
24#include <stddef.h>
25#include <stdarg.h>
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -020026#include <limits.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020027#include <unistd.h>
28#include <errno.h>
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -020029#include <fnmatch.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020030#include <string.h>
31#include <ctype.h>
Lucas De Marchi221631d2011-11-24 16:41:01 -020032#include <sys/utsname.h>
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -020033#include <sys/stat.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020034
35#include "libkmod.h"
Lucas De Marchi83b855a2013-07-04 16:13:11 -030036#include "libkmod-internal.h"
Lucas De Marchi9ba6f572011-11-30 20:31:45 -020037#include "libkmod-index.h"
Lucas De Marchi586fc302011-11-21 14:35:35 -020038
Lucas De Marchifd186ae2011-12-06 03:38:37 -020039#define KMOD_HASH_SIZE (256)
40#define KMOD_LRU_MAX (128)
Lucas De Marchi38052742012-02-16 20:43:16 -020041#define _KMOD_INDEX_MODULES_SIZE KMOD_INDEX_MODULES_BUILTIN + 1
Lucas De Marchifd186ae2011-12-06 03:38:37 -020042
Lucas De Marchi586fc302011-11-21 14:35:35 -020043/**
44 * SECTION:libkmod
45 * @short_description: libkmod context
46 *
47 * The context contains the default values for the library user,
48 * and is passed to all library operations.
49 */
50
Lucas De Marchi63be91c2012-01-16 10:43:34 -020051static struct _index_files {
52 const char *fn;
53 const char *prefix;
54} index_files[] = {
Lucas De Marchib08314f2012-01-16 12:01:48 -020055 [KMOD_INDEX_MODULES_DEP] = { .fn = "modules.dep", .prefix = "" },
56 [KMOD_INDEX_MODULES_ALIAS] = { .fn = "modules.alias", .prefix = "alias " },
57 [KMOD_INDEX_MODULES_SYMBOL] = { .fn = "modules.symbols", .prefix = "alias "},
Lucas De Marchi38052742012-02-16 20:43:16 -020058 [KMOD_INDEX_MODULES_BUILTIN] = { .fn = "modules.builtin", .prefix = ""},
Lucas De Marchia4a75022011-12-08 14:56:48 -020059};
60
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -020061static const char *default_config_paths[] = {
Kay Sieversa308abe2011-12-20 17:58:05 +010062 SYSCONFDIR "/modprobe.d",
Lucas De Marchi436da1e2012-03-15 09:19:34 -030063 "/run/modprobe.d",
Dave Reisnerc5b37db2012-09-27 11:00:42 -040064 "/lib/modprobe.d",
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -020065 NULL
66};
67
Lucas De Marchi586fc302011-11-21 14:35:35 -020068/**
69 * kmod_ctx:
70 *
71 * Opaque object representing the library context.
72 */
73struct kmod_ctx {
74 int refcount;
Gustavo Sverzut Barbieri8d3f3ef2011-12-02 21:10:24 -020075 int log_priority;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -020076 void (*log_fn)(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -020077 int priority, const char *file, int line,
78 const char *fn, const char *format, va_list args);
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -020079 void *log_data;
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -020080 const void *userdata;
81 char *dirname;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -020082 struct kmod_config *config;
Lucas De Marchi822913d2011-12-27 12:13:54 -020083 struct hash *modules_by_name;
Lucas De Marchib08314f2012-01-16 12:01:48 -020084 struct index_mm *indexes[_KMOD_INDEX_MODULES_SIZE];
85 unsigned long long indexes_stamp[_KMOD_INDEX_MODULES_SIZE];
Lucas De Marchi586fc302011-11-21 14:35:35 -020086};
87
Lucas De Marchi71928282012-05-10 20:58:46 -030088void kmod_log(const struct kmod_ctx *ctx,
89 int priority, const char *file, int line, const char *fn,
90 const char *format, ...)
Lucas De Marchi586fc302011-11-21 14:35:35 -020091{
92 va_list args;
93
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -020094 if (ctx->log_fn == NULL)
95 return;
96
Lucas De Marchi586fc302011-11-21 14:35:35 -020097 va_start(args, format);
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -020098 ctx->log_fn(ctx->log_data, priority, file, line, fn, format, args);
Lucas De Marchi586fc302011-11-21 14:35:35 -020099 va_end(args);
100}
101
Lucas De Marchi1958af82013-04-21 16:16:18 -0300102_printf_format_(6, 0)
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200103static void log_filep(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -0200104 int priority, const char *file, int line,
105 const char *fn, const char *format, va_list args)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200106{
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200107 FILE *fp = data;
Gustavo Sverzut Barbierie3cb0902012-01-07 19:25:03 -0200108#ifdef ENABLE_DEBUG
109 char buf[16];
110 const char *priname;
111 switch (priority) {
112 case LOG_EMERG:
113 priname = "EMERGENCY";
114 break;
115 case LOG_ALERT:
116 priname = "ALERT";
117 break;
118 case LOG_CRIT:
119 priname = "CRITICAL";
120 break;
121 case LOG_ERR:
122 priname = "ERROR";
123 break;
124 case LOG_WARNING:
125 priname = "WARNING";
126 break;
127 case LOG_NOTICE:
128 priname = "NOTICE";
129 break;
130 case LOG_INFO:
131 priname = "INFO";
132 break;
133 case LOG_DEBUG:
134 priname = "DEBUG";
135 break;
136 default:
137 snprintf(buf, sizeof(buf), "L:%d", priority);
138 priname = buf;
139 }
140 fprintf(fp, "libkmod: %s %s:%d %s: ", priname, file, line, fn);
141#else
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200142 fprintf(fp, "libkmod: %s: ", fn);
Gustavo Sverzut Barbierie3cb0902012-01-07 19:25:03 -0200143#endif
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200144 vfprintf(fp, format, args);
Lucas De Marchi586fc302011-11-21 14:35:35 -0200145}
146
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200147const char *kmod_get_dirname(const struct kmod_ctx *ctx)
Lucas De Marchi221631d2011-11-24 16:41:01 -0200148{
149 return ctx->dirname;
150}
151
Lucas De Marchi586fc302011-11-21 14:35:35 -0200152/**
153 * kmod_get_userdata:
154 * @ctx: kmod library context
155 *
156 * Retrieve stored data pointer from library context. This might be useful
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200157 * to access from callbacks.
Lucas De Marchi586fc302011-11-21 14:35:35 -0200158 *
159 * Returns: stored userdata
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200160 */
Lucas De Marchi6d177552011-11-23 11:52:30 -0200161KMOD_EXPORT void *kmod_get_userdata(const struct kmod_ctx *ctx)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200162{
163 if (ctx == NULL)
164 return NULL;
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200165 return (void *)ctx->userdata;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200166}
167
168/**
169 * kmod_set_userdata:
170 * @ctx: kmod library context
171 * @userdata: data pointer
172 *
173 * Store custom @userdata in the library context.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200174 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200175KMOD_EXPORT void kmod_set_userdata(struct kmod_ctx *ctx, const void *userdata)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200176{
177 if (ctx == NULL)
178 return;
179 ctx->userdata = userdata;
180}
181
182static int log_priority(const char *priority)
183{
184 char *endptr;
185 int prio;
186
187 prio = strtol(priority, &endptr, 10);
188 if (endptr[0] == '\0' || isspace(endptr[0]))
189 return prio;
190 if (strncmp(priority, "err", 3) == 0)
191 return LOG_ERR;
192 if (strncmp(priority, "info", 4) == 0)
193 return LOG_INFO;
194 if (strncmp(priority, "debug", 5) == 0)
195 return LOG_DEBUG;
196 return 0;
197}
198
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400199static const char *dirname_default_prefix = "/lib/modules";
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200200
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200201static char *get_kernel_release(const char *dirname)
Lucas De Marchi221631d2011-11-24 16:41:01 -0200202{
203 struct utsname u;
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200204 char *p;
205
206 if (dirname != NULL)
Lucas De Marchi2e092e12012-01-14 02:31:51 -0200207 return path_make_absolute_cwd(dirname);
Lucas De Marchi221631d2011-11-24 16:41:01 -0200208
209 if (uname(&u) < 0)
210 return NULL;
211
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200212 if (asprintf(&p, "%s/%s", dirname_default_prefix, u.release) < 0)
213 return NULL;
214
215 return p;
Lucas De Marchi221631d2011-11-24 16:41:01 -0200216}
217
Lucas De Marchi586fc302011-11-21 14:35:35 -0200218/**
219 * kmod_new:
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200220 * @dirname: what to consider as linux module's directory, if NULL
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400221 * defaults to /lib/modules/`uname -r`. If it's relative,
Chengwei Yang491c4902013-05-04 17:07:02 +0800222 * it's treated as relative to the current working directory.
223 * Otherwise, give an absolute dirname.
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200224 * @config_paths: ordered array of paths (directories or files) where
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200225 * to load from user-defined configuration parameters such as
226 * alias, blacklists, commands (install, remove). If
227 * NULL defaults to /run/modprobe.d, /etc/modprobe.d and
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400228 * /lib/modprobe.d. Give an empty vector if configuration should
229 * not be read. This array must be null terminated.
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200230 *
Lucas De Marchie1daa4f2012-01-09 03:09:49 -0200231 * Create kmod library context. This reads the kmod configuration
232 * and fills in the default values.
233 *
234 * The initial refcount is 1, and needs to be decremented to
235 * release the resources of the kmod library context.
236 *
Lucas De Marchi586fc302011-11-21 14:35:35 -0200237 * Returns: a new kmod library context
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200238 */
Lucas De Marchic35347f2011-12-12 10:48:02 -0200239KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname,
240 const char * const *config_paths)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200241{
242 const char *env;
Lucas De Marchi52a77042011-11-21 15:07:27 -0200243 struct kmod_ctx *ctx;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200244 int err;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200245
Lucas De Marchi52a77042011-11-21 15:07:27 -0200246 ctx = calloc(1, sizeof(struct kmod_ctx));
247 if (!ctx)
248 return NULL;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200249
Lucas De Marchi52a77042011-11-21 15:07:27 -0200250 ctx->refcount = 1;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200251 ctx->log_fn = log_filep;
252 ctx->log_data = stderr;
Lucas De Marchi52a77042011-11-21 15:07:27 -0200253 ctx->log_priority = LOG_ERR;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200254
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200255 ctx->dirname = get_kernel_release(dirname);
Lucas De Marchi221631d2011-11-24 16:41:01 -0200256
Lucas De Marchi586fc302011-11-21 14:35:35 -0200257 /* environment overwrites config */
Cristian Rodríguez41a51c22013-02-11 15:07:52 -0300258 env = secure_getenv("KMOD_LOG");
Lucas De Marchi586fc302011-11-21 14:35:35 -0200259 if (env != NULL)
Lucas De Marchi52a77042011-11-21 15:07:27 -0200260 kmod_set_log_priority(ctx, log_priority(env));
Lucas De Marchi586fc302011-11-21 14:35:35 -0200261
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200262 if (config_paths == NULL)
263 config_paths = default_config_paths;
264 err = kmod_config_new(ctx, &ctx->config, config_paths);
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200265 if (err < 0) {
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200266 ERR(ctx, "could not create config\n");
267 goto fail;
268 }
269
Lucas De Marchi822913d2011-12-27 12:13:54 -0200270 ctx->modules_by_name = hash_new(KMOD_HASH_SIZE, NULL);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200271 if (ctx->modules_by_name == NULL) {
272 ERR(ctx, "could not create by-name hash\n");
273 goto fail;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200274 }
Lucas De Marchi7c2ab352011-11-29 18:07:43 -0200275
Lucas De Marchiae6df842011-11-25 01:05:30 -0200276 INFO(ctx, "ctx %p created\n", ctx);
277 DBG(ctx, "log_priority=%d\n", ctx->log_priority);
Lucas De Marchi52a77042011-11-21 15:07:27 -0200278
279 return ctx;
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200280
281fail:
282 free(ctx->modules_by_name);
283 free(ctx->dirname);
284 free(ctx);
285 return NULL;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200286}
287
288/**
289 * kmod_ref:
290 * @ctx: kmod library context
291 *
292 * Take a reference of the kmod library context.
293 *
294 * Returns: the passed kmod library context
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200295 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200296KMOD_EXPORT struct kmod_ctx *kmod_ref(struct kmod_ctx *ctx)
297{
298 if (ctx == NULL)
299 return NULL;
300 ctx->refcount++;
301 return ctx;
302}
303
304/**
305 * kmod_unref:
306 * @ctx: kmod library context
307 *
308 * Drop a reference of the kmod library context. If the refcount
309 * reaches zero, the resources of the context will be released.
Chengwei Yang491c4902013-05-04 17:07:02 +0800310 *
311 * Returns: the passed kmod library context or NULL if it's freed
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200312 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200313KMOD_EXPORT struct kmod_ctx *kmod_unref(struct kmod_ctx *ctx)
314{
315 if (ctx == NULL)
316 return NULL;
Lucas De Marchi4d1e6892011-11-24 15:41:48 -0200317
318 if (--ctx->refcount > 0)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200319 return ctx;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200320
Lucas De Marchiae6df842011-11-25 01:05:30 -0200321 INFO(ctx, "context %p released\n", ctx);
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200322
323 kmod_unload_resources(ctx);
Lucas De Marchi822913d2011-12-27 12:13:54 -0200324 hash_free(ctx->modules_by_name);
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200325 free(ctx->dirname);
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200326 if (ctx->config)
327 kmod_config_free(ctx->config);
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200328
Lucas De Marchi586fc302011-11-21 14:35:35 -0200329 free(ctx);
330 return NULL;
331}
332
333/**
334 * kmod_set_log_fn:
335 * @ctx: kmod library context
336 * @log_fn: function to be called for logging messages
Lucas De Marchib5b4d8e2012-01-04 21:07:59 -0200337 * @data: data to pass to log function
Lucas De Marchi586fc302011-11-21 14:35:35 -0200338 *
339 * The built-in logging writes to stderr. It can be
340 * overridden by a custom function, to plug log messages
341 * into the user's logging functionality.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200342 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200343KMOD_EXPORT void kmod_set_log_fn(struct kmod_ctx *ctx,
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200344 void (*log_fn)(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -0200345 int priority, const char *file,
346 int line, const char *fn,
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200347 const char *format, va_list args),
348 const void *data)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200349{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200350 if (ctx == NULL)
351 return;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200352 ctx->log_fn = log_fn;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200353 ctx->log_data = (void *)data;
Lucas De Marchiae6df842011-11-25 01:05:30 -0200354 INFO(ctx, "custom logging function %p registered\n", log_fn);
Lucas De Marchi586fc302011-11-21 14:35:35 -0200355}
356
357/**
358 * kmod_get_log_priority:
359 * @ctx: kmod library context
360 *
361 * Returns: the current logging priority
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200362 */
Lucas De Marchi6d177552011-11-23 11:52:30 -0200363KMOD_EXPORT int kmod_get_log_priority(const struct kmod_ctx *ctx)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200364{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200365 if (ctx == NULL)
366 return -1;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200367 return ctx->log_priority;
368}
369
370/**
371 * kmod_set_log_priority:
372 * @ctx: kmod library context
373 * @priority: the new logging priority
374 *
375 * Set the current logging priority. The value controls which messages
376 * are logged.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200377 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200378KMOD_EXPORT void kmod_set_log_priority(struct kmod_ctx *ctx, int priority)
379{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200380 if (ctx == NULL)
381 return;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200382 ctx->log_priority = priority;
383}
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200384
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200385struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx,
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200386 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200387{
388 struct kmod_module *mod;
389
Lucas De Marchi822913d2011-12-27 12:13:54 -0200390 mod = hash_find(ctx->modules_by_name, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200391
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200392 DBG(ctx, "get module name='%s' found=%p\n", key, mod);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200393
394 return mod;
395}
396
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200397void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod,
398 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200399{
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200400 DBG(ctx, "add %p key='%s'\n", mod, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200401
Lucas De Marchi822913d2011-12-27 12:13:54 -0200402 hash_add(ctx->modules_by_name, key, mod);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200403}
404
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200405void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod,
406 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200407{
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200408 DBG(ctx, "del %p key='%s'\n", mod, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200409
Lucas De Marchi822913d2011-12-27 12:13:54 -0200410 hash_del(ctx->modules_by_name, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200411}
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200412
Lucas De Marchia0094822011-12-02 09:53:31 -0200413static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,
Lucas De Marchi810803d2011-12-09 16:06:04 -0200414 enum kmod_index index_number,
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200415 const char *name,
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200416 struct kmod_list **list)
417{
Lucas De Marchi6f1bc6e2011-12-02 10:02:05 -0200418 int err, nmatch = 0;
Lucas De Marchi0fbdfef2011-12-02 09:56:22 -0200419 struct index_file *idx;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200420 struct index_value *realnames, *realname;
421
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200422 if (ctx->indexes[index_number] != NULL) {
Gustavo Sverzut Barbieri3e245be2011-12-10 09:28:42 -0200423 DBG(ctx, "use mmaped index '%s' for name=%s\n",
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200424 index_files[index_number].fn, name);
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200425 realnames = index_mm_searchwild(ctx->indexes[index_number],
426 name);
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200427 } else {
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200428 char fn[PATH_MAX];
429
Gustavo Sverzut Barbieri3b209952011-12-10 09:21:03 -0200430 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200431 index_files[index_number].fn);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200432
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200433 DBG(ctx, "file=%s name=%s\n", fn, name);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200434
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200435 idx = index_file_open(fn);
436 if (idx == NULL)
437 return -ENOSYS;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200438
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200439 realnames = index_searchwild(idx, name);
440 index_file_close(idx);
441 }
Lucas De Marchi4272d082011-12-09 15:33:37 -0200442
Ulisses Furquima955f712011-12-15 19:17:49 -0200443 for (realname = realnames; realname; realname = realname->next) {
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200444 struct kmod_module *mod;
445
Lucas De Marchiee3b3ff2011-12-13 14:20:48 -0200446 err = kmod_module_new_from_alias(ctx, name, realname->value, &mod);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200447 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200448 ERR(ctx, "Could not create module for alias=%s realname=%s: %s\n",
449 name, realname->value, strerror(-err));
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200450 goto fail;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200451 }
452
453 *list = kmod_list_append(*list, mod);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200454 nmatch++;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200455 }
456
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200457 index_values_free(realnames);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200458 return nmatch;
459
460fail:
461 *list = kmod_list_remove_n_latest(*list, nmatch);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200462 return err;
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200463
464}
465
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200466int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name,
467 struct kmod_list **list)
468{
Lucas De Marchi0c010fa2011-12-28 13:33:26 -0200469 if (!strstartswith(name, "symbol:"))
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200470 return 0;
471
Lucas De Marchib08314f2012-01-16 12:01:48 -0200472 return kmod_lookup_alias_from_alias_bin(ctx, KMOD_INDEX_MODULES_SYMBOL,
473 name, list);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200474}
475
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200476int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name,
477 struct kmod_list **list)
478{
Lucas De Marchib08314f2012-01-16 12:01:48 -0200479 return kmod_lookup_alias_from_alias_bin(ctx, KMOD_INDEX_MODULES_ALIAS,
480 name, list);
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200481}
482
Lucas De Marchi38052742012-02-16 20:43:16 -0200483int kmod_lookup_alias_from_builtin_file(struct kmod_ctx *ctx, const char *name,
484 struct kmod_list **list)
485{
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300486 char *line = NULL;
487 int err = 0;
Lucas De Marchi38052742012-02-16 20:43:16 -0200488
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300489 assert(*list == NULL);
Lucas De Marchi38052742012-02-16 20:43:16 -0200490
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300491 if (ctx->indexes[KMOD_INDEX_MODULES_BUILTIN]) {
492 DBG(ctx, "use mmaped index '%s' modname=%s\n",
493 index_files[KMOD_INDEX_MODULES_BUILTIN].fn,
494 name);
495 line = index_mm_search(ctx->indexes[KMOD_INDEX_MODULES_BUILTIN],
496 name);
497 } else {
498 struct index_file *idx;
499 char fn[PATH_MAX];
500
501 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
502 index_files[KMOD_INDEX_MODULES_BUILTIN].fn);
503 DBG(ctx, "file=%s modname=%s\n", fn, name);
504
505 idx = index_file_open(fn);
506 if (idx == NULL) {
507 DBG(ctx, "could not open builtin file '%s'\n", fn);
508 goto finish;
509 }
510
511 line = index_search(idx, name);
512 index_file_close(idx);
Lucas De Marchi38052742012-02-16 20:43:16 -0200513 }
514
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300515 if (line != NULL) {
516 struct kmod_module *mod;
517
518 err = kmod_module_new_from_name(ctx, name, &mod);
519 if (err < 0) {
520 ERR(ctx, "Could not create module from name %s: %s\n",
521 name, strerror(-err));
522 goto finish;
523 }
524
525 kmod_module_set_builtin(mod, true);
526 *list = kmod_list_append(*list, mod);
527 if (*list == NULL)
528 err = -ENOMEM;
529 }
530
531finish:
532 free(line);
Lucas De Marchi38052742012-02-16 20:43:16 -0200533 return err;
534}
535
Lucas De Marchi671d4892011-12-05 20:23:05 -0200536char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name)
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200537{
538 struct index_file *idx;
539 char fn[PATH_MAX];
540 char *line;
541
Lucas De Marchib08314f2012-01-16 12:01:48 -0200542 if (ctx->indexes[KMOD_INDEX_MODULES_DEP]) {
Gustavo Sverzut Barbieri85132102011-12-10 09:26:27 -0200543 DBG(ctx, "use mmaped index '%s' modname=%s\n",
Lucas De Marchib08314f2012-01-16 12:01:48 -0200544 index_files[KMOD_INDEX_MODULES_DEP].fn, name);
545 return index_mm_search(ctx->indexes[KMOD_INDEX_MODULES_DEP],
546 name);
Gustavo Sverzut Barbieri85132102011-12-10 09:26:27 -0200547 }
548
Lucas De Marchia4a75022011-12-08 14:56:48 -0200549 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
Lucas De Marchib08314f2012-01-16 12:01:48 -0200550 index_files[KMOD_INDEX_MODULES_DEP].fn);
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200551
552 DBG(ctx, "file=%s modname=%s\n", fn, name);
553
554 idx = index_file_open(fn);
555 if (idx == NULL) {
Lucas De Marchiadca3cd2012-02-17 05:00:09 -0200556 DBG(ctx, "could not open moddep file '%s'\n", fn);
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200557 return NULL;
558 }
559
560 line = index_search(idx, name);
561 index_file_close(idx);
562
563 return line;
564}
565
Lucas De Marchi64700e42011-12-01 15:57:53 -0200566int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name,
567 struct kmod_list **list)
568{
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200569 char *line;
Lucas De Marchi64700e42011-12-01 15:57:53 -0200570 int n = 0;
571
572 /*
573 * Module names do not contain ':'. Return early if we know it will
574 * not be found.
575 */
576 if (strchr(name, ':'))
577 return 0;
578
Lucas De Marchi671d4892011-12-05 20:23:05 -0200579 line = kmod_search_moddep(ctx, name);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200580 if (line != NULL) {
581 struct kmod_module *mod;
582
583 n = kmod_module_new_from_name(ctx, name, &mod);
584 if (n < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200585 ERR(ctx, "Could not create module from name %s: %s\n",
586 name, strerror(-n));
Lucas De Marchi64700e42011-12-01 15:57:53 -0200587 goto finish;
588 }
589
590 *list = kmod_list_append(*list, mod);
Lucas De Marchi671d4892011-12-05 20:23:05 -0200591 kmod_module_parse_depline(mod, line);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200592 }
593
594finish:
595 free(line);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200596
597 return n;
598}
599
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200600int kmod_lookup_alias_from_config(struct kmod_ctx *ctx, const char *name,
601 struct kmod_list **list)
602{
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200603 struct kmod_config *config = ctx->config;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200604 struct kmod_list *l;
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200605 int err, nmatch = 0;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200606
607 kmod_list_foreach(l, config->aliases) {
608 const char *aliasname = kmod_alias_get_name(l);
609 const char *modname = kmod_alias_get_modname(l);
610
611 if (fnmatch(aliasname, name, 0) == 0) {
612 struct kmod_module *mod;
613
Lucas De Marchiee3b3ff2011-12-13 14:20:48 -0200614 err = kmod_module_new_from_alias(ctx, aliasname,
615 modname, &mod);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200616 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200617 ERR(ctx, "Could not create module for alias=%s modname=%s: %s\n",
618 name, modname, strerror(-err));
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200619 goto fail;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200620 }
621
622 *list = kmod_list_append(*list, mod);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200623 nmatch++;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200624 }
625 }
626
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200627 return nmatch;
628
629fail:
630 *list = kmod_list_remove_n_latest(*list, nmatch);
631 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200632}
Gustavo Sverzut Barbieri1487a642011-12-08 05:17:43 -0200633
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200634int kmod_lookup_alias_from_commands(struct kmod_ctx *ctx, const char *name,
635 struct kmod_list **list)
636{
637 struct kmod_config *config = ctx->config;
638 struct kmod_list *l, *node;
639 int err, nmatch = 0;
640
641 kmod_list_foreach(l, config->install_commands) {
642 const char *modname = kmod_command_get_modname(l);
643
644 if (streq(modname, name)) {
645 const char *cmd = kmod_command_get_command(l);
646 struct kmod_module *mod;
647
648 err = kmod_module_new_from_name(ctx, modname, &mod);
649 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200650 ERR(ctx, "Could not create module from name %s: %s\n",
651 modname, strerror(-err));
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200652 return err;
653 }
654
655 node = kmod_list_append(*list, mod);
656 if (node == NULL) {
657 ERR(ctx, "out of memory\n");
658 return -ENOMEM;
659 }
660
661 *list = node;
662 nmatch = 1;
663
664 kmod_module_set_install_commands(mod, cmd);
665
666 /*
667 * match only the first one, like modprobe from
668 * module-init-tools does
669 */
670 break;
671 }
672 }
673
674 if (nmatch)
675 return nmatch;
676
677 kmod_list_foreach(l, config->remove_commands) {
678 const char *modname = kmod_command_get_modname(l);
679
680 if (streq(modname, name)) {
681 const char *cmd = kmod_command_get_command(l);
682 struct kmod_module *mod;
683
684 err = kmod_module_new_from_name(ctx, modname, &mod);
685 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200686 ERR(ctx, "Could not create module from name %s: %s\n",
687 modname, strerror(-err));
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200688 return err;
689 }
690
691 node = kmod_list_append(*list, mod);
692 if (node == NULL) {
693 ERR(ctx, "out of memory\n");
694 return -ENOMEM;
695 }
696
697 *list = node;
698 nmatch = 1;
699
700 kmod_module_set_remove_commands(mod, cmd);
701
702 /*
703 * match only the first one, like modprobe from
704 * module-init-tools does
705 */
706 break;
707 }
708 }
709
710 return nmatch;
711}
712
Lucas De Marchiece09aa2012-01-18 01:26:44 -0200713void kmod_set_modules_visited(struct kmod_ctx *ctx, bool visited)
714{
715 struct hash_iter iter;
716 const void *v;
717
718 hash_iter_init(ctx->modules_by_name, &iter);
719 while (hash_iter_next(&iter, NULL, &v))
720 kmod_module_set_visited((struct kmod_module *)v, visited);
721}
722
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200723static bool is_cache_invalid(const char *path, unsigned long long stamp)
724{
725 struct stat st;
726
727 if (stat(path, &st) < 0)
728 return true;
729
Lucas De Marchi6068aaa2012-01-17 12:10:42 -0200730 if (stamp != stat_mstamp(&st))
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200731 return true;
732
733 return false;
734}
735
736/**
737 * kmod_validate_resources:
738 * @ctx: kmod library context
739 *
740 * Check if indexes and configuration files changed on disk and the current
741 * context is not valid anymore.
742 *
Lucas De Marchif4cc6ea2012-01-09 02:35:41 -0200743 * Returns: KMOD_RESOURCES_OK if resources are still valid,
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200744 * KMOD_RESOURCES_MUST_RELOAD if it's sufficient to call
745 * kmod_unload_resources() and kmod_load_resources() or
746 * KMOD_RESOURCES_MUST_RECREATE if @ctx must be re-created.
747 */
748KMOD_EXPORT int kmod_validate_resources(struct kmod_ctx *ctx)
749{
750 struct kmod_list *l;
751 size_t i;
752
753 if (ctx == NULL || ctx->config == NULL)
754 return KMOD_RESOURCES_MUST_RECREATE;
755
756 kmod_list_foreach(l, ctx->config->paths) {
757 struct kmod_config_path *cf = l->data;
758
759 if (is_cache_invalid(cf->path, cf->stamp))
760 return KMOD_RESOURCES_MUST_RECREATE;
761 }
762
Lucas De Marchib08314f2012-01-16 12:01:48 -0200763 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200764 char path[PATH_MAX];
765
766 if (ctx->indexes[i] == NULL)
767 continue;
768
769 snprintf(path, sizeof(path), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200770 index_files[i].fn);
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200771
772 if (is_cache_invalid(path, ctx->indexes_stamp[i]))
773 return KMOD_RESOURCES_MUST_RELOAD;
774 }
775
776 return KMOD_RESOURCES_OK;
777}
778
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200779/**
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200780 * kmod_load_resources:
781 * @ctx: kmod library context
782 *
783 * Load indexes and keep them open in @ctx. This way it's faster to lookup
784 * information within the indexes. If this function is not called before a
785 * search, the necessary index is always opened and closed.
786 *
787 * If user will do more than one or two lookups, insertions, deletions, most
788 * likely it's good to call this function first. Particularly in a daemon like
789 * udev that on bootup issues hundreds of calls to lookup the index, calling
790 * this function will speedup the searches.
791 *
792 * Returns: 0 on success or < 0 otherwise.
793 */
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200794KMOD_EXPORT int kmod_load_resources(struct kmod_ctx *ctx)
795{
796 size_t i;
797
798 if (ctx == NULL)
799 return -ENOENT;
800
Lucas De Marchib08314f2012-01-16 12:01:48 -0200801 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchi6de8f6e2011-12-14 03:58:31 -0200802 char path[PATH_MAX];
Lucas De Marchi3e676762011-12-14 03:53:43 -0200803
Lucas De Marchi16ca3662011-12-20 12:29:13 -0200804 if (ctx->indexes[i] != NULL) {
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200805 INFO(ctx, "Index %s already loaded\n",
806 index_files[i].fn);
Lucas De Marchi3e676762011-12-14 03:53:43 -0200807 continue;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200808 }
Lucas De Marchi3e676762011-12-14 03:53:43 -0200809
Lucas De Marchi6de8f6e2011-12-14 03:58:31 -0200810 snprintf(path, sizeof(path), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200811 index_files[i].fn);
Lucas De Marchi2e2e2522012-03-02 20:33:26 -0300812 ctx->indexes[i] = index_mm_open(ctx, path,
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200813 &ctx->indexes_stamp[i]);
Lucas De Marchi3e676762011-12-14 03:53:43 -0200814 if (ctx->indexes[i] == NULL)
815 goto fail;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200816 }
817
818 return 0;
819
820fail:
821 kmod_unload_resources(ctx);
822 return -ENOMEM;
823}
824
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200825/**
826 * kmod_unload_resources:
827 * @ctx: kmod library context
828 *
829 * Unload all the indexes. This will free the resources to maintain the index
830 * open and all subsequent searches will need to open and close the index.
831 *
832 * User is free to call kmod_load_resources() and kmod_unload_resources() as
833 * many times as wanted during the lifecycle of @ctx. For example, if a daemon
834 * knows that when starting up it will lookup a lot of modules, it could call
835 * kmod_load_resources() and after the first burst of searches is gone, it
836 * could free the resources by calling kmod_unload_resources().
837 *
838 * Returns: 0 on success or < 0 otherwise.
839 */
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200840KMOD_EXPORT void kmod_unload_resources(struct kmod_ctx *ctx)
841{
842 size_t i;
843
844 if (ctx == NULL)
845 return;
846
Lucas De Marchib08314f2012-01-16 12:01:48 -0200847 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200848 if (ctx->indexes[i] != NULL) {
849 index_mm_close(ctx->indexes[i]);
850 ctx->indexes[i] = NULL;
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200851 ctx->indexes_stamp[i] = 0;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200852 }
853 }
854}
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200855
Lucas De Marchi02244822012-01-16 16:43:47 -0200856/**
857 * kmod_dump_index:
858 * @ctx: kmod library context
Chengwei Yangd7152f62013-05-04 17:07:03 +0800859 * @type: index to dump, valid indexes are
860 * KMOD_INDEX_MODULES_DEP: index of module dependencies;
861 * KMOD_INDEX_MODULES_ALIAS: index of module aliases;
862 * KMOD_INDEX_MODULES_SYMBOL: index of symbol aliases;
863 * KMOD_INDEX_MODULES_BUILTIN: index of builtin module.
Lucas De Marchi02244822012-01-16 16:43:47 -0200864 * @fd: file descriptor to dump index to
865 *
Lucas De Marchi09e9ae52012-01-17 10:05:02 -0200866 * Dump index to file descriptor. Note that this function doesn't use stdio.h
867 * so call fflush() before calling this function to be sure data is written in
868 * order.
Lucas De Marchi02244822012-01-16 16:43:47 -0200869 *
870 * Returns: 0 on success or < 0 otherwise.
871 */
Lucas De Marchi758428a2012-01-16 15:56:17 -0200872KMOD_EXPORT int kmod_dump_index(struct kmod_ctx *ctx, enum kmod_index type,
873 int fd)
874{
875 if (ctx == NULL)
876 return -ENOSYS;
877
878 if (type < 0 || type >= _KMOD_INDEX_MODULES_SIZE)
879 return -ENOENT;
880
881 if (ctx->indexes[type] != NULL) {
882 DBG(ctx, "use mmaped index '%s'\n", index_files[type].fn);
883 index_mm_dump(ctx->indexes[type], fd,
884 index_files[type].prefix);
885 } else {
886 char fn[PATH_MAX];
887 struct index_file *idx;
888
889 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
890 index_files[type].fn);
891
892 DBG(ctx, "file=%s\n", fn);
893
894 idx = index_file_open(fn);
895 if (idx == NULL)
896 return -ENOSYS;
897
898 index_dump(idx, fd, index_files[type].prefix);
899 index_file_close(idx);
900 }
901
902 return 0;
903}
904
Lucas De Marchie7fc2c82012-06-12 01:43:46 -0300905const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx)
Lucas De Marchic1c9c442011-12-24 10:50:47 -0200906{
Lucas De Marchie7fc2c82012-06-12 01:43:46 -0300907 return ctx->config;
Lucas De Marchi8b5ee612012-01-13 01:14:46 -0200908}