blob: 643fd3801bd07f6ab45e42993095197eb08318b1 [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
Lucas De Marchidea2dfe2014-12-25 23:32:03 -020017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Lucas De Marchi586fc302011-11-21 14:35:35 -020018 */
19
Lucas De Marchiee1d1882012-02-27 18:48:02 -030020#include <assert.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030021#include <ctype.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020022#include <errno.h>
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -020023#include <fnmatch.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030024#include <limits.h>
25#include <stdarg.h>
26#include <stddef.h>
27#include <stdio.h>
28#include <stdlib.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020029#include <string.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030030#include <unistd.h>
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -020031#include <sys/stat.h>
Lucas De Marchic2e42862014-10-03 01:41:42 -030032#include <sys/utsname.h>
Lucas De Marchi586fc302011-11-21 14:35:35 -020033
Lucas De Marchi0db718e2014-10-03 00:29:18 -030034#include <shared/hash.h>
Lucas De Marchi96573a02014-10-03 00:01:35 -030035#include <shared/util.h>
36
Lucas De Marchi586fc302011-11-21 14:35:35 -020037#include "libkmod.h"
Lucas De Marchi83b855a2013-07-04 16:13:11 -030038#include "libkmod-internal.h"
Lucas De Marchi9ba6f572011-11-30 20:31:45 -020039#include "libkmod-index.h"
Lucas De Marchi586fc302011-11-21 14:35:35 -020040
Lucas De Marchifd186ae2011-12-06 03:38:37 -020041#define KMOD_HASH_SIZE (256)
42#define KMOD_LRU_MAX (128)
Lucas De Marchi38052742012-02-16 20:43:16 -020043#define _KMOD_INDEX_MODULES_SIZE KMOD_INDEX_MODULES_BUILTIN + 1
Lucas De Marchifd186ae2011-12-06 03:38:37 -020044
Lucas De Marchi586fc302011-11-21 14:35:35 -020045/**
46 * SECTION:libkmod
47 * @short_description: libkmod context
48 *
49 * The context contains the default values for the library user,
50 * and is passed to all library operations.
51 */
52
Lucas De Marchi63be91c2012-01-16 10:43:34 -020053static struct _index_files {
54 const char *fn;
55 const char *prefix;
56} index_files[] = {
Lucas De Marchib08314f2012-01-16 12:01:48 -020057 [KMOD_INDEX_MODULES_DEP] = { .fn = "modules.dep", .prefix = "" },
58 [KMOD_INDEX_MODULES_ALIAS] = { .fn = "modules.alias", .prefix = "alias " },
59 [KMOD_INDEX_MODULES_SYMBOL] = { .fn = "modules.symbols", .prefix = "alias "},
Lucas De Marchi38052742012-02-16 20:43:16 -020060 [KMOD_INDEX_MODULES_BUILTIN] = { .fn = "modules.builtin", .prefix = ""},
Lucas De Marchia4a75022011-12-08 14:56:48 -020061};
62
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -020063static const char *default_config_paths[] = {
Kay Sieversa308abe2011-12-20 17:58:05 +010064 SYSCONFDIR "/modprobe.d",
Lucas De Marchi436da1e2012-03-15 09:19:34 -030065 "/run/modprobe.d",
Dave Reisnerc5b37db2012-09-27 11:00:42 -040066 "/lib/modprobe.d",
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -020067 NULL
68};
69
Lucas De Marchi586fc302011-11-21 14:35:35 -020070/**
71 * kmod_ctx:
72 *
73 * Opaque object representing the library context.
74 */
75struct kmod_ctx {
76 int refcount;
Gustavo Sverzut Barbieri8d3f3ef2011-12-02 21:10:24 -020077 int log_priority;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -020078 void (*log_fn)(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -020079 int priority, const char *file, int line,
80 const char *fn, const char *format, va_list args);
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -020081 void *log_data;
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -020082 const void *userdata;
83 char *dirname;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -020084 struct kmod_config *config;
Lucas De Marchi822913d2011-12-27 12:13:54 -020085 struct hash *modules_by_name;
Lucas De Marchib08314f2012-01-16 12:01:48 -020086 struct index_mm *indexes[_KMOD_INDEX_MODULES_SIZE];
87 unsigned long long indexes_stamp[_KMOD_INDEX_MODULES_SIZE];
Lucas De Marchi586fc302011-11-21 14:35:35 -020088};
89
Lucas De Marchi71928282012-05-10 20:58:46 -030090void kmod_log(const struct kmod_ctx *ctx,
91 int priority, const char *file, int line, const char *fn,
92 const char *format, ...)
Lucas De Marchi586fc302011-11-21 14:35:35 -020093{
94 va_list args;
95
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -020096 if (ctx->log_fn == NULL)
97 return;
98
Lucas De Marchi586fc302011-11-21 14:35:35 -020099 va_start(args, format);
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200100 ctx->log_fn(ctx->log_data, priority, file, line, fn, format, args);
Lucas De Marchi586fc302011-11-21 14:35:35 -0200101 va_end(args);
102}
103
Lucas De Marchi1958af82013-04-21 16:16:18 -0300104_printf_format_(6, 0)
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200105static void log_filep(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -0200106 int priority, const char *file, int line,
107 const char *fn, const char *format, va_list args)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200108{
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200109 FILE *fp = data;
Gustavo Sverzut Barbierie3cb0902012-01-07 19:25:03 -0200110#ifdef ENABLE_DEBUG
111 char buf[16];
112 const char *priname;
113 switch (priority) {
114 case LOG_EMERG:
115 priname = "EMERGENCY";
116 break;
117 case LOG_ALERT:
118 priname = "ALERT";
119 break;
120 case LOG_CRIT:
121 priname = "CRITICAL";
122 break;
123 case LOG_ERR:
124 priname = "ERROR";
125 break;
126 case LOG_WARNING:
127 priname = "WARNING";
128 break;
129 case LOG_NOTICE:
130 priname = "NOTICE";
131 break;
132 case LOG_INFO:
133 priname = "INFO";
134 break;
135 case LOG_DEBUG:
136 priname = "DEBUG";
137 break;
138 default:
139 snprintf(buf, sizeof(buf), "L:%d", priority);
140 priname = buf;
141 }
142 fprintf(fp, "libkmod: %s %s:%d %s: ", priname, file, line, fn);
143#else
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200144 fprintf(fp, "libkmod: %s: ", fn);
Gustavo Sverzut Barbierie3cb0902012-01-07 19:25:03 -0200145#endif
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200146 vfprintf(fp, format, args);
Lucas De Marchi586fc302011-11-21 14:35:35 -0200147}
148
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200149const char *kmod_get_dirname(const struct kmod_ctx *ctx)
Lucas De Marchi221631d2011-11-24 16:41:01 -0200150{
151 return ctx->dirname;
152}
153
Lucas De Marchi586fc302011-11-21 14:35:35 -0200154/**
155 * kmod_get_userdata:
156 * @ctx: kmod library context
157 *
158 * Retrieve stored data pointer from library context. This might be useful
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200159 * to access from callbacks.
Lucas De Marchi586fc302011-11-21 14:35:35 -0200160 *
161 * Returns: stored userdata
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200162 */
Lucas De Marchi6d177552011-11-23 11:52:30 -0200163KMOD_EXPORT void *kmod_get_userdata(const struct kmod_ctx *ctx)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200164{
165 if (ctx == NULL)
166 return NULL;
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200167 return (void *)ctx->userdata;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200168}
169
170/**
171 * kmod_set_userdata:
172 * @ctx: kmod library context
173 * @userdata: data pointer
174 *
175 * Store custom @userdata in the library context.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200176 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200177KMOD_EXPORT void kmod_set_userdata(struct kmod_ctx *ctx, const void *userdata)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200178{
179 if (ctx == NULL)
180 return;
181 ctx->userdata = userdata;
182}
183
184static int log_priority(const char *priority)
185{
186 char *endptr;
187 int prio;
188
189 prio = strtol(priority, &endptr, 10);
190 if (endptr[0] == '\0' || isspace(endptr[0]))
191 return prio;
192 if (strncmp(priority, "err", 3) == 0)
193 return LOG_ERR;
194 if (strncmp(priority, "info", 4) == 0)
195 return LOG_INFO;
196 if (strncmp(priority, "debug", 5) == 0)
197 return LOG_DEBUG;
198 return 0;
199}
200
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400201static const char *dirname_default_prefix = "/lib/modules";
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200202
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200203static char *get_kernel_release(const char *dirname)
Lucas De Marchi221631d2011-11-24 16:41:01 -0200204{
205 struct utsname u;
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200206 char *p;
207
208 if (dirname != NULL)
Lucas De Marchi2e092e12012-01-14 02:31:51 -0200209 return path_make_absolute_cwd(dirname);
Lucas De Marchi221631d2011-11-24 16:41:01 -0200210
211 if (uname(&u) < 0)
212 return NULL;
213
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200214 if (asprintf(&p, "%s/%s", dirname_default_prefix, u.release) < 0)
215 return NULL;
216
217 return p;
Lucas De Marchi221631d2011-11-24 16:41:01 -0200218}
219
Lucas De Marchi586fc302011-11-21 14:35:35 -0200220/**
221 * kmod_new:
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200222 * @dirname: what to consider as linux module's directory, if NULL
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400223 * defaults to /lib/modules/`uname -r`. If it's relative,
Chengwei Yang491c4902013-05-04 17:07:02 +0800224 * it's treated as relative to the current working directory.
225 * Otherwise, give an absolute dirname.
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200226 * @config_paths: ordered array of paths (directories or files) where
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200227 * to load from user-defined configuration parameters such as
228 * alias, blacklists, commands (install, remove). If
229 * NULL defaults to /run/modprobe.d, /etc/modprobe.d and
Dave Reisnerc5b37db2012-09-27 11:00:42 -0400230 * /lib/modprobe.d. Give an empty vector if configuration should
231 * not be read. This array must be null terminated.
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200232 *
Lucas De Marchie1daa4f2012-01-09 03:09:49 -0200233 * Create kmod library context. This reads the kmod configuration
234 * and fills in the default values.
235 *
236 * The initial refcount is 1, and needs to be decremented to
237 * release the resources of the kmod library context.
238 *
Lucas De Marchi586fc302011-11-21 14:35:35 -0200239 * Returns: a new kmod library context
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200240 */
Lucas De Marchic35347f2011-12-12 10:48:02 -0200241KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname,
242 const char * const *config_paths)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200243{
244 const char *env;
Lucas De Marchi52a77042011-11-21 15:07:27 -0200245 struct kmod_ctx *ctx;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200246 int err;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200247
Lucas De Marchi52a77042011-11-21 15:07:27 -0200248 ctx = calloc(1, sizeof(struct kmod_ctx));
249 if (!ctx)
250 return NULL;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200251
Lucas De Marchi52a77042011-11-21 15:07:27 -0200252 ctx->refcount = 1;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200253 ctx->log_fn = log_filep;
254 ctx->log_data = stderr;
Lucas De Marchi52a77042011-11-21 15:07:27 -0200255 ctx->log_priority = LOG_ERR;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200256
Lucas De Marchi904c63a2011-11-30 20:27:50 -0200257 ctx->dirname = get_kernel_release(dirname);
Lucas De Marchi221631d2011-11-24 16:41:01 -0200258
Lucas De Marchi586fc302011-11-21 14:35:35 -0200259 /* environment overwrites config */
Cristian Rodríguez41a51c22013-02-11 15:07:52 -0300260 env = secure_getenv("KMOD_LOG");
Lucas De Marchi586fc302011-11-21 14:35:35 -0200261 if (env != NULL)
Lucas De Marchi52a77042011-11-21 15:07:27 -0200262 kmod_set_log_priority(ctx, log_priority(env));
Lucas De Marchi586fc302011-11-21 14:35:35 -0200263
Gustavo Sverzut Barbiericb8d4d32011-12-11 20:37:01 -0200264 if (config_paths == NULL)
265 config_paths = default_config_paths;
266 err = kmod_config_new(ctx, &ctx->config, config_paths);
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200267 if (err < 0) {
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200268 ERR(ctx, "could not create config\n");
269 goto fail;
270 }
271
Lucas De Marchi822913d2011-12-27 12:13:54 -0200272 ctx->modules_by_name = hash_new(KMOD_HASH_SIZE, NULL);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200273 if (ctx->modules_by_name == NULL) {
274 ERR(ctx, "could not create by-name hash\n");
275 goto fail;
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200276 }
Lucas De Marchi7c2ab352011-11-29 18:07:43 -0200277
Lucas De Marchiae6df842011-11-25 01:05:30 -0200278 INFO(ctx, "ctx %p created\n", ctx);
279 DBG(ctx, "log_priority=%d\n", ctx->log_priority);
Lucas De Marchi52a77042011-11-21 15:07:27 -0200280
281 return ctx;
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200282
283fail:
284 free(ctx->modules_by_name);
285 free(ctx->dirname);
286 free(ctx);
287 return NULL;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200288}
289
290/**
291 * kmod_ref:
292 * @ctx: kmod library context
293 *
294 * Take a reference of the kmod library context.
295 *
296 * Returns: the passed kmod library context
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200297 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200298KMOD_EXPORT struct kmod_ctx *kmod_ref(struct kmod_ctx *ctx)
299{
300 if (ctx == NULL)
301 return NULL;
302 ctx->refcount++;
303 return ctx;
304}
305
306/**
307 * kmod_unref:
308 * @ctx: kmod library context
309 *
310 * Drop a reference of the kmod library context. If the refcount
311 * reaches zero, the resources of the context will be released.
Chengwei Yang491c4902013-05-04 17:07:02 +0800312 *
313 * Returns: the passed kmod library context or NULL if it's freed
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200314 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200315KMOD_EXPORT struct kmod_ctx *kmod_unref(struct kmod_ctx *ctx)
316{
317 if (ctx == NULL)
318 return NULL;
Lucas De Marchi4d1e6892011-11-24 15:41:48 -0200319
320 if (--ctx->refcount > 0)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200321 return ctx;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200322
Lucas De Marchiae6df842011-11-25 01:05:30 -0200323 INFO(ctx, "context %p released\n", ctx);
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200324
325 kmod_unload_resources(ctx);
Lucas De Marchi822913d2011-12-27 12:13:54 -0200326 hash_free(ctx->modules_by_name);
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200327 free(ctx->dirname);
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200328 if (ctx->config)
329 kmod_config_free(ctx->config);
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200330
Lucas De Marchi586fc302011-11-21 14:35:35 -0200331 free(ctx);
332 return NULL;
333}
334
335/**
336 * kmod_set_log_fn:
337 * @ctx: kmod library context
338 * @log_fn: function to be called for logging messages
Lucas De Marchib5b4d8e2012-01-04 21:07:59 -0200339 * @data: data to pass to log function
Lucas De Marchi586fc302011-11-21 14:35:35 -0200340 *
341 * The built-in logging writes to stderr. It can be
342 * overridden by a custom function, to plug log messages
343 * into the user's logging functionality.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200344 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200345KMOD_EXPORT void kmod_set_log_fn(struct kmod_ctx *ctx,
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200346 void (*log_fn)(void *data,
Lucas De Marchie4351b02011-11-21 14:59:23 -0200347 int priority, const char *file,
348 int line, const char *fn,
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200349 const char *format, va_list args),
350 const void *data)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200351{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200352 if (ctx == NULL)
353 return;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200354 ctx->log_fn = log_fn;
Gustavo Sverzut Barbieri1bdd9512011-12-08 13:47:55 -0200355 ctx->log_data = (void *)data;
Lucas De Marchiae6df842011-11-25 01:05:30 -0200356 INFO(ctx, "custom logging function %p registered\n", log_fn);
Lucas De Marchi586fc302011-11-21 14:35:35 -0200357}
358
359/**
360 * kmod_get_log_priority:
361 * @ctx: kmod library context
362 *
363 * Returns: the current logging priority
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200364 */
Lucas De Marchi6d177552011-11-23 11:52:30 -0200365KMOD_EXPORT int kmod_get_log_priority(const struct kmod_ctx *ctx)
Lucas De Marchi586fc302011-11-21 14:35:35 -0200366{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200367 if (ctx == NULL)
368 return -1;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200369 return ctx->log_priority;
370}
371
372/**
373 * kmod_set_log_priority:
374 * @ctx: kmod library context
375 * @priority: the new logging priority
376 *
377 * Set the current logging priority. The value controls which messages
378 * are logged.
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200379 */
Lucas De Marchi586fc302011-11-21 14:35:35 -0200380KMOD_EXPORT void kmod_set_log_priority(struct kmod_ctx *ctx, int priority)
381{
Gustavo Sverzut Barbierie5c60f12011-12-08 13:58:46 -0200382 if (ctx == NULL)
383 return;
Lucas De Marchi586fc302011-11-21 14:35:35 -0200384 ctx->log_priority = priority;
385}
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200386
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200387struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx,
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200388 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200389{
390 struct kmod_module *mod;
391
Lucas De Marchi822913d2011-12-27 12:13:54 -0200392 mod = hash_find(ctx->modules_by_name, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200393
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200394 DBG(ctx, "get module name='%s' found=%p\n", key, mod);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200395
396 return mod;
397}
398
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200399void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod,
400 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200401{
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200402 DBG(ctx, "add %p key='%s'\n", mod, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200403
Lucas De Marchi822913d2011-12-27 12:13:54 -0200404 hash_add(ctx->modules_by_name, key, mod);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200405}
406
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200407void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod,
408 const char *key)
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200409{
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200410 DBG(ctx, "del %p key='%s'\n", mod, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200411
Lucas De Marchi822913d2011-12-27 12:13:54 -0200412 hash_del(ctx->modules_by_name, key);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200413}
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200414
Lucas De Marchia0094822011-12-02 09:53:31 -0200415static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,
Lucas De Marchi810803d2011-12-09 16:06:04 -0200416 enum kmod_index index_number,
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200417 const char *name,
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200418 struct kmod_list **list)
419{
Lucas De Marchi6f1bc6e2011-12-02 10:02:05 -0200420 int err, nmatch = 0;
Lucas De Marchi0fbdfef2011-12-02 09:56:22 -0200421 struct index_file *idx;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200422 struct index_value *realnames, *realname;
423
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200424 if (ctx->indexes[index_number] != NULL) {
Gustavo Sverzut Barbieri3e245be2011-12-10 09:28:42 -0200425 DBG(ctx, "use mmaped index '%s' for name=%s\n",
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200426 index_files[index_number].fn, name);
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200427 realnames = index_mm_searchwild(ctx->indexes[index_number],
428 name);
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200429 } else {
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200430 char fn[PATH_MAX];
431
Gustavo Sverzut Barbieri3b209952011-12-10 09:21:03 -0200432 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200433 index_files[index_number].fn);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200434
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200435 DBG(ctx, "file=%s name=%s\n", fn, name);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200436
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200437 idx = index_file_open(fn);
438 if (idx == NULL)
439 return -ENOSYS;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200440
Lucas De Marchi65a84f52011-12-09 16:11:42 -0200441 realnames = index_searchwild(idx, name);
442 index_file_close(idx);
443 }
Lucas De Marchi4272d082011-12-09 15:33:37 -0200444
Ulisses Furquima955f712011-12-15 19:17:49 -0200445 for (realname = realnames; realname; realname = realname->next) {
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200446 struct kmod_module *mod;
447
Lucas De Marchiee3b3ff2011-12-13 14:20:48 -0200448 err = kmod_module_new_from_alias(ctx, name, realname->value, &mod);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200449 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200450 ERR(ctx, "Could not create module for alias=%s realname=%s: %s\n",
451 name, realname->value, strerror(-err));
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200452 goto fail;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200453 }
454
455 *list = kmod_list_append(*list, mod);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200456 nmatch++;
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200457 }
458
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200459 index_values_free(realnames);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200460 return nmatch;
461
462fail:
463 *list = kmod_list_remove_n_latest(*list, nmatch);
Leandro Pereirae84d9122014-04-28 21:01:48 -0300464 index_values_free(realnames);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200465 return err;
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200466
467}
468
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200469int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name,
470 struct kmod_list **list)
471{
Lucas De Marchi0c010fa2011-12-28 13:33:26 -0200472 if (!strstartswith(name, "symbol:"))
Lucas De Marchi7b30f4f2011-12-01 16:25:37 -0200473 return 0;
474
Lucas De Marchib08314f2012-01-16 12:01:48 -0200475 return kmod_lookup_alias_from_alias_bin(ctx, KMOD_INDEX_MODULES_SYMBOL,
476 name, list);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200477}
478
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200479int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name,
480 struct kmod_list **list)
481{
Lucas De Marchib08314f2012-01-16 12:01:48 -0200482 return kmod_lookup_alias_from_alias_bin(ctx, KMOD_INDEX_MODULES_ALIAS,
483 name, list);
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200484}
485
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300486static char *lookup_builtin_file(struct kmod_ctx *ctx, const char *name)
Lucas De Marchi38052742012-02-16 20:43:16 -0200487{
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300488 char *line;
Lucas De Marchi38052742012-02-16 20:43:16 -0200489
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300490 if (ctx->indexes[KMOD_INDEX_MODULES_BUILTIN]) {
491 DBG(ctx, "use mmaped index '%s' modname=%s\n",
492 index_files[KMOD_INDEX_MODULES_BUILTIN].fn,
493 name);
494 line = index_mm_search(ctx->indexes[KMOD_INDEX_MODULES_BUILTIN],
495 name);
496 } else {
497 struct index_file *idx;
498 char fn[PATH_MAX];
499
500 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
501 index_files[KMOD_INDEX_MODULES_BUILTIN].fn);
502 DBG(ctx, "file=%s modname=%s\n", fn, name);
503
504 idx = index_file_open(fn);
505 if (idx == NULL) {
506 DBG(ctx, "could not open builtin file '%s'\n", fn);
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300507 return NULL;
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300508 }
509
510 line = index_search(idx, name);
511 index_file_close(idx);
Lucas De Marchi38052742012-02-16 20:43:16 -0200512 }
513
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300514 return line;
515}
516
517int kmod_lookup_alias_from_builtin_file(struct kmod_ctx *ctx, const char *name,
518 struct kmod_list **list)
519{
520 char *line;
521 int err = 0;
522
523 assert(*list == NULL);
524
525 line = lookup_builtin_file(ctx, name);
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300526 if (line != NULL) {
527 struct kmod_module *mod;
528
529 err = kmod_module_new_from_name(ctx, name, &mod);
530 if (err < 0) {
531 ERR(ctx, "Could not create module from name %s: %s\n",
532 name, strerror(-err));
533 goto finish;
534 }
535
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300536 /* already mark it as builtin since it's being created from
537 * this index */
Lucas De Marchiee1d1882012-02-27 18:48:02 -0300538 kmod_module_set_builtin(mod, true);
539 *list = kmod_list_append(*list, mod);
540 if (*list == NULL)
541 err = -ENOMEM;
542 }
543
544finish:
545 free(line);
Lucas De Marchi38052742012-02-16 20:43:16 -0200546 return err;
547}
548
Harish Jenny K Nfd44a982015-02-22 15:41:07 -0300549bool kmod_lookup_alias_is_builtin(struct kmod_ctx *ctx, const char *name)
550{
551 _cleanup_free_ char *line;
552
553 line = lookup_builtin_file(ctx, name);
554
555 return line != NULL;
556}
557
Lucas De Marchi671d4892011-12-05 20:23:05 -0200558char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name)
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200559{
560 struct index_file *idx;
561 char fn[PATH_MAX];
562 char *line;
563
Lucas De Marchib08314f2012-01-16 12:01:48 -0200564 if (ctx->indexes[KMOD_INDEX_MODULES_DEP]) {
Gustavo Sverzut Barbieri85132102011-12-10 09:26:27 -0200565 DBG(ctx, "use mmaped index '%s' modname=%s\n",
Lucas De Marchib08314f2012-01-16 12:01:48 -0200566 index_files[KMOD_INDEX_MODULES_DEP].fn, name);
567 return index_mm_search(ctx->indexes[KMOD_INDEX_MODULES_DEP],
568 name);
Gustavo Sverzut Barbieri85132102011-12-10 09:26:27 -0200569 }
570
Lucas De Marchia4a75022011-12-08 14:56:48 -0200571 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
Lucas De Marchib08314f2012-01-16 12:01:48 -0200572 index_files[KMOD_INDEX_MODULES_DEP].fn);
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200573
574 DBG(ctx, "file=%s modname=%s\n", fn, name);
575
576 idx = index_file_open(fn);
577 if (idx == NULL) {
Lucas De Marchiadca3cd2012-02-17 05:00:09 -0200578 DBG(ctx, "could not open moddep file '%s'\n", fn);
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200579 return NULL;
580 }
581
582 line = index_search(idx, name);
583 index_file_close(idx);
584
585 return line;
586}
587
Lucas De Marchi64700e42011-12-01 15:57:53 -0200588int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name,
589 struct kmod_list **list)
590{
Lucas De Marchi1eb2ef62011-12-05 19:58:39 -0200591 char *line;
Lucas De Marchi64700e42011-12-01 15:57:53 -0200592 int n = 0;
593
594 /*
595 * Module names do not contain ':'. Return early if we know it will
596 * not be found.
597 */
598 if (strchr(name, ':'))
599 return 0;
600
Lucas De Marchi671d4892011-12-05 20:23:05 -0200601 line = kmod_search_moddep(ctx, name);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200602 if (line != NULL) {
603 struct kmod_module *mod;
604
605 n = kmod_module_new_from_name(ctx, name, &mod);
606 if (n < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200607 ERR(ctx, "Could not create module from name %s: %s\n",
608 name, strerror(-n));
Lucas De Marchi64700e42011-12-01 15:57:53 -0200609 goto finish;
610 }
611
612 *list = kmod_list_append(*list, mod);
Lucas De Marchi671d4892011-12-05 20:23:05 -0200613 kmod_module_parse_depline(mod, line);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200614 }
615
616finish:
617 free(line);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200618
619 return n;
620}
621
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200622int kmod_lookup_alias_from_config(struct kmod_ctx *ctx, const char *name,
623 struct kmod_list **list)
624{
Gustavo Sverzut Barbierid13e6062011-12-02 21:40:22 -0200625 struct kmod_config *config = ctx->config;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200626 struct kmod_list *l;
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200627 int err, nmatch = 0;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200628
629 kmod_list_foreach(l, config->aliases) {
630 const char *aliasname = kmod_alias_get_name(l);
631 const char *modname = kmod_alias_get_modname(l);
632
633 if (fnmatch(aliasname, name, 0) == 0) {
634 struct kmod_module *mod;
635
Lucas De Marchiee3b3ff2011-12-13 14:20:48 -0200636 err = kmod_module_new_from_alias(ctx, aliasname,
637 modname, &mod);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200638 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200639 ERR(ctx, "Could not create module for alias=%s modname=%s: %s\n",
640 name, modname, strerror(-err));
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200641 goto fail;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200642 }
643
644 *list = kmod_list_append(*list, mod);
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200645 nmatch++;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200646 }
647 }
648
Lucas De Marchi23fc91c2011-12-01 15:35:31 -0200649 return nmatch;
650
651fail:
652 *list = kmod_list_remove_n_latest(*list, nmatch);
653 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200654}
Gustavo Sverzut Barbieri1487a642011-12-08 05:17:43 -0200655
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200656int kmod_lookup_alias_from_commands(struct kmod_ctx *ctx, const char *name,
657 struct kmod_list **list)
658{
659 struct kmod_config *config = ctx->config;
660 struct kmod_list *l, *node;
661 int err, nmatch = 0;
662
663 kmod_list_foreach(l, config->install_commands) {
664 const char *modname = kmod_command_get_modname(l);
665
666 if (streq(modname, name)) {
667 const char *cmd = kmod_command_get_command(l);
668 struct kmod_module *mod;
669
670 err = kmod_module_new_from_name(ctx, modname, &mod);
671 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200672 ERR(ctx, "Could not create module from name %s: %s\n",
673 modname, strerror(-err));
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200674 return err;
675 }
676
677 node = kmod_list_append(*list, mod);
678 if (node == NULL) {
679 ERR(ctx, "out of memory\n");
680 return -ENOMEM;
681 }
682
683 *list = node;
684 nmatch = 1;
685
686 kmod_module_set_install_commands(mod, cmd);
687
688 /*
689 * match only the first one, like modprobe from
690 * module-init-tools does
691 */
692 break;
693 }
694 }
695
696 if (nmatch)
697 return nmatch;
698
699 kmod_list_foreach(l, config->remove_commands) {
700 const char *modname = kmod_command_get_modname(l);
701
702 if (streq(modname, name)) {
703 const char *cmd = kmod_command_get_command(l);
704 struct kmod_module *mod;
705
706 err = kmod_module_new_from_name(ctx, modname, &mod);
707 if (err < 0) {
Gustavo Sverzut Barbieridfa96f12012-01-07 19:37:37 -0200708 ERR(ctx, "Could not create module from name %s: %s\n",
709 modname, strerror(-err));
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200710 return err;
711 }
712
713 node = kmod_list_append(*list, mod);
714 if (node == NULL) {
715 ERR(ctx, "out of memory\n");
716 return -ENOMEM;
717 }
718
719 *list = node;
720 nmatch = 1;
721
722 kmod_module_set_remove_commands(mod, cmd);
723
724 /*
725 * match only the first one, like modprobe from
726 * module-init-tools does
727 */
728 break;
729 }
730 }
731
732 return nmatch;
733}
734
Lucas De Marchiece09aa2012-01-18 01:26:44 -0200735void kmod_set_modules_visited(struct kmod_ctx *ctx, bool visited)
736{
737 struct hash_iter iter;
738 const void *v;
739
740 hash_iter_init(ctx->modules_by_name, &iter);
741 while (hash_iter_next(&iter, NULL, &v))
742 kmod_module_set_visited((struct kmod_module *)v, visited);
743}
744
Michal Marek450bd1b2014-03-31 15:18:50 +0200745void kmod_set_modules_required(struct kmod_ctx *ctx, bool required)
746{
747 struct hash_iter iter;
748 const void *v;
749
750 hash_iter_init(ctx->modules_by_name, &iter);
751 while (hash_iter_next(&iter, NULL, &v))
752 kmod_module_set_required((struct kmod_module *)v, required);
753}
754
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200755static bool is_cache_invalid(const char *path, unsigned long long stamp)
756{
757 struct stat st;
758
759 if (stat(path, &st) < 0)
760 return true;
761
Lucas De Marchi6068aaa2012-01-17 12:10:42 -0200762 if (stamp != stat_mstamp(&st))
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200763 return true;
764
765 return false;
766}
767
768/**
769 * kmod_validate_resources:
770 * @ctx: kmod library context
771 *
772 * Check if indexes and configuration files changed on disk and the current
773 * context is not valid anymore.
774 *
Lucas De Marchif4cc6ea2012-01-09 02:35:41 -0200775 * Returns: KMOD_RESOURCES_OK if resources are still valid,
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200776 * KMOD_RESOURCES_MUST_RELOAD if it's sufficient to call
777 * kmod_unload_resources() and kmod_load_resources() or
778 * KMOD_RESOURCES_MUST_RECREATE if @ctx must be re-created.
779 */
780KMOD_EXPORT int kmod_validate_resources(struct kmod_ctx *ctx)
781{
782 struct kmod_list *l;
783 size_t i;
784
785 if (ctx == NULL || ctx->config == NULL)
786 return KMOD_RESOURCES_MUST_RECREATE;
787
788 kmod_list_foreach(l, ctx->config->paths) {
789 struct kmod_config_path *cf = l->data;
790
791 if (is_cache_invalid(cf->path, cf->stamp))
792 return KMOD_RESOURCES_MUST_RECREATE;
793 }
794
Lucas De Marchib08314f2012-01-16 12:01:48 -0200795 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200796 char path[PATH_MAX];
797
798 if (ctx->indexes[i] == NULL)
799 continue;
800
801 snprintf(path, sizeof(path), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200802 index_files[i].fn);
Lucas De Marchic4dc3ca2011-12-31 19:28:31 -0200803
804 if (is_cache_invalid(path, ctx->indexes_stamp[i]))
805 return KMOD_RESOURCES_MUST_RELOAD;
806 }
807
808 return KMOD_RESOURCES_OK;
809}
810
Lucas De Marchi54ba8b32011-12-09 16:42:14 -0200811/**
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200812 * kmod_load_resources:
813 * @ctx: kmod library context
814 *
815 * Load indexes and keep them open in @ctx. This way it's faster to lookup
816 * information within the indexes. If this function is not called before a
817 * search, the necessary index is always opened and closed.
818 *
819 * If user will do more than one or two lookups, insertions, deletions, most
820 * likely it's good to call this function first. Particularly in a daemon like
821 * udev that on bootup issues hundreds of calls to lookup the index, calling
822 * this function will speedup the searches.
823 *
824 * Returns: 0 on success or < 0 otherwise.
825 */
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200826KMOD_EXPORT int kmod_load_resources(struct kmod_ctx *ctx)
827{
828 size_t i;
829
830 if (ctx == NULL)
831 return -ENOENT;
832
Lucas De Marchib08314f2012-01-16 12:01:48 -0200833 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchi6de8f6e2011-12-14 03:58:31 -0200834 char path[PATH_MAX];
Lucas De Marchi3e676762011-12-14 03:53:43 -0200835
Lucas De Marchi16ca3662011-12-20 12:29:13 -0200836 if (ctx->indexes[i] != NULL) {
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200837 INFO(ctx, "Index %s already loaded\n",
838 index_files[i].fn);
Lucas De Marchi3e676762011-12-14 03:53:43 -0200839 continue;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200840 }
Lucas De Marchi3e676762011-12-14 03:53:43 -0200841
Lucas De Marchi6de8f6e2011-12-14 03:58:31 -0200842 snprintf(path, sizeof(path), "%s/%s.bin", ctx->dirname,
Lucas De Marchi63be91c2012-01-16 10:43:34 -0200843 index_files[i].fn);
Lucas De Marchi2e2e2522012-03-02 20:33:26 -0300844 ctx->indexes[i] = index_mm_open(ctx, path,
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200845 &ctx->indexes_stamp[i]);
Lucas De Marchi3e676762011-12-14 03:53:43 -0200846 if (ctx->indexes[i] == NULL)
847 goto fail;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200848 }
849
850 return 0;
851
852fail:
853 kmod_unload_resources(ctx);
854 return -ENOMEM;
855}
856
Lucas De Marchibe5a6de2011-12-14 03:44:38 -0200857/**
858 * kmod_unload_resources:
859 * @ctx: kmod library context
860 *
861 * Unload all the indexes. This will free the resources to maintain the index
862 * open and all subsequent searches will need to open and close the index.
863 *
864 * User is free to call kmod_load_resources() and kmod_unload_resources() as
865 * many times as wanted during the lifecycle of @ctx. For example, if a daemon
866 * knows that when starting up it will lookup a lot of modules, it could call
867 * kmod_load_resources() and after the first burst of searches is gone, it
868 * could free the resources by calling kmod_unload_resources().
869 *
870 * Returns: 0 on success or < 0 otherwise.
871 */
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200872KMOD_EXPORT void kmod_unload_resources(struct kmod_ctx *ctx)
873{
874 size_t i;
875
876 if (ctx == NULL)
877 return;
878
Lucas De Marchib08314f2012-01-16 12:01:48 -0200879 for (i = 0; i < _KMOD_INDEX_MODULES_SIZE; i++) {
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200880 if (ctx->indexes[i] != NULL) {
881 index_mm_close(ctx->indexes[i]);
882 ctx->indexes[i] = NULL;
Lucas De Marchi9fd58f32011-12-31 18:53:24 -0200883 ctx->indexes_stamp[i] = 0;
Lucas De Marchi33bb69b2011-12-08 14:59:51 -0200884 }
885 }
886}
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200887
Lucas De Marchi02244822012-01-16 16:43:47 -0200888/**
889 * kmod_dump_index:
890 * @ctx: kmod library context
Chengwei Yangd7152f62013-05-04 17:07:03 +0800891 * @type: index to dump, valid indexes are
892 * KMOD_INDEX_MODULES_DEP: index of module dependencies;
893 * KMOD_INDEX_MODULES_ALIAS: index of module aliases;
894 * KMOD_INDEX_MODULES_SYMBOL: index of symbol aliases;
895 * KMOD_INDEX_MODULES_BUILTIN: index of builtin module.
Lucas De Marchi02244822012-01-16 16:43:47 -0200896 * @fd: file descriptor to dump index to
897 *
Lucas De Marchi09e9ae52012-01-17 10:05:02 -0200898 * Dump index to file descriptor. Note that this function doesn't use stdio.h
899 * so call fflush() before calling this function to be sure data is written in
900 * order.
Lucas De Marchi02244822012-01-16 16:43:47 -0200901 *
902 * Returns: 0 on success or < 0 otherwise.
903 */
Lucas De Marchi758428a2012-01-16 15:56:17 -0200904KMOD_EXPORT int kmod_dump_index(struct kmod_ctx *ctx, enum kmod_index type,
905 int fd)
906{
907 if (ctx == NULL)
908 return -ENOSYS;
909
910 if (type < 0 || type >= _KMOD_INDEX_MODULES_SIZE)
911 return -ENOENT;
912
913 if (ctx->indexes[type] != NULL) {
914 DBG(ctx, "use mmaped index '%s'\n", index_files[type].fn);
915 index_mm_dump(ctx->indexes[type], fd,
916 index_files[type].prefix);
917 } else {
918 char fn[PATH_MAX];
919 struct index_file *idx;
920
921 snprintf(fn, sizeof(fn), "%s/%s.bin", ctx->dirname,
922 index_files[type].fn);
923
924 DBG(ctx, "file=%s\n", fn);
925
926 idx = index_file_open(fn);
927 if (idx == NULL)
928 return -ENOSYS;
929
930 index_dump(idx, fd, index_files[type].prefix);
931 index_file_close(idx);
932 }
933
934 return 0;
935}
936
Lucas De Marchie7fc2c82012-06-12 01:43:46 -0300937const struct kmod_config *kmod_get_config(const struct kmod_ctx *ctx)
Lucas De Marchic1c9c442011-12-24 10:50:47 -0200938{
Lucas De Marchie7fc2c82012-06-12 01:43:46 -0300939 return ctx->config;
Lucas De Marchi8b5ee612012-01-13 01:14:46 -0200940}