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