blob: 4e19af92d694487721ef6ecb5a049cc246599bbb [file] [log] [blame]
Lucas De Marchi8f788d52011-11-25 01:22:56 -02001/*
2 * libkmod - interface to kernel module operations
3 *
4 * Copyright (C) 2011 ProFUSION embedded systems
Lucas De Marchi8f788d52011-11-25 01:22:56 -02005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
Lucas De Marchicb451f32011-12-12 18:24:35 -02008 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
Lucas De Marchi8f788d52011-11-25 01:22:56 -020010 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
Lucas De Marchi7636e722011-12-01 17:56:03 -020021#include <assert.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020022#include <stdio.h>
23#include <stdlib.h>
24#include <stddef.h>
25#include <stdarg.h>
26#include <unistd.h>
27#include <errno.h>
28#include <string.h>
29#include <ctype.h>
30#include <inttypes.h>
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -020031#include <limits.h>
32#include <dirent.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020033#include <sys/stat.h>
34#include <sys/types.h>
35#include <sys/mman.h>
36#include <string.h>
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -020037#include <fnmatch.h>
Lucas De Marchi8f788d52011-11-25 01:22:56 -020038
39#include "libkmod.h"
40#include "libkmod-private.h"
41
42/**
43 * kmod_module:
44 *
45 * Opaque object representing a module.
46 */
47struct kmod_module {
48 struct kmod_ctx *ctx;
Lucas De Marchi8bdeca12011-12-15 13:11:51 -020049 char *hashkey;
Lucas De Marchi219f9c32011-12-13 13:07:40 -020050 char *name;
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -020051 char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -020052 struct kmod_list *dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020053 char *options;
Lucas De Marchi60f67602011-12-16 03:33:26 -020054 const char *install_commands; /* owned by kmod_config */
55 const char *remove_commands; /* owned by kmod_config */
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -020056 struct {
57 struct kmod_list *pre;
58 struct kmod_list *post;
59 } softdeps;
Lucas De Marchi6ad5f262011-12-13 14:12:50 -020060 char *alias; /* only set if this module was created from an alias */
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -020061 int n_dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020062 int refcount;
Lucas De Marchi7636e722011-12-01 17:56:03 -020063 struct {
64 bool dep : 1;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020065 bool options : 1;
66 bool install_commands : 1;
67 bool remove_commands : 1;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -020068 bool softdeps : 1;
Lucas De Marchi7636e722011-12-01 17:56:03 -020069 } init;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020070};
71
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -020072inline char *modname_normalize(const char *modname, char buf[NAME_MAX],
Lucas De Marchi6c343b12011-12-06 09:01:01 -020073 size_t *len)
Lucas De Marchi8f788d52011-11-25 01:22:56 -020074{
Lucas De Marchid753b8c2011-12-05 18:14:51 -020075 size_t s;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020076
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020077 for (s = 0; s < NAME_MAX - 1; s++) {
78 const char c = modname[s];
79 if (c == '-')
80 buf[s] = '_';
81 else if (c == '\0' || c == '.')
82 break;
83 else
84 buf[s] = c;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020085 }
Lucas De Marchi28c175e2011-12-12 11:52:59 -020086
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020087 buf[s] = '\0';
Lucas De Marchid753b8c2011-12-05 18:14:51 -020088
89 if (len)
90 *len = s;
91
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020092 return buf;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020093}
94
Lucas De Marchi6c343b12011-12-06 09:01:01 -020095static char *path_to_modname(const char *path, char buf[NAME_MAX], size_t *len)
96{
97 char *modname;
98
99 modname = basename(path);
100 if (modname == NULL || modname[0] == '\0')
101 return NULL;
102
103 return modname_normalize(modname, buf, len);
104}
105
Lucas De Marchic35347f2011-12-12 10:48:02 -0200106static inline const char *path_join(const char *path, size_t prefixlen,
107 char buf[PATH_MAX])
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200108{
109 size_t pathlen;
110
111 if (path[0] == '/')
112 return path;
113
114 pathlen = strlen(path);
115 if (prefixlen + pathlen + 1 >= PATH_MAX)
116 return NULL;
117
118 memcpy(buf + prefixlen, path, pathlen + 1);
119 return buf;
120}
121
Lucas De Marchi671d4892011-12-05 20:23:05 -0200122int kmod_module_parse_depline(struct kmod_module *mod, char *line)
Lucas De Marchi7636e722011-12-01 17:56:03 -0200123{
124 struct kmod_ctx *ctx = mod->ctx;
125 struct kmod_list *list = NULL;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200126 const char *dirname;
127 char buf[PATH_MAX];
Lucas De Marchi7636e722011-12-01 17:56:03 -0200128 char *p, *saveptr;
Lucas De Marchi45f27782011-12-12 17:23:04 -0200129 int err = 0, n = 0;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200130 size_t dirnamelen;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200131
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200132 if (mod->init.dep)
133 return mod->n_dep;
134 assert(mod->dep == NULL);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200135 mod->init.dep = true;
136
137 p = strchr(line, ':');
138 if (p == NULL)
139 return 0;
140
Lucas De Marchi671d4892011-12-05 20:23:05 -0200141 *p = '\0';
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200142 dirname = kmod_get_dirname(mod->ctx);
143 dirnamelen = strlen(dirname);
144 if (dirnamelen + 2 >= PATH_MAX)
145 return 0;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200146
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200147 memcpy(buf, dirname, dirnamelen);
148 buf[dirnamelen] = '/';
149 dirnamelen++;
150 buf[dirnamelen] = '\0';
151
152 if (mod->path == NULL) {
153 const char *str = path_join(line, dirnamelen, buf);
154 if (str == NULL)
155 return 0;
156 mod->path = strdup(str);
157 if (mod->path == NULL)
158 return 0;
159 }
Lucas De Marchi671d4892011-12-05 20:23:05 -0200160
Lucas De Marchi7636e722011-12-01 17:56:03 -0200161 p++;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200162 for (p = strtok_r(p, " \t", &saveptr); p != NULL;
163 p = strtok_r(NULL, " \t", &saveptr)) {
Lucas De Marchi1fc1c9a2011-12-02 10:00:03 -0200164 struct kmod_module *depmod;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200165 const char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200166
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200167 path = path_join(p, dirnamelen, buf);
168 if (path == NULL) {
169 ERR(ctx, "could not join path '%s' and '%s'.\n",
170 dirname, p);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200171 goto fail;
172 }
173
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200174 err = kmod_module_new_from_path(ctx, path, &depmod);
175 if (err < 0) {
176 ERR(ctx, "ctx=%p path=%s error=%s\n",
177 ctx, path, strerror(-err));
178 goto fail;
179 }
180
181 DBG(ctx, "add dep: %s\n", path);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200182
Lucas De Marchib94a7372011-12-26 20:10:49 -0200183 list = kmod_list_prepend(list, depmod);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200184 n++;
185 }
186
187 DBG(ctx, "%d dependencies for %s\n", n, mod->name);
188
189 mod->dep = list;
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200190 mod->n_dep = n;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200191 return n;
192
193fail:
194 kmod_module_unref_list(list);
195 mod->init.dep = false;
196 return err;
197}
198
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200199/**
200 * kmod_module_new_from_name:
201 * @ctx: kmod library context
202 * @name: name of the module
203 * @mod: where to save the created struct kmod_module
204 *
205 * Create a new struct kmod_module using the module name. @name can not be an
206 * alias, file name or anything else; it must be a module name. There's no
207 * check if the module does exists in the system.
208 *
209 * This function is also used internally by many others that return a new
210 * struct kmod_module or a new list of modules.
211 *
212 * The initial refcount is 1, and needs to be decremented to release the
213 * resources of the kmod_module. Since libkmod keeps track of all
214 * kmod_modules created, they are all released upon @ctx destruction too. Do
215 * not unref @ctx before all the desired operations with the returned
216 * kmod_module are done.
217 *
218 * Returns: 0 on success or < 0 otherwise. It fails if name is not a valid
219 * module name or if memory allocation failed.
220 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200221KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
222 const char *name,
223 struct kmod_module **mod)
224{
225 struct kmod_module *m;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200226 size_t namelen;
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200227 char name_norm[NAME_MAX];
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200228 char *namesep;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200229
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200230 if (ctx == NULL || name == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200231 return -ENOENT;
232
Luis Felipe Strano Moraes9efaf2f2011-12-20 08:13:56 -0800233 if (alias_normalize(name, name_norm, &namelen) < 0) {
234 DBG(ctx, "invalid alias: %s\n", name);
235 return -EINVAL;
236 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200237
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200238 m = kmod_pool_get_module(ctx, name_norm);
239 if (m != NULL) {
240 *mod = kmod_module_ref(m);
241 return 0;
242 }
243
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200244 namesep = strchr(name_norm, '/');
245 m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200246 if (m == NULL) {
247 free(m);
248 return -ENOMEM;
249 }
250
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200251 memset(m, 0, sizeof(*m));
252
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200253 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200254 m->name = (char *)m + sizeof(*m);
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200255 memcpy(m->name, name_norm, namelen + 1);
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200256
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200257 if (namesep) {
258 size_t len = namesep - name_norm;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200259
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200260 m->name[len] = '\0';
261 m->alias = m->name + len + 1;
262 m->hashkey = m->name + namelen + 1;
263 memcpy(m->hashkey, name_norm, namelen + 1);
264 } else {
265 m->hashkey = m->name;
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200266 }
267
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200268 m->refcount = 1;
269 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200270 *mod = m;
271
272 return 0;
273}
274
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200275int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
276 const char *name, struct kmod_module **mod)
277{
278 int err;
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200279 char key[NAME_MAX];
280 size_t namelen = strlen(name);
281 size_t aliaslen = strlen(alias);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200282
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200283 if (namelen + aliaslen + 2 > NAME_MAX)
284 return -ENAMETOOLONG;
285
286 memcpy(key, name, namelen);
287 memcpy(key + namelen + 1, alias, aliaslen + 1);
288 key[namelen] = '/';
289
290 err = kmod_module_new_from_name(ctx, key, mod);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200291 if (err < 0)
292 return err;
293
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200294 return 0;
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200295}
296
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200297/**
298 * kmod_module_new_from_path:
299 * @ctx: kmod library context
300 * @path: path where to find the given module
301 * @mod: where to save the created struct kmod_module
302 *
303 * Create a new struct kmod_module using the module path. @path must be an
304 * existent file with in the filesystem and must be accessible to libkmod.
305 *
306 * The initial refcount is 1, and needs to be decremented to release the
307 * resources of the kmod_module. Since libkmod keeps track of all
308 * kmod_modules created, they are all released upon @ctx destruction too. Do
309 * not unref @ctx before all the desired operations with the returned
310 * kmod_module are done.
311 *
312 * If @path is relative, it's treated as relative to the current working
313 * directory. Otherwise, give an absolute path.
314 *
315 * Returns: 0 on success or < 0 otherwise. It fails if file does not exist, if
316 * it's not a valid file for a kmod_module or if memory allocation failed.
317 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200318KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
319 const char *path,
320 struct kmod_module **mod)
321{
322 struct kmod_module *m;
323 int err;
324 struct stat st;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200325 char name[NAME_MAX];
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200326 char *abspath;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200327 size_t namelen;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200328
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200329 if (ctx == NULL || path == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200330 return -ENOENT;
331
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200332 abspath = path_make_absolute_cwd(path);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200333 if (abspath == NULL) {
334 DBG(ctx, "no absolute path for %s\n", path);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200335 return -ENOMEM;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200336 }
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200337
338 err = stat(abspath, &st);
339 if (err < 0) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200340 err = -errno;
341 DBG(ctx, "stat %s: %s\n", path, strerror(errno));
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200342 free(abspath);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200343 return err;
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200344 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200345
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200346 if (path_to_modname(path, name, &namelen) == NULL) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200347 DBG(ctx, "could not get modname from path %s\n", path);
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200348 free(abspath);
349 return -ENOENT;
350 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200351
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200352 m = kmod_pool_get_module(ctx, name);
353 if (m != NULL) {
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200354 if (m->path == NULL)
355 m->path = abspath;
356 else if (streq(m->path, abspath))
357 free(abspath);
358 else {
359 ERR(ctx, "kmod_module '%s' already exists with different path\n",
360 name);
361 free(abspath);
362 return -EEXIST;
363 }
364
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200365 *mod = kmod_module_ref(m);
366 return 0;
367 }
368
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200369 m = malloc(sizeof(*m) + namelen + 1);
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200370 if (m == NULL)
371 return -errno;
372
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200373 memset(m, 0, sizeof(*m));
374
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200375 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200376 m->name = (char *)m + sizeof(*m);
Lucas De Marchi9dec2442011-12-18 15:12:19 -0200377 memcpy(m->name, name, namelen + 1);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200378 m->path = abspath;
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200379 m->hashkey = m->name;
Gustavo Sverzut Barbieri87ca03b2011-12-04 12:34:02 -0200380 m->refcount = 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200381
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200382 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200383
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200384 *mod = m;
385
386 return 0;
387}
388
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200389/**
390 * kmod_module_unref:
391 * @mod: kmod module
392 *
393 * Drop a reference of the kmod module. If the refcount reaches zero, its
394 * resources are released.
395 *
396 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
397 * returns the passed @mod with its refcount decremented.
398 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200399KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
400{
401 if (mod == NULL)
402 return NULL;
403
404 if (--mod->refcount > 0)
405 return mod;
406
407 DBG(mod->ctx, "kmod_module %p released\n", mod);
408
Lucas De Marchi4084c172011-12-15 13:43:22 -0200409 kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -0200410 kmod_module_unref_list(mod->softdeps.pre);
411 kmod_module_unref_list(mod->softdeps.post);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200412 kmod_module_unref_list(mod->dep);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200413 kmod_unref(mod->ctx);
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200414 free(mod->options);
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -0200415 free(mod->path);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200416 free(mod);
417 return NULL;
418}
419
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200420/**
421 * kmod_module_ref:
422 * @mod: kmod module
423 *
424 * Take a reference of the kmod module, incrementing its refcount.
425 *
426 * Returns: the passed @module with its refcount incremented.
427 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200428KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
429{
430 if (mod == NULL)
431 return NULL;
432
433 mod->refcount++;
434
435 return mod;
436}
437
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200438#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
439 do { \
440 if ((_err) < 0) \
441 goto _label_err; \
442 if (*(_list) != NULL) \
443 goto finish; \
444 } while (0)
445
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200446/**
447 * kmod_module_new_from_lookup:
448 * @ctx: kmod library context
449 * @given_alias: alias to look for
450 * @list: an empty list where to save the list of modules matching
451 * @given_alias
452 *
453 * Create a new list of kmod modules using an alias or module name and lookup
454 * libkmod's configuration files and indexes in order to find the module.
455 * Once it's found in one of the places, it stops searching and create the
456 * list of modules that is saved in @list.
457 *
458 * The search order is: 1. aliases in configuration file; 2. module names in
459 * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
460 * in modules.alias index.
461 *
462 * The initial refcount is 1, and needs to be decremented to release the
463 * resources of the kmod_module. The returned @list must be released by
464 * calling kmod_module_unref_list(). Since libkmod keeps track of all
465 * kmod_modules created, they are all released upon @ctx destruction too. Do
466 * not unref @ctx before all the desired operations with the returned list are
467 * completed.
468 *
469 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
470 * methods failed, which is basically due to memory allocation fail. If module
471 * is not found, it still returns 0, but @list is an empty list.
472 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200473KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200474 const char *given_alias,
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200475 struct kmod_list **list)
476{
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200477 int err;
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200478 char alias[NAME_MAX];
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200479
Lucas De Marchi4308b172011-12-13 10:26:04 -0200480 if (ctx == NULL || given_alias == NULL)
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200481 return -ENOENT;
482
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200483 if (list == NULL || *list != NULL) {
484 ERR(ctx, "An empty list is needed to create lookup\n");
485 return -ENOSYS;
486 }
487
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200488 if (alias_normalize(given_alias, alias, NULL) < 0) {
489 DBG(ctx, "invalid alias: %s\n", given_alias);
Lucas De Marchid470db12011-12-13 10:28:00 -0200490 return -EINVAL;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200491 }
492
493 DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200494
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200495 /* Aliases from config file override all the others */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200496 err = kmod_lookup_alias_from_config(ctx, alias, list);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200497 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200498
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200499 DBG(ctx, "lookup modules.dep %s\n", alias);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200500 err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
501 CHECK_ERR_AND_FINISH(err, fail, list, finish);
502
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200503 DBG(ctx, "lookup modules.symbols %s\n", alias);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200504 err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
505 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200506
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200507 DBG(ctx, "lookup install and remove commands %s\n", alias);
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200508 err = kmod_lookup_alias_from_commands(ctx, alias, list);
509 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200510
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200511 DBG(ctx, "lookup modules.aliases %s\n", alias);
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200512 err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
513 CHECK_ERR_AND_FINISH(err, fail, list, finish);
514
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200515finish:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200516 DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200517 return err;
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200518fail:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200519 DBG(ctx, "Failed to lookup %s\n", alias);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200520 kmod_module_unref_list(*list);
521 *list = NULL;
Lucas De Marchi84f42202011-12-02 10:03:34 -0200522 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200523}
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200524#undef CHECK_ERR_AND_FINISH
525
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200526/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200527 * kmod_module_unref_list:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200528 * @list: list of kmod modules
529 *
530 * Drop a reference of each kmod module in @list and releases the resources
531 * taken by the list itself.
532 *
533 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
534 * returns the passed @mod with its refcount decremented.
535 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200536KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
537{
538 for (; list != NULL; list = kmod_list_remove(list))
539 kmod_module_unref(list->data);
540
541 return 0;
542}
543
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200544static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
545{
546 if (!mod->init.dep) {
547 /* lazy init */
548 char *line = kmod_search_moddep(mod->ctx, mod->name);
549
550 if (line == NULL)
551 return NULL;
552
553 kmod_module_parse_depline((struct kmod_module *)mod, line);
554 free(line);
555
556 if (!mod->init.dep)
557 return NULL;
558 }
559
560 return mod->dep;
561}
562
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200563/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200564 * kmod_module_get_dependencies:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200565 * @mod: kmod module
566 *
567 * Search the modules.dep index to find the dependencies of the given @mod.
568 * The result is cached in @mod, so subsequent calls to this function will
569 * return the already searched list of modules.
570 *
571 * Returns: NULL on failure or if there are any dependencies. Otherwise it
572 * returns a list of kmod modules that can be released by calling
573 * kmod_module_unref_list().
574 */
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200575KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200576{
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200577 struct kmod_list *l, *l_new, *list_new = NULL;
578
579 if (mod == NULL)
580 return NULL;
581
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200582 module_get_dependencies_noref(mod);
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200583
584 kmod_list_foreach(l, mod->dep) {
585 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
586 if (l_new == NULL) {
587 kmod_module_unref(l->data);
588 goto fail;
589 }
590
591 list_new = l_new;
592 }
593
594 return list_new;
595
596fail:
597 ERR(mod->ctx, "out of memory\n");
598 kmod_module_unref_list(list_new);
599 return NULL;
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200600}
601
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200602/**
603 * kmod_module_get_module:
604 * @entry: an entry in a list of kmod modules.
605 *
606 * Get the kmod module of this @entry in the list, increasing its refcount.
607 * After it's used, unref it. Since the refcount is incremented upon return,
608 * you still have to call kmod_module_unref_list() to release the list of kmod
609 * modules.
610 *
611 * Returns: NULL on failure or the kmod_module contained in this list entry
612 * with its refcount incremented.
613 */
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200614KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200615{
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200616 if (entry == NULL)
617 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200618
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200619 return kmod_module_ref(entry->data);
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200620}
621
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200622/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200623 * kmod_module_get_name:
624 * @mod: kmod module
625 *
626 * Get the name of this kmod module. Name is always available, independently
627 * if it was created by kmod_module_new_from_name() or another function and
628 * it's always normalized (dashes are replaced with underscores).
629 *
630 * Returns: the name of this kmod module.
631 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200632KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200633{
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200634 if (mod == NULL)
635 return NULL;
636
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200637 return mod->name;
638}
639
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200640/**
641 * kmod_module_get_path:
642 * @mod: kmod module
643 *
644 * Get the path of this kmod module. If this kmod module was not created by
645 * path, it can search the modules.dep index in order to find out the module
646 * under context's dirname (see kmod_get_dirname()).
647 *
648 * Returns: the path of this kmod module or NULL if such information is not
649 * available.
650 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200651KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200652{
Lucas De Marchie005fac2011-12-08 10:42:34 -0200653 char *line;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200654
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200655 if (mod == NULL)
656 return NULL;
657
Gustavo Sverzut Barbierid01c67e2011-12-11 19:42:02 -0200658 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200659
Lucas De Marchie005fac2011-12-08 10:42:34 -0200660 if (mod->path != NULL)
661 return mod->path;
662 if (mod->init.dep)
663 return NULL;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200664
Lucas De Marchie005fac2011-12-08 10:42:34 -0200665 /* lazy init */
666 line = kmod_search_moddep(mod->ctx, mod->name);
667 if (line == NULL)
668 return NULL;
669
670 kmod_module_parse_depline((struct kmod_module *) mod, line);
671 free(line);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200672
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200673 return mod->path;
674}
675
676
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200677extern long delete_module(const char *name, unsigned int flags);
678
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200679/**
680 * kmod_module_remove_module:
681 * @mod: kmod module
682 * @flags: flags to pass to Linux kernel when removing the module
683 *
684 * Remove a module from Linux kernel.
685 *
686 * Returns: 0 on success or < 0 on failure.
687 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200688KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
689 unsigned int flags)
690{
691 int err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200692
693 if (mod == NULL)
694 return -ENOENT;
695
696 /* Filter out other flags */
697 flags &= (KMOD_REMOVE_FORCE | KMOD_REMOVE_NOWAIT);
698
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200699 err = delete_module(mod->name, flags);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200700 if (err != 0) {
Lucas De Marchi63af0612011-12-14 12:07:37 -0200701 ERR(mod->ctx, "Could not remove '%s': %s\n", mod->name,
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200702 strerror(-err));
703 return err;
704 }
705
706 return 0;
707}
708
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200709extern long init_module(const void *mem, unsigned long len, const char *args);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200710
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200711/**
712 * kmod_module_insert_module:
713 * @mod: kmod module
Lucas De Marchi142db572011-12-20 23:39:30 -0200714 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
715 * behavior of this function.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200716 * @options: module's options to pass to Linux Kernel.
717 *
718 * Insert a module in Linux kernel. It opens the file pointed by @mod,
719 * mmap'ing it and passing to kernel.
720 *
721 * Returns: 0 on success or < 0 on failure.
722 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200723KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200724 unsigned int flags,
725 const char *options)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200726{
727 int err;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200728 const void *mem;
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200729 off_t size;
730 struct kmod_file *file;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200731 struct kmod_elf *elf = NULL;
732 const char *path;
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200733 const char *args = options ? options : "";
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200734
735 if (mod == NULL)
736 return -ENOENT;
737
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200738 path = kmod_module_get_path(mod);
739 if (path == NULL) {
Lucas De Marchif304afe2011-12-20 23:39:56 -0200740 ERR(mod->ctx, "Could not find module by name='%s'\n", mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200741 return -ENOSYS;
742 }
743
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200744 file = kmod_file_open(path);
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200745 if (file == NULL) {
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200746 err = -errno;
747 return err;
748 }
749
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200750 size = kmod_file_get_size(file);
751 mem = kmod_file_get_contents(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200752
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200753 if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
754 elf = kmod_elf_new(mem, size);
755 if (elf == NULL) {
756 err = -errno;
757 goto elf_failed;
758 }
759
760 if (flags & KMOD_INSERT_FORCE_MODVERSION) {
761 err = kmod_elf_strip_section(elf, "__versions");
762 if (err < 0)
763 INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
764 }
765
766 if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
767 err = kmod_elf_strip_vermagic(elf);
768 if (err < 0)
769 INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
770 }
771
772 mem = kmod_elf_get_memory(elf);
773 }
774
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200775 err = init_module(mem, size, args);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200776 if (err < 0)
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200777 ERR(mod->ctx, "Failed to insert module '%s'\n", path);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200778
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200779 if (elf != NULL)
780 kmod_elf_unref(elf);
781elf_failed:
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200782 kmod_file_unref(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200783
784 return err;
785}
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200786
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200787/**
788 * kmod_module_get_options:
789 * @mod: kmod module
790 *
791 * Get options of this kmod module. Options come from the configuration file
792 * and are cached in @mod. The first call to this function will search for
793 * this module in configuration and subsequent calls return the cached string.
794 *
795 * Returns: a string with all the options separated by spaces. This string is
796 * owned by @mod, do not free it.
797 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200798KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
799{
800 if (mod == NULL)
801 return NULL;
802
803 if (!mod->init.options) {
804 /* lazy init */
805 struct kmod_module *m = (struct kmod_module *)mod;
806 const struct kmod_list *l, *ctx_options;
807 char *opts = NULL;
808 size_t optslen = 0;
809
810 ctx_options = kmod_get_options(mod->ctx);
811
812 kmod_list_foreach(l, ctx_options) {
813 const char *modname = kmod_option_get_modname(l);
814 const char *str;
815 size_t len;
816 void *tmp;
817
Lucas De Marchi07b8c822011-12-13 14:21:24 -0200818 DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
819 if (!(streq(modname, mod->name) || (mod->alias != NULL &&
820 streq(modname, mod->alias))))
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200821 continue;
822
Lucas De Marchi07b8c822011-12-13 14:21:24 -0200823 DBG(mod->ctx, "passed = modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200824 str = kmod_option_get_options(l);
825 len = strlen(str);
826 if (len < 1)
827 continue;
828
829 tmp = realloc(opts, optslen + len + 2);
830 if (tmp == NULL) {
831 free(opts);
832 goto failed;
833 }
834
835 opts = tmp;
836
837 if (optslen > 0) {
838 opts[optslen] = ' ';
839 optslen++;
840 }
841
842 memcpy(opts + optslen, str, len);
843 optslen += len;
844 opts[optslen] = '\0';
845 }
846
847 m->init.options = true;
848 m->options = opts;
849 }
850
851 return mod->options;
852
853failed:
854 ERR(mod->ctx, "out of memory\n");
855 return NULL;
856}
857
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200858/**
859 * kmod_module_get_install_commands:
860 * @mod: kmod module
861 *
862 * Get install commands for this kmod module. Install commands come from the
863 * configuration file and are cached in @mod. The first call to this function
864 * will search for this module in configuration and subsequent calls return
865 * the cached string. The install commands are returned as they were in the
866 * configuration, concatenated by ';'. No other processing is made in this
867 * string.
868 *
869 * Returns: a string with all install commands separated by semicolons. This
870 * string is owned by @mod, do not free it.
871 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200872KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
873{
874 if (mod == NULL)
875 return NULL;
876
877 if (!mod->init.install_commands) {
878 /* lazy init */
879 struct kmod_module *m = (struct kmod_module *)mod;
880 const struct kmod_list *l, *ctx_install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200881
882 ctx_install_commands = kmod_get_install_commands(mod->ctx);
883
884 kmod_list_foreach(l, ctx_install_commands) {
885 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200886
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -0200887 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200888 continue;
889
Lucas De Marchi60f67602011-12-16 03:33:26 -0200890 m->install_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200891
Lucas De Marchi60f67602011-12-16 03:33:26 -0200892 /*
893 * find only the first command, as modprobe from
894 * module-init-tools does
895 */
896 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200897 }
898
899 m->init.install_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200900 }
901
902 return mod->install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200903}
904
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200905void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
906{
907 mod->init.install_commands = true;
908 mod->install_commands = cmd;
909}
910
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -0200911static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
912{
913 struct kmod_list *ret = NULL;
914 unsigned i;
915
916 for (i = 0; i < count; i++) {
917 const char *depname = array[i];
918 struct kmod_list *lst = NULL;
919 int err;
920
921 err = kmod_module_new_from_lookup(ctx, depname, &lst);
922 if (err < 0) {
923 ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
924 continue;
925 } else if (lst != NULL)
926 ret = kmod_list_append_list(ret, lst);
927 }
928 return ret;
929}
930
931/**
932 * kmod_module_get_softdeps:
933 * @mod: kmod module
934 * @pre: where to save the list of preceding soft dependencies.
935 * @post: where to save the list of post soft dependencies.
936 *
937 * Get soft dependencies for this kmod module. Soft dependencies come
938 * from configuration file and are cached in @mod. The first call
939 * to this function will search for this module in configuration and
940 * subsequent calls return the known results.
941 *
942 * Both @pre and @post are newly created list of kmod_module and
943 * should be unreferenced with kmod_module_unref_list().
944 *
945 * Returns: 0 on success or < 0 otherwise.
946 */
947KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod, struct kmod_list **pre, struct kmod_list **post)
948{
949 const struct kmod_list *l;
950 struct kmod_list *l_new;
951
952 if (mod == NULL || pre == NULL || post == NULL)
953 return -ENOENT;
954
955 assert(*pre == NULL);
956 assert(*post == NULL);
957
958 if (!mod->init.softdeps) {
959 /* lazy init */
960 struct kmod_module *m = (struct kmod_module *)mod;
961 const struct kmod_list *ctx_softdeps;
962
963 ctx_softdeps = kmod_get_softdeps(mod->ctx);
964
965 kmod_list_foreach(l, ctx_softdeps) {
966 const char *modname = kmod_softdep_get_name(l);
967 const char * const *array;
968 unsigned count;
969
970 if (fnmatch(modname, mod->name, 0) != 0)
971 continue;
972
973 array = kmod_softdep_get_pre(l, &count);
974 m->softdeps.pre = lookup_softdep(mod->ctx, array, count);
975 array = kmod_softdep_get_post(l, &count);
976 m->softdeps.post = lookup_softdep(mod->ctx, array, count);
977 /*
978 * find only the first command, as modprobe from
979 * module-init-tools does
980 */
981 break;
982 }
983
984 m->init.softdeps = true;
985 }
986
987 kmod_list_foreach(l, mod->softdeps.pre) {
988 l_new = kmod_list_append(*pre, kmod_module_ref(l->data));
989 if (l_new == NULL) {
990 kmod_module_unref(l->data);
991 goto fail;
992 }
993 *pre = l_new;
994 }
995
996 kmod_list_foreach(l, mod->softdeps.post) {
997 l_new = kmod_list_append(*post, kmod_module_ref(l->data));
998 if (l_new == NULL) {
999 kmod_module_unref(l->data);
1000 goto fail;
1001 }
1002 *post = l_new;
1003 }
1004
1005 return 0;
1006
1007fail:
1008 kmod_module_unref_list(*pre);
1009 *pre = NULL;
1010 kmod_module_unref_list(*post);
1011 *post = NULL;
1012 return -ENOMEM;
1013}
1014
1015
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001016/**
1017 * kmod_module_get_remove_commands:
1018 * @mod: kmod module
1019 *
1020 * Get remove commands for this kmod module. Remove commands come from the
1021 * configuration file and are cached in @mod. The first call to this function
1022 * will search for this module in configuration and subsequent calls return
1023 * the cached string. The remove commands are returned as they were in the
1024 * configuration, concatenated by ';'. No other processing is made in this
1025 * string.
1026 *
1027 * Returns: a string with all remove commands separated by semicolons. This
1028 * string is owned by @mod, do not free it.
1029 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001030KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
1031{
1032 if (mod == NULL)
1033 return NULL;
1034
1035 if (!mod->init.remove_commands) {
1036 /* lazy init */
1037 struct kmod_module *m = (struct kmod_module *)mod;
1038 const struct kmod_list *l, *ctx_remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001039
1040 ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
1041
1042 kmod_list_foreach(l, ctx_remove_commands) {
1043 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001044
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001045 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001046 continue;
1047
Lucas De Marchi60f67602011-12-16 03:33:26 -02001048 m->remove_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001049
Lucas De Marchi60f67602011-12-16 03:33:26 -02001050 /*
1051 * find only the first command, as modprobe from
1052 * module-init-tools does
1053 */
1054 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001055 }
1056
1057 m->init.remove_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001058 }
1059
1060 return mod->remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001061}
1062
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001063void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
1064{
1065 mod->init.remove_commands = true;
1066 mod->remove_commands = cmd;
1067}
1068
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001069/**
1070 * SECTION:libkmod-loaded
1071 * @short_description: currently loaded modules
1072 *
1073 * Information about currently loaded modules, as reported by Linux kernel.
1074 * These information are not cached by libkmod and are always read from /sys
1075 * and /proc/modules.
1076 */
1077
1078/**
1079 * kmod_module_new_from_loaded:
1080 * @ctx: kmod library context
1081 * @list: where to save the list of loaded modules
1082 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001083 * Create a new list of kmod modules with all modules currently loaded in
1084 * kernel. It uses /proc/modules to get the names of loaded modules and to
1085 * create kmod modules by calling kmod_module_new_from_name() in each of them.
1086 * They are put are put in @list in no particular order.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001087 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001088 * The initial refcount is 1, and needs to be decremented to release the
1089 * resources of the kmod_module. The returned @list must be released by
1090 * calling kmod_module_unref_list(). Since libkmod keeps track of all
1091 * kmod_modules created, they are all released upon @ctx destruction too. Do
1092 * not unref @ctx before all the desired operations with the returned list are
1093 * completed.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001094 *
1095 * Returns: 0 on success or < 0 on error.
1096 */
1097KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
1098 struct kmod_list **list)
1099{
1100 struct kmod_list *l = NULL;
1101 FILE *fp;
1102 char line[4096];
1103
1104 if (ctx == NULL || list == NULL)
1105 return -ENOENT;
1106
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001107 fp = fopen("/proc/modules", "re");
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001108 if (fp == NULL) {
1109 int err = -errno;
1110 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
1111 return err;
1112 }
1113
1114 while (fgets(line, sizeof(line), fp)) {
1115 struct kmod_module *m;
1116 struct kmod_list *node;
1117 int err;
1118 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
1119
1120 err = kmod_module_new_from_name(ctx, name, &m);
1121 if (err < 0) {
1122 ERR(ctx, "could not get module from name '%s': %s\n",
1123 name, strerror(-err));
1124 continue;
1125 }
1126
1127 node = kmod_list_append(l, m);
1128 if (node)
1129 l = node;
1130 else {
1131 ERR(ctx, "out of memory\n");
1132 kmod_module_unref(m);
1133 }
1134 }
1135
1136 fclose(fp);
1137 *list = l;
1138
1139 return 0;
1140}
1141
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001142/**
1143 * kmod_module_initstate_str:
1144 * @state: the state as returned by kmod_module_get_initstate()
1145 *
1146 * Translate a initstate to a string.
1147 *
1148 * Returns: the string associated to the @state. This string is statically
1149 * allocated, do not free it.
1150 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001151KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
1152{
1153 switch (state) {
1154 case KMOD_MODULE_BUILTIN:
1155 return "builtin";
1156 case KMOD_MODULE_LIVE:
1157 return "live";
1158 case KMOD_MODULE_COMING:
1159 return "coming";
1160 case KMOD_MODULE_GOING:
1161 return "going";
1162 default:
1163 return NULL;
1164 }
1165}
1166
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001167/**
1168 * kmod_module_get_initstate:
1169 * @mod: kmod module
1170 *
1171 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
1172 * /sys filesystem.
1173 *
1174 * Returns: < 0 on error or enum kmod_initstate if module is found in kernel.
1175 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001176KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
1177{
1178 char path[PATH_MAX], buf[32];
1179 int fd, err, pathlen;
1180
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001181 if (mod == NULL)
1182 return -ENOENT;
1183
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001184 pathlen = snprintf(path, sizeof(path),
1185 "/sys/module/%s/initstate", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001186 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001187 if (fd < 0) {
1188 err = -errno;
1189
1190 if (pathlen > (int)sizeof("/initstate") - 1) {
1191 struct stat st;
1192 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
1193 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
1194 return KMOD_MODULE_BUILTIN;
1195 }
1196
Gustavo Sverzut Barbieri926f67a2011-12-11 19:33:03 -02001197 DBG(mod->ctx, "could not open '%s': %s\n",
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001198 path, strerror(-err));
1199 return err;
1200 }
1201
1202 err = read_str_safe(fd, buf, sizeof(buf));
1203 close(fd);
1204 if (err < 0) {
1205 ERR(mod->ctx, "could not read from '%s': %s\n",
1206 path, strerror(-err));
1207 return err;
1208 }
1209
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001210 if (streq(buf, "live\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001211 return KMOD_MODULE_LIVE;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001212 else if (streq(buf, "coming\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001213 return KMOD_MODULE_COMING;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001214 else if (streq(buf, "going\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001215 return KMOD_MODULE_GOING;
1216
1217 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
1218 return -EINVAL;
1219}
1220
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001221/**
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001222 * kmod_module_get_size:
1223 * @mod: kmod module
1224 *
1225 * Get the size of this kmod module as returned by Linux kernel. It reads the
1226 * file /proc/modules to search for this module and get its size.
1227 *
1228 * Returns: the size of this kmod module.
1229 */
1230KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
1231{
1232 // FIXME TODO: this should be available from /sys/module/foo
1233 FILE *fp;
1234 char line[4096];
1235 int lineno = 0;
1236 long size = -ENOENT;
1237
1238 if (mod == NULL)
1239 return -ENOENT;
1240
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001241 fp = fopen("/proc/modules", "re");
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001242 if (fp == NULL) {
1243 int err = -errno;
1244 ERR(mod->ctx,
1245 "could not open /proc/modules: %s\n", strerror(errno));
1246 return err;
1247 }
1248
1249 while (fgets(line, sizeof(line), fp)) {
1250 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
1251 long value;
1252
1253 lineno++;
1254 if (tok == NULL || !streq(tok, mod->name))
1255 continue;
1256
1257 tok = strtok_r(NULL, " \t", &saveptr);
1258 if (tok == NULL) {
1259 ERR(mod->ctx,
1260 "invalid line format at /proc/modules:%d\n", lineno);
1261 break;
1262 }
1263
1264 value = strtol(tok, &endptr, 10);
1265 if (endptr == tok || *endptr != '\0') {
1266 ERR(mod->ctx,
1267 "invalid line format at /proc/modules:%d\n", lineno);
1268 break;
1269 }
1270
1271 size = value;
1272 break;
1273 }
1274 fclose(fp);
1275 return size;
1276}
1277
1278/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001279 * kmod_module_get_refcnt:
1280 * @mod: kmod module
1281 *
1282 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
1283 * /sys filesystem.
1284 *
1285 * Returns: 0 on success or < 0 on failure.
1286 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001287KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
1288{
1289 char path[PATH_MAX];
1290 long refcnt;
1291 int fd, err;
1292
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001293 if (mod == NULL)
1294 return -ENOENT;
1295
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001296 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001297 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001298 if (fd < 0) {
1299 err = -errno;
1300 ERR(mod->ctx, "could not open '%s': %s\n",
1301 path, strerror(errno));
1302 return err;
1303 }
1304
1305 err = read_str_long(fd, &refcnt, 10);
1306 close(fd);
1307 if (err < 0) {
1308 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
1309 path, strerror(-err));
1310 return err;
1311 }
1312
1313 return (int)refcnt;
1314}
1315
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001316/**
1317 * kmod_module_get_holders:
1318 * @mod: kmod module
1319 *
1320 * Get a list of kmod modules that are holding this @mod, as returned by Linux
1321 * Kernel. After use, free the @list by calling kmod_module_unref_list().
1322 *
1323 * Returns: a new list of kmod modules on success or NULL on failure.
1324 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001325KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
1326{
1327 char dname[PATH_MAX];
1328 struct kmod_list *list = NULL;
1329 DIR *d;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001330
1331 if (mod == NULL)
1332 return NULL;
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001333
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001334 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
1335
1336 d = opendir(dname);
1337 if (d == NULL) {
1338 ERR(mod->ctx, "could not open '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001339 dname, strerror(errno));
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001340 return NULL;
1341 }
1342
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001343 for (;;) {
1344 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001345 struct kmod_module *holder;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001346 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001347 int err;
1348
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001349 err = readdir_r(d, &de, &entp);
1350 if (err != 0) {
1351 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1352 mod->name, strerror(-err));
1353 goto fail;
1354 }
1355
1356 if (entp == NULL)
1357 break;
1358
1359 if (de.d_name[0] == '.') {
1360 if (de.d_name[1] == '\0' ||
1361 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001362 continue;
1363 }
1364
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001365 err = kmod_module_new_from_name(mod->ctx, de.d_name, &holder);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001366 if (err < 0) {
1367 ERR(mod->ctx, "could not create module for '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001368 de.d_name, strerror(-err));
1369 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001370 }
1371
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001372 l = kmod_list_append(list, holder);
1373 if (l != NULL) {
1374 list = l;
1375 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001376 ERR(mod->ctx, "out of memory\n");
1377 kmod_module_unref(holder);
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001378 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001379 }
1380 }
1381
1382 closedir(d);
1383 return list;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001384
1385fail:
1386 closedir(d);
1387 kmod_module_unref_list(list);
1388 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001389}
1390
1391struct kmod_module_section {
1392 unsigned long address;
1393 char name[];
1394};
1395
1396static void kmod_module_section_free(struct kmod_module_section *section)
1397{
1398 free(section);
1399}
1400
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001401/**
1402 * kmod_module_get_sections:
1403 * @mod: kmod module
1404 *
1405 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
1406 * structure contained in this list is internal to libkmod and their fields
1407 * can be obtained by calling kmod_module_section_get_name() and
1408 * kmod_module_section_get_address().
1409 *
1410 * After use, free the @list by calling kmod_module_section_free_list().
1411 *
1412 * Returns: a new list of kmod module sections on success or NULL on failure.
1413 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001414KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1415{
1416 char dname[PATH_MAX];
1417 struct kmod_list *list = NULL;
1418 DIR *d;
1419 int dfd;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001420
1421 if (mod == NULL)
1422 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001423
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001424 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1425
1426 d = opendir(dname);
1427 if (d == NULL) {
1428 ERR(mod->ctx, "could not open '%s': %s\n",
1429 dname, strerror(errno));
1430 return NULL;
1431 }
1432
1433 dfd = dirfd(d);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001434
1435 for (;;) {
1436 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001437 struct kmod_module_section *section;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001438 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001439 unsigned long address;
1440 size_t namesz;
1441 int fd, err;
1442
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001443 err = readdir_r(d, &de, &entp);
1444 if (err != 0) {
1445 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1446 mod->name, strerror(-err));
1447 goto fail;
1448 }
1449
1450 if (de.d_name[0] == '.') {
1451 if (de.d_name[1] == '\0' ||
1452 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001453 continue;
1454 }
1455
Cristian Rodríguez8e3e5832011-12-16 14:46:52 -03001456 fd = openat(dfd, de.d_name, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001457 if (fd < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001458 ERR(mod->ctx, "could not open '%s/%s': %m\n",
1459 dname, de.d_name);
1460 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001461 }
1462
1463 err = read_str_ulong(fd, &address, 16);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001464 close(fd);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001465 if (err < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001466 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
1467 dname, de.d_name);
1468 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001469 }
1470
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001471 namesz = strlen(de.d_name) + 1;
1472 section = malloc(sizeof(*section) + namesz);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001473
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001474 if (section == NULL) {
1475 ERR(mod->ctx, "out of memory\n");
1476 goto fail;
1477 }
1478
1479 section->address = address;
1480 memcpy(section->name, de.d_name, namesz);
1481
1482 l = kmod_list_append(list, section);
1483 if (l != NULL) {
1484 list = l;
1485 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001486 ERR(mod->ctx, "out of memory\n");
1487 free(section);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001488 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001489 }
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001490 }
1491
1492 closedir(d);
1493 return list;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001494
1495fail:
1496 closedir(d);
1497 kmod_module_unref_list(list);
1498 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001499}
1500
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001501/**
1502 * kmod_module_section_get_module_name:
1503 * @entry: a list entry representing a kmod module section
1504 *
1505 * Get the name of a kmod module section.
1506 *
1507 * After use, free the @list by calling kmod_module_section_free_list().
1508 *
1509 * Returns: the name of this kmod module section on success or NULL on
1510 * failure. The string is owned by the section, do not free it.
1511 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001512KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
1513{
1514 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001515
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001516 if (entry == NULL)
1517 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001518
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001519 section = entry->data;
1520 return section->name;
1521}
1522
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001523/**
1524 * kmod_module_section_get_address:
1525 * @entry: a list entry representing a kmod module section
1526 *
1527 * Get the address of a kmod module section.
1528 *
1529 * After use, free the @list by calling kmod_module_section_free_list().
1530 *
1531 * Returns: the address of this kmod module section on success or ULONG_MAX
1532 * on failure.
1533 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001534KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
1535{
1536 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001537
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001538 if (entry == NULL)
1539 return (unsigned long)-1;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001540
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001541 section = entry->data;
1542 return section->address;
1543}
1544
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001545/**
1546 * kmod_module_section_free_list:
1547 * @list: kmod module section list
1548 *
1549 * Release the resources taken by @list
1550 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001551KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
1552{
1553 while (list) {
1554 kmod_module_section_free(list->data);
1555 list = kmod_list_remove(list);
1556 }
1557}
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001558
1559struct kmod_module_info {
1560 char *key;
1561 char value[];
1562};
1563
1564static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
1565{
1566 struct kmod_module_info *info;
1567
1568 info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
1569 if (info == NULL)
1570 return NULL;
1571
1572 info->key = (char *)info + sizeof(struct kmod_module_info)
1573 + valuelen + 1;
1574 memcpy(info->key, key, keylen);
1575 info->key[keylen] = '\0';
1576 memcpy(info->value, value, valuelen);
1577 info->value[valuelen] = '\0';
1578 return info;
1579}
1580
1581static void kmod_module_info_free(struct kmod_module_info *info)
1582{
1583 free(info);
1584}
1585
1586/**
1587 * kmod_module_get_info:
1588 * @mod: kmod module
1589 * @list: where to return list of module information. Use
1590 * kmod_module_info_get_key() and
1591 * kmod_module_info_get_value(). Release this list with
1592 * kmod_module_info_unref_list()
1593 *
1594 * Get a list of entries in ELF section ".modinfo", these contain
1595 * alias, license, depends, vermagic and other keys with respective
1596 * values.
1597 *
1598 * After use, free the @list by calling kmod_module_info_free_list().
1599 *
1600 * Returns: 0 on success or < 0 otherwise.
1601 */
1602KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
1603{
1604 struct kmod_file *file;
1605 struct kmod_elf *elf;
1606 const char *path;
1607 const void *mem;
1608 char **strings;
1609 size_t size;
1610 int i, count, ret = 0;
1611
1612 if (mod == NULL || list == NULL)
1613 return -ENOENT;
1614
1615 assert(*list == NULL);
1616
1617 path = kmod_module_get_path(mod);
1618 if (path == NULL)
1619 return -ENOENT;
1620
1621 file = kmod_file_open(path);
1622 if (file == NULL)
1623 return -errno;
1624
1625 size = kmod_file_get_size(file);
1626 mem = kmod_file_get_contents(file);
1627
1628 elf = kmod_elf_new(mem, size);
1629 if (elf == NULL) {
1630 ret = -errno;
1631 goto elf_open_error;
1632 }
1633
1634 count = kmod_elf_get_strings(elf, ".modinfo", &strings);
1635 if (count < 0) {
1636 ret = count;
1637 goto get_strings_error;
1638 }
1639
1640 for (i = 0; i < count; i++) {
1641 struct kmod_module_info *info;
1642 struct kmod_list *n;
1643 const char *key, *value;
1644 size_t keylen, valuelen;
1645
1646 key = strings[i];
1647 value = strchr(key, '=');
1648 if (value == NULL) {
1649 keylen = strlen(key);
1650 valuelen = 0;
1651 } else {
1652 keylen = value - key;
1653 value++;
1654 valuelen = strlen(value);
1655 }
1656
1657 info = kmod_module_info_new(key, keylen, value, valuelen);
1658 if (info == NULL) {
1659 ret = -errno;
1660 kmod_module_info_free_list(*list);
1661 *list = NULL;
1662 goto list_error;
1663 }
1664
1665 n = kmod_list_append(*list, info);
1666 if (n != NULL)
1667 *list = n;
1668 else {
1669 kmod_module_info_free(info);
1670 kmod_module_info_free_list(*list);
1671 *list = NULL;
1672 ret = -ENOMEM;
1673 goto list_error;
1674 }
1675 }
1676 ret = count;
1677
1678list_error:
1679 free(strings);
1680get_strings_error:
1681 kmod_elf_unref(elf);
1682elf_open_error:
1683 kmod_file_unref(file);
1684
1685 return ret;
1686}
1687
1688/**
1689 * kmod_module_info_get_key:
1690 * @entry: a list entry representing a kmod module info
1691 *
1692 * Get the key of a kmod module info.
1693 *
1694 * Returns: the key of this kmod module info on success or NULL on
1695 * failure. The string is owned by the info, do not free it.
1696 */
1697KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
1698{
1699 struct kmod_module_info *info;
1700
1701 if (entry == NULL)
1702 return NULL;
1703
1704 info = entry->data;
1705 return info->key;
1706}
1707
1708/**
1709 * kmod_module_info_get_value:
1710 * @entry: a list entry representing a kmod module info
1711 *
1712 * Get the value of a kmod module info.
1713 *
1714 * Returns: the value of this kmod module info on success or NULL on
1715 * failure. The string is owned by the info, do not free it.
1716 */
1717KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
1718{
1719 struct kmod_module_info *info;
1720
1721 if (entry == NULL)
1722 return NULL;
1723
1724 info = entry->data;
1725 return info->value;
1726}
1727
1728/**
1729 * kmod_module_info_free_list:
1730 * @list: kmod module info list
1731 *
1732 * Release the resources taken by @list
1733 */
1734KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
1735{
1736 while (list) {
1737 kmod_module_info_free(list->data);
1738 list = kmod_list_remove(list);
1739 }
1740}
1741
1742struct kmod_module_version {
1743 uint64_t crc;
1744 char symbol[];
1745};
1746
1747static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
1748{
1749 struct kmod_module_version *mv;
1750 size_t symbollen = strlen(symbol) + 1;
1751
1752 mv = malloc(sizeof(struct kmod_module_version) + symbollen);
1753 if (mv == NULL)
1754 return NULL;
1755
1756 mv->crc = crc;
1757 memcpy(mv->symbol, symbol, symbollen);
1758 return mv;
1759}
1760
1761static void kmod_module_version_free(struct kmod_module_version *version)
1762{
1763 free(version);
1764}
1765
1766/**
1767 * kmod_module_get_versions:
1768 * @mod: kmod module
1769 * @list: where to return list of module versions. Use
1770 * kmod_module_versions_get_symbol() and
1771 * kmod_module_versions_get_crc(). Release this list with
1772 * kmod_module_versions_unref_list()
1773 *
1774 * Get a list of entries in ELF section "__versions".
1775 *
1776 * After use, free the @list by calling kmod_module_versions_free_list().
1777 *
1778 * Returns: 0 on success or < 0 otherwise.
1779 */
1780KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
1781{
1782 struct kmod_file *file;
1783 struct kmod_elf *elf;
1784 const char *path;
1785 const void *mem;
1786 struct kmod_modversion *versions;
1787 size_t size;
1788 int i, count, ret = 0;
1789
1790 if (mod == NULL || list == NULL)
1791 return -ENOENT;
1792
1793 assert(*list == NULL);
1794
1795 path = kmod_module_get_path(mod);
1796 if (path == NULL)
1797 return -ENOENT;
1798
1799 file = kmod_file_open(path);
1800 if (file == NULL)
1801 return -errno;
1802
1803 size = kmod_file_get_size(file);
1804 mem = kmod_file_get_contents(file);
1805
1806 elf = kmod_elf_new(mem, size);
1807 if (elf == NULL) {
1808 ret = -errno;
1809 goto elf_open_error;
1810 }
1811
1812 count = kmod_elf_get_modversions(elf, &versions);
1813 if (count < 0) {
1814 ret = count;
1815 goto get_strings_error;
1816 }
1817
1818 for (i = 0; i < count; i++) {
1819 struct kmod_module_version *mv;
1820 struct kmod_list *n;
1821
1822 mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
1823 if (mv == NULL) {
1824 ret = -errno;
1825 kmod_module_versions_free_list(*list);
1826 *list = NULL;
1827 goto list_error;
1828 }
1829
1830 n = kmod_list_append(*list, mv);
1831 if (n != NULL)
1832 *list = n;
1833 else {
1834 kmod_module_version_free(mv);
1835 kmod_module_versions_free_list(*list);
1836 *list = NULL;
1837 ret = -ENOMEM;
1838 goto list_error;
1839 }
1840 }
1841 ret = count;
1842
1843list_error:
1844 free(versions);
1845get_strings_error:
1846 kmod_elf_unref(elf);
1847elf_open_error:
1848 kmod_file_unref(file);
1849
1850 return ret;
1851}
1852
1853/**
1854 * kmod_module_versions_get_symbol:
1855 * @entry: a list entry representing a kmod module versions
1856 *
1857 * Get the symbol of a kmod module versions.
1858 *
1859 * Returns: the symbol of this kmod module versions on success or NULL
1860 * on failure. The string is owned by the versions, do not free it.
1861 */
1862KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
1863{
1864 struct kmod_module_version *version;
1865
1866 if (entry == NULL)
1867 return NULL;
1868
1869 version = entry->data;
1870 return version->symbol;
1871}
1872
1873/**
1874 * kmod_module_version_get_crc:
1875 * @entry: a list entry representing a kmod module version
1876 *
1877 * Get the crc of a kmod module version.
1878 *
1879 * Returns: the crc of this kmod module version on success or NULL on
1880 * failure. The string is owned by the version, do not free it.
1881 */
1882KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
1883{
1884 struct kmod_module_version *version;
1885
1886 if (entry == NULL)
1887 return 0;
1888
1889 version = entry->data;
1890 return version->crc;
1891}
1892
1893/**
1894 * kmod_module_versions_free_list:
1895 * @list: kmod module versions list
1896 *
1897 * Release the resources taken by @list
1898 */
1899KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
1900{
1901 while (list) {
1902 kmod_module_version_free(list->data);
1903 list = kmod_list_remove(list);
1904 }
1905}
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02001906
1907struct kmod_module_symbol {
1908 uint64_t crc;
1909 char symbol[];
1910};
1911
1912static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
1913{
1914 struct kmod_module_symbol *mv;
1915 size_t symbollen = strlen(symbol) + 1;
1916
1917 mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
1918 if (mv == NULL)
1919 return NULL;
1920
1921 mv->crc = crc;
1922 memcpy(mv->symbol, symbol, symbollen);
1923 return mv;
1924}
1925
1926static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
1927{
1928 free(symbol);
1929}
1930
1931/**
1932 * kmod_module_get_symbols:
1933 * @mod: kmod module
1934 * @list: where to return list of module symbols. Use
1935 * kmod_module_symbols_get_symbol() and
1936 * kmod_module_symbols_get_crc(). Release this list with
1937 * kmod_module_symbols_unref_list()
1938 *
1939 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
1940 *
1941 * After use, free the @list by calling kmod_module_symbols_free_list().
1942 *
1943 * Returns: 0 on success or < 0 otherwise.
1944 */
1945KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
1946{
1947 struct kmod_file *file;
1948 struct kmod_elf *elf;
1949 const char *path;
1950 const void *mem;
1951 struct kmod_modversion *symbols;
1952 size_t size;
1953 int i, count, ret = 0;
1954
1955 if (mod == NULL || list == NULL)
1956 return -ENOENT;
1957
1958 assert(*list == NULL);
1959
1960 path = kmod_module_get_path(mod);
1961 if (path == NULL)
1962 return -ENOENT;
1963
1964 file = kmod_file_open(path);
1965 if (file == NULL)
1966 return -errno;
1967
1968 size = kmod_file_get_size(file);
1969 mem = kmod_file_get_contents(file);
1970
1971 elf = kmod_elf_new(mem, size);
1972 if (elf == NULL) {
1973 ret = -errno;
1974 goto elf_open_error;
1975 }
1976
1977 count = kmod_elf_get_symbols(elf, &symbols);
1978 if (count < 0) {
1979 ret = count;
1980 goto get_strings_error;
1981 }
1982
1983 for (i = 0; i < count; i++) {
1984 struct kmod_module_symbol *mv;
1985 struct kmod_list *n;
1986
1987 mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
1988 if (mv == NULL) {
1989 ret = -errno;
1990 kmod_module_symbols_free_list(*list);
1991 *list = NULL;
1992 goto list_error;
1993 }
1994
1995 n = kmod_list_append(*list, mv);
1996 if (n != NULL)
1997 *list = n;
1998 else {
1999 kmod_module_symbol_free(mv);
2000 kmod_module_symbols_free_list(*list);
2001 *list = NULL;
2002 ret = -ENOMEM;
2003 goto list_error;
2004 }
2005 }
2006 ret = count;
2007
2008list_error:
2009 free(symbols);
2010get_strings_error:
2011 kmod_elf_unref(elf);
2012elf_open_error:
2013 kmod_file_unref(file);
2014
2015 return ret;
2016}
2017
2018/**
2019 * kmod_module_symbols_get_symbol:
2020 * @entry: a list entry representing a kmod module symbols
2021 *
2022 * Get the symbol of a kmod module symbols.
2023 *
2024 * Returns: the symbol of this kmod module symbols on success or NULL
2025 * on failure. The string is owned by the symbols, do not free it.
2026 */
2027KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
2028{
2029 struct kmod_module_symbol *symbol;
2030
2031 if (entry == NULL)
2032 return NULL;
2033
2034 symbol = entry->data;
2035 return symbol->symbol;
2036}
2037
2038/**
2039 * kmod_module_symbol_get_crc:
2040 * @entry: a list entry representing a kmod module symbol
2041 *
2042 * Get the crc of a kmod module symbol.
2043 *
2044 * Returns: the crc of this kmod module symbol on success or NULL on
2045 * failure. The string is owned by the symbol, do not free it.
2046 */
2047KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
2048{
2049 struct kmod_module_symbol *symbol;
2050
2051 if (entry == NULL)
2052 return 0;
2053
2054 symbol = entry->data;
2055 return symbol->crc;
2056}
2057
2058/**
2059 * kmod_module_symbols_free_list:
2060 * @list: kmod module symbols list
2061 *
2062 * Release the resources taken by @list
2063 */
2064KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
2065{
2066 while (list) {
2067 kmod_module_symbol_free(list->data);
2068 list = kmod_list_remove(list);
2069 }
2070}
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002071
2072struct kmod_module_dependency_symbol {
2073 uint64_t crc;
2074 uint8_t bind;
2075 char symbol[];
2076};
2077
2078static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
2079{
2080 struct kmod_module_dependency_symbol *mv;
2081 size_t symbollen = strlen(symbol) + 1;
2082
2083 mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
2084 if (mv == NULL)
2085 return NULL;
2086
2087 mv->crc = crc;
2088 mv->bind = bind;
2089 memcpy(mv->symbol, symbol, symbollen);
2090 return mv;
2091}
2092
2093static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
2094{
2095 free(dependency_symbol);
2096}
2097
2098/**
2099 * kmod_module_get_dependency_symbols:
2100 * @mod: kmod module
2101 * @list: where to return list of module dependency_symbols. Use
2102 * kmod_module_dependency_symbol_get_symbol() and
2103 * kmod_module_dependency_symbol_get_crc(). Release this list with
2104 * kmod_module_dependency_symbols_free_list()
2105 *
2106 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2107 *
2108 * After use, free the @list by calling
2109 * kmod_module_dependency_symbols_free_list().
2110 *
2111 * Returns: 0 on success or < 0 otherwise.
2112 */
2113KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
2114{
2115 struct kmod_file *file;
2116 struct kmod_elf *elf;
2117 const char *path;
2118 const void *mem;
2119 struct kmod_modversion *symbols;
2120 size_t size;
2121 int i, count, ret = 0;
2122
2123 if (mod == NULL || list == NULL)
2124 return -ENOENT;
2125
2126 assert(*list == NULL);
2127
2128 path = kmod_module_get_path(mod);
2129 if (path == NULL)
2130 return -ENOENT;
2131
2132 file = kmod_file_open(path);
2133 if (file == NULL)
2134 return -errno;
2135
2136 size = kmod_file_get_size(file);
2137 mem = kmod_file_get_contents(file);
2138
2139 elf = kmod_elf_new(mem, size);
2140 if (elf == NULL) {
2141 ret = -errno;
2142 goto elf_open_error;
2143 }
2144
2145 count = kmod_elf_get_dependency_symbols(elf, &symbols);
2146 if (count < 0) {
2147 ret = count;
2148 goto get_strings_error;
2149 }
2150
2151 for (i = 0; i < count; i++) {
2152 struct kmod_module_dependency_symbol *mv;
2153 struct kmod_list *n;
2154
2155 mv = kmod_module_dependency_symbols_new(symbols[i].crc,
2156 symbols[i].bind,
2157 symbols[i].symbol);
2158 if (mv == NULL) {
2159 ret = -errno;
2160 kmod_module_dependency_symbols_free_list(*list);
2161 *list = NULL;
2162 goto list_error;
2163 }
2164
2165 n = kmod_list_append(*list, mv);
2166 if (n != NULL)
2167 *list = n;
2168 else {
2169 kmod_module_dependency_symbol_free(mv);
2170 kmod_module_dependency_symbols_free_list(*list);
2171 *list = NULL;
2172 ret = -ENOMEM;
2173 goto list_error;
2174 }
2175 }
2176 ret = count;
2177
2178list_error:
2179 free(symbols);
2180get_strings_error:
2181 kmod_elf_unref(elf);
2182elf_open_error:
2183 kmod_file_unref(file);
2184
2185 return ret;
2186}
2187
2188/**
2189 * kmod_module_dependency_symbol_get_symbol:
2190 * @entry: a list entry representing a kmod module dependency_symbols
2191 *
2192 * Get the dependency symbol of a kmod module
2193 *
2194 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
2195 * on failure. The string is owned by the dependency_symbols, do not free it.
2196 */
2197KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
2198{
2199 struct kmod_module_dependency_symbol *dependency_symbol;
2200
2201 if (entry == NULL)
2202 return NULL;
2203
2204 dependency_symbol = entry->data;
2205 return dependency_symbol->symbol;
2206}
2207
2208/**
2209 * kmod_module_dependency_symbol_get_crc:
2210 * @entry: a list entry representing a kmod module dependency_symbol
2211 *
2212 * Get the crc of a kmod module dependency_symbol.
2213 *
2214 * Returns: the crc of this kmod module dependency_symbol on success or NULL on
2215 * failure. The string is owned by the dependency_symbol, do not free it.
2216 */
2217KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
2218{
2219 struct kmod_module_dependency_symbol *dependency_symbol;
2220
2221 if (entry == NULL)
2222 return 0;
2223
2224 dependency_symbol = entry->data;
2225 return dependency_symbol->crc;
2226}
2227
2228/**
2229 * kmod_module_dependency_symbol_get_bind:
2230 * @entry: a list entry representing a kmod module dependency_symbol
2231 *
2232 * Get the bind type of a kmod module dependency_symbol.
2233 *
2234 * Returns: the bind of this kmod module dependency_symbol on success
2235 * or < 0 on failure.
2236 */
2237KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
2238{
2239 struct kmod_module_dependency_symbol *dependency_symbol;
2240
2241 if (entry == NULL)
2242 return 0;
2243
2244 dependency_symbol = entry->data;
2245 return dependency_symbol->bind;
2246}
2247
2248/**
2249 * kmod_module_dependency_symbols_free_list:
2250 * @list: kmod module dependency_symbols list
2251 *
2252 * Release the resources taken by @list
2253 */
2254KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
2255{
2256 while (list) {
2257 kmod_module_dependency_symbol_free(list->data);
2258 list = kmod_list_remove(list);
2259 }
2260}