blob: d81725f9a8a9541717ca3c4e84750574e0bbb8c6 [file] [log] [blame]
Lucas De Marchi8f788d52011-11-25 01:22:56 -02001/*
2 * libkmod - interface to kernel module operations
3 *
Lucas De Marchia66a6a92012-01-09 00:40:50 -02004 * Copyright (C) 2011-2012 ProFUSION embedded systems
Lucas De Marchi8f788d52011-11-25 01:22:56 -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 Marchi8f788d52011-11-25 01:22:56 -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 Marchi7636e722011-12-01 17:56:03 -020021#include <assert.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020022#include <stdio.h>
23#include <stdlib.h>
24#include <stddef.h>
25#include <stdarg.h>
26#include <unistd.h>
27#include <errno.h>
28#include <string.h>
29#include <ctype.h>
30#include <inttypes.h>
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -020031#include <limits.h>
32#include <dirent.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020033#include <sys/stat.h>
34#include <sys/types.h>
35#include <sys/mman.h>
Thierry Vignaudeff917c2012-01-17 17:32:48 -020036#include <sys/wait.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020037#include <string.h>
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -020038#include <fnmatch.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020039
40#include "libkmod.h"
41#include "libkmod-private.h"
42
43/**
Lucas De Marchi66819512012-01-09 04:47:40 -020044 * SECTION:libkmod-module
45 * @short_description: operate on kernel modules
46 */
47
48/**
Lucas De Marchi8f788d52011-11-25 01:22:56 -020049 * kmod_module:
50 *
51 * Opaque object representing a module.
52 */
53struct kmod_module {
54 struct kmod_ctx *ctx;
Lucas De Marchi8bdeca12011-12-15 13:11:51 -020055 char *hashkey;
Lucas De Marchi219f9c32011-12-13 13:07:40 -020056 char *name;
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -020057 char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -020058 struct kmod_list *dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020059 char *options;
Lucas De Marchi60f67602011-12-16 03:33:26 -020060 const char *install_commands; /* owned by kmod_config */
61 const char *remove_commands; /* owned by kmod_config */
Lucas De Marchi6ad5f262011-12-13 14:12:50 -020062 char *alias; /* only set if this module was created from an alias */
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -020063 int n_dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020064 int refcount;
Lucas De Marchi7636e722011-12-01 17:56:03 -020065 struct {
66 bool dep : 1;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020067 bool options : 1;
68 bool install_commands : 1;
69 bool remove_commands : 1;
Lucas De Marchi7636e722011-12-01 17:56:03 -020070 } init;
Lucas De Marchib1a51252012-01-29 01:49:09 -020071
72 /*
73 * private field used by kmod_module_get_probe_list() to detect
74 * dependency loops
75 */
Lucas De Marchiece09aa2012-01-18 01:26:44 -020076 bool visited : 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020077};
78
Lucas De Marchic35347f2011-12-12 10:48:02 -020079static inline const char *path_join(const char *path, size_t prefixlen,
80 char buf[PATH_MAX])
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -020081{
82 size_t pathlen;
83
84 if (path[0] == '/')
85 return path;
86
87 pathlen = strlen(path);
88 if (prefixlen + pathlen + 1 >= PATH_MAX)
89 return NULL;
90
91 memcpy(buf + prefixlen, path, pathlen + 1);
92 return buf;
93}
94
Lucas De Marchi671d4892011-12-05 20:23:05 -020095int kmod_module_parse_depline(struct kmod_module *mod, char *line)
Lucas De Marchi7636e722011-12-01 17:56:03 -020096{
97 struct kmod_ctx *ctx = mod->ctx;
98 struct kmod_list *list = NULL;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -020099 const char *dirname;
100 char buf[PATH_MAX];
Lucas De Marchi7636e722011-12-01 17:56:03 -0200101 char *p, *saveptr;
Lucas De Marchi45f27782011-12-12 17:23:04 -0200102 int err = 0, n = 0;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200103 size_t dirnamelen;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200104
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200105 if (mod->init.dep)
106 return mod->n_dep;
107 assert(mod->dep == NULL);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200108 mod->init.dep = true;
109
110 p = strchr(line, ':');
111 if (p == NULL)
112 return 0;
113
Lucas De Marchi671d4892011-12-05 20:23:05 -0200114 *p = '\0';
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200115 dirname = kmod_get_dirname(mod->ctx);
116 dirnamelen = strlen(dirname);
117 if (dirnamelen + 2 >= PATH_MAX)
118 return 0;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200119
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200120 memcpy(buf, dirname, dirnamelen);
121 buf[dirnamelen] = '/';
122 dirnamelen++;
123 buf[dirnamelen] = '\0';
124
125 if (mod->path == NULL) {
126 const char *str = path_join(line, dirnamelen, buf);
127 if (str == NULL)
128 return 0;
129 mod->path = strdup(str);
130 if (mod->path == NULL)
131 return 0;
132 }
Lucas De Marchi671d4892011-12-05 20:23:05 -0200133
Lucas De Marchi7636e722011-12-01 17:56:03 -0200134 p++;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200135 for (p = strtok_r(p, " \t", &saveptr); p != NULL;
136 p = strtok_r(NULL, " \t", &saveptr)) {
Lucas De Marchi1fc1c9a2011-12-02 10:00:03 -0200137 struct kmod_module *depmod;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200138 const char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200139
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200140 path = path_join(p, dirnamelen, buf);
141 if (path == NULL) {
142 ERR(ctx, "could not join path '%s' and '%s'.\n",
143 dirname, p);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200144 goto fail;
145 }
146
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200147 err = kmod_module_new_from_path(ctx, path, &depmod);
148 if (err < 0) {
149 ERR(ctx, "ctx=%p path=%s error=%s\n",
150 ctx, path, strerror(-err));
151 goto fail;
152 }
153
154 DBG(ctx, "add dep: %s\n", path);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200155
Lucas De Marchib94a7372011-12-26 20:10:49 -0200156 list = kmod_list_prepend(list, depmod);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200157 n++;
158 }
159
160 DBG(ctx, "%d dependencies for %s\n", n, mod->name);
161
162 mod->dep = list;
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200163 mod->n_dep = n;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200164 return n;
165
166fail:
167 kmod_module_unref_list(list);
168 mod->init.dep = false;
169 return err;
170}
171
Lucas De Marchiece09aa2012-01-18 01:26:44 -0200172void kmod_module_set_visited(struct kmod_module *mod, bool visited)
173{
174 mod->visited = visited;
175}
176
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200177/**
178 * kmod_module_new_from_name:
179 * @ctx: kmod library context
180 * @name: name of the module
181 * @mod: where to save the created struct kmod_module
182 *
183 * Create a new struct kmod_module using the module name. @name can not be an
184 * alias, file name or anything else; it must be a module name. There's no
185 * check if the module does exists in the system.
186 *
187 * This function is also used internally by many others that return a new
188 * struct kmod_module or a new list of modules.
189 *
190 * The initial refcount is 1, and needs to be decremented to release the
191 * resources of the kmod_module. Since libkmod keeps track of all
192 * kmod_modules created, they are all released upon @ctx destruction too. Do
193 * not unref @ctx before all the desired operations with the returned
194 * kmod_module are done.
195 *
196 * Returns: 0 on success or < 0 otherwise. It fails if name is not a valid
197 * module name or if memory allocation failed.
198 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200199KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
200 const char *name,
201 struct kmod_module **mod)
202{
203 struct kmod_module *m;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200204 size_t namelen;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200205 char name_norm[PATH_MAX];
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200206 char *namesep;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200207
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200208 if (ctx == NULL || name == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200209 return -ENOENT;
210
Luis Felipe Strano Moraes9efaf2f2011-12-20 08:13:56 -0800211 if (alias_normalize(name, name_norm, &namelen) < 0) {
212 DBG(ctx, "invalid alias: %s\n", name);
213 return -EINVAL;
214 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200215
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200216 m = kmod_pool_get_module(ctx, name_norm);
217 if (m != NULL) {
218 *mod = kmod_module_ref(m);
219 return 0;
220 }
221
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200222 namesep = strchr(name_norm, '/');
223 m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200224 if (m == NULL) {
225 free(m);
226 return -ENOMEM;
227 }
228
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200229 memset(m, 0, sizeof(*m));
230
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200231 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200232 m->name = (char *)m + sizeof(*m);
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200233 memcpy(m->name, name_norm, namelen + 1);
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200234
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200235 if (namesep) {
236 size_t len = namesep - name_norm;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200237
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200238 m->name[len] = '\0';
239 m->alias = m->name + len + 1;
240 m->hashkey = m->name + namelen + 1;
241 memcpy(m->hashkey, name_norm, namelen + 1);
242 } else {
243 m->hashkey = m->name;
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200244 }
245
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200246 m->refcount = 1;
247 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200248 *mod = m;
249
250 return 0;
251}
252
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200253int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
254 const char *name, struct kmod_module **mod)
255{
256 int err;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200257 char key[PATH_MAX];
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200258 size_t namelen = strlen(name);
259 size_t aliaslen = strlen(alias);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200260
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200261 if (namelen + aliaslen + 2 > PATH_MAX)
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200262 return -ENAMETOOLONG;
263
264 memcpy(key, name, namelen);
265 memcpy(key + namelen + 1, alias, aliaslen + 1);
266 key[namelen] = '/';
267
268 err = kmod_module_new_from_name(ctx, key, mod);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200269 if (err < 0)
270 return err;
271
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200272 return 0;
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200273}
274
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200275/**
276 * kmod_module_new_from_path:
277 * @ctx: kmod library context
278 * @path: path where to find the given module
279 * @mod: where to save the created struct kmod_module
280 *
281 * Create a new struct kmod_module using the module path. @path must be an
282 * existent file with in the filesystem and must be accessible to libkmod.
283 *
284 * The initial refcount is 1, and needs to be decremented to release the
285 * resources of the kmod_module. Since libkmod keeps track of all
286 * kmod_modules created, they are all released upon @ctx destruction too. Do
287 * not unref @ctx before all the desired operations with the returned
288 * kmod_module are done.
289 *
290 * If @path is relative, it's treated as relative to the current working
291 * directory. Otherwise, give an absolute path.
292 *
293 * Returns: 0 on success or < 0 otherwise. It fails if file does not exist, if
294 * it's not a valid file for a kmod_module or if memory allocation failed.
295 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200296KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
297 const char *path,
298 struct kmod_module **mod)
299{
300 struct kmod_module *m;
301 int err;
302 struct stat st;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200303 char name[PATH_MAX];
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200304 char *abspath;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200305 size_t namelen;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200306
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200307 if (ctx == NULL || path == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200308 return -ENOENT;
309
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200310 abspath = path_make_absolute_cwd(path);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200311 if (abspath == NULL) {
312 DBG(ctx, "no absolute path for %s\n", path);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200313 return -ENOMEM;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200314 }
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200315
316 err = stat(abspath, &st);
317 if (err < 0) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200318 err = -errno;
319 DBG(ctx, "stat %s: %s\n", path, strerror(errno));
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200320 free(abspath);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200321 return err;
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200322 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200323
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200324 if (path_to_modname(path, name, &namelen) == NULL) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200325 DBG(ctx, "could not get modname from path %s\n", path);
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200326 free(abspath);
327 return -ENOENT;
328 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200329
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200330 m = kmod_pool_get_module(ctx, name);
331 if (m != NULL) {
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200332 if (m->path == NULL)
333 m->path = abspath;
334 else if (streq(m->path, abspath))
335 free(abspath);
336 else {
Lucas De Marchiebaa7be2011-12-27 18:10:19 -0200337 ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n",
338 name, abspath, m->path);
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200339 free(abspath);
340 return -EEXIST;
341 }
342
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200343 *mod = kmod_module_ref(m);
344 return 0;
345 }
346
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200347 m = malloc(sizeof(*m) + namelen + 1);
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200348 if (m == NULL)
349 return -errno;
350
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200351 memset(m, 0, sizeof(*m));
352
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200353 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200354 m->name = (char *)m + sizeof(*m);
Lucas De Marchi9dec2442011-12-18 15:12:19 -0200355 memcpy(m->name, name, namelen + 1);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200356 m->path = abspath;
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200357 m->hashkey = m->name;
Gustavo Sverzut Barbieri87ca03b2011-12-04 12:34:02 -0200358 m->refcount = 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200359
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200360 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200361
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200362 *mod = m;
363
364 return 0;
365}
366
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200367/**
368 * kmod_module_unref:
369 * @mod: kmod module
370 *
371 * Drop a reference of the kmod module. If the refcount reaches zero, its
372 * resources are released.
373 *
374 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
375 * returns the passed @mod with its refcount decremented.
376 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200377KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
378{
379 if (mod == NULL)
380 return NULL;
381
382 if (--mod->refcount > 0)
383 return mod;
384
385 DBG(mod->ctx, "kmod_module %p released\n", mod);
386
Lucas De Marchi4084c172011-12-15 13:43:22 -0200387 kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200388 kmod_module_unref_list(mod->dep);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200389 kmod_unref(mod->ctx);
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200390 free(mod->options);
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -0200391 free(mod->path);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200392 free(mod);
393 return NULL;
394}
395
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200396/**
397 * kmod_module_ref:
398 * @mod: kmod module
399 *
400 * Take a reference of the kmod module, incrementing its refcount.
401 *
402 * Returns: the passed @module with its refcount incremented.
403 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200404KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
405{
406 if (mod == NULL)
407 return NULL;
408
409 mod->refcount++;
410
411 return mod;
412}
413
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200414#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
415 do { \
416 if ((_err) < 0) \
417 goto _label_err; \
418 if (*(_list) != NULL) \
419 goto finish; \
420 } while (0)
421
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200422/**
423 * kmod_module_new_from_lookup:
424 * @ctx: kmod library context
425 * @given_alias: alias to look for
426 * @list: an empty list where to save the list of modules matching
427 * @given_alias
428 *
429 * Create a new list of kmod modules using an alias or module name and lookup
430 * libkmod's configuration files and indexes in order to find the module.
431 * Once it's found in one of the places, it stops searching and create the
432 * list of modules that is saved in @list.
433 *
434 * The search order is: 1. aliases in configuration file; 2. module names in
435 * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
436 * in modules.alias index.
437 *
438 * The initial refcount is 1, and needs to be decremented to release the
439 * resources of the kmod_module. The returned @list must be released by
440 * calling kmod_module_unref_list(). Since libkmod keeps track of all
441 * kmod_modules created, they are all released upon @ctx destruction too. Do
442 * not unref @ctx before all the desired operations with the returned list are
443 * completed.
444 *
445 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
446 * methods failed, which is basically due to memory allocation fail. If module
447 * is not found, it still returns 0, but @list is an empty list.
448 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200449KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200450 const char *given_alias,
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200451 struct kmod_list **list)
452{
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200453 int err;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200454 char alias[PATH_MAX];
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200455
Lucas De Marchi4308b172011-12-13 10:26:04 -0200456 if (ctx == NULL || given_alias == NULL)
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200457 return -ENOENT;
458
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200459 if (list == NULL || *list != NULL) {
460 ERR(ctx, "An empty list is needed to create lookup\n");
461 return -ENOSYS;
462 }
463
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200464 if (alias_normalize(given_alias, alias, NULL) < 0) {
465 DBG(ctx, "invalid alias: %s\n", given_alias);
Lucas De Marchid470db12011-12-13 10:28:00 -0200466 return -EINVAL;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200467 }
468
469 DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200470
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200471 /* Aliases from config file override all the others */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200472 err = kmod_lookup_alias_from_config(ctx, alias, list);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200473 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200474
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200475 DBG(ctx, "lookup modules.dep %s\n", alias);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200476 err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
477 CHECK_ERR_AND_FINISH(err, fail, list, finish);
478
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200479 DBG(ctx, "lookup modules.symbols %s\n", alias);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200480 err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
481 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200482
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200483 DBG(ctx, "lookup install and remove commands %s\n", alias);
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200484 err = kmod_lookup_alias_from_commands(ctx, alias, list);
485 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200486
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200487 DBG(ctx, "lookup modules.aliases %s\n", alias);
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200488 err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
489 CHECK_ERR_AND_FINISH(err, fail, list, finish);
490
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200491finish:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200492 DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200493 return err;
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200494fail:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200495 DBG(ctx, "Failed to lookup %s\n", alias);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200496 kmod_module_unref_list(*list);
497 *list = NULL;
Lucas De Marchi84f42202011-12-02 10:03:34 -0200498 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200499}
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200500#undef CHECK_ERR_AND_FINISH
501
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200502/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200503 * kmod_module_unref_list:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200504 * @list: list of kmod modules
505 *
506 * Drop a reference of each kmod module in @list and releases the resources
507 * taken by the list itself.
508 *
509 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
510 * returns the passed @mod with its refcount decremented.
511 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200512KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
513{
514 for (; list != NULL; list = kmod_list_remove(list))
515 kmod_module_unref(list->data);
516
517 return 0;
518}
519
Lucas De Marchi0d467432011-12-31 11:15:52 -0200520/**
521 * kmod_module_get_filtered_blacklist:
522 * @ctx: kmod library context
523 * @input: list of kmod_module to be filtered with blacklist
524 * @output: where to save the new list
525 *
526 * Given a list @input, this function filter it out with config's blacklist
527 * ans save it in @output.
528 *
529 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
530 * list.
531 */
532KMOD_EXPORT int kmod_module_get_filtered_blacklist(const struct kmod_ctx *ctx,
533 const struct kmod_list *input,
534 struct kmod_list **output)
535{
536 const struct kmod_list *li;
537 const struct kmod_list *blacklist;
538
539 if (ctx == NULL || output == NULL)
540 return -ENOENT;
541
542 *output = NULL;
543 if (input == NULL)
544 return 0;
545
546 blacklist = kmod_get_blacklists(ctx);
547 kmod_list_foreach(li, input) {
548 struct kmod_module *mod = li->data;
549 const struct kmod_list *lb;
550 struct kmod_list *node;
551 bool filtered = false;
552
553 kmod_list_foreach(lb, blacklist) {
554 const char *name = lb->data;
555
Lucas De Marchi4926cb52011-12-31 11:21:52 -0200556 if (streq(name, mod->name)) {
Lucas De Marchi0d467432011-12-31 11:15:52 -0200557 filtered = true;
558 break;
559 }
560 }
561
562 if (filtered)
563 continue;
564
565 node = kmod_list_append(*output, mod);
566 if (node == NULL)
567 goto fail;
568
569 *output = node;
570 kmod_module_ref(mod);
571 }
572
573 return 0;
574
575fail:
576 kmod_module_unref_list(*output);
577 *output = NULL;
578 return -ENOMEM;
579}
580
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200581static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
582{
583 if (!mod->init.dep) {
584 /* lazy init */
585 char *line = kmod_search_moddep(mod->ctx, mod->name);
586
587 if (line == NULL)
588 return NULL;
589
590 kmod_module_parse_depline((struct kmod_module *)mod, line);
591 free(line);
592
593 if (!mod->init.dep)
594 return NULL;
595 }
596
597 return mod->dep;
598}
599
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200600/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200601 * kmod_module_get_dependencies:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200602 * @mod: kmod module
603 *
604 * Search the modules.dep index to find the dependencies of the given @mod.
605 * The result is cached in @mod, so subsequent calls to this function will
606 * return the already searched list of modules.
607 *
608 * Returns: NULL on failure or if there are any dependencies. Otherwise it
609 * returns a list of kmod modules that can be released by calling
610 * kmod_module_unref_list().
611 */
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200612KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200613{
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200614 struct kmod_list *l, *l_new, *list_new = NULL;
615
616 if (mod == NULL)
617 return NULL;
618
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200619 module_get_dependencies_noref(mod);
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200620
621 kmod_list_foreach(l, mod->dep) {
622 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
623 if (l_new == NULL) {
624 kmod_module_unref(l->data);
625 goto fail;
626 }
627
628 list_new = l_new;
629 }
630
631 return list_new;
632
633fail:
634 ERR(mod->ctx, "out of memory\n");
635 kmod_module_unref_list(list_new);
636 return NULL;
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200637}
638
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200639/**
640 * kmod_module_get_module:
641 * @entry: an entry in a list of kmod modules.
642 *
643 * Get the kmod module of this @entry in the list, increasing its refcount.
644 * After it's used, unref it. Since the refcount is incremented upon return,
645 * you still have to call kmod_module_unref_list() to release the list of kmod
646 * modules.
647 *
648 * Returns: NULL on failure or the kmod_module contained in this list entry
649 * with its refcount incremented.
650 */
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200651KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200652{
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200653 if (entry == NULL)
654 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200655
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200656 return kmod_module_ref(entry->data);
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200657}
658
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200659/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200660 * kmod_module_get_name:
661 * @mod: kmod module
662 *
663 * Get the name of this kmod module. Name is always available, independently
664 * if it was created by kmod_module_new_from_name() or another function and
665 * it's always normalized (dashes are replaced with underscores).
666 *
667 * Returns: the name of this kmod module.
668 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200669KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200670{
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200671 if (mod == NULL)
672 return NULL;
673
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200674 return mod->name;
675}
676
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200677/**
678 * kmod_module_get_path:
679 * @mod: kmod module
680 *
681 * Get the path of this kmod module. If this kmod module was not created by
682 * path, it can search the modules.dep index in order to find out the module
Lucas De Marchidb74cee2012-01-09 03:45:19 -0200683 * under context's dirname.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200684 *
685 * Returns: the path of this kmod module or NULL if such information is not
686 * available.
687 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200688KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200689{
Lucas De Marchie005fac2011-12-08 10:42:34 -0200690 char *line;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200691
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200692 if (mod == NULL)
693 return NULL;
694
Gustavo Sverzut Barbierid01c67e2011-12-11 19:42:02 -0200695 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200696
Lucas De Marchie005fac2011-12-08 10:42:34 -0200697 if (mod->path != NULL)
698 return mod->path;
699 if (mod->init.dep)
700 return NULL;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200701
Lucas De Marchie005fac2011-12-08 10:42:34 -0200702 /* lazy init */
703 line = kmod_search_moddep(mod->ctx, mod->name);
704 if (line == NULL)
705 return NULL;
706
707 kmod_module_parse_depline((struct kmod_module *) mod, line);
708 free(line);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200709
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200710 return mod->path;
711}
712
713
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200714extern long delete_module(const char *name, unsigned int flags);
715
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200716/**
717 * kmod_module_remove_module:
718 * @mod: kmod module
719 * @flags: flags to pass to Linux kernel when removing the module
720 *
721 * Remove a module from Linux kernel.
722 *
723 * Returns: 0 on success or < 0 on failure.
724 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200725KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
726 unsigned int flags)
727{
728 int err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200729
730 if (mod == NULL)
731 return -ENOENT;
732
733 /* Filter out other flags */
734 flags &= (KMOD_REMOVE_FORCE | KMOD_REMOVE_NOWAIT);
735
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200736 err = delete_module(mod->name, flags);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200737 if (err != 0) {
Lucas De Marchiba998b92012-01-11 00:08:14 -0200738 err = -errno;
739 ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200740 }
741
Lucas De Marchiba998b92012-01-11 00:08:14 -0200742 return err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200743}
744
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200745extern long init_module(const void *mem, unsigned long len, const char *args);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200746
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200747/**
748 * kmod_module_insert_module:
749 * @mod: kmod module
Lucas De Marchi142db572011-12-20 23:39:30 -0200750 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
751 * behavior of this function.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200752 * @options: module's options to pass to Linux Kernel.
753 *
754 * Insert a module in Linux kernel. It opens the file pointed by @mod,
755 * mmap'ing it and passing to kernel.
756 *
Lucas De Marchibbf59322011-12-30 14:13:33 -0200757 * Returns: 0 on success or < 0 on failure. If module is already loaded it
758 * returns -EEXIST.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200759 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200760KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200761 unsigned int flags,
762 const char *options)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200763{
764 int err;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200765 const void *mem;
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200766 off_t size;
767 struct kmod_file *file;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200768 struct kmod_elf *elf = NULL;
769 const char *path;
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200770 const char *args = options ? options : "";
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200771
772 if (mod == NULL)
773 return -ENOENT;
774
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200775 path = kmod_module_get_path(mod);
776 if (path == NULL) {
Dave Reisnerb787b562012-01-04 10:59:49 -0500777 ERR(mod->ctx, "could not find module by name='%s'\n", mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200778 return -ENOSYS;
779 }
780
Lucas De Marchic68e92f2012-01-04 08:19:34 -0200781 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200782 if (file == NULL) {
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200783 err = -errno;
784 return err;
785 }
786
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200787 size = kmod_file_get_size(file);
788 mem = kmod_file_get_contents(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200789
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200790 if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
791 elf = kmod_elf_new(mem, size);
792 if (elf == NULL) {
793 err = -errno;
794 goto elf_failed;
795 }
796
797 if (flags & KMOD_INSERT_FORCE_MODVERSION) {
798 err = kmod_elf_strip_section(elf, "__versions");
799 if (err < 0)
800 INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
801 }
802
803 if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
804 err = kmod_elf_strip_vermagic(elf);
805 if (err < 0)
806 INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
807 }
808
809 mem = kmod_elf_get_memory(elf);
810 }
811
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200812 err = init_module(mem, size, args);
Lucas De Marchibbf59322011-12-30 14:13:33 -0200813 if (err < 0) {
814 err = -errno;
815 INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
816 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200817
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200818 if (elf != NULL)
819 kmod_elf_unref(elf);
820elf_failed:
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200821 kmod_file_unref(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200822
823 return err;
824}
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200825
Lucas De Marchiddbda022011-12-27 11:40:10 -0200826static bool module_is_blacklisted(struct kmod_module *mod)
827{
828 struct kmod_ctx *ctx = mod->ctx;
829 const struct kmod_list *bl = kmod_get_blacklists(ctx);
830 const struct kmod_list *l;
831
832 kmod_list_foreach(l, bl) {
833 const char *modname = kmod_blacklist_get_modname(l);
834
835 if (streq(modname, mod->name))
836 return true;
837 }
838
839 return false;
840}
841
Lucas De Marchiddbda022011-12-27 11:40:10 -0200842static int command_do(struct kmod_module *mod, const char *type,
843 const char *cmd)
844{
845 const char *modname = kmod_module_get_name(mod);
846 int err;
847
848 DBG(mod->ctx, "%s %s\n", type, cmd);
849
850 setenv("MODPROBE_MODULE", modname, 1);
851 err = system(cmd);
852 unsetenv("MODPROBE_MODULE");
853
854 if (err == -1 || WEXITSTATUS(err)) {
855 ERR(mod->ctx, "Error running %s command for %s\n",
856 type, modname);
857 if (err != -1)
858 err = -WEXITSTATUS(err);
859 }
860
861 return err;
862}
863
Lucas De Marchib1a51252012-01-29 01:49:09 -0200864struct probe_insert_cb {
865 int (*run_install)(struct kmod_module *m, const char *cmd, void *data);
866 void *data;
867};
868
Lucas De Marchiddbda022011-12-27 11:40:10 -0200869static int module_do_install_commands(struct kmod_module *mod,
870 const char *options,
871 struct probe_insert_cb *cb)
872{
873 const char *command = kmod_module_get_install_commands(mod);
874 char *p, *cmd;
875 int err;
876 size_t cmdlen, options_len, varlen;
877
878 assert(command);
879
880 if (options == NULL)
881 options = "";
882
883 options_len = strlen(options);
884 cmdlen = strlen(command);
885 varlen = sizeof("$CMDLINE_OPTS") - 1;
886
887 cmd = memdup(command, cmdlen + 1);
888 if (cmd == NULL)
889 return -ENOMEM;
890
891 while ((p = strstr(cmd, "$CMDLINE_OPTS")) != NULL) {
892 size_t prefixlen = p - cmd;
893 size_t suffixlen = cmdlen - prefixlen - varlen;
894 size_t slen = cmdlen - varlen + options_len;
895 char *suffix = p + varlen;
896 char *s = malloc(slen + 1);
897 if (s == NULL) {
898 free(cmd);
899 return -ENOMEM;
900 }
901 memcpy(s, cmd, p - cmd);
902 memcpy(s + prefixlen, options, options_len);
903 memcpy(s + prefixlen + options_len, suffix, suffixlen);
904 s[slen] = '\0';
905
906 free(cmd);
907 cmd = s;
908 cmdlen = slen;
909 }
910
911 if (cb->run_install != NULL)
912 err = cb->run_install(mod, cmd, cb->data);
913 else
914 err = command_do(mod, "install", cmd);
915
916 free(cmd);
917
918 return err;
919}
920
Lucas De Marchiddbda022011-12-27 11:40:10 -0200921static char *module_options_concat(const char *opt, const char *xopt)
922{
923 // TODO: we might need to check if xopt overrides options on opt
924 size_t optlen = opt == NULL ? 0 : strlen(opt);
925 size_t xoptlen = xopt == NULL ? 0 : strlen(xopt);
926 char *r;
927
928 if (optlen == 0 && xoptlen == 0)
929 return NULL;
930
931 r = malloc(optlen + xoptlen + 2);
932
933 if (opt != NULL) {
934 memcpy(r, opt, optlen);
935 r[optlen] = ' ';
936 optlen++;
937 }
938
939 if (xopt != NULL)
940 memcpy(r + optlen, xopt, xoptlen);
941
942 r[optlen + xoptlen] = '\0';
943
944 return r;
945}
946
Lucas De Marchib1a51252012-01-29 01:49:09 -0200947static int __kmod_module_get_probe_list(struct kmod_module *mod,
948 struct kmod_list **list);
949
950/* re-entrant */
951static int __kmod_module_fill_softdep(struct kmod_module *mod,
952 struct kmod_list **list)
Lucas De Marchiddbda022011-12-27 11:40:10 -0200953{
Lucas De Marchib1a51252012-01-29 01:49:09 -0200954 struct kmod_list *pre = NULL, *post = NULL, *l;
Lucas De Marchiddbda022011-12-27 11:40:10 -0200955 int err;
Lucas De Marchiddbda022011-12-27 11:40:10 -0200956
957 err = kmod_module_get_softdeps(mod, &pre, &post);
Lucas De Marchib1a51252012-01-29 01:49:09 -0200958 if (err < 0) {
959 ERR(mod->ctx, "could not get softdep: %s", strerror(-err));
960 goto fail;
961 }
Lucas De Marchiddbda022011-12-27 11:40:10 -0200962
Lucas De Marchib1a51252012-01-29 01:49:09 -0200963 kmod_list_foreach(l, pre) {
964 struct kmod_module *m = l->data;
965 err = __kmod_module_get_probe_list(m, list);
966 if (err < 0)
967 goto fail;
968 }
Lucas De Marchiddbda022011-12-27 11:40:10 -0200969
Lucas De Marchib1a51252012-01-29 01:49:09 -0200970 l = kmod_list_append(*list, kmod_module_ref(mod));
971 if (l == NULL) {
972 kmod_module_unref(mod);
973 err = -ENOMEM;
974 goto fail;
975 }
976 *list = l;
977 mod->visited = true;
Lucas De Marchiddbda022011-12-27 11:40:10 -0200978
Lucas De Marchib1a51252012-01-29 01:49:09 -0200979 kmod_list_foreach(l, post) {
980 struct kmod_module *m = l->data;
981 err = __kmod_module_get_probe_list(m, list);
982 if (err < 0)
983 goto fail;
984 }
Lucas De Marchiddbda022011-12-27 11:40:10 -0200985
Lucas De Marchib1a51252012-01-29 01:49:09 -0200986fail:
Lucas De Marchiddbda022011-12-27 11:40:10 -0200987 kmod_module_unref_list(pre);
988 kmod_module_unref_list(post);
989
990 return err;
991}
992
Lucas De Marchib1a51252012-01-29 01:49:09 -0200993/* re-entrant */
994static int __kmod_module_get_probe_list(struct kmod_module *mod,
995 struct kmod_list **list)
996{
997 struct kmod_list *dep, *l;
998 int err = 0;
999
1000 if (mod->visited) {
1001 DBG(mod->ctx, "Ignore module '%s': already visited\n",
1002 mod->name);
1003 return 0;
1004 }
1005
1006 dep = kmod_module_get_dependencies(mod);
1007
1008 /*
1009 * Use its softdeps and commands: just put it in the end of the list
1010 */
1011 l = kmod_list_append(dep, kmod_module_ref(mod));
1012 if (l == NULL) {
1013 kmod_module_unref(mod);
1014 err = -ENOMEM;
1015 goto finish;
1016 }
1017 dep = l;
1018
1019 kmod_list_foreach(l, dep) {
1020 struct kmod_module *m = l->data;
1021 err = __kmod_module_fill_softdep(m, list);
1022 if (err < 0)
1023 break;
1024 }
1025
1026finish:
1027 kmod_module_unref_list(dep);
1028 return err;
1029}
1030
1031static int kmod_module_get_probe_list(struct kmod_module *mod,
1032 struct kmod_list **list)
1033{
1034 int err;
1035
1036 assert(mod != NULL);
1037 assert(list != NULL && *list == NULL);
1038
1039 /*
1040 * Make sure we don't get screwed by previous calls to this function
1041 */
1042 kmod_set_modules_visited(mod->ctx, false);
1043
1044 err = __kmod_module_get_probe_list(mod, list);
1045 if (err < 0) {
1046 kmod_module_unref_list(*list);
1047 *list = NULL;
1048 }
1049
1050 return err;
1051}
1052
Lucas De Marchiddbda022011-12-27 11:40:10 -02001053/**
1054 * kmod_module_probe_insert_module:
1055 * @mod: kmod module
1056 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
1057 * behavior of this function.
Lucas De Marchib1a51252012-01-29 01:49:09 -02001058 * @extra_options: module's options to pass to Linux Kernel. It applies only
1059 * to @mod, not to its dependencies.
1060 * @run_install: function to run when @mod is backed by an install command.
Lucas De Marchiddbda022011-12-27 11:40:10 -02001061 * @data: data to give back to @run_install callback
1062 *
Lucas De Marchib1a51252012-01-29 01:49:09 -02001063 * Insert a module in Linux kernel resolving dependencies, soft dependencies,
Lucas De Marchiddbda022011-12-27 11:40:10 -02001064 * install commands and applying blacklist.
1065 *
1066 * If @run_install is NULL, and the flag KMOD_PROBE_STOP_ON_COMMANDS is not
Lucas De Marchib1a51252012-01-29 01:49:09 -02001067 * given, this function will fork and exec by calling system(3). Don't pass a
1068 * NULL argument in @run_install if your binary is setuid/setgid (see warning
1069 * in system(3)). If you need control over the execution of an install
1070 * command, give a callback function instead.
Lucas De Marchiddbda022011-12-27 11:40:10 -02001071 *
Lucas De Marchib1a51252012-01-29 01:49:09 -02001072 * Returns: 0 on success, > 0 if stopped by a reason given in @flags or < 0 on
1073 * failure.
Lucas De Marchiddbda022011-12-27 11:40:10 -02001074 */
1075KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
1076 unsigned int flags, const char *extra_options,
1077 int (*run_install)(struct kmod_module *m,
1078 const char *cmd, void *data),
1079 const void *data)
1080{
Lucas De Marchib1a51252012-01-29 01:49:09 -02001081 struct kmod_list *list = NULL, *l;
Lucas De Marchiddbda022011-12-27 11:40:10 -02001082 struct probe_insert_cb cb;
Lucas De Marchib1a51252012-01-29 01:49:09 -02001083 int err;
1084
1085 if (mod == NULL)
1086 return -ENOENT;
1087
1088 err = flags & (KMOD_PROBE_APPLY_BLACKLIST |
1089 KMOD_PROBE_APPLY_BLACKLIST_ALL);
1090 if (err != 0) {
1091 if (module_is_blacklisted(mod))
1092 return err;
1093 }
1094
1095 err = kmod_module_get_probe_list(mod, &list);
1096 if (err < 0)
1097 return err;
1098
1099 if (flags & KMOD_PROBE_APPLY_BLACKLIST_ALL) {
1100 struct kmod_list *filtered = NULL;
1101
1102 err = kmod_module_get_filtered_blacklist(mod->ctx,
1103 list, &filtered);
1104 if (err < 0)
1105 return err;
1106
1107 kmod_module_unref_list(list);
1108 if (filtered == NULL)
1109 return KMOD_PROBE_APPLY_BLACKLIST_ALL;
1110
1111 list = filtered;
1112 }
Lucas De Marchiddbda022011-12-27 11:40:10 -02001113
1114 cb.run_install = run_install;
1115 cb.data = (void *) data;
1116
Lucas De Marchib1a51252012-01-29 01:49:09 -02001117 kmod_list_foreach(l, list) {
1118 struct kmod_module *m = l->data;
1119 const char *moptions = kmod_module_get_options(m);
1120 const char *cmd = kmod_module_get_install_commands(m);
1121 char *options = module_options_concat(moptions,
1122 m == mod ? extra_options : NULL);
1123
1124 if (cmd != NULL) {
1125 if (flags & KMOD_PROBE_STOP_ON_COMMAND) {
1126 DBG(mod->ctx, "Stopping on '%s': "
1127 "install command\n", m->name);
1128 err = KMOD_PROBE_STOP_ON_COMMAND;
1129 free(options);
1130 break;
1131 }
1132 err = module_do_install_commands(m, options, &cb);
1133 } else {
1134 int state = kmod_module_get_initstate(m);
1135
1136 if (state == KMOD_MODULE_LIVE ||
1137 state == KMOD_MODULE_COMING ||
1138 state == KMOD_MODULE_BUILTIN) {
1139 DBG(mod->ctx, "Ignoring '%s': "
1140 "module already loaded\n", m->name);
1141 free(options);
1142 continue;
1143 }
1144 err = kmod_module_insert_module(m, flags, options);
1145 }
1146
1147 free(options);
1148
1149 /*
1150 * Ignore "already loaded" error. We need to check here
1151 * because of race conditions. We checked first if module was
1152 * already loaded but it may have been loaded between the
1153 * check and the moment we try to insert it.
1154 */
1155 if (err < 0 && err != -EEXIST &&
1156 (flags & KMOD_PROBE_STOP_ON_DEP_FAILURE))
1157 break;
1158 }
1159
1160 kmod_module_unref_list(list);
1161 return err;
Lucas De Marchiddbda022011-12-27 11:40:10 -02001162}
1163
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001164/**
1165 * kmod_module_get_options:
1166 * @mod: kmod module
1167 *
1168 * Get options of this kmod module. Options come from the configuration file
1169 * and are cached in @mod. The first call to this function will search for
1170 * this module in configuration and subsequent calls return the cached string.
1171 *
1172 * Returns: a string with all the options separated by spaces. This string is
1173 * owned by @mod, do not free it.
1174 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001175KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
1176{
1177 if (mod == NULL)
1178 return NULL;
1179
1180 if (!mod->init.options) {
1181 /* lazy init */
1182 struct kmod_module *m = (struct kmod_module *)mod;
1183 const struct kmod_list *l, *ctx_options;
1184 char *opts = NULL;
1185 size_t optslen = 0;
1186
1187 ctx_options = kmod_get_options(mod->ctx);
1188
1189 kmod_list_foreach(l, ctx_options) {
1190 const char *modname = kmod_option_get_modname(l);
1191 const char *str;
1192 size_t len;
1193 void *tmp;
1194
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001195 DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
1196 if (!(streq(modname, mod->name) || (mod->alias != NULL &&
1197 streq(modname, mod->alias))))
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001198 continue;
1199
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001200 DBG(mod->ctx, "passed = modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001201 str = kmod_option_get_options(l);
1202 len = strlen(str);
1203 if (len < 1)
1204 continue;
1205
1206 tmp = realloc(opts, optslen + len + 2);
1207 if (tmp == NULL) {
1208 free(opts);
1209 goto failed;
1210 }
1211
1212 opts = tmp;
1213
1214 if (optslen > 0) {
1215 opts[optslen] = ' ';
1216 optslen++;
1217 }
1218
1219 memcpy(opts + optslen, str, len);
1220 optslen += len;
1221 opts[optslen] = '\0';
1222 }
1223
1224 m->init.options = true;
1225 m->options = opts;
1226 }
1227
1228 return mod->options;
1229
1230failed:
1231 ERR(mod->ctx, "out of memory\n");
1232 return NULL;
1233}
1234
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001235/**
1236 * kmod_module_get_install_commands:
1237 * @mod: kmod module
1238 *
1239 * Get install commands for this kmod module. Install commands come from the
1240 * configuration file and are cached in @mod. The first call to this function
1241 * will search for this module in configuration and subsequent calls return
1242 * the cached string. The install commands are returned as they were in the
1243 * configuration, concatenated by ';'. No other processing is made in this
1244 * string.
1245 *
1246 * Returns: a string with all install commands separated by semicolons. This
1247 * string is owned by @mod, do not free it.
1248 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001249KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
1250{
1251 if (mod == NULL)
1252 return NULL;
1253
1254 if (!mod->init.install_commands) {
1255 /* lazy init */
1256 struct kmod_module *m = (struct kmod_module *)mod;
1257 const struct kmod_list *l, *ctx_install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001258
1259 ctx_install_commands = kmod_get_install_commands(mod->ctx);
1260
1261 kmod_list_foreach(l, ctx_install_commands) {
1262 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001263
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001264 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001265 continue;
1266
Lucas De Marchi60f67602011-12-16 03:33:26 -02001267 m->install_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001268
Lucas De Marchi60f67602011-12-16 03:33:26 -02001269 /*
1270 * find only the first command, as modprobe from
1271 * module-init-tools does
1272 */
1273 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001274 }
1275
1276 m->init.install_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001277 }
1278
1279 return mod->install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001280}
1281
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001282void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
1283{
1284 mod->init.install_commands = true;
1285 mod->install_commands = cmd;
1286}
1287
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001288static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
1289{
1290 struct kmod_list *ret = NULL;
1291 unsigned i;
1292
1293 for (i = 0; i < count; i++) {
1294 const char *depname = array[i];
1295 struct kmod_list *lst = NULL;
1296 int err;
1297
1298 err = kmod_module_new_from_lookup(ctx, depname, &lst);
1299 if (err < 0) {
1300 ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
1301 continue;
1302 } else if (lst != NULL)
1303 ret = kmod_list_append_list(ret, lst);
1304 }
1305 return ret;
1306}
1307
1308/**
1309 * kmod_module_get_softdeps:
1310 * @mod: kmod module
1311 * @pre: where to save the list of preceding soft dependencies.
1312 * @post: where to save the list of post soft dependencies.
1313 *
1314 * Get soft dependencies for this kmod module. Soft dependencies come
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001315 * from configuration file and are not cached in @mod because it may include
1316 * dependency cycles that would make we leak kmod_module. Any call
1317 * to this function will search for this module in configuration, allocate a
1318 * list and return the result.
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001319 *
1320 * Both @pre and @post are newly created list of kmod_module and
1321 * should be unreferenced with kmod_module_unref_list().
1322 *
1323 * Returns: 0 on success or < 0 otherwise.
1324 */
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001325KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
1326 struct kmod_list **pre,
1327 struct kmod_list **post)
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001328{
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001329 const struct kmod_list *l, *ctx_softdeps;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001330
1331 if (mod == NULL || pre == NULL || post == NULL)
1332 return -ENOENT;
1333
1334 assert(*pre == NULL);
1335 assert(*post == NULL);
1336
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001337 ctx_softdeps = kmod_get_softdeps(mod->ctx);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001338
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001339 kmod_list_foreach(l, ctx_softdeps) {
1340 const char *modname = kmod_softdep_get_name(l);
1341 const char * const *array;
1342 unsigned count;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001343
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001344 if (fnmatch(modname, mod->name, 0) != 0)
1345 continue;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001346
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001347 array = kmod_softdep_get_pre(l, &count);
1348 *pre = lookup_softdep(mod->ctx, array, count);
1349 array = kmod_softdep_get_post(l, &count);
1350 *post = lookup_softdep(mod->ctx, array, count);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001351
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001352 /*
1353 * find only the first command, as modprobe from
1354 * module-init-tools does
1355 */
1356 break;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001357 }
1358
1359 return 0;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001360}
1361
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001362/**
1363 * kmod_module_get_remove_commands:
1364 * @mod: kmod module
1365 *
1366 * Get remove commands for this kmod module. Remove commands come from the
1367 * configuration file and are cached in @mod. The first call to this function
1368 * will search for this module in configuration and subsequent calls return
1369 * the cached string. The remove commands are returned as they were in the
1370 * configuration, concatenated by ';'. No other processing is made in this
1371 * string.
1372 *
1373 * Returns: a string with all remove commands separated by semicolons. This
1374 * string is owned by @mod, do not free it.
1375 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001376KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
1377{
1378 if (mod == NULL)
1379 return NULL;
1380
1381 if (!mod->init.remove_commands) {
1382 /* lazy init */
1383 struct kmod_module *m = (struct kmod_module *)mod;
1384 const struct kmod_list *l, *ctx_remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001385
1386 ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
1387
1388 kmod_list_foreach(l, ctx_remove_commands) {
1389 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001390
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001391 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001392 continue;
1393
Lucas De Marchi60f67602011-12-16 03:33:26 -02001394 m->remove_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001395
Lucas De Marchi60f67602011-12-16 03:33:26 -02001396 /*
1397 * find only the first command, as modprobe from
1398 * module-init-tools does
1399 */
1400 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001401 }
1402
1403 m->init.remove_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001404 }
1405
1406 return mod->remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001407}
1408
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001409void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
1410{
1411 mod->init.remove_commands = true;
1412 mod->remove_commands = cmd;
1413}
1414
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001415/**
1416 * SECTION:libkmod-loaded
1417 * @short_description: currently loaded modules
1418 *
1419 * Information about currently loaded modules, as reported by Linux kernel.
1420 * These information are not cached by libkmod and are always read from /sys
1421 * and /proc/modules.
1422 */
1423
1424/**
1425 * kmod_module_new_from_loaded:
1426 * @ctx: kmod library context
1427 * @list: where to save the list of loaded modules
1428 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001429 * Create a new list of kmod modules with all modules currently loaded in
1430 * kernel. It uses /proc/modules to get the names of loaded modules and to
1431 * create kmod modules by calling kmod_module_new_from_name() in each of them.
1432 * They are put are put in @list in no particular order.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001433 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001434 * The initial refcount is 1, and needs to be decremented to release the
1435 * resources of the kmod_module. The returned @list must be released by
1436 * calling kmod_module_unref_list(). Since libkmod keeps track of all
1437 * kmod_modules created, they are all released upon @ctx destruction too. Do
1438 * not unref @ctx before all the desired operations with the returned list are
1439 * completed.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001440 *
1441 * Returns: 0 on success or < 0 on error.
1442 */
1443KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
1444 struct kmod_list **list)
1445{
1446 struct kmod_list *l = NULL;
1447 FILE *fp;
1448 char line[4096];
1449
1450 if (ctx == NULL || list == NULL)
1451 return -ENOENT;
1452
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001453 fp = fopen("/proc/modules", "re");
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001454 if (fp == NULL) {
1455 int err = -errno;
1456 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
1457 return err;
1458 }
1459
1460 while (fgets(line, sizeof(line), fp)) {
1461 struct kmod_module *m;
1462 struct kmod_list *node;
1463 int err;
1464 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
1465
1466 err = kmod_module_new_from_name(ctx, name, &m);
1467 if (err < 0) {
1468 ERR(ctx, "could not get module from name '%s': %s\n",
1469 name, strerror(-err));
1470 continue;
1471 }
1472
1473 node = kmod_list_append(l, m);
1474 if (node)
1475 l = node;
1476 else {
1477 ERR(ctx, "out of memory\n");
1478 kmod_module_unref(m);
1479 }
1480 }
1481
1482 fclose(fp);
1483 *list = l;
1484
1485 return 0;
1486}
1487
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001488/**
1489 * kmod_module_initstate_str:
1490 * @state: the state as returned by kmod_module_get_initstate()
1491 *
1492 * Translate a initstate to a string.
1493 *
1494 * Returns: the string associated to the @state. This string is statically
1495 * allocated, do not free it.
1496 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001497KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
1498{
1499 switch (state) {
1500 case KMOD_MODULE_BUILTIN:
1501 return "builtin";
1502 case KMOD_MODULE_LIVE:
1503 return "live";
1504 case KMOD_MODULE_COMING:
1505 return "coming";
1506 case KMOD_MODULE_GOING:
1507 return "going";
1508 default:
1509 return NULL;
1510 }
1511}
1512
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001513/**
1514 * kmod_module_get_initstate:
1515 * @mod: kmod module
1516 *
1517 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
1518 * /sys filesystem.
1519 *
1520 * Returns: < 0 on error or enum kmod_initstate if module is found in kernel.
1521 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001522KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
1523{
1524 char path[PATH_MAX], buf[32];
1525 int fd, err, pathlen;
1526
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001527 if (mod == NULL)
1528 return -ENOENT;
1529
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001530 pathlen = snprintf(path, sizeof(path),
1531 "/sys/module/%s/initstate", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001532 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001533 if (fd < 0) {
1534 err = -errno;
1535
Lucas De Marchiddbda022011-12-27 11:40:10 -02001536 DBG(mod->ctx, "could not open '%s': %s\n",
1537 path, strerror(-err));
1538
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001539 if (pathlen > (int)sizeof("/initstate") - 1) {
1540 struct stat st;
1541 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
1542 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
1543 return KMOD_MODULE_BUILTIN;
1544 }
1545
Gustavo Sverzut Barbieri926f67a2011-12-11 19:33:03 -02001546 DBG(mod->ctx, "could not open '%s': %s\n",
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001547 path, strerror(-err));
1548 return err;
1549 }
1550
1551 err = read_str_safe(fd, buf, sizeof(buf));
1552 close(fd);
1553 if (err < 0) {
1554 ERR(mod->ctx, "could not read from '%s': %s\n",
1555 path, strerror(-err));
1556 return err;
1557 }
1558
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001559 if (streq(buf, "live\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001560 return KMOD_MODULE_LIVE;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001561 else if (streq(buf, "coming\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001562 return KMOD_MODULE_COMING;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001563 else if (streq(buf, "going\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001564 return KMOD_MODULE_GOING;
1565
1566 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
1567 return -EINVAL;
1568}
1569
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001570/**
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001571 * kmod_module_get_size:
1572 * @mod: kmod module
1573 *
1574 * Get the size of this kmod module as returned by Linux kernel. It reads the
1575 * file /proc/modules to search for this module and get its size.
1576 *
1577 * Returns: the size of this kmod module.
1578 */
1579KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
1580{
1581 // FIXME TODO: this should be available from /sys/module/foo
1582 FILE *fp;
1583 char line[4096];
1584 int lineno = 0;
1585 long size = -ENOENT;
1586
1587 if (mod == NULL)
1588 return -ENOENT;
1589
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001590 fp = fopen("/proc/modules", "re");
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001591 if (fp == NULL) {
1592 int err = -errno;
1593 ERR(mod->ctx,
1594 "could not open /proc/modules: %s\n", strerror(errno));
1595 return err;
1596 }
1597
1598 while (fgets(line, sizeof(line), fp)) {
1599 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
1600 long value;
1601
1602 lineno++;
1603 if (tok == NULL || !streq(tok, mod->name))
1604 continue;
1605
1606 tok = strtok_r(NULL, " \t", &saveptr);
1607 if (tok == NULL) {
1608 ERR(mod->ctx,
1609 "invalid line format at /proc/modules:%d\n", lineno);
1610 break;
1611 }
1612
1613 value = strtol(tok, &endptr, 10);
1614 if (endptr == tok || *endptr != '\0') {
1615 ERR(mod->ctx,
1616 "invalid line format at /proc/modules:%d\n", lineno);
1617 break;
1618 }
1619
1620 size = value;
1621 break;
1622 }
1623 fclose(fp);
1624 return size;
1625}
1626
1627/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001628 * kmod_module_get_refcnt:
1629 * @mod: kmod module
1630 *
1631 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
1632 * /sys filesystem.
1633 *
1634 * Returns: 0 on success or < 0 on failure.
1635 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001636KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
1637{
1638 char path[PATH_MAX];
1639 long refcnt;
1640 int fd, err;
1641
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001642 if (mod == NULL)
1643 return -ENOENT;
1644
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001645 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001646 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001647 if (fd < 0) {
1648 err = -errno;
1649 ERR(mod->ctx, "could not open '%s': %s\n",
1650 path, strerror(errno));
1651 return err;
1652 }
1653
1654 err = read_str_long(fd, &refcnt, 10);
1655 close(fd);
1656 if (err < 0) {
1657 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
1658 path, strerror(-err));
1659 return err;
1660 }
1661
1662 return (int)refcnt;
1663}
1664
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001665/**
1666 * kmod_module_get_holders:
1667 * @mod: kmod module
1668 *
1669 * Get a list of kmod modules that are holding this @mod, as returned by Linux
1670 * Kernel. After use, free the @list by calling kmod_module_unref_list().
1671 *
1672 * Returns: a new list of kmod modules on success or NULL on failure.
1673 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001674KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
1675{
1676 char dname[PATH_MAX];
1677 struct kmod_list *list = NULL;
1678 DIR *d;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001679
1680 if (mod == NULL)
1681 return NULL;
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001682
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001683 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
1684
1685 d = opendir(dname);
1686 if (d == NULL) {
1687 ERR(mod->ctx, "could not open '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001688 dname, strerror(errno));
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001689 return NULL;
1690 }
1691
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001692 for (;;) {
1693 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001694 struct kmod_module *holder;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001695 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001696 int err;
1697
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001698 err = readdir_r(d, &de, &entp);
1699 if (err != 0) {
1700 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1701 mod->name, strerror(-err));
1702 goto fail;
1703 }
1704
1705 if (entp == NULL)
1706 break;
1707
1708 if (de.d_name[0] == '.') {
1709 if (de.d_name[1] == '\0' ||
1710 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001711 continue;
1712 }
1713
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001714 err = kmod_module_new_from_name(mod->ctx, de.d_name, &holder);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001715 if (err < 0) {
1716 ERR(mod->ctx, "could not create module for '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001717 de.d_name, strerror(-err));
1718 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001719 }
1720
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001721 l = kmod_list_append(list, holder);
1722 if (l != NULL) {
1723 list = l;
1724 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001725 ERR(mod->ctx, "out of memory\n");
1726 kmod_module_unref(holder);
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001727 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001728 }
1729 }
1730
1731 closedir(d);
1732 return list;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001733
1734fail:
1735 closedir(d);
1736 kmod_module_unref_list(list);
1737 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001738}
1739
1740struct kmod_module_section {
1741 unsigned long address;
1742 char name[];
1743};
1744
1745static void kmod_module_section_free(struct kmod_module_section *section)
1746{
1747 free(section);
1748}
1749
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001750/**
1751 * kmod_module_get_sections:
1752 * @mod: kmod module
1753 *
1754 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
1755 * structure contained in this list is internal to libkmod and their fields
1756 * can be obtained by calling kmod_module_section_get_name() and
1757 * kmod_module_section_get_address().
1758 *
1759 * After use, free the @list by calling kmod_module_section_free_list().
1760 *
1761 * Returns: a new list of kmod module sections on success or NULL on failure.
1762 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001763KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1764{
1765 char dname[PATH_MAX];
1766 struct kmod_list *list = NULL;
1767 DIR *d;
1768 int dfd;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001769
1770 if (mod == NULL)
1771 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001772
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001773 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1774
1775 d = opendir(dname);
1776 if (d == NULL) {
1777 ERR(mod->ctx, "could not open '%s': %s\n",
1778 dname, strerror(errno));
1779 return NULL;
1780 }
1781
1782 dfd = dirfd(d);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001783
1784 for (;;) {
1785 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001786 struct kmod_module_section *section;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001787 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001788 unsigned long address;
1789 size_t namesz;
1790 int fd, err;
1791
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001792 err = readdir_r(d, &de, &entp);
1793 if (err != 0) {
1794 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1795 mod->name, strerror(-err));
1796 goto fail;
1797 }
1798
1799 if (de.d_name[0] == '.') {
1800 if (de.d_name[1] == '\0' ||
1801 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001802 continue;
1803 }
1804
Cristian Rodríguez8e3e5832011-12-16 14:46:52 -03001805 fd = openat(dfd, de.d_name, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001806 if (fd < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001807 ERR(mod->ctx, "could not open '%s/%s': %m\n",
1808 dname, de.d_name);
1809 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001810 }
1811
1812 err = read_str_ulong(fd, &address, 16);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001813 close(fd);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001814 if (err < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001815 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
1816 dname, de.d_name);
1817 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001818 }
1819
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001820 namesz = strlen(de.d_name) + 1;
1821 section = malloc(sizeof(*section) + namesz);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001822
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001823 if (section == NULL) {
1824 ERR(mod->ctx, "out of memory\n");
1825 goto fail;
1826 }
1827
1828 section->address = address;
1829 memcpy(section->name, de.d_name, namesz);
1830
1831 l = kmod_list_append(list, section);
1832 if (l != NULL) {
1833 list = l;
1834 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001835 ERR(mod->ctx, "out of memory\n");
1836 free(section);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001837 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001838 }
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001839 }
1840
1841 closedir(d);
1842 return list;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001843
1844fail:
1845 closedir(d);
1846 kmod_module_unref_list(list);
1847 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001848}
1849
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001850/**
1851 * kmod_module_section_get_module_name:
1852 * @entry: a list entry representing a kmod module section
1853 *
1854 * Get the name of a kmod module section.
1855 *
1856 * After use, free the @list by calling kmod_module_section_free_list().
1857 *
1858 * Returns: the name of this kmod module section on success or NULL on
1859 * failure. The string is owned by the section, do not free it.
1860 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001861KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
1862{
1863 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001864
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001865 if (entry == NULL)
1866 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001867
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001868 section = entry->data;
1869 return section->name;
1870}
1871
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001872/**
1873 * kmod_module_section_get_address:
1874 * @entry: a list entry representing a kmod module section
1875 *
1876 * Get the address of a kmod module section.
1877 *
1878 * After use, free the @list by calling kmod_module_section_free_list().
1879 *
1880 * Returns: the address of this kmod module section on success or ULONG_MAX
1881 * on failure.
1882 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001883KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
1884{
1885 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001886
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001887 if (entry == NULL)
1888 return (unsigned long)-1;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001889
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001890 section = entry->data;
1891 return section->address;
1892}
1893
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001894/**
1895 * kmod_module_section_free_list:
1896 * @list: kmod module section list
1897 *
1898 * Release the resources taken by @list
1899 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001900KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
1901{
1902 while (list) {
1903 kmod_module_section_free(list->data);
1904 list = kmod_list_remove(list);
1905 }
1906}
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001907
1908struct kmod_module_info {
1909 char *key;
1910 char value[];
1911};
1912
1913static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
1914{
1915 struct kmod_module_info *info;
1916
1917 info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
1918 if (info == NULL)
1919 return NULL;
1920
1921 info->key = (char *)info + sizeof(struct kmod_module_info)
1922 + valuelen + 1;
1923 memcpy(info->key, key, keylen);
1924 info->key[keylen] = '\0';
1925 memcpy(info->value, value, valuelen);
1926 info->value[valuelen] = '\0';
1927 return info;
1928}
1929
1930static void kmod_module_info_free(struct kmod_module_info *info)
1931{
1932 free(info);
1933}
1934
1935/**
1936 * kmod_module_get_info:
1937 * @mod: kmod module
1938 * @list: where to return list of module information. Use
1939 * kmod_module_info_get_key() and
1940 * kmod_module_info_get_value(). Release this list with
Lucas De Marchidb74cee2012-01-09 03:45:19 -02001941 * kmod_module_info_free_list()
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001942 *
1943 * Get a list of entries in ELF section ".modinfo", these contain
1944 * alias, license, depends, vermagic and other keys with respective
1945 * values.
1946 *
1947 * After use, free the @list by calling kmod_module_info_free_list().
1948 *
1949 * Returns: 0 on success or < 0 otherwise.
1950 */
1951KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
1952{
1953 struct kmod_file *file;
1954 struct kmod_elf *elf;
1955 const char *path;
1956 const void *mem;
1957 char **strings;
1958 size_t size;
1959 int i, count, ret = 0;
1960
1961 if (mod == NULL || list == NULL)
1962 return -ENOENT;
1963
1964 assert(*list == NULL);
1965
1966 path = kmod_module_get_path(mod);
1967 if (path == NULL)
1968 return -ENOENT;
1969
Lucas De Marchic68e92f2012-01-04 08:19:34 -02001970 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001971 if (file == NULL)
1972 return -errno;
1973
1974 size = kmod_file_get_size(file);
1975 mem = kmod_file_get_contents(file);
1976
1977 elf = kmod_elf_new(mem, size);
1978 if (elf == NULL) {
1979 ret = -errno;
1980 goto elf_open_error;
1981 }
1982
1983 count = kmod_elf_get_strings(elf, ".modinfo", &strings);
1984 if (count < 0) {
1985 ret = count;
1986 goto get_strings_error;
1987 }
1988
1989 for (i = 0; i < count; i++) {
1990 struct kmod_module_info *info;
1991 struct kmod_list *n;
1992 const char *key, *value;
1993 size_t keylen, valuelen;
1994
1995 key = strings[i];
1996 value = strchr(key, '=');
1997 if (value == NULL) {
1998 keylen = strlen(key);
1999 valuelen = 0;
2000 } else {
2001 keylen = value - key;
2002 value++;
2003 valuelen = strlen(value);
2004 }
2005
2006 info = kmod_module_info_new(key, keylen, value, valuelen);
2007 if (info == NULL) {
2008 ret = -errno;
2009 kmod_module_info_free_list(*list);
2010 *list = NULL;
2011 goto list_error;
2012 }
2013
2014 n = kmod_list_append(*list, info);
2015 if (n != NULL)
2016 *list = n;
2017 else {
2018 kmod_module_info_free(info);
2019 kmod_module_info_free_list(*list);
2020 *list = NULL;
2021 ret = -ENOMEM;
2022 goto list_error;
2023 }
2024 }
2025 ret = count;
2026
2027list_error:
2028 free(strings);
2029get_strings_error:
2030 kmod_elf_unref(elf);
2031elf_open_error:
2032 kmod_file_unref(file);
2033
2034 return ret;
2035}
2036
2037/**
2038 * kmod_module_info_get_key:
2039 * @entry: a list entry representing a kmod module info
2040 *
2041 * Get the key of a kmod module info.
2042 *
2043 * Returns: the key of this kmod module info on success or NULL on
2044 * failure. The string is owned by the info, do not free it.
2045 */
2046KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
2047{
2048 struct kmod_module_info *info;
2049
2050 if (entry == NULL)
2051 return NULL;
2052
2053 info = entry->data;
2054 return info->key;
2055}
2056
2057/**
2058 * kmod_module_info_get_value:
2059 * @entry: a list entry representing a kmod module info
2060 *
2061 * Get the value of a kmod module info.
2062 *
2063 * Returns: the value of this kmod module info on success or NULL on
2064 * failure. The string is owned by the info, do not free it.
2065 */
2066KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
2067{
2068 struct kmod_module_info *info;
2069
2070 if (entry == NULL)
2071 return NULL;
2072
2073 info = entry->data;
2074 return info->value;
2075}
2076
2077/**
2078 * kmod_module_info_free_list:
2079 * @list: kmod module info list
2080 *
2081 * Release the resources taken by @list
2082 */
2083KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
2084{
2085 while (list) {
2086 kmod_module_info_free(list->data);
2087 list = kmod_list_remove(list);
2088 }
2089}
2090
2091struct kmod_module_version {
2092 uint64_t crc;
2093 char symbol[];
2094};
2095
2096static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
2097{
2098 struct kmod_module_version *mv;
2099 size_t symbollen = strlen(symbol) + 1;
2100
2101 mv = malloc(sizeof(struct kmod_module_version) + symbollen);
2102 if (mv == NULL)
2103 return NULL;
2104
2105 mv->crc = crc;
2106 memcpy(mv->symbol, symbol, symbollen);
2107 return mv;
2108}
2109
2110static void kmod_module_version_free(struct kmod_module_version *version)
2111{
2112 free(version);
2113}
2114
2115/**
2116 * kmod_module_get_versions:
2117 * @mod: kmod module
2118 * @list: where to return list of module versions. Use
Lucas De Marchidb74cee2012-01-09 03:45:19 -02002119 * kmod_module_version_get_symbol() and
2120 * kmod_module_version_get_crc(). Release this list with
2121 * kmod_module_versions_free_list()
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02002122 *
2123 * Get a list of entries in ELF section "__versions".
2124 *
2125 * After use, free the @list by calling kmod_module_versions_free_list().
2126 *
2127 * Returns: 0 on success or < 0 otherwise.
2128 */
2129KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
2130{
2131 struct kmod_file *file;
2132 struct kmod_elf *elf;
2133 const char *path;
2134 const void *mem;
2135 struct kmod_modversion *versions;
2136 size_t size;
2137 int i, count, ret = 0;
2138
2139 if (mod == NULL || list == NULL)
2140 return -ENOENT;
2141
2142 assert(*list == NULL);
2143
2144 path = kmod_module_get_path(mod);
2145 if (path == NULL)
2146 return -ENOENT;
2147
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002148 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02002149 if (file == NULL)
2150 return -errno;
2151
2152 size = kmod_file_get_size(file);
2153 mem = kmod_file_get_contents(file);
2154
2155 elf = kmod_elf_new(mem, size);
2156 if (elf == NULL) {
2157 ret = -errno;
2158 goto elf_open_error;
2159 }
2160
2161 count = kmod_elf_get_modversions(elf, &versions);
2162 if (count < 0) {
2163 ret = count;
2164 goto get_strings_error;
2165 }
2166
2167 for (i = 0; i < count; i++) {
2168 struct kmod_module_version *mv;
2169 struct kmod_list *n;
2170
2171 mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
2172 if (mv == NULL) {
2173 ret = -errno;
2174 kmod_module_versions_free_list(*list);
2175 *list = NULL;
2176 goto list_error;
2177 }
2178
2179 n = kmod_list_append(*list, mv);
2180 if (n != NULL)
2181 *list = n;
2182 else {
2183 kmod_module_version_free(mv);
2184 kmod_module_versions_free_list(*list);
2185 *list = NULL;
2186 ret = -ENOMEM;
2187 goto list_error;
2188 }
2189 }
2190 ret = count;
2191
2192list_error:
2193 free(versions);
2194get_strings_error:
2195 kmod_elf_unref(elf);
2196elf_open_error:
2197 kmod_file_unref(file);
2198
2199 return ret;
2200}
2201
2202/**
2203 * kmod_module_versions_get_symbol:
2204 * @entry: a list entry representing a kmod module versions
2205 *
2206 * Get the symbol of a kmod module versions.
2207 *
2208 * Returns: the symbol of this kmod module versions on success or NULL
2209 * on failure. The string is owned by the versions, do not free it.
2210 */
2211KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
2212{
2213 struct kmod_module_version *version;
2214
2215 if (entry == NULL)
2216 return NULL;
2217
2218 version = entry->data;
2219 return version->symbol;
2220}
2221
2222/**
2223 * kmod_module_version_get_crc:
2224 * @entry: a list entry representing a kmod module version
2225 *
2226 * Get the crc of a kmod module version.
2227 *
2228 * Returns: the crc of this kmod module version on success or NULL on
2229 * failure. The string is owned by the version, do not free it.
2230 */
2231KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
2232{
2233 struct kmod_module_version *version;
2234
2235 if (entry == NULL)
2236 return 0;
2237
2238 version = entry->data;
2239 return version->crc;
2240}
2241
2242/**
2243 * kmod_module_versions_free_list:
2244 * @list: kmod module versions list
2245 *
2246 * Release the resources taken by @list
2247 */
2248KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
2249{
2250 while (list) {
2251 kmod_module_version_free(list->data);
2252 list = kmod_list_remove(list);
2253 }
2254}
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002255
2256struct kmod_module_symbol {
2257 uint64_t crc;
2258 char symbol[];
2259};
2260
2261static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
2262{
2263 struct kmod_module_symbol *mv;
2264 size_t symbollen = strlen(symbol) + 1;
2265
2266 mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
2267 if (mv == NULL)
2268 return NULL;
2269
2270 mv->crc = crc;
2271 memcpy(mv->symbol, symbol, symbollen);
2272 return mv;
2273}
2274
2275static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
2276{
2277 free(symbol);
2278}
2279
2280/**
2281 * kmod_module_get_symbols:
2282 * @mod: kmod module
2283 * @list: where to return list of module symbols. Use
Lucas De Marchidb74cee2012-01-09 03:45:19 -02002284 * kmod_module_symbol_get_symbol() and
2285 * kmod_module_symbol_get_crc(). Release this list with
2286 * kmod_module_symbols_free_list()
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002287 *
2288 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2289 *
2290 * After use, free the @list by calling kmod_module_symbols_free_list().
2291 *
2292 * Returns: 0 on success or < 0 otherwise.
2293 */
2294KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
2295{
2296 struct kmod_file *file;
2297 struct kmod_elf *elf;
2298 const char *path;
2299 const void *mem;
2300 struct kmod_modversion *symbols;
2301 size_t size;
2302 int i, count, ret = 0;
2303
2304 if (mod == NULL || list == NULL)
2305 return -ENOENT;
2306
2307 assert(*list == NULL);
2308
2309 path = kmod_module_get_path(mod);
2310 if (path == NULL)
2311 return -ENOENT;
2312
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002313 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002314 if (file == NULL)
2315 return -errno;
2316
2317 size = kmod_file_get_size(file);
2318 mem = kmod_file_get_contents(file);
2319
2320 elf = kmod_elf_new(mem, size);
2321 if (elf == NULL) {
2322 ret = -errno;
2323 goto elf_open_error;
2324 }
2325
2326 count = kmod_elf_get_symbols(elf, &symbols);
2327 if (count < 0) {
2328 ret = count;
2329 goto get_strings_error;
2330 }
2331
2332 for (i = 0; i < count; i++) {
2333 struct kmod_module_symbol *mv;
2334 struct kmod_list *n;
2335
2336 mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
2337 if (mv == NULL) {
2338 ret = -errno;
2339 kmod_module_symbols_free_list(*list);
2340 *list = NULL;
2341 goto list_error;
2342 }
2343
2344 n = kmod_list_append(*list, mv);
2345 if (n != NULL)
2346 *list = n;
2347 else {
2348 kmod_module_symbol_free(mv);
2349 kmod_module_symbols_free_list(*list);
2350 *list = NULL;
2351 ret = -ENOMEM;
2352 goto list_error;
2353 }
2354 }
2355 ret = count;
2356
2357list_error:
2358 free(symbols);
2359get_strings_error:
2360 kmod_elf_unref(elf);
2361elf_open_error:
2362 kmod_file_unref(file);
2363
2364 return ret;
2365}
2366
2367/**
Lucas De Marchidb74cee2012-01-09 03:45:19 -02002368 * kmod_module_symbol_get_symbol:
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002369 * @entry: a list entry representing a kmod module symbols
2370 *
2371 * Get the symbol of a kmod module symbols.
2372 *
2373 * Returns: the symbol of this kmod module symbols on success or NULL
2374 * on failure. The string is owned by the symbols, do not free it.
2375 */
2376KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
2377{
2378 struct kmod_module_symbol *symbol;
2379
2380 if (entry == NULL)
2381 return NULL;
2382
2383 symbol = entry->data;
2384 return symbol->symbol;
2385}
2386
2387/**
2388 * kmod_module_symbol_get_crc:
2389 * @entry: a list entry representing a kmod module symbol
2390 *
2391 * Get the crc of a kmod module symbol.
2392 *
2393 * Returns: the crc of this kmod module symbol on success or NULL on
2394 * failure. The string is owned by the symbol, do not free it.
2395 */
2396KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
2397{
2398 struct kmod_module_symbol *symbol;
2399
2400 if (entry == NULL)
2401 return 0;
2402
2403 symbol = entry->data;
2404 return symbol->crc;
2405}
2406
2407/**
2408 * kmod_module_symbols_free_list:
2409 * @list: kmod module symbols list
2410 *
2411 * Release the resources taken by @list
2412 */
2413KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
2414{
2415 while (list) {
2416 kmod_module_symbol_free(list->data);
2417 list = kmod_list_remove(list);
2418 }
2419}
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002420
2421struct kmod_module_dependency_symbol {
2422 uint64_t crc;
2423 uint8_t bind;
2424 char symbol[];
2425};
2426
2427static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
2428{
2429 struct kmod_module_dependency_symbol *mv;
2430 size_t symbollen = strlen(symbol) + 1;
2431
2432 mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
2433 if (mv == NULL)
2434 return NULL;
2435
2436 mv->crc = crc;
2437 mv->bind = bind;
2438 memcpy(mv->symbol, symbol, symbollen);
2439 return mv;
2440}
2441
2442static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
2443{
2444 free(dependency_symbol);
2445}
2446
2447/**
2448 * kmod_module_get_dependency_symbols:
2449 * @mod: kmod module
2450 * @list: where to return list of module dependency_symbols. Use
2451 * kmod_module_dependency_symbol_get_symbol() and
2452 * kmod_module_dependency_symbol_get_crc(). Release this list with
2453 * kmod_module_dependency_symbols_free_list()
2454 *
2455 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2456 *
2457 * After use, free the @list by calling
2458 * kmod_module_dependency_symbols_free_list().
2459 *
2460 * Returns: 0 on success or < 0 otherwise.
2461 */
2462KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
2463{
2464 struct kmod_file *file;
2465 struct kmod_elf *elf;
2466 const char *path;
2467 const void *mem;
2468 struct kmod_modversion *symbols;
2469 size_t size;
2470 int i, count, ret = 0;
2471
2472 if (mod == NULL || list == NULL)
2473 return -ENOENT;
2474
2475 assert(*list == NULL);
2476
2477 path = kmod_module_get_path(mod);
2478 if (path == NULL)
2479 return -ENOENT;
2480
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002481 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002482 if (file == NULL)
2483 return -errno;
2484
2485 size = kmod_file_get_size(file);
2486 mem = kmod_file_get_contents(file);
2487
2488 elf = kmod_elf_new(mem, size);
2489 if (elf == NULL) {
2490 ret = -errno;
2491 goto elf_open_error;
2492 }
2493
2494 count = kmod_elf_get_dependency_symbols(elf, &symbols);
2495 if (count < 0) {
2496 ret = count;
2497 goto get_strings_error;
2498 }
2499
2500 for (i = 0; i < count; i++) {
2501 struct kmod_module_dependency_symbol *mv;
2502 struct kmod_list *n;
2503
2504 mv = kmod_module_dependency_symbols_new(symbols[i].crc,
2505 symbols[i].bind,
2506 symbols[i].symbol);
2507 if (mv == NULL) {
2508 ret = -errno;
2509 kmod_module_dependency_symbols_free_list(*list);
2510 *list = NULL;
2511 goto list_error;
2512 }
2513
2514 n = kmod_list_append(*list, mv);
2515 if (n != NULL)
2516 *list = n;
2517 else {
2518 kmod_module_dependency_symbol_free(mv);
2519 kmod_module_dependency_symbols_free_list(*list);
2520 *list = NULL;
2521 ret = -ENOMEM;
2522 goto list_error;
2523 }
2524 }
2525 ret = count;
2526
2527list_error:
2528 free(symbols);
2529get_strings_error:
2530 kmod_elf_unref(elf);
2531elf_open_error:
2532 kmod_file_unref(file);
2533
2534 return ret;
2535}
2536
2537/**
2538 * kmod_module_dependency_symbol_get_symbol:
2539 * @entry: a list entry representing a kmod module dependency_symbols
2540 *
2541 * Get the dependency symbol of a kmod module
2542 *
2543 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
2544 * on failure. The string is owned by the dependency_symbols, do not free it.
2545 */
2546KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
2547{
2548 struct kmod_module_dependency_symbol *dependency_symbol;
2549
2550 if (entry == NULL)
2551 return NULL;
2552
2553 dependency_symbol = entry->data;
2554 return dependency_symbol->symbol;
2555}
2556
2557/**
2558 * kmod_module_dependency_symbol_get_crc:
2559 * @entry: a list entry representing a kmod module dependency_symbol
2560 *
2561 * Get the crc of a kmod module dependency_symbol.
2562 *
2563 * Returns: the crc of this kmod module dependency_symbol on success or NULL on
2564 * failure. The string is owned by the dependency_symbol, do not free it.
2565 */
2566KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
2567{
2568 struct kmod_module_dependency_symbol *dependency_symbol;
2569
2570 if (entry == NULL)
2571 return 0;
2572
2573 dependency_symbol = entry->data;
2574 return dependency_symbol->crc;
2575}
2576
2577/**
2578 * kmod_module_dependency_symbol_get_bind:
2579 * @entry: a list entry representing a kmod module dependency_symbol
2580 *
2581 * Get the bind type of a kmod module dependency_symbol.
2582 *
2583 * Returns: the bind of this kmod module dependency_symbol on success
2584 * or < 0 on failure.
2585 */
2586KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
2587{
2588 struct kmod_module_dependency_symbol *dependency_symbol;
2589
2590 if (entry == NULL)
2591 return 0;
2592
2593 dependency_symbol = entry->data;
2594 return dependency_symbol->bind;
2595}
2596
2597/**
2598 * kmod_module_dependency_symbols_free_list:
2599 * @list: kmod module dependency_symbols list
2600 *
2601 * Release the resources taken by @list
2602 */
2603KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
2604{
2605 while (list) {
2606 kmod_module_dependency_symbol_free(list->data);
2607 list = kmod_list_remove(list);
2608 }
2609}