]> git.ipfire.org Git - thirdparty/kmod.git/blame - libkmod/libkmod-module.c
CODING-STYLE: add include order
[thirdparty/kmod.git] / libkmod / libkmod-module.c
CommitLineData
8f788d58
LDM
1/*
2 * libkmod - interface to kernel module operations
3 *
e6b0e49b 4 * Copyright (C) 2011-2013 ProFUSION embedded systems
8f788d58
LDM
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
cb451f35
LDM
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
8f788d58
LDM
10 *
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
dea2dfee 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
8f788d58
LDM
18 */
19
7636e72b 20#include <assert.h>
8f788d58 21#include <ctype.h>
c2e4286b
LDM
22#include <dirent.h>
23#include <errno.h>
24#include <fnmatch.h>
8f788d58 25#include <inttypes.h>
f12ae3c4 26#include <limits.h>
c2e4286b
LDM
27#include <stdarg.h>
28#include <stddef.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
8f788d58 33#include <sys/mman.h>
c2e4286b 34#include <sys/stat.h>
144d1826 35#include <sys/syscall.h>
c2e4286b 36#include <sys/types.h>
eff917c0 37#include <sys/wait.h>
144d1826
KC
38#ifdef HAVE_LINUX_MODULE_H
39#include <linux/module.h>
40#endif
41
96573a02
LDM
42#include <shared/util.h>
43
8f788d58 44#include "libkmod.h"
83b855a6 45#include "libkmod-internal.h"
8f788d58 46
6681951b
LDM
47/**
48 * SECTION:libkmod-module
49 * @short_description: operate on kernel modules
50 */
51
8f788d58
LDM
52/**
53 * kmod_module:
54 *
55 * Opaque object representing a module.
56 */
57struct kmod_module {
58 struct kmod_ctx *ctx;
8bdeca11 59 char *hashkey;
219f9c38 60 char *name;
f1fb6f85 61 char *path;
7636e72b 62 struct kmod_list *dep;
bd3f5535 63 char *options;
60f6760e
LDM
64 const char *install_commands; /* owned by kmod_config */
65 const char *remove_commands; /* owned by kmod_config */
6ad5f263 66 char *alias; /* only set if this module was created from an alias */
1eff942e 67 struct kmod_file *file;
b6a534f7 68 int n_dep;
bd3f5535 69 int refcount;
7636e72b
LDM
70 struct {
71 bool dep : 1;
bd3f5535
GSB
72 bool options : 1;
73 bool install_commands : 1;
74 bool remove_commands : 1;
7636e72b 75 } init;
b1a51256
LDM
76
77 /*
78 * private field used by kmod_module_get_probe_list() to detect
79 * dependency loops
80 */
ece09aac 81 bool visited : 1;
89e92487
LDM
82
83 /*
84 * set by kmod_module_get_probe_list: indicates for probe_insert()
85 * whether the module's command and softdep should be ignored
86 */
87 bool ignorecmd : 1;
3805274b 88
450bd1b4
MM
89 /*
90 * set by kmod_module_get_probe_list: indicates whether this is the
91 * module the user asked for or its dependency, or whether this
92 * is a softdep only
93 */
94 bool required : 1;
95
3805274b
LDM
96 /*
97 * if module was created by searching the modules.builtin file, this
98 * is set. There's nothing much useful one can do with such a
99 * "module", except knowing it's builtin.
100 */
101 bool builtin : 1;
8f788d58
LDM
102};
103
c35347f1
LDM
104static inline const char *path_join(const char *path, size_t prefixlen,
105 char buf[PATH_MAX])
e18ad35c
GSB
106{
107 size_t pathlen;
108
109 if (path[0] == '/')
110 return path;
111
112 pathlen = strlen(path);
113 if (prefixlen + pathlen + 1 >= PATH_MAX)
114 return NULL;
115
116 memcpy(buf + prefixlen, path, pathlen + 1);
117 return buf;
118}
119
af9572c6
DR
120static inline bool module_is_inkernel(struct kmod_module *mod)
121{
122 int state = kmod_module_get_initstate(mod);
3805274b 123
af9572c6 124 if (state == KMOD_MODULE_LIVE ||
af9572c6
DR
125 state == KMOD_MODULE_BUILTIN)
126 return true;
3805274b
LDM
127
128 return false;
af9572c6
DR
129}
130
671d4894 131int kmod_module_parse_depline(struct kmod_module *mod, char *line)
7636e72b
LDM
132{
133 struct kmod_ctx *ctx = mod->ctx;
134 struct kmod_list *list = NULL;
e18ad35c
GSB
135 const char *dirname;
136 char buf[PATH_MAX];
7636e72b 137 char *p, *saveptr;
45f27781 138 int err = 0, n = 0;
e18ad35c 139 size_t dirnamelen;
7636e72b 140
b6a534f7
GSB
141 if (mod->init.dep)
142 return mod->n_dep;
143 assert(mod->dep == NULL);
7636e72b
LDM
144 mod->init.dep = true;
145
146 p = strchr(line, ':');
147 if (p == NULL)
148 return 0;
149
671d4894 150 *p = '\0';
e18ad35c
GSB
151 dirname = kmod_get_dirname(mod->ctx);
152 dirnamelen = strlen(dirname);
153 if (dirnamelen + 2 >= PATH_MAX)
154 return 0;
28c175ed 155
e18ad35c
GSB
156 memcpy(buf, dirname, dirnamelen);
157 buf[dirnamelen] = '/';
158 dirnamelen++;
159 buf[dirnamelen] = '\0';
160
161 if (mod->path == NULL) {
162 const char *str = path_join(line, dirnamelen, buf);
163 if (str == NULL)
164 return 0;
165 mod->path = strdup(str);
166 if (mod->path == NULL)
167 return 0;
168 }
671d4894 169
7636e72b 170 p++;
7636e72b
LDM
171 for (p = strtok_r(p, " \t", &saveptr); p != NULL;
172 p = strtok_r(NULL, " \t", &saveptr)) {
1fc1c9a0 173 struct kmod_module *depmod;
e18ad35c
GSB
174 const char *path;
175
176 path = path_join(p, dirnamelen, buf);
177 if (path == NULL) {
178 ERR(ctx, "could not join path '%s' and '%s'.\n",
179 dirname, p);
180 goto fail;
181 }
7636e72b 182
e18ad35c 183 err = kmod_module_new_from_path(ctx, path, &depmod);
7636e72b 184 if (err < 0) {
e18ad35c
GSB
185 ERR(ctx, "ctx=%p path=%s error=%s\n",
186 ctx, path, strerror(-err));
7636e72b
LDM
187 goto fail;
188 }
189
e18ad35c 190 DBG(ctx, "add dep: %s\n", path);
7636e72b 191
b94a7379 192 list = kmod_list_prepend(list, depmod);
7636e72b
LDM
193 n++;
194 }
195
196 DBG(ctx, "%d dependencies for %s\n", n, mod->name);
197
198 mod->dep = list;
b6a534f7 199 mod->n_dep = n;
7636e72b
LDM
200 return n;
201
202fail:
203 kmod_module_unref_list(list);
204 mod->init.dep = false;
205 return err;
206}
207
ece09aac
LDM
208void kmod_module_set_visited(struct kmod_module *mod, bool visited)
209{
210 mod->visited = visited;
211}
212
3805274b
LDM
213void kmod_module_set_builtin(struct kmod_module *mod, bool builtin)
214{
215 mod->builtin = builtin;
216}
217
450bd1b4
MM
218void kmod_module_set_required(struct kmod_module *mod, bool required)
219{
220 mod->required = required;
221}
222
9c7f3ad0
LDM
223/*
224 * Memory layout with alias:
225 *
226 * struct kmod_module {
227 * hashkey -----.
228 * alias -----. |
229 * name ----. | |
230 * } | | |
231 * name <----------' | |
232 * alias <-----------' |
233 * name\alias <--------'
234 *
235 * Memory layout without alias:
236 *
237 * struct kmod_module {
238 * hashkey ---.
239 * alias -----|----> NULL
240 * name ----. |
241 * } | |
242 * name <----------'-'
243 *
244 * @key is "name\alias" or "name" (in which case alias == NULL)
245 */
246static int kmod_module_new(struct kmod_ctx *ctx, const char *key,
247 const char *name, size_t namelen,
248 const char *alias, size_t aliaslen,
249 struct kmod_module **mod)
250{
251 struct kmod_module *m;
252 size_t keylen;
253
254 m = kmod_pool_get_module(ctx, key);
255 if (m != NULL) {
256 *mod = kmod_module_ref(m);
257 return 0;
258 }
259
260 if (alias == NULL)
261 keylen = namelen;
262 else
263 keylen = namelen + aliaslen + 1;
264
265 m = malloc(sizeof(*m) + (alias == NULL ? 1 : 2) * (keylen + 1));
9f02561d 266 if (m == NULL)
9c7f3ad0 267 return -ENOMEM;
9c7f3ad0
LDM
268
269 memset(m, 0, sizeof(*m));
270
271 m->ctx = kmod_ref(ctx);
272 m->name = (char *)m + sizeof(*m);
273 memcpy(m->name, key, keylen + 1);
274 if (alias == NULL) {
275 m->hashkey = m->name;
276 m->alias = NULL;
277 } else {
278 m->name[namelen] = '\0';
279 m->alias = m->name + namelen + 1;
280 m->hashkey = m->name + keylen + 1;
281 memcpy(m->hashkey, key, keylen + 1);
282 }
283
284 m->refcount = 1;
285 kmod_pool_add_module(ctx, m, m->hashkey);
286 *mod = m;
287
288 return 0;
289}
290
7afc98a1
LDM
291/**
292 * kmod_module_new_from_name:
293 * @ctx: kmod library context
294 * @name: name of the module
295 * @mod: where to save the created struct kmod_module
296 *
297 * Create a new struct kmod_module using the module name. @name can not be an
298 * alias, file name or anything else; it must be a module name. There's no
9a252c21 299 * check if the module exists in the system.
7afc98a1
LDM
300 *
301 * This function is also used internally by many others that return a new
302 * struct kmod_module or a new list of modules.
303 *
304 * The initial refcount is 1, and needs to be decremented to release the
305 * resources of the kmod_module. Since libkmod keeps track of all
306 * kmod_modules created, they are all released upon @ctx destruction too. Do
307 * not unref @ctx before all the desired operations with the returned
308 * kmod_module are done.
309 *
310 * Returns: 0 on success or < 0 otherwise. It fails if name is not a valid
311 * module name or if memory allocation failed.
312 */
8f788d58
LDM
313KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
314 const char *name,
315 struct kmod_module **mod)
316{
d753b8ca 317 size_t namelen;
6daceb2f 318 char name_norm[PATH_MAX];
8f788d58 319
818f8e8a 320 if (ctx == NULL || name == NULL || mod == NULL)
8f788d58
LDM
321 return -ENOENT;
322
9c7f3ad0 323 modname_normalize(name, name_norm, &namelen);
113c66a5 324
9c7f3ad0 325 return kmod_module_new(ctx, name_norm, name_norm, namelen, NULL, 0, mod);
8f788d58
LDM
326}
327
6ad5f263
LDM
328int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
329 const char *name, struct kmod_module **mod)
330{
331 int err;
6daceb2f 332 char key[PATH_MAX];
113c66a5
LDM
333 size_t namelen = strlen(name);
334 size_t aliaslen = strlen(alias);
6ad5f263 335
6daceb2f 336 if (namelen + aliaslen + 2 > PATH_MAX)
113c66a5 337 return -ENAMETOOLONG;
6ad5f263 338
113c66a5
LDM
339 memcpy(key, name, namelen);
340 memcpy(key + namelen + 1, alias, aliaslen + 1);
9c7f3ad0 341 key[namelen] = '\\';
6ad5f263 342
9c7f3ad0 343 err = kmod_module_new(ctx, key, name, namelen, alias, aliaslen, mod);
113c66a5
LDM
344 if (err < 0)
345 return err;
6ad5f263
LDM
346
347 return 0;
6ad5f263
LDM
348}
349
7afc98a1
LDM
350/**
351 * kmod_module_new_from_path:
352 * @ctx: kmod library context
353 * @path: path where to find the given module
354 * @mod: where to save the created struct kmod_module
355 *
356 * Create a new struct kmod_module using the module path. @path must be an
357 * existent file with in the filesystem and must be accessible to libkmod.
358 *
359 * The initial refcount is 1, and needs to be decremented to release the
360 * resources of the kmod_module. Since libkmod keeps track of all
361 * kmod_modules created, they are all released upon @ctx destruction too. Do
362 * not unref @ctx before all the desired operations with the returned
363 * kmod_module are done.
364 *
365 * If @path is relative, it's treated as relative to the current working
366 * directory. Otherwise, give an absolute path.
367 *
368 * Returns: 0 on success or < 0 otherwise. It fails if file does not exist, if
369 * it's not a valid file for a kmod_module or if memory allocation failed.
370 */
8f788d58
LDM
371KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
372 const char *path,
373 struct kmod_module **mod)
374{
375 struct kmod_module *m;
376 int err;
377 struct stat st;
6daceb2f 378 char name[PATH_MAX];
71e975cd 379 char *abspath;
d753b8ca 380 size_t namelen;
8f788d58 381
818f8e8a 382 if (ctx == NULL || path == NULL || mod == NULL)
8f788d58
LDM
383 return -ENOENT;
384
71e975cd 385 abspath = path_make_absolute_cwd(path);
b55df2ee
GSB
386 if (abspath == NULL) {
387 DBG(ctx, "no absolute path for %s\n", path);
71e975cd 388 return -ENOMEM;
b55df2ee 389 }
71e975cd
LDM
390
391 err = stat(abspath, &st);
392 if (err < 0) {
b55df2ee
GSB
393 err = -errno;
394 DBG(ctx, "stat %s: %s\n", path, strerror(errno));
71e975cd 395 free(abspath);
b55df2ee 396 return err;
71e975cd 397 }
8f788d58 398
973c80ba 399 if (path_to_modname(path, name, &namelen) == NULL) {
b55df2ee 400 DBG(ctx, "could not get modname from path %s\n", path);
973c80ba
GSB
401 free(abspath);
402 return -ENOENT;
403 }
d753b8ca 404
fd186ae9
LDM
405 m = kmod_pool_get_module(ctx, name);
406 if (m != NULL) {
6bd0b8d0
LDM
407 if (m->path == NULL)
408 m->path = abspath;
409 else if (streq(m->path, abspath))
410 free(abspath);
411 else {
ebaa7beb 412 ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n",
9c7f3ad0 413 name, abspath, m->path);
6bd0b8d0
LDM
414 free(abspath);
415 return -EEXIST;
416 }
417
fd186ae9
LDM
418 *mod = kmod_module_ref(m);
419 return 0;
420 }
421
9c7f3ad0 422 err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
c1bc88c9
LP
423 if (err < 0) {
424 free(abspath);
9c7f3ad0 425 return err;
c1bc88c9 426 }
788ef0f7 427
71e975cd 428 m->path = abspath;
8f788d58
LDM
429 *mod = m;
430
431 return 0;
432}
433
7afc98a1
LDM
434/**
435 * kmod_module_unref:
436 * @mod: kmod module
437 *
438 * Drop a reference of the kmod module. If the refcount reaches zero, its
439 * resources are released.
440 *
441 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
442 * returns the passed @mod with its refcount decremented.
443 */
8f788d58
LDM
444KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
445{
446 if (mod == NULL)
447 return NULL;
448
449 if (--mod->refcount > 0)
450 return mod;
451
452 DBG(mod->ctx, "kmod_module %p released\n", mod);
453
4084c176 454 kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
7636e72b 455 kmod_module_unref_list(mod->dep);
1eff942e
LDM
456
457 if (mod->file)
458 kmod_file_unref(mod->file);
459
8f788d58 460 kmod_unref(mod->ctx);
bd3f5535 461 free(mod->options);
f1fb6f85 462 free(mod->path);
8f788d58
LDM
463 free(mod);
464 return NULL;
465}
466
7afc98a1
LDM
467/**
468 * kmod_module_ref:
469 * @mod: kmod module
470 *
471 * Take a reference of the kmod module, incrementing its refcount.
472 *
473 * Returns: the passed @module with its refcount incremented.
474 */
8f788d58
LDM
475KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
476{
477 if (mod == NULL)
478 return NULL;
479
480 mod->refcount++;
481
482 return mod;
483}
484
b14dcfda
LDM
485#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
486 do { \
487 if ((_err) < 0) \
488 goto _label_err; \
489 if (*(_list) != NULL) \
490 goto finish; \
491 } while (0)
492
7afc98a1
LDM
493/**
494 * kmod_module_new_from_lookup:
495 * @ctx: kmod library context
496 * @given_alias: alias to look for
497 * @list: an empty list where to save the list of modules matching
498 * @given_alias
499 *
500 * Create a new list of kmod modules using an alias or module name and lookup
501 * libkmod's configuration files and indexes in order to find the module.
502 * Once it's found in one of the places, it stops searching and create the
503 * list of modules that is saved in @list.
504 *
505 * The search order is: 1. aliases in configuration file; 2. module names in
506 * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
507 * in modules.alias index.
508 *
509 * The initial refcount is 1, and needs to be decremented to release the
510 * resources of the kmod_module. The returned @list must be released by
511 * calling kmod_module_unref_list(). Since libkmod keeps track of all
512 * kmod_modules created, they are all released upon @ctx destruction too. Do
513 * not unref @ctx before all the desired operations with the returned list are
514 * completed.
515 *
516 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
517 * methods failed, which is basically due to memory allocation fail. If module
518 * is not found, it still returns 0, but @list is an empty list.
519 */
7f3eb0cc 520KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
d917f274 521 const char *given_alias,
7f3eb0cc
LDM
522 struct kmod_list **list)
523{
7f3eb0cc 524 int err;
6daceb2f 525 char alias[PATH_MAX];
7f3eb0cc 526
4308b176 527 if (ctx == NULL || given_alias == NULL)
7f3eb0cc
LDM
528 return -ENOENT;
529
7f3eb0cc
LDM
530 if (list == NULL || *list != NULL) {
531 ERR(ctx, "An empty list is needed to create lookup\n");
532 return -ENOSYS;
533 }
534
b55df2ee
GSB
535 if (alias_normalize(given_alias, alias, NULL) < 0) {
536 DBG(ctx, "invalid alias: %s\n", given_alias);
d470db10 537 return -EINVAL;
b55df2ee
GSB
538 }
539
540 DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
d917f274 541
b14dcfda 542 /* Aliases from config file override all the others */
7f3eb0cc 543 err = kmod_lookup_alias_from_config(ctx, alias, list);
b14dcfda 544 CHECK_ERR_AND_FINISH(err, fail, list, finish);
7f3eb0cc 545
b55df2ee 546 DBG(ctx, "lookup modules.dep %s\n", alias);
64700e47
LDM
547 err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
548 CHECK_ERR_AND_FINISH(err, fail, list, finish);
549
b55df2ee 550 DBG(ctx, "lookup modules.symbols %s\n", alias);
9ba6f57b
LDM
551 err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
552 CHECK_ERR_AND_FINISH(err, fail, list, finish);
b14dcfda 553
b55df2ee 554 DBG(ctx, "lookup install and remove commands %s\n", alias);
f4fc5523
LDM
555 err = kmod_lookup_alias_from_commands(ctx, alias, list);
556 CHECK_ERR_AND_FINISH(err, fail, list, finish);
7afc98a1 557
b55df2ee 558 DBG(ctx, "lookup modules.aliases %s\n", alias);
49e61ca3
LDM
559 err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
560 CHECK_ERR_AND_FINISH(err, fail, list, finish);
561
3805274b
LDM
562 DBG(ctx, "lookup modules.builtin %s\n", alias);
563 err = kmod_lookup_alias_from_builtin_file(ctx, alias, list);
564 CHECK_ERR_AND_FINISH(err, fail, list, finish);
565
b14dcfda 566finish:
b55df2ee 567 DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
7f3eb0cc 568 return err;
b14dcfda 569fail:
b55df2ee 570 DBG(ctx, "Failed to lookup %s\n", alias);
b14dcfda
LDM
571 kmod_module_unref_list(*list);
572 *list = NULL;
84f42204 573 return err;
7f3eb0cc 574}
b14dcfda
LDM
575#undef CHECK_ERR_AND_FINISH
576
7afc98a1 577/**
91428ae1 578 * kmod_module_unref_list:
7afc98a1
LDM
579 * @list: list of kmod modules
580 *
581 * Drop a reference of each kmod module in @list and releases the resources
582 * taken by the list itself.
583 *
491c4902 584 * Returns: 0
7afc98a1 585 */
7f3eb0cc
LDM
586KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
587{
588 for (; list != NULL; list = kmod_list_remove(list))
589 kmod_module_unref(list->data);
590
591 return 0;
592}
593
0d46743c
LDM
594/**
595 * kmod_module_get_filtered_blacklist:
596 * @ctx: kmod library context
597 * @input: list of kmod_module to be filtered with blacklist
598 * @output: where to save the new list
599 *
471a7d00 600 * This function should not be used. Use kmod_module_apply_filter instead.
d80b103c 601 *
0d46743c 602 * Given a list @input, this function filter it out with config's blacklist
d80b103c 603 * and save it in @output.
0d46743c
LDM
604 *
605 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
606 * list.
607 */
608KMOD_EXPORT int kmod_module_get_filtered_blacklist(const struct kmod_ctx *ctx,
609 const struct kmod_list *input,
610 struct kmod_list **output)
611{
d80b103c 612 return kmod_module_apply_filter(ctx, KMOD_FILTER_BLACKLIST, input, output);
0d46743c
LDM
613}
614
b72f74b5
LDM
615static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
616{
617 if (!mod->init.dep) {
618 /* lazy init */
619 char *line = kmod_search_moddep(mod->ctx, mod->name);
620
621 if (line == NULL)
622 return NULL;
623
624 kmod_module_parse_depline((struct kmod_module *)mod, line);
625 free(line);
626
627 if (!mod->init.dep)
628 return NULL;
629 }
630
631 return mod->dep;
632}
633
7afc98a1 634/**
91428ae1 635 * kmod_module_get_dependencies:
7afc98a1
LDM
636 * @mod: kmod module
637 *
638 * Search the modules.dep index to find the dependencies of the given @mod.
639 * The result is cached in @mod, so subsequent calls to this function will
640 * return the already searched list of modules.
641 *
491c4902
CY
642 * Returns: NULL on failure. Otherwise it returns a list of kmod modules
643 * that can be released by calling kmod_module_unref_list().
7afc98a1 644 */
f1cd799f 645KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
0835fc3b 646{
f1cd799f
LDM
647 struct kmod_list *l, *l_new, *list_new = NULL;
648
649 if (mod == NULL)
650 return NULL;
651
b72f74b5 652 module_get_dependencies_noref(mod);
f1cd799f
LDM
653
654 kmod_list_foreach(l, mod->dep) {
655 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
656 if (l_new == NULL) {
657 kmod_module_unref(l->data);
658 goto fail;
659 }
660
661 list_new = l_new;
662 }
663
664 return list_new;
665
666fail:
667 ERR(mod->ctx, "out of memory\n");
668 kmod_module_unref_list(list_new);
669 return NULL;
0835fc3b
LDM
670}
671
7afc98a1
LDM
672/**
673 * kmod_module_get_module:
674 * @entry: an entry in a list of kmod modules.
675 *
676 * Get the kmod module of this @entry in the list, increasing its refcount.
677 * After it's used, unref it. Since the refcount is incremented upon return,
678 * you still have to call kmod_module_unref_list() to release the list of kmod
679 * modules.
680 *
681 * Returns: NULL on failure or the kmod_module contained in this list entry
682 * with its refcount incremented.
683 */
ad4d1ae5 684KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
6e869df7 685{
ad4d1ae5
GSB
686 if (entry == NULL)
687 return NULL;
28c175ed 688
ad4d1ae5 689 return kmod_module_ref(entry->data);
6e869df7
LDM
690}
691
7afc98a1
LDM
692/**
693 * kmod_module_get_name:
694 * @mod: kmod module
695 *
696 * Get the name of this kmod module. Name is always available, independently
697 * if it was created by kmod_module_new_from_name() or another function and
698 * it's always normalized (dashes are replaced with underscores).
699 *
700 * Returns: the name of this kmod module.
701 */
1ce08a56 702KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
6e869df7 703{
818f8e8a
LDM
704 if (mod == NULL)
705 return NULL;
706
6e869df7
LDM
707 return mod->name;
708}
709
7afc98a1
LDM
710/**
711 * kmod_module_get_path:
712 * @mod: kmod module
713 *
714 * Get the path of this kmod module. If this kmod module was not created by
715 * path, it can search the modules.dep index in order to find out the module
db74ceec 716 * under context's dirname.
7afc98a1
LDM
717 *
718 * Returns: the path of this kmod module or NULL if such information is not
719 * available.
720 */
1ce08a56 721KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
6e869df7 722{
e005facd 723 char *line;
c5e7b1f7 724
818f8e8a
LDM
725 if (mod == NULL)
726 return NULL;
727
d01c67e3 728 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
c5e7b1f7 729
e005facd
LDM
730 if (mod->path != NULL)
731 return mod->path;
732 if (mod->init.dep)
733 return NULL;
c5e7b1f7 734
e005facd
LDM
735 /* lazy init */
736 line = kmod_search_moddep(mod->ctx, mod->name);
737 if (line == NULL)
738 return NULL;
739
740 kmod_module_parse_depline((struct kmod_module *) mod, line);
741 free(line);
c5e7b1f7 742
6e869df7
LDM
743 return mod->path;
744}
745
746
8f788d58
LDM
747extern long delete_module(const char *name, unsigned int flags);
748
7afc98a1
LDM
749/**
750 * kmod_module_remove_module:
751 * @mod: kmod module
7ab88044 752 * @flags: flags to pass to Linux kernel when removing the module. The only valid flag is
d7152f62
CY
753 * KMOD_REMOVE_FORCE: force remove module regardless if it's still in
754 * use by a kernel subsystem or other process;
7ab88044
LDM
755 * KMOD_REMOVE_NOWAIT is always enforced, causing us to pass O_NONBLOCK to
756 * delete_module(2).
7afc98a1
LDM
757 *
758 * Remove a module from Linux kernel.
759 *
760 * Returns: 0 on success or < 0 on failure.
761 */
8f788d58
LDM
762KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
763 unsigned int flags)
764{
765 int err;
8f788d58
LDM
766
767 if (mod == NULL)
768 return -ENOENT;
769
7ab88044
LDM
770 /* Filter out other flags and force ONONBLOCK */
771 flags &= KMOD_REMOVE_FORCE;
772 flags |= KMOD_REMOVE_NOWAIT;
8f788d58 773
d753b8ca 774 err = delete_module(mod->name, flags);
8f788d58 775 if (err != 0) {
ba998b9c
LDM
776 err = -errno;
777 ERR(mod->ctx, "could not remove '%s': %m\n", mod->name);
8f788d58
LDM
778 }
779
ba998b9c 780 return err;
8f788d58
LDM
781}
782
708624a4 783extern long init_module(const void *mem, unsigned long len, const char *args);
8f788d58 784
7afc98a1
LDM
785/**
786 * kmod_module_insert_module:
787 * @mod: kmod module
142db570 788 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
d7152f62
CY
789 * behavior of this function, valid flags are
790 * KMOD_INSERT_FORCE_VERMAGIC: ignore kernel version magic;
791 * KMOD_INSERT_FORCE_MODVERSION: ignore symbol version hashes.
7afc98a1
LDM
792 * @options: module's options to pass to Linux Kernel.
793 *
794 * Insert a module in Linux kernel. It opens the file pointed by @mod,
795 * mmap'ing it and passing to kernel.
796 *
bbf59327
LDM
797 * Returns: 0 on success or < 0 on failure. If module is already loaded it
798 * returns -EEXIST.
7afc98a1 799 */
8f788d58 800KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
3a721bbc
GSB
801 unsigned int flags,
802 const char *options)
8f788d58
LDM
803{
804 int err;
708624a4 805 const void *mem;
3d8226ed 806 off_t size;
c2f4d85a 807 struct kmod_elf *elf;
708624a4 808 const char *path;
3a721bbc 809 const char *args = options ? options : "";
8f788d58
LDM
810
811 if (mod == NULL)
812 return -ENOENT;
813
708624a4
GSB
814 path = kmod_module_get_path(mod);
815 if (path == NULL) {
b787b569 816 ERR(mod->ctx, "could not find module by name='%s'\n", mod->name);
8f788d58
LDM
817 return -ENOSYS;
818 }
819
c2f4d85a
MM
820 mod->file = kmod_file_open(mod->ctx, path);
821 if (mod->file == NULL) {
8f788d58
LDM
822 err = -errno;
823 return err;
824 }
825
c2f4d85a 826 if (kmod_file_get_direct(mod->file)) {
144d1826
KC
827 unsigned int kernel_flags = 0;
828
144d1826
KC
829 if (flags & KMOD_INSERT_FORCE_VERMAGIC)
830 kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
831 if (flags & KMOD_INSERT_FORCE_MODVERSION)
832 kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;
144d1826 833
c2f4d85a 834 err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
144d1826
KC
835 if (err == 0 || errno != ENOSYS)
836 goto init_finished;
837 }
838
708624a4 839 if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
c2f4d85a 840 elf = kmod_file_get_elf(mod->file);
708624a4
GSB
841 if (elf == NULL) {
842 err = -errno;
c2f4d85a 843 return err;
708624a4
GSB
844 }
845
846 if (flags & KMOD_INSERT_FORCE_MODVERSION) {
847 err = kmod_elf_strip_section(elf, "__versions");
848 if (err < 0)
849 INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
850 }
851
852 if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
853 err = kmod_elf_strip_vermagic(elf);
854 if (err < 0)
855 INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
856 }
857
858 mem = kmod_elf_get_memory(elf);
c2f4d85a
MM
859 } else {
860 mem = kmod_file_get_contents(mod->file);
708624a4 861 }
c2f4d85a 862 size = kmod_file_get_size(mod->file);
708624a4 863
3d8226ed 864 err = init_module(mem, size, args);
144d1826 865init_finished:
bbf59327
LDM
866 if (err < 0) {
867 err = -errno;
868 INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
869 }
8f788d58
LDM
870 return err;
871}
f12ae3c4 872
ddbda022
LDM
873static bool module_is_blacklisted(struct kmod_module *mod)
874{
875 struct kmod_ctx *ctx = mod->ctx;
e7fc2c86
LDM
876 const struct kmod_config *config = kmod_get_config(ctx);
877 const struct kmod_list *bl = config->blacklists;
ddbda022
LDM
878 const struct kmod_list *l;
879
880 kmod_list_foreach(l, bl) {
881 const char *modname = kmod_blacklist_get_modname(l);
882
883 if (streq(modname, mod->name))
884 return true;
885 }
886
887 return false;
888}
889
d80b103c
DR
890/**
891 * kmod_module_apply_filter
892 * @ctx: kmod library context
d7152f62
CY
893 * @filter_type: bitmask to filter modules out, valid types are
894 * KMOD_FILTER_BLACKLIST: filter modules in blacklist out;
895 * KMOD_FILTER_BUILTIN: filter builtin modules out.
d80b103c
DR
896 * @input: list of kmod_module to be filtered
897 * @output: where to save the new list
898 *
899 * Given a list @input, this function filter it out by the filter mask
900 * and save it in @output.
901 *
902 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
903 * list.
904 */
905KMOD_EXPORT int kmod_module_apply_filter(const struct kmod_ctx *ctx,
906 enum kmod_filter filter_type,
907 const struct kmod_list *input,
908 struct kmod_list **output)
909{
910 const struct kmod_list *li;
911
912 if (ctx == NULL || output == NULL)
913 return -ENOENT;
914
915 *output = NULL;
916 if (input == NULL)
917 return 0;
918
919 kmod_list_foreach(li, input) {
920 struct kmod_module *mod = li->data;
921 struct kmod_list *node;
922
923 if ((filter_type & KMOD_FILTER_BLACKLIST) &&
924 module_is_blacklisted(mod))
925 continue;
926
bdda7e14 927 if ((filter_type & KMOD_FILTER_BUILTIN) && mod->builtin)
d80b103c
DR
928 continue;
929
930 node = kmod_list_append(*output, mod);
931 if (node == NULL)
932 goto fail;
933
934 *output = node;
935 kmod_module_ref(mod);
936 }
937
938 return 0;
939
940fail:
941 kmod_module_unref_list(*output);
942 *output = NULL;
943 return -ENOMEM;
944}
945
ddbda022
LDM
946static int command_do(struct kmod_module *mod, const char *type,
947 const char *cmd)
948{
949 const char *modname = kmod_module_get_name(mod);
950 int err;
951
952 DBG(mod->ctx, "%s %s\n", type, cmd);
953
954 setenv("MODPROBE_MODULE", modname, 1);
955 err = system(cmd);
956 unsetenv("MODPROBE_MODULE");
957
958 if (err == -1 || WEXITSTATUS(err)) {
959 ERR(mod->ctx, "Error running %s command for %s\n",
960 type, modname);
961 if (err != -1)
962 err = -WEXITSTATUS(err);
963 }
964
965 return err;
966}
967
b1a51256
LDM
968struct probe_insert_cb {
969 int (*run_install)(struct kmod_module *m, const char *cmd, void *data);
970 void *data;
971};
972
ddbda022
LDM
973static int module_do_install_commands(struct kmod_module *mod,
974 const char *options,
975 struct probe_insert_cb *cb)
976{
977 const char *command = kmod_module_get_install_commands(mod);
9f02561d
LDM
978 char *p;
979 _cleanup_free_ char *cmd;
ddbda022
LDM
980 int err;
981 size_t cmdlen, options_len, varlen;
982
983 assert(command);
984
985 if (options == NULL)
986 options = "";
987
988 options_len = strlen(options);
989 cmdlen = strlen(command);
990 varlen = sizeof("$CMDLINE_OPTS") - 1;
991
992 cmd = memdup(command, cmdlen + 1);
993 if (cmd == NULL)
994 return -ENOMEM;
995
996 while ((p = strstr(cmd, "$CMDLINE_OPTS")) != NULL) {
997 size_t prefixlen = p - cmd;
998 size_t suffixlen = cmdlen - prefixlen - varlen;
999 size_t slen = cmdlen - varlen + options_len;
1000 char *suffix = p + varlen;
1001 char *s = malloc(slen + 1);
9f02561d 1002 if (!s)
ddbda022 1003 return -ENOMEM;
9f02561d 1004
ddbda022
LDM
1005 memcpy(s, cmd, p - cmd);
1006 memcpy(s + prefixlen, options, options_len);
1007 memcpy(s + prefixlen + options_len, suffix, suffixlen);
1008 s[slen] = '\0';
1009
1010 free(cmd);
1011 cmd = s;
1012 cmdlen = slen;
1013 }
1014
1015 if (cb->run_install != NULL)
1016 err = cb->run_install(mod, cmd, cb->data);
1017 else
1018 err = command_do(mod, "install", cmd);
1019
ddbda022
LDM
1020 return err;
1021}
1022
ddbda022
LDM
1023static char *module_options_concat(const char *opt, const char *xopt)
1024{
1025 // TODO: we might need to check if xopt overrides options on opt
1026 size_t optlen = opt == NULL ? 0 : strlen(opt);
1027 size_t xoptlen = xopt == NULL ? 0 : strlen(xopt);
1028 char *r;
1029
1030 if (optlen == 0 && xoptlen == 0)
1031 return NULL;
1032
1033 r = malloc(optlen + xoptlen + 2);
1034
1035 if (opt != NULL) {
1036 memcpy(r, opt, optlen);
1037 r[optlen] = ' ';
1038 optlen++;
1039 }
1040
1041 if (xopt != NULL)
1042 memcpy(r + optlen, xopt, xoptlen);
1043
1044 r[optlen + xoptlen] = '\0';
1045
1046 return r;
1047}
1048
b1a51256 1049static int __kmod_module_get_probe_list(struct kmod_module *mod,
450bd1b4 1050 bool required,
89e92487 1051 bool ignorecmd,
b1a51256
LDM
1052 struct kmod_list **list);
1053
1054/* re-entrant */
1055static int __kmod_module_fill_softdep(struct kmod_module *mod,
1056 struct kmod_list **list)
ddbda022 1057{
b1a51256 1058 struct kmod_list *pre = NULL, *post = NULL, *l;
ddbda022 1059 int err;
ddbda022 1060
b1a51256
LDM
1061 err = kmod_module_get_softdeps(mod, &pre, &post);
1062 if (err < 0) {
050db08c
LDM
1063 ERR(mod->ctx, "could not get softdep: %s\n",
1064 strerror(-err));
b1a51256 1065 goto fail;
ddbda022
LDM
1066 }
1067
b1a51256
LDM
1068 kmod_list_foreach(l, pre) {
1069 struct kmod_module *m = l->data;
450bd1b4 1070 err = __kmod_module_get_probe_list(m, false, false, list);
b1a51256
LDM
1071 if (err < 0)
1072 goto fail;
1073 }
ddbda022 1074
b1a51256
LDM
1075 l = kmod_list_append(*list, kmod_module_ref(mod));
1076 if (l == NULL) {
1077 kmod_module_unref(mod);
1078 err = -ENOMEM;
1079 goto fail;
ddbda022 1080 }
b1a51256 1081 *list = l;
89e92487 1082 mod->ignorecmd = (pre != NULL || post != NULL);
ddbda022 1083
b1a51256
LDM
1084 kmod_list_foreach(l, post) {
1085 struct kmod_module *m = l->data;
450bd1b4 1086 err = __kmod_module_get_probe_list(m, false, false, list);
b1a51256
LDM
1087 if (err < 0)
1088 goto fail;
1089 }
ddbda022 1090
b1a51256
LDM
1091fail:
1092 kmod_module_unref_list(pre);
1093 kmod_module_unref_list(post);
ddbda022 1094
b1a51256
LDM
1095 return err;
1096}
ddbda022 1097
b1a51256
LDM
1098/* re-entrant */
1099static int __kmod_module_get_probe_list(struct kmod_module *mod,
450bd1b4 1100 bool required,
89e92487 1101 bool ignorecmd,
b1a51256
LDM
1102 struct kmod_list **list)
1103{
1104 struct kmod_list *dep, *l;
1105 int err = 0;
ddbda022 1106
b1a51256
LDM
1107 if (mod->visited) {
1108 DBG(mod->ctx, "Ignore module '%s': already visited\n",
1109 mod->name);
1110 return 0;
1111 }
8cd0f9e4 1112 mod->visited = true;
ddbda022 1113
b1a51256 1114 dep = kmod_module_get_dependencies(mod);
450bd1b4
MM
1115 if (required) {
1116 /*
1117 * Called from kmod_module_probe_insert_module(); set the
1118 * ->required flag on mod and all its dependencies before
1119 * they are possibly visited through some softdeps.
1120 */
1121 mod->required = true;
1122 kmod_list_foreach(l, dep) {
1123 struct kmod_module *m = l->data;
1124 m->required = true;
1125 }
1126 }
1127
b1a51256
LDM
1128 kmod_list_foreach(l, dep) {
1129 struct kmod_module *m = l->data;
1130 err = __kmod_module_fill_softdep(m, list);
1131 if (err < 0)
89e92487 1132 goto finish;
b1a51256 1133 }
ddbda022 1134
89e92487
LDM
1135 if (ignorecmd) {
1136 l = kmod_list_append(*list, kmod_module_ref(mod));
1137 if (l == NULL) {
1138 kmod_module_unref(mod);
1139 err = -ENOMEM;
1140 goto finish;
1141 }
1142 *list = l;
1143 mod->ignorecmd = true;
1144 } else
1145 err = __kmod_module_fill_softdep(mod, list);
1146
ddbda022 1147finish:
b1a51256
LDM
1148 kmod_module_unref_list(dep);
1149 return err;
1150}
1151
1152static int kmod_module_get_probe_list(struct kmod_module *mod,
89e92487 1153 bool ignorecmd,
b1a51256
LDM
1154 struct kmod_list **list)
1155{
1156 int err;
1157
1158 assert(mod != NULL);
1159 assert(list != NULL && *list == NULL);
1160
1161 /*
1162 * Make sure we don't get screwed by previous calls to this function
1163 */
1164 kmod_set_modules_visited(mod->ctx, false);
450bd1b4 1165 kmod_set_modules_required(mod->ctx, false);
b1a51256 1166
450bd1b4 1167 err = __kmod_module_get_probe_list(mod, true, ignorecmd, list);
b1a51256
LDM
1168 if (err < 0) {
1169 kmod_module_unref_list(*list);
1170 *list = NULL;
1171 }
ddbda022
LDM
1172
1173 return err;
1174}
1175
1176/**
1177 * kmod_module_probe_insert_module:
1178 * @mod: kmod module
1179 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
d7152f62
CY
1180 * behavior of this function, valid flags are
1181 * KMOD_PROBE_FORCE_VERMAGIC: ignore kernel version magic;
1182 * KMOD_PROBE_FORCE_MODVERSION: ignore symbol version hashes;
1183 * KMOD_PROBE_IGNORE_COMMAND: whether the probe should ignore install
1184 * commands and softdeps configured in the system;
1185 * KMOD_PROBE_IGNORE_LOADED: do not check whether the module is already
1186 * live in kernel or not;
1187 * KMOD_PROBE_DRY_RUN: dry run, do not insert module, just call the
1188 * associated callback function;
1189 * KMOD_PROBE_FAIL_ON_LOADED: if KMOD_PROBE_IGNORE_LOADED is not specified
1190 * and the module is already live in kernel, the function will fail if this
1191 * flag is specified;
1192 * KMOD_PROBE_APPLY_BLACKLIST_ALL: probe will apply KMOD_FILTER_BLACKLIST
1193 * filter to this module and its dependencies. If any of the dependencies (or
1194 * the module) is blacklisted, the probe will fail, unless the blacklisted
1195 * module is already live in kernel;
1196 * KMOD_PROBE_APPLY_BLACKLIST: probe will fail if the module is blacklisted;
1197 * KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY: probe will fail if the module is an
1198 * alias and is blacklisted.
b1a51256
LDM
1199 * @extra_options: module's options to pass to Linux Kernel. It applies only
1200 * to @mod, not to its dependencies.
1201 * @run_install: function to run when @mod is backed by an install command.
ddbda022 1202 * @data: data to give back to @run_install callback
6bd0713d
LDM
1203 * @print_action: function to call with the action being taken (install or
1204 * insmod). It's useful for tools like modprobe when running with verbose
1205 * output or in dry-run mode.
ddbda022 1206 *
b1a51256 1207 * Insert a module in Linux kernel resolving dependencies, soft dependencies,
ddbda022
LDM
1208 * install commands and applying blacklist.
1209 *
7aed4608
LDM
1210 * If @run_install is NULL, this function will fork and exec by calling
1211 * system(3). Don't pass a NULL argument in @run_install if your binary is
1212 * setuid/setgid (see warning in system(3)). If you need control over the
1213 * execution of an install command, give a callback function instead.
ddbda022 1214 *
b1a51256
LDM
1215 * Returns: 0 on success, > 0 if stopped by a reason given in @flags or < 0 on
1216 * failure.
ddbda022
LDM
1217 */
1218KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
1219 unsigned int flags, const char *extra_options,
1220 int (*run_install)(struct kmod_module *m,
1221 const char *cmd, void *data),
6bd0713d
LDM
1222 const void *data,
1223 void (*print_action)(struct kmod_module *m,
1224 bool install,
1225 const char *options))
ddbda022 1226{
b1a51256 1227 struct kmod_list *list = NULL, *l;
ddbda022 1228 struct probe_insert_cb cb;
b1a51256
LDM
1229 int err;
1230
1231 if (mod == NULL)
1232 return -ENOENT;
1233
269de2e0
LDM
1234 if (!(flags & KMOD_PROBE_IGNORE_LOADED)
1235 && module_is_inkernel(mod)) {
814a57ba 1236 if (flags & KMOD_PROBE_FAIL_ON_LOADED)
af9572c6
DR
1237 return -EEXIST;
1238 else
1239 return 0;
1240 }
1241
6882017f
LDM
1242 /*
1243 * Ugly assignement + check. We need to check if we were told to check
1244 * blacklist and also return the reason why we failed.
1245 * KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY will take effect only if the
1246 * module is an alias, so we also need to check it
1247 */
1248 if ((mod->alias != NULL && ((err = flags & KMOD_PROBE_APPLY_BLACKLIST_ALIAS_ONLY)))
1249 || (err = flags & KMOD_PROBE_APPLY_BLACKLIST_ALL)
1250 || (err = flags & KMOD_PROBE_APPLY_BLACKLIST)) {
b1a51256
LDM
1251 if (module_is_blacklisted(mod))
1252 return err;
1253 }
1254
89e92487
LDM
1255 err = kmod_module_get_probe_list(mod,
1256 !!(flags & KMOD_PROBE_IGNORE_COMMAND), &list);
b1a51256
LDM
1257 if (err < 0)
1258 return err;
1259
1260 if (flags & KMOD_PROBE_APPLY_BLACKLIST_ALL) {
1261 struct kmod_list *filtered = NULL;
1262
d80b103c
DR
1263 err = kmod_module_apply_filter(mod->ctx,
1264 KMOD_FILTER_BLACKLIST, list, &filtered);
b1a51256
LDM
1265 if (err < 0)
1266 return err;
1267
1268 kmod_module_unref_list(list);
1269 if (filtered == NULL)
1270 return KMOD_PROBE_APPLY_BLACKLIST_ALL;
1271
1272 list = filtered;
1273 }
ddbda022
LDM
1274
1275 cb.run_install = run_install;
1276 cb.data = (void *) data;
1277
b1a51256
LDM
1278 kmod_list_foreach(l, list) {
1279 struct kmod_module *m = l->data;
1280 const char *moptions = kmod_module_get_options(m);
1281 const char *cmd = kmod_module_get_install_commands(m);
abd5557b
LDM
1282 char *options;
1283
1284 if (!(flags & KMOD_PROBE_IGNORE_LOADED)
1285 && module_is_inkernel(m)) {
1286 DBG(mod->ctx, "Ignoring module '%s': already loaded\n",
1287 m->name);
1288 err = -EEXIST;
1289 goto finish_module;
1290 }
1291
1292 options = module_options_concat(moptions,
b1a51256
LDM
1293 m == mod ? extra_options : NULL);
1294
89e92487 1295 if (cmd != NULL && !m->ignorecmd) {
6bd0713d
LDM
1296 if (print_action != NULL)
1297 print_action(m, true, options ?: "");
1298
4c1ffb75
LDM
1299 if (!(flags & KMOD_PROBE_DRY_RUN))
1300 err = module_do_install_commands(m, options,
1301 &cb);
b1a51256 1302 } else {
6bd0713d
LDM
1303 if (print_action != NULL)
1304 print_action(m, false, options ?: "");
1305
4c1ffb75
LDM
1306 if (!(flags & KMOD_PROBE_DRY_RUN))
1307 err = kmod_module_insert_module(m, flags,
1308 options);
b1a51256
LDM
1309 }
1310
1311 free(options);
1312
abd5557b 1313finish_module:
b1a51256 1314 /*
5f351473 1315 * Treat "already loaded" error. If we were told to stop on
3bc92e89
LDM
1316 * already loaded and the module being loaded is not a softdep
1317 * or dep, bail out. Otherwise, just ignore and continue.
5f351473
LDM
1318 *
1319 * We need to check here because of race conditions. We
1320 * checked first if module was already loaded but it may have
1321 * been loaded between the check and the moment we try to
1322 * insert it.
b1a51256 1323 */
5f351473 1324 if (err == -EEXIST && m == mod &&
814a57ba 1325 (flags & KMOD_PROBE_FAIL_ON_LOADED))
5f351473 1326 break;
5f351473 1327
450bd1b4
MM
1328 /*
1329 * Ignore errors from softdeps
1330 */
1331 if (err == -EEXIST || !m->required)
3bc92e89 1332 err = 0;
450bd1b4 1333
3bc92e89 1334 else if (err < 0)
b1a51256
LDM
1335 break;
1336 }
ddbda022 1337
b1a51256
LDM
1338 kmod_module_unref_list(list);
1339 return err;
1340}
ddbda022 1341
7afc98a1
LDM
1342/**
1343 * kmod_module_get_options:
1344 * @mod: kmod module
1345 *
1346 * Get options of this kmod module. Options come from the configuration file
1347 * and are cached in @mod. The first call to this function will search for
1348 * this module in configuration and subsequent calls return the cached string.
1349 *
1350 * Returns: a string with all the options separated by spaces. This string is
1351 * owned by @mod, do not free it.
1352 */
49ce6d07
LDM
1353KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
1354{
1355 if (mod == NULL)
1356 return NULL;
1357
1358 if (!mod->init.options) {
1359 /* lazy init */
1360 struct kmod_module *m = (struct kmod_module *)mod;
e7fc2c86
LDM
1361 const struct kmod_list *l;
1362 const struct kmod_config *config;
49ce6d07
LDM
1363 char *opts = NULL;
1364 size_t optslen = 0;
1365
e7fc2c86 1366 config = kmod_get_config(mod->ctx);
49ce6d07 1367
e7fc2c86 1368 kmod_list_foreach(l, config->options) {
49ce6d07
LDM
1369 const char *modname = kmod_option_get_modname(l);
1370 const char *str;
1371 size_t len;
1372 void *tmp;
1373
07b8c823
LDM
1374 DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
1375 if (!(streq(modname, mod->name) || (mod->alias != NULL &&
1376 streq(modname, mod->alias))))
49ce6d07
LDM
1377 continue;
1378
07b8c823 1379 DBG(mod->ctx, "passed = modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
49ce6d07
LDM
1380 str = kmod_option_get_options(l);
1381 len = strlen(str);
1382 if (len < 1)
1383 continue;
1384
1385 tmp = realloc(opts, optslen + len + 2);
1386 if (tmp == NULL) {
1387 free(opts);
1388 goto failed;
1389 }
1390
1391 opts = tmp;
1392
1393 if (optslen > 0) {
1394 opts[optslen] = ' ';
1395 optslen++;
1396 }
1397
1398 memcpy(opts + optslen, str, len);
1399 optslen += len;
1400 opts[optslen] = '\0';
1401 }
1402
1403 m->init.options = true;
1404 m->options = opts;
1405 }
1406
1407 return mod->options;
1408
1409failed:
1410 ERR(mod->ctx, "out of memory\n");
1411 return NULL;
1412}
1413
7afc98a1
LDM
1414/**
1415 * kmod_module_get_install_commands:
1416 * @mod: kmod module
1417 *
1418 * Get install commands for this kmod module. Install commands come from the
1419 * configuration file and are cached in @mod. The first call to this function
1420 * will search for this module in configuration and subsequent calls return
1421 * the cached string. The install commands are returned as they were in the
1422 * configuration, concatenated by ';'. No other processing is made in this
1423 * string.
1424 *
1425 * Returns: a string with all install commands separated by semicolons. This
1426 * string is owned by @mod, do not free it.
1427 */
49ce6d07
LDM
1428KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
1429{
1430 if (mod == NULL)
1431 return NULL;
1432
1433 if (!mod->init.install_commands) {
1434 /* lazy init */
1435 struct kmod_module *m = (struct kmod_module *)mod;
e7fc2c86
LDM
1436 const struct kmod_list *l;
1437 const struct kmod_config *config;
49ce6d07 1438
e7fc2c86 1439 config = kmod_get_config(mod->ctx);
49ce6d07 1440
e7fc2c86 1441 kmod_list_foreach(l, config->install_commands) {
49ce6d07 1442 const char *modname = kmod_command_get_modname(l);
49ce6d07 1443
a6bf2495 1444 if (fnmatch(modname, mod->name, 0) != 0)
49ce6d07
LDM
1445 continue;
1446
60f6760e 1447 m->install_commands = kmod_command_get_command(l);
49ce6d07 1448
60f6760e
LDM
1449 /*
1450 * find only the first command, as modprobe from
1451 * module-init-tools does
1452 */
1453 break;
49ce6d07
LDM
1454 }
1455
1456 m->init.install_commands = true;
49ce6d07
LDM
1457 }
1458
1459 return mod->install_commands;
49ce6d07
LDM
1460}
1461
f4fc5523
LDM
1462void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
1463{
1464 mod->init.install_commands = true;
1465 mod->install_commands = cmd;
1466}
1467
1c522600
GSB
1468static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
1469{
1470 struct kmod_list *ret = NULL;
1471 unsigned i;
1472
1473 for (i = 0; i < count; i++) {
1474 const char *depname = array[i];
1475 struct kmod_list *lst = NULL;
1476 int err;
1477
1478 err = kmod_module_new_from_lookup(ctx, depname, &lst);
1479 if (err < 0) {
1480 ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
1481 continue;
1482 } else if (lst != NULL)
1483 ret = kmod_list_append_list(ret, lst);
1484 }
1485 return ret;
1486}
1487
1488/**
1489 * kmod_module_get_softdeps:
1490 * @mod: kmod module
1491 * @pre: where to save the list of preceding soft dependencies.
1492 * @post: where to save the list of post soft dependencies.
1493 *
1494 * Get soft dependencies for this kmod module. Soft dependencies come
2bd7cbf6
LDM
1495 * from configuration file and are not cached in @mod because it may include
1496 * dependency cycles that would make we leak kmod_module. Any call
1497 * to this function will search for this module in configuration, allocate a
1498 * list and return the result.
1c522600
GSB
1499 *
1500 * Both @pre and @post are newly created list of kmod_module and
1501 * should be unreferenced with kmod_module_unref_list().
1502 *
1503 * Returns: 0 on success or < 0 otherwise.
1504 */
2bd7cbf6
LDM
1505KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
1506 struct kmod_list **pre,
1507 struct kmod_list **post)
1c522600 1508{
e7fc2c86
LDM
1509 const struct kmod_list *l;
1510 const struct kmod_config *config;
1c522600
GSB
1511
1512 if (mod == NULL || pre == NULL || post == NULL)
1513 return -ENOENT;
1514
1515 assert(*pre == NULL);
1516 assert(*post == NULL);
1517
e7fc2c86 1518 config = kmod_get_config(mod->ctx);
1c522600 1519
e7fc2c86 1520 kmod_list_foreach(l, config->softdeps) {
2bd7cbf6
LDM
1521 const char *modname = kmod_softdep_get_name(l);
1522 const char * const *array;
1523 unsigned count;
1c522600 1524
2bd7cbf6
LDM
1525 if (fnmatch(modname, mod->name, 0) != 0)
1526 continue;
1c522600 1527
2bd7cbf6
LDM
1528 array = kmod_softdep_get_pre(l, &count);
1529 *pre = lookup_softdep(mod->ctx, array, count);
1530 array = kmod_softdep_get_post(l, &count);
1531 *post = lookup_softdep(mod->ctx, array, count);
1c522600 1532
2bd7cbf6
LDM
1533 /*
1534 * find only the first command, as modprobe from
1535 * module-init-tools does
1536 */
1537 break;
1c522600
GSB
1538 }
1539
1540 return 0;
1c522600
GSB
1541}
1542
7afc98a1
LDM
1543/**
1544 * kmod_module_get_remove_commands:
1545 * @mod: kmod module
1546 *
1547 * Get remove commands for this kmod module. Remove commands come from the
1548 * configuration file and are cached in @mod. The first call to this function
1549 * will search for this module in configuration and subsequent calls return
1550 * the cached string. The remove commands are returned as they were in the
1551 * configuration, concatenated by ';'. No other processing is made in this
1552 * string.
1553 *
1554 * Returns: a string with all remove commands separated by semicolons. This
1555 * string is owned by @mod, do not free it.
1556 */
49ce6d07
LDM
1557KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
1558{
1559 if (mod == NULL)
1560 return NULL;
1561
1562 if (!mod->init.remove_commands) {
1563 /* lazy init */
1564 struct kmod_module *m = (struct kmod_module *)mod;
e7fc2c86
LDM
1565 const struct kmod_list *l;
1566 const struct kmod_config *config;
49ce6d07 1567
e7fc2c86 1568 config = kmod_get_config(mod->ctx);
49ce6d07 1569
e7fc2c86 1570 kmod_list_foreach(l, config->remove_commands) {
49ce6d07 1571 const char *modname = kmod_command_get_modname(l);
49ce6d07 1572
a6bf2495 1573 if (fnmatch(modname, mod->name, 0) != 0)
49ce6d07
LDM
1574 continue;
1575
60f6760e 1576 m->remove_commands = kmod_command_get_command(l);
49ce6d07 1577
60f6760e
LDM
1578 /*
1579 * find only the first command, as modprobe from
1580 * module-init-tools does
1581 */
1582 break;
49ce6d07
LDM
1583 }
1584
1585 m->init.remove_commands = true;
49ce6d07
LDM
1586 }
1587
1588 return mod->remove_commands;
49ce6d07
LDM
1589}
1590
f4fc5523
LDM
1591void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
1592{
1593 mod->init.remove_commands = true;
1594 mod->remove_commands = cmd;
1595}
1596
49ce6d07
LDM
1597/**
1598 * SECTION:libkmod-loaded
1599 * @short_description: currently loaded modules
1600 *
1601 * Information about currently loaded modules, as reported by Linux kernel.
1602 * These information are not cached by libkmod and are always read from /sys
1603 * and /proc/modules.
1604 */
1605
1606/**
1607 * kmod_module_new_from_loaded:
1608 * @ctx: kmod library context
1609 * @list: where to save the list of loaded modules
1610 *
7afc98a1
LDM
1611 * Create a new list of kmod modules with all modules currently loaded in
1612 * kernel. It uses /proc/modules to get the names of loaded modules and to
1613 * create kmod modules by calling kmod_module_new_from_name() in each of them.
491c4902 1614 * They are put in @list in no particular order.
49ce6d07 1615 *
7afc98a1
LDM
1616 * The initial refcount is 1, and needs to be decremented to release the
1617 * resources of the kmod_module. The returned @list must be released by
1618 * calling kmod_module_unref_list(). Since libkmod keeps track of all
1619 * kmod_modules created, they are all released upon @ctx destruction too. Do
1620 * not unref @ctx before all the desired operations with the returned list are
1621 * completed.
49ce6d07
LDM
1622 *
1623 * Returns: 0 on success or < 0 on error.
1624 */
1625KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
1626 struct kmod_list **list)
1627{
1628 struct kmod_list *l = NULL;
1629 FILE *fp;
1630 char line[4096];
1631
1632 if (ctx == NULL || list == NULL)
1633 return -ENOENT;
1634
79e5ea91 1635 fp = fopen("/proc/modules", "re");
49ce6d07
LDM
1636 if (fp == NULL) {
1637 int err = -errno;
1638 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
1639 return err;
1640 }
1641
1642 while (fgets(line, sizeof(line), fp)) {
1643 struct kmod_module *m;
1644 struct kmod_list *node;
1645 int err;
1646 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
1647
1648 err = kmod_module_new_from_name(ctx, name, &m);
1649 if (err < 0) {
1650 ERR(ctx, "could not get module from name '%s': %s\n",
1651 name, strerror(-err));
1652 continue;
1653 }
1654
1655 node = kmod_list_append(l, m);
1656 if (node)
1657 l = node;
1658 else {
1659 ERR(ctx, "out of memory\n");
1660 kmod_module_unref(m);
1661 }
1662 }
1663
1664 fclose(fp);
1665 *list = l;
1666
1667 return 0;
1668}
1669
7afc98a1
LDM
1670/**
1671 * kmod_module_initstate_str:
1672 * @state: the state as returned by kmod_module_get_initstate()
1673 *
1674 * Translate a initstate to a string.
1675 *
1676 * Returns: the string associated to the @state. This string is statically
1677 * allocated, do not free it.
1678 */
f12ae3c4
GSB
1679KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
1680{
7bede7b6
DR
1681 switch (state) {
1682 case KMOD_MODULE_BUILTIN:
1683 return "builtin";
1684 case KMOD_MODULE_LIVE:
1685 return "live";
1686 case KMOD_MODULE_COMING:
1687 return "coming";
1688 case KMOD_MODULE_GOING:
1689 return "going";
1690 default:
1691 return NULL;
1692 }
f12ae3c4
GSB
1693}
1694
7afc98a1
LDM
1695/**
1696 * kmod_module_get_initstate:
1697 * @mod: kmod module
1698 *
1699 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
1700 * /sys filesystem.
1701 *
d7152f62
CY
1702 * Returns: < 0 on error or module state if module is found in kernel, valid states are
1703 * KMOD_MODULE_BUILTIN: module is builtin;
1704 * KMOD_MODULE_LIVE: module is live in kernel;
1705 * KMOD_MODULE_COMING: module is being loaded;
1706 * KMOD_MODULE_GOING: module is being unloaded.
7afc98a1 1707 */
f12ae3c4
GSB
1708KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
1709{
1710 char path[PATH_MAX], buf[32];
1711 int fd, err, pathlen;
1712
818f8e8a
LDM
1713 if (mod == NULL)
1714 return -ENOENT;
1715
3805274b
LDM
1716 if (mod->builtin)
1717 return KMOD_MODULE_BUILTIN;
1718
f12ae3c4
GSB
1719 pathlen = snprintf(path, sizeof(path),
1720 "/sys/module/%s/initstate", mod->name);
79e5ea91 1721 fd = open(path, O_RDONLY|O_CLOEXEC);
f12ae3c4
GSB
1722 if (fd < 0) {
1723 err = -errno;
1724
ddbda022
LDM
1725 DBG(mod->ctx, "could not open '%s': %s\n",
1726 path, strerror(-err));
1727
f12ae3c4
GSB
1728 if (pathlen > (int)sizeof("/initstate") - 1) {
1729 struct stat st;
1730 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
1731 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
1732 return KMOD_MODULE_BUILTIN;
1733 }
1734
926f67a6 1735 DBG(mod->ctx, "could not open '%s': %s\n",
f12ae3c4
GSB
1736 path, strerror(-err));
1737 return err;
1738 }
1739
1740 err = read_str_safe(fd, buf, sizeof(buf));
1741 close(fd);
1742 if (err < 0) {
1743 ERR(mod->ctx, "could not read from '%s': %s\n",
1744 path, strerror(-err));
1745 return err;
1746 }
1747
877e80cd 1748 if (streq(buf, "live\n"))
f12ae3c4 1749 return KMOD_MODULE_LIVE;
877e80cd 1750 else if (streq(buf, "coming\n"))
f12ae3c4 1751 return KMOD_MODULE_COMING;
877e80cd 1752 else if (streq(buf, "going\n"))
f12ae3c4
GSB
1753 return KMOD_MODULE_GOING;
1754
1755 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
1756 return -EINVAL;
1757}
1758
2d7bab5c
LDM
1759/**
1760 * kmod_module_get_size:
1761 * @mod: kmod module
1762 *
486f9013
DR
1763 * Get the size of this kmod module as returned by Linux kernel. If supported,
1764 * the size is read from the coresize attribute in /sys/module. For older
1765 * kernels, this falls back on /proc/modules and searches for the specified
1766 * module to get its size.
2d7bab5c
LDM
1767 *
1768 * Returns: the size of this kmod module.
1769 */
1770KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
1771{
2d7bab5c
LDM
1772 FILE *fp;
1773 char line[4096];
1774 int lineno = 0;
1775 long size = -ENOENT;
486f9013 1776 int dfd, cfd;
2d7bab5c
LDM
1777
1778 if (mod == NULL)
1779 return -ENOENT;
1780
486f9013
DR
1781 /* try to open the module dir in /sys. If this fails, don't
1782 * bother trying to find the size as we know the module isn't
1783 * loaded.
1784 */
1785 snprintf(line, sizeof(line), "/sys/module/%s", mod->name);
74c26943 1786 dfd = open(line, O_RDONLY|O_CLOEXEC);
486f9013
DR
1787 if (dfd < 0)
1788 return -errno;
1789
1790 /* available as of linux 3.3.x */
1791 cfd = openat(dfd, "coresize", O_RDONLY|O_CLOEXEC);
1792 if (cfd >= 0) {
1793 if (read_str_long(cfd, &size, 10) < 0)
1794 ERR(mod->ctx, "failed to read coresize from %s\n", line);
1795 close(cfd);
1796 goto done;
1797 }
1798
1799 /* fall back on parsing /proc/modules */
79e5ea91 1800 fp = fopen("/proc/modules", "re");
2d7bab5c
LDM
1801 if (fp == NULL) {
1802 int err = -errno;
1803 ERR(mod->ctx,
1804 "could not open /proc/modules: %s\n", strerror(errno));
30bfd48a 1805 close(dfd);
2d7bab5c
LDM
1806 return err;
1807 }
1808
1809 while (fgets(line, sizeof(line), fp)) {
1810 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
1811 long value;
1812
1813 lineno++;
1814 if (tok == NULL || !streq(tok, mod->name))
1815 continue;
1816
1817 tok = strtok_r(NULL, " \t", &saveptr);
1818 if (tok == NULL) {
1819 ERR(mod->ctx,
1820 "invalid line format at /proc/modules:%d\n", lineno);
1821 break;
1822 }
1823
1824 value = strtol(tok, &endptr, 10);
1825 if (endptr == tok || *endptr != '\0') {
1826 ERR(mod->ctx,
1827 "invalid line format at /proc/modules:%d\n", lineno);
1828 break;
1829 }
1830
1831 size = value;
1832 break;
1833 }
1834 fclose(fp);
486f9013
DR
1835
1836done:
1837 close(dfd);
2d7bab5c
LDM
1838 return size;
1839}
1840
7afc98a1
LDM
1841/**
1842 * kmod_module_get_refcnt:
1843 * @mod: kmod module
1844 *
1845 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
1846 * /sys filesystem.
1847 *
1848 * Returns: 0 on success or < 0 on failure.
1849 */
f12ae3c4
GSB
1850KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
1851{
1852 char path[PATH_MAX];
1853 long refcnt;
1854 int fd, err;
1855
818f8e8a
LDM
1856 if (mod == NULL)
1857 return -ENOENT;
1858
f12ae3c4 1859 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
79e5ea91 1860 fd = open(path, O_RDONLY|O_CLOEXEC);
f12ae3c4
GSB
1861 if (fd < 0) {
1862 err = -errno;
9c5f057c 1863 DBG(mod->ctx, "could not open '%s': %s\n",
f12ae3c4
GSB
1864 path, strerror(errno));
1865 return err;
1866 }
1867
1868 err = read_str_long(fd, &refcnt, 10);
1869 close(fd);
1870 if (err < 0) {
1871 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
1872 path, strerror(-err));
1873 return err;
1874 }
1875
1876 return (int)refcnt;
1877}
1878
7afc98a1
LDM
1879/**
1880 * kmod_module_get_holders:
1881 * @mod: kmod module
1882 *
1883 * Get a list of kmod modules that are holding this @mod, as returned by Linux
1884 * Kernel. After use, free the @list by calling kmod_module_unref_list().
1885 *
1886 * Returns: a new list of kmod modules on success or NULL on failure.
1887 */
f12ae3c4
GSB
1888KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
1889{
1890 char dname[PATH_MAX];
1891 struct kmod_list *list = NULL;
7e0385c4 1892 struct dirent *dent;
f12ae3c4 1893 DIR *d;
f12ae3c4 1894
b9a7da39 1895 if (mod == NULL || mod->ctx == NULL)
f12ae3c4 1896 return NULL;
818f8e8a 1897
f12ae3c4
GSB
1898 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
1899
1900 d = opendir(dname);
1901 if (d == NULL) {
1902 ERR(mod->ctx, "could not open '%s': %s\n",
53886ddd 1903 dname, strerror(errno));
f12ae3c4
GSB
1904 return NULL;
1905 }
1906
7e0385c4 1907 for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
f12ae3c4 1908 struct kmod_module *holder;
53886ddd 1909 struct kmod_list *l;
f12ae3c4
GSB
1910 int err;
1911
7e0385c4
LDM
1912 if (dent->d_name[0] == '.') {
1913 if (dent->d_name[1] == '\0' ||
1914 (dent->d_name[1] == '.' && dent->d_name[2] == '\0'))
f12ae3c4
GSB
1915 continue;
1916 }
1917
7e0385c4
LDM
1918 err = kmod_module_new_from_name(mod->ctx, dent->d_name,
1919 &holder);
f12ae3c4
GSB
1920 if (err < 0) {
1921 ERR(mod->ctx, "could not create module for '%s': %s\n",
7e0385c4 1922 dent->d_name, strerror(-err));
53886ddd 1923 goto fail;
f12ae3c4
GSB
1924 }
1925
53886ddd
LDM
1926 l = kmod_list_append(list, holder);
1927 if (l != NULL) {
1928 list = l;
1929 } else {
f12ae3c4
GSB
1930 ERR(mod->ctx, "out of memory\n");
1931 kmod_module_unref(holder);
53886ddd 1932 goto fail;
f12ae3c4
GSB
1933 }
1934 }
1935
1936 closedir(d);
1937 return list;
53886ddd
LDM
1938
1939fail:
1940 closedir(d);
1941 kmod_module_unref_list(list);
1942 return NULL;
f12ae3c4
GSB
1943}
1944
1945struct kmod_module_section {
1946 unsigned long address;
1947 char name[];
1948};
1949
1950static void kmod_module_section_free(struct kmod_module_section *section)
1951{
1952 free(section);
1953}
1954
7afc98a1
LDM
1955/**
1956 * kmod_module_get_sections:
1957 * @mod: kmod module
1958 *
1959 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
1960 * structure contained in this list is internal to libkmod and their fields
1961 * can be obtained by calling kmod_module_section_get_name() and
1962 * kmod_module_section_get_address().
1963 *
1964 * After use, free the @list by calling kmod_module_section_free_list().
1965 *
1966 * Returns: a new list of kmod module sections on success or NULL on failure.
1967 */
f12ae3c4
GSB
1968KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1969{
1970 char dname[PATH_MAX];
1971 struct kmod_list *list = NULL;
7e0385c4 1972 struct dirent *dent;
f12ae3c4
GSB
1973 DIR *d;
1974 int dfd;
f12ae3c4
GSB
1975
1976 if (mod == NULL)
1977 return NULL;
28c175ed 1978
f12ae3c4
GSB
1979 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1980
1981 d = opendir(dname);
1982 if (d == NULL) {
1983 ERR(mod->ctx, "could not open '%s': %s\n",
1984 dname, strerror(errno));
1985 return NULL;
1986 }
1987
1988 dfd = dirfd(d);
40923bdb 1989
7e0385c4 1990 for (dent = readdir(d); dent; dent = readdir(d)) {
f12ae3c4 1991 struct kmod_module_section *section;
40923bdb 1992 struct kmod_list *l;
f12ae3c4
GSB
1993 unsigned long address;
1994 size_t namesz;
1995 int fd, err;
1996
7e0385c4
LDM
1997 if (dent->d_name[0] == '.') {
1998 if (dent->d_name[1] == '\0' ||
1999 (dent->d_name[1] == '.' && dent->d_name[2] == '\0'))
f12ae3c4
GSB
2000 continue;
2001 }
2002
7e0385c4 2003 fd = openat(dfd, dent->d_name, O_RDONLY|O_CLOEXEC);
f12ae3c4 2004 if (fd < 0) {
40923bdb 2005 ERR(mod->ctx, "could not open '%s/%s': %m\n",
7e0385c4 2006 dname, dent->d_name);
40923bdb 2007 goto fail;
f12ae3c4
GSB
2008 }
2009
2010 err = read_str_ulong(fd, &address, 16);
40923bdb 2011 close(fd);
f12ae3c4 2012 if (err < 0) {
40923bdb 2013 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
7e0385c4 2014 dname, dent->d_name);
40923bdb
LDM
2015 goto fail;
2016 }
2017
7e0385c4 2018 namesz = strlen(dent->d_name) + 1;
40923bdb
LDM
2019 section = malloc(sizeof(*section) + namesz);
2020
2021 if (section == NULL) {
2022 ERR(mod->ctx, "out of memory\n");
2023 goto fail;
f12ae3c4
GSB
2024 }
2025
f12ae3c4 2026 section->address = address;
7e0385c4 2027 memcpy(section->name, dent->d_name, namesz);
f12ae3c4 2028
40923bdb
LDM
2029 l = kmod_list_append(list, section);
2030 if (l != NULL) {
2031 list = l;
2032 } else {
f12ae3c4
GSB
2033 ERR(mod->ctx, "out of memory\n");
2034 free(section);
40923bdb 2035 goto fail;
f12ae3c4 2036 }
f12ae3c4
GSB
2037 }
2038
2039 closedir(d);
2040 return list;
40923bdb
LDM
2041
2042fail:
2043 closedir(d);
2044 kmod_module_unref_list(list);
2045 return NULL;
f12ae3c4
GSB
2046}
2047
7afc98a1
LDM
2048/**
2049 * kmod_module_section_get_module_name:
2050 * @entry: a list entry representing a kmod module section
2051 *
2052 * Get the name of a kmod module section.
2053 *
2054 * After use, free the @list by calling kmod_module_section_free_list().
2055 *
2056 * Returns: the name of this kmod module section on success or NULL on
2057 * failure. The string is owned by the section, do not free it.
2058 */
f12ae3c4
GSB
2059KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
2060{
2061 struct kmod_module_section *section;
28c175ed 2062
f12ae3c4
GSB
2063 if (entry == NULL)
2064 return NULL;
28c175ed 2065
f12ae3c4
GSB
2066 section = entry->data;
2067 return section->name;
2068}
2069
7afc98a1
LDM
2070/**
2071 * kmod_module_section_get_address:
2072 * @entry: a list entry representing a kmod module section
2073 *
2074 * Get the address of a kmod module section.
2075 *
2076 * After use, free the @list by calling kmod_module_section_free_list().
2077 *
2078 * Returns: the address of this kmod module section on success or ULONG_MAX
2079 * on failure.
2080 */
f12ae3c4
GSB
2081KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
2082{
2083 struct kmod_module_section *section;
28c175ed 2084
f12ae3c4
GSB
2085 if (entry == NULL)
2086 return (unsigned long)-1;
28c175ed 2087
f12ae3c4
GSB
2088 section = entry->data;
2089 return section->address;
2090}
2091
7afc98a1
LDM
2092/**
2093 * kmod_module_section_free_list:
2094 * @list: kmod module section list
2095 *
2096 * Release the resources taken by @list
2097 */
f12ae3c4
GSB
2098KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
2099{
2100 while (list) {
2101 kmod_module_section_free(list->data);
2102 list = kmod_list_remove(list);
2103 }
2104}
708624a4 2105
1eff942e
LDM
2106static struct kmod_elf *kmod_module_get_elf(const struct kmod_module *mod)
2107{
2108 if (mod->file == NULL) {
2109 const char *path = kmod_module_get_path(mod);
2110
2111 if (path == NULL) {
2112 errno = ENOENT;
2113 return NULL;
2114 }
2115
2116 ((struct kmod_module *)mod)->file = kmod_file_open(mod->ctx,
2117 path);
2118 if (mod->file == NULL)
2119 return NULL;
2120 }
2121
2122 return kmod_file_get_elf(mod->file);
2123}
2124
708624a4
GSB
2125struct kmod_module_info {
2126 char *key;
2127 char value[];
2128};
2129
2130static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
2131{
2132 struct kmod_module_info *info;
2133
2134 info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
2135 if (info == NULL)
2136 return NULL;
2137
2138 info->key = (char *)info + sizeof(struct kmod_module_info)
818af4f6 2139 + valuelen + 1;
708624a4
GSB
2140 memcpy(info->key, key, keylen);
2141 info->key[keylen] = '\0';
2142 memcpy(info->value, value, valuelen);
2143 info->value[valuelen] = '\0';
2144 return info;
2145}
2146
2147static void kmod_module_info_free(struct kmod_module_info *info)
2148{
2149 free(info);
2150}
2151
f64458ca
MM
2152static struct kmod_list *kmod_module_info_append(struct kmod_list **list, const char *key, size_t keylen, const char *value, size_t valuelen)
2153{
2154 struct kmod_module_info *info;
2155 struct kmod_list *n;
2156
2157 info = kmod_module_info_new(key, keylen, value, valuelen);
6333934e 2158 if (info == NULL)
f64458ca 2159 return NULL;
f64458ca 2160 n = kmod_list_append(*list, info);
6333934e
MM
2161 if (n != NULL)
2162 *list = n;
2163 else
f64458ca 2164 kmod_module_info_free(info);
f64458ca
MM
2165 return n;
2166}
2167
708624a4
GSB
2168/**
2169 * kmod_module_get_info:
2170 * @mod: kmod module
2171 * @list: where to return list of module information. Use
2172 * kmod_module_info_get_key() and
2173 * kmod_module_info_get_value(). Release this list with
db74ceec 2174 * kmod_module_info_free_list()
708624a4
GSB
2175 *
2176 * Get a list of entries in ELF section ".modinfo", these contain
2177 * alias, license, depends, vermagic and other keys with respective
8fe1681c
MM
2178 * values. If the module is signed (CONFIG_MODULE_SIG), information
2179 * about the module signature is included as well: signer,
2180 * sig_key and sig_hashalgo.
708624a4
GSB
2181 *
2182 * After use, free the @list by calling kmod_module_info_free_list().
2183 *
2184 * Returns: 0 on success or < 0 otherwise.
2185 */
2186KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
2187{
708624a4 2188 struct kmod_elf *elf;
708624a4 2189 char **strings;
f64458ca 2190 int i, count, ret = -ENOMEM;
8fe1681c 2191 struct kmod_signature_info sig_info;
708624a4
GSB
2192
2193 if (mod == NULL || list == NULL)
2194 return -ENOENT;
2195
2196 assert(*list == NULL);
2197
1eff942e
LDM
2198 elf = kmod_module_get_elf(mod);
2199 if (elf == NULL)
708624a4
GSB
2200 return -errno;
2201
708624a4 2202 count = kmod_elf_get_strings(elf, ".modinfo", &strings);
1eff942e
LDM
2203 if (count < 0)
2204 return count;
708624a4
GSB
2205
2206 for (i = 0; i < count; i++) {
708624a4
GSB
2207 struct kmod_list *n;
2208 const char *key, *value;
2209 size_t keylen, valuelen;
2210
2211 key = strings[i];
2212 value = strchr(key, '=');
2213 if (value == NULL) {
2214 keylen = strlen(key);
2215 valuelen = 0;
818af4f6 2216 value = key;
708624a4
GSB
2217 } else {
2218 keylen = value - key;
2219 value++;
2220 valuelen = strlen(value);
2221 }
2222
f64458ca
MM
2223 n = kmod_module_info_append(list, key, keylen, value, valuelen);
2224 if (n == NULL)
708624a4 2225 goto list_error;
708624a4 2226 }
8fe1681c
MM
2227
2228 if (kmod_module_signature_info(mod->file, &sig_info)) {
2229 struct kmod_list *n;
2230 char *key_hex;
2231
2232 n = kmod_module_info_append(list, "signer", strlen("signer"),
2233 sig_info.signer, sig_info.signer_len);
2234 if (n == NULL)
2235 goto list_error;
2236 count++;
2237
2238 /* Display the key id as 01:12:DE:AD:BE:EF:... */
2239 key_hex = malloc(sig_info.key_id_len * 3);
2240 if (key_hex == NULL)
2241 goto list_error;
2242 for (i = 0; i < (int)sig_info.key_id_len; i++) {
2243 sprintf(key_hex + i * 3, "%02X",
2244 (unsigned char)sig_info.key_id[i]);
2245 if (i < (int)sig_info.key_id_len - 1)
2246 key_hex[i * 3 + 2] = ':';
2247 }
2248 n = kmod_module_info_append(list, "sig_key", strlen("sig_key"),
2249 key_hex, sig_info.key_id_len * 3 - 1);
2250 free(key_hex);
2251 if (n == NULL)
2252 goto list_error;
2253 count++;
2254
2255 n = kmod_module_info_append(list,
2256 "sig_hashalgo", strlen("sig_hashalgo"),
2257 sig_info.hash_algo, strlen(sig_info.hash_algo));
2258 if (n == NULL)
2259 goto list_error;
2260 count++;
2261
2262 /*
2263 * Omit sig_info.id_type and sig_info.algo for now, as these
2264 * are currently constant.
2265 */
2266 }
708624a4
GSB
2267 ret = count;
2268
2269list_error:
6333934e
MM
2270 if (ret < 0) {
2271 kmod_module_info_free_list(*list);
2272 *list = NULL;
2273 }
708624a4 2274 free(strings);
708624a4
GSB
2275 return ret;
2276}
2277
2278/**
2279 * kmod_module_info_get_key:
2280 * @entry: a list entry representing a kmod module info
2281 *
2282 * Get the key of a kmod module info.
2283 *
2284 * Returns: the key of this kmod module info on success or NULL on
2285 * failure. The string is owned by the info, do not free it.
2286 */
2287KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
2288{
2289 struct kmod_module_info *info;
2290
2291 if (entry == NULL)
2292 return NULL;
2293
2294 info = entry->data;
2295 return info->key;
2296}
2297
2298/**
2299 * kmod_module_info_get_value:
2300 * @entry: a list entry representing a kmod module info
2301 *
2302 * Get the value of a kmod module info.
2303 *
2304 * Returns: the value of this kmod module info on success or NULL on
2305 * failure. The string is owned by the info, do not free it.
2306 */
2307KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
2308{
2309 struct kmod_module_info *info;
2310
2311 if (entry == NULL)
2312 return NULL;
2313
2314 info = entry->data;
2315 return info->value;
2316}
2317
2318/**
2319 * kmod_module_info_free_list:
2320 * @list: kmod module info list
2321 *
2322 * Release the resources taken by @list
2323 */
2324KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
2325{
2326 while (list) {
2327 kmod_module_info_free(list->data);
2328 list = kmod_list_remove(list);
2329 }
2330}
2331
2332struct kmod_module_version {
2333 uint64_t crc;
2334 char symbol[];
2335};
2336
2337static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
2338{
2339 struct kmod_module_version *mv;
2340 size_t symbollen = strlen(symbol) + 1;
2341
2342 mv = malloc(sizeof(struct kmod_module_version) + symbollen);
2343 if (mv == NULL)
2344 return NULL;
2345
2346 mv->crc = crc;
2347 memcpy(mv->symbol, symbol, symbollen);
2348 return mv;
2349}
2350
2351static void kmod_module_version_free(struct kmod_module_version *version)
2352{
2353 free(version);
2354}
2355
2356/**
2357 * kmod_module_get_versions:
2358 * @mod: kmod module
2359 * @list: where to return list of module versions. Use
db74ceec
LDM
2360 * kmod_module_version_get_symbol() and
2361 * kmod_module_version_get_crc(). Release this list with
2362 * kmod_module_versions_free_list()
708624a4
GSB
2363 *
2364 * Get a list of entries in ELF section "__versions".
2365 *
2366 * After use, free the @list by calling kmod_module_versions_free_list().
2367 *
2368 * Returns: 0 on success or < 0 otherwise.
2369 */
2370KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
2371{
708624a4 2372 struct kmod_elf *elf;
708624a4 2373 struct kmod_modversion *versions;
708624a4
GSB
2374 int i, count, ret = 0;
2375
2376 if (mod == NULL || list == NULL)
2377 return -ENOENT;
2378
2379 assert(*list == NULL);
2380
1eff942e
LDM
2381 elf = kmod_module_get_elf(mod);
2382 if (elf == NULL)
708624a4
GSB
2383 return -errno;
2384
708624a4 2385 count = kmod_elf_get_modversions(elf, &versions);
1eff942e
LDM
2386 if (count < 0)
2387 return count;
708624a4
GSB
2388
2389 for (i = 0; i < count; i++) {
2390 struct kmod_module_version *mv;
2391 struct kmod_list *n;
2392
2393 mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
2394 if (mv == NULL) {
2395 ret = -errno;
2396 kmod_module_versions_free_list(*list);
2397 *list = NULL;
2398 goto list_error;
2399 }
2400
2401 n = kmod_list_append(*list, mv);
2402 if (n != NULL)
2403 *list = n;
2404 else {
2405 kmod_module_version_free(mv);
2406 kmod_module_versions_free_list(*list);
2407 *list = NULL;
2408 ret = -ENOMEM;
2409 goto list_error;
2410 }
2411 }
2412 ret = count;
2413
2414list_error:
2415 free(versions);
708624a4
GSB
2416 return ret;
2417}
2418
2419/**
491c4902 2420 * kmod_module_version_get_symbol:
708624a4
GSB
2421 * @entry: a list entry representing a kmod module versions
2422 *
2423 * Get the symbol of a kmod module versions.
2424 *
2425 * Returns: the symbol of this kmod module versions on success or NULL
2426 * on failure. The string is owned by the versions, do not free it.
2427 */
2428KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
2429{
2430 struct kmod_module_version *version;
2431
2432 if (entry == NULL)
2433 return NULL;
2434
2435 version = entry->data;
2436 return version->symbol;
2437}
2438
2439/**
2440 * kmod_module_version_get_crc:
2441 * @entry: a list entry representing a kmod module version
2442 *
2443 * Get the crc of a kmod module version.
2444 *
2445 * Returns: the crc of this kmod module version on success or NULL on
2446 * failure. The string is owned by the version, do not free it.
2447 */
2448KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
2449{
2450 struct kmod_module_version *version;
2451
2452 if (entry == NULL)
2453 return 0;
2454
2455 version = entry->data;
2456 return version->crc;
2457}
2458
2459/**
2460 * kmod_module_versions_free_list:
2461 * @list: kmod module versions list
2462 *
2463 * Release the resources taken by @list
2464 */
2465KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
2466{
2467 while (list) {
2468 kmod_module_version_free(list->data);
2469 list = kmod_list_remove(list);
2470 }
2471}
45e6db9c
GSB
2472
2473struct kmod_module_symbol {
2474 uint64_t crc;
2475 char symbol[];
2476};
2477
2478static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
2479{
2480 struct kmod_module_symbol *mv;
2481 size_t symbollen = strlen(symbol) + 1;
2482
2483 mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
2484 if (mv == NULL)
2485 return NULL;
2486
2487 mv->crc = crc;
2488 memcpy(mv->symbol, symbol, symbollen);
2489 return mv;
2490}
2491
2492static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
2493{
2494 free(symbol);
2495}
2496
2497/**
2498 * kmod_module_get_symbols:
2499 * @mod: kmod module
2500 * @list: where to return list of module symbols. Use
db74ceec
LDM
2501 * kmod_module_symbol_get_symbol() and
2502 * kmod_module_symbol_get_crc(). Release this list with
2503 * kmod_module_symbols_free_list()
45e6db9c
GSB
2504 *
2505 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2506 *
2507 * After use, free the @list by calling kmod_module_symbols_free_list().
2508 *
2509 * Returns: 0 on success or < 0 otherwise.
2510 */
2511KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
2512{
45e6db9c 2513 struct kmod_elf *elf;
45e6db9c 2514 struct kmod_modversion *symbols;
45e6db9c
GSB
2515 int i, count, ret = 0;
2516
2517 if (mod == NULL || list == NULL)
2518 return -ENOENT;
2519
2520 assert(*list == NULL);
2521
1eff942e
LDM
2522 elf = kmod_module_get_elf(mod);
2523 if (elf == NULL)
45e6db9c
GSB
2524 return -errno;
2525
45e6db9c 2526 count = kmod_elf_get_symbols(elf, &symbols);
1eff942e
LDM
2527 if (count < 0)
2528 return count;
45e6db9c
GSB
2529
2530 for (i = 0; i < count; i++) {
2531 struct kmod_module_symbol *mv;
2532 struct kmod_list *n;
2533
2534 mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
2535 if (mv == NULL) {
2536 ret = -errno;
2537 kmod_module_symbols_free_list(*list);
2538 *list = NULL;
2539 goto list_error;
2540 }
2541
2542 n = kmod_list_append(*list, mv);
2543 if (n != NULL)
2544 *list = n;
2545 else {
2546 kmod_module_symbol_free(mv);
2547 kmod_module_symbols_free_list(*list);
2548 *list = NULL;
2549 ret = -ENOMEM;
2550 goto list_error;
2551 }
2552 }
2553 ret = count;
2554
2555list_error:
2556 free(symbols);
45e6db9c
GSB
2557 return ret;
2558}
2559
2560/**
db74ceec 2561 * kmod_module_symbol_get_symbol:
45e6db9c
GSB
2562 * @entry: a list entry representing a kmod module symbols
2563 *
2564 * Get the symbol of a kmod module symbols.
2565 *
2566 * Returns: the symbol of this kmod module symbols on success or NULL
2567 * on failure. The string is owned by the symbols, do not free it.
2568 */
2569KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
2570{
2571 struct kmod_module_symbol *symbol;
2572
2573 if (entry == NULL)
2574 return NULL;
2575
2576 symbol = entry->data;
2577 return symbol->symbol;
2578}
2579
2580/**
2581 * kmod_module_symbol_get_crc:
2582 * @entry: a list entry representing a kmod module symbol
2583 *
2584 * Get the crc of a kmod module symbol.
2585 *
2586 * Returns: the crc of this kmod module symbol on success or NULL on
2587 * failure. The string is owned by the symbol, do not free it.
2588 */
2589KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
2590{
2591 struct kmod_module_symbol *symbol;
2592
2593 if (entry == NULL)
2594 return 0;
2595
2596 symbol = entry->data;
2597 return symbol->crc;
2598}
2599
2600/**
2601 * kmod_module_symbols_free_list:
2602 * @list: kmod module symbols list
2603 *
2604 * Release the resources taken by @list
2605 */
2606KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
2607{
2608 while (list) {
2609 kmod_module_symbol_free(list->data);
2610 list = kmod_list_remove(list);
2611 }
2612}
674f8590
GSB
2613
2614struct kmod_module_dependency_symbol {
2615 uint64_t crc;
2616 uint8_t bind;
2617 char symbol[];
2618};
2619
2620static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
2621{
2622 struct kmod_module_dependency_symbol *mv;
2623 size_t symbollen = strlen(symbol) + 1;
2624
2625 mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
2626 if (mv == NULL)
2627 return NULL;
2628
2629 mv->crc = crc;
2630 mv->bind = bind;
2631 memcpy(mv->symbol, symbol, symbollen);
2632 return mv;
2633}
2634
2635static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
2636{
2637 free(dependency_symbol);
2638}
2639
2640/**
2641 * kmod_module_get_dependency_symbols:
2642 * @mod: kmod module
2643 * @list: where to return list of module dependency_symbols. Use
2644 * kmod_module_dependency_symbol_get_symbol() and
2645 * kmod_module_dependency_symbol_get_crc(). Release this list with
2646 * kmod_module_dependency_symbols_free_list()
2647 *
2648 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2649 *
2650 * After use, free the @list by calling
2651 * kmod_module_dependency_symbols_free_list().
2652 *
2653 * Returns: 0 on success or < 0 otherwise.
2654 */
2655KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
2656{
674f8590 2657 struct kmod_elf *elf;
674f8590 2658 struct kmod_modversion *symbols;
674f8590
GSB
2659 int i, count, ret = 0;
2660
2661 if (mod == NULL || list == NULL)
2662 return -ENOENT;
2663
2664 assert(*list == NULL);
2665
1eff942e
LDM
2666 elf = kmod_module_get_elf(mod);
2667 if (elf == NULL)
674f8590
GSB
2668 return -errno;
2669
674f8590 2670 count = kmod_elf_get_dependency_symbols(elf, &symbols);
1eff942e
LDM
2671 if (count < 0)
2672 return count;
674f8590
GSB
2673
2674 for (i = 0; i < count; i++) {
2675 struct kmod_module_dependency_symbol *mv;
2676 struct kmod_list *n;
2677
2678 mv = kmod_module_dependency_symbols_new(symbols[i].crc,
2679 symbols[i].bind,
2680 symbols[i].symbol);
2681 if (mv == NULL) {
2682 ret = -errno;
2683 kmod_module_dependency_symbols_free_list(*list);
2684 *list = NULL;
2685 goto list_error;
2686 }
2687
2688 n = kmod_list_append(*list, mv);
2689 if (n != NULL)
2690 *list = n;
2691 else {
2692 kmod_module_dependency_symbol_free(mv);
2693 kmod_module_dependency_symbols_free_list(*list);
2694 *list = NULL;
2695 ret = -ENOMEM;
2696 goto list_error;
2697 }
2698 }
2699 ret = count;
2700
2701list_error:
2702 free(symbols);
674f8590
GSB
2703 return ret;
2704}
2705
2706/**
2707 * kmod_module_dependency_symbol_get_symbol:
2708 * @entry: a list entry representing a kmod module dependency_symbols
2709 *
2710 * Get the dependency symbol of a kmod module
2711 *
2712 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
2713 * on failure. The string is owned by the dependency_symbols, do not free it.
2714 */
2715KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
2716{
2717 struct kmod_module_dependency_symbol *dependency_symbol;
2718
2719 if (entry == NULL)
2720 return NULL;
2721
2722 dependency_symbol = entry->data;
2723 return dependency_symbol->symbol;
2724}
2725
2726/**
2727 * kmod_module_dependency_symbol_get_crc:
2728 * @entry: a list entry representing a kmod module dependency_symbol
2729 *
2730 * Get the crc of a kmod module dependency_symbol.
2731 *
2732 * Returns: the crc of this kmod module dependency_symbol on success or NULL on
2733 * failure. The string is owned by the dependency_symbol, do not free it.
2734 */
2735KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
2736{
2737 struct kmod_module_dependency_symbol *dependency_symbol;
2738
2739 if (entry == NULL)
2740 return 0;
2741
2742 dependency_symbol = entry->data;
2743 return dependency_symbol->crc;
2744}
2745
2746/**
2747 * kmod_module_dependency_symbol_get_bind:
2748 * @entry: a list entry representing a kmod module dependency_symbol
2749 *
2750 * Get the bind type of a kmod module dependency_symbol.
2751 *
2752 * Returns: the bind of this kmod module dependency_symbol on success
2753 * or < 0 on failure.
2754 */
2755KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
2756{
2757 struct kmod_module_dependency_symbol *dependency_symbol;
2758
2759 if (entry == NULL)
2760 return 0;
2761
2762 dependency_symbol = entry->data;
2763 return dependency_symbol->bind;
2764}
2765
2766/**
2767 * kmod_module_dependency_symbols_free_list:
2768 * @list: kmod module dependency_symbols list
2769 *
2770 * Release the resources taken by @list
2771 */
2772KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
2773{
2774 while (list) {
2775 kmod_module_dependency_symbol_free(list->data);
2776 list = kmod_list_remove(list);
2777 }
2778}