blob: 880bac5f0ae6af173e366ae07340e048abe0acf4 [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 */
Lucas De Marchi6ad5f262011-12-13 14:12:50 -020056 char *alias; /* only set if this module was created from an alias */
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -020057 int n_dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020058 int refcount;
Lucas De Marchi7636e722011-12-01 17:56:03 -020059 struct {
60 bool dep : 1;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020061 bool options : 1;
62 bool install_commands : 1;
63 bool remove_commands : 1;
Lucas De Marchi7636e722011-12-01 17:56:03 -020064 } init;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020065};
66
Lucas De Marchic35347f2011-12-12 10:48:02 -020067static inline const char *path_join(const char *path, size_t prefixlen,
68 char buf[PATH_MAX])
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -020069{
70 size_t pathlen;
71
72 if (path[0] == '/')
73 return path;
74
75 pathlen = strlen(path);
76 if (prefixlen + pathlen + 1 >= PATH_MAX)
77 return NULL;
78
79 memcpy(buf + prefixlen, path, pathlen + 1);
80 return buf;
81}
82
Lucas De Marchi671d4892011-12-05 20:23:05 -020083int kmod_module_parse_depline(struct kmod_module *mod, char *line)
Lucas De Marchi7636e722011-12-01 17:56:03 -020084{
85 struct kmod_ctx *ctx = mod->ctx;
86 struct kmod_list *list = NULL;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -020087 const char *dirname;
88 char buf[PATH_MAX];
Lucas De Marchi7636e722011-12-01 17:56:03 -020089 char *p, *saveptr;
Lucas De Marchi45f27782011-12-12 17:23:04 -020090 int err = 0, n = 0;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -020091 size_t dirnamelen;
Lucas De Marchi7636e722011-12-01 17:56:03 -020092
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -020093 if (mod->init.dep)
94 return mod->n_dep;
95 assert(mod->dep == NULL);
Lucas De Marchi7636e722011-12-01 17:56:03 -020096 mod->init.dep = true;
97
98 p = strchr(line, ':');
99 if (p == NULL)
100 return 0;
101
Lucas De Marchi671d4892011-12-05 20:23:05 -0200102 *p = '\0';
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200103 dirname = kmod_get_dirname(mod->ctx);
104 dirnamelen = strlen(dirname);
105 if (dirnamelen + 2 >= PATH_MAX)
106 return 0;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200107
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200108 memcpy(buf, dirname, dirnamelen);
109 buf[dirnamelen] = '/';
110 dirnamelen++;
111 buf[dirnamelen] = '\0';
112
113 if (mod->path == NULL) {
114 const char *str = path_join(line, dirnamelen, buf);
115 if (str == NULL)
116 return 0;
117 mod->path = strdup(str);
118 if (mod->path == NULL)
119 return 0;
120 }
Lucas De Marchi671d4892011-12-05 20:23:05 -0200121
Lucas De Marchi7636e722011-12-01 17:56:03 -0200122 p++;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200123 for (p = strtok_r(p, " \t", &saveptr); p != NULL;
124 p = strtok_r(NULL, " \t", &saveptr)) {
Lucas De Marchi1fc1c9a2011-12-02 10:00:03 -0200125 struct kmod_module *depmod;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200126 const char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200127
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200128 path = path_join(p, dirnamelen, buf);
129 if (path == NULL) {
130 ERR(ctx, "could not join path '%s' and '%s'.\n",
131 dirname, p);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200132 goto fail;
133 }
134
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200135 err = kmod_module_new_from_path(ctx, path, &depmod);
136 if (err < 0) {
137 ERR(ctx, "ctx=%p path=%s error=%s\n",
138 ctx, path, strerror(-err));
139 goto fail;
140 }
141
142 DBG(ctx, "add dep: %s\n", path);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200143
Lucas De Marchib94a7372011-12-26 20:10:49 -0200144 list = kmod_list_prepend(list, depmod);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200145 n++;
146 }
147
148 DBG(ctx, "%d dependencies for %s\n", n, mod->name);
149
150 mod->dep = list;
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200151 mod->n_dep = n;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200152 return n;
153
154fail:
155 kmod_module_unref_list(list);
156 mod->init.dep = false;
157 return err;
158}
159
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200160/**
161 * kmod_module_new_from_name:
162 * @ctx: kmod library context
163 * @name: name of the module
164 * @mod: where to save the created struct kmod_module
165 *
166 * Create a new struct kmod_module using the module name. @name can not be an
167 * alias, file name or anything else; it must be a module name. There's no
168 * check if the module does exists in the system.
169 *
170 * This function is also used internally by many others that return a new
171 * struct kmod_module or a new list of modules.
172 *
173 * The initial refcount is 1, and needs to be decremented to release the
174 * resources of the kmod_module. Since libkmod keeps track of all
175 * kmod_modules created, they are all released upon @ctx destruction too. Do
176 * not unref @ctx before all the desired operations with the returned
177 * kmod_module are done.
178 *
179 * Returns: 0 on success or < 0 otherwise. It fails if name is not a valid
180 * module name or if memory allocation failed.
181 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200182KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
183 const char *name,
184 struct kmod_module **mod)
185{
186 struct kmod_module *m;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200187 size_t namelen;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200188 char name_norm[PATH_MAX];
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200189 char *namesep;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200190
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200191 if (ctx == NULL || name == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200192 return -ENOENT;
193
Luis Felipe Strano Moraes9efaf2f2011-12-20 08:13:56 -0800194 if (alias_normalize(name, name_norm, &namelen) < 0) {
195 DBG(ctx, "invalid alias: %s\n", name);
196 return -EINVAL;
197 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200198
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200199 m = kmod_pool_get_module(ctx, name_norm);
200 if (m != NULL) {
201 *mod = kmod_module_ref(m);
202 return 0;
203 }
204
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200205 namesep = strchr(name_norm, '/');
206 m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200207 if (m == NULL) {
208 free(m);
209 return -ENOMEM;
210 }
211
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200212 memset(m, 0, sizeof(*m));
213
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200214 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200215 m->name = (char *)m + sizeof(*m);
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200216 memcpy(m->name, name_norm, namelen + 1);
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200217
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200218 if (namesep) {
219 size_t len = namesep - name_norm;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200220
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200221 m->name[len] = '\0';
222 m->alias = m->name + len + 1;
223 m->hashkey = m->name + namelen + 1;
224 memcpy(m->hashkey, name_norm, namelen + 1);
225 } else {
226 m->hashkey = m->name;
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200227 }
228
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200229 m->refcount = 1;
230 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200231 *mod = m;
232
233 return 0;
234}
235
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200236int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
237 const char *name, struct kmod_module **mod)
238{
239 int err;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200240 char key[PATH_MAX];
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200241 size_t namelen = strlen(name);
242 size_t aliaslen = strlen(alias);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200243
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200244 if (namelen + aliaslen + 2 > PATH_MAX)
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200245 return -ENAMETOOLONG;
246
247 memcpy(key, name, namelen);
248 memcpy(key + namelen + 1, alias, aliaslen + 1);
249 key[namelen] = '/';
250
251 err = kmod_module_new_from_name(ctx, key, mod);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200252 if (err < 0)
253 return err;
254
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200255 return 0;
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200256}
257
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200258/**
259 * kmod_module_new_from_path:
260 * @ctx: kmod library context
261 * @path: path where to find the given module
262 * @mod: where to save the created struct kmod_module
263 *
264 * Create a new struct kmod_module using the module path. @path must be an
265 * existent file with in the filesystem and must be accessible to libkmod.
266 *
267 * The initial refcount is 1, and needs to be decremented to release the
268 * resources of the kmod_module. Since libkmod keeps track of all
269 * kmod_modules created, they are all released upon @ctx destruction too. Do
270 * not unref @ctx before all the desired operations with the returned
271 * kmod_module are done.
272 *
273 * If @path is relative, it's treated as relative to the current working
274 * directory. Otherwise, give an absolute path.
275 *
276 * Returns: 0 on success or < 0 otherwise. It fails if file does not exist, if
277 * it's not a valid file for a kmod_module or if memory allocation failed.
278 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200279KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
280 const char *path,
281 struct kmod_module **mod)
282{
283 struct kmod_module *m;
284 int err;
285 struct stat st;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200286 char name[PATH_MAX];
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200287 char *abspath;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200288 size_t namelen;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200289
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200290 if (ctx == NULL || path == NULL || mod == NULL)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200291 return -ENOENT;
292
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200293 abspath = path_make_absolute_cwd(path);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200294 if (abspath == NULL) {
295 DBG(ctx, "no absolute path for %s\n", path);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200296 return -ENOMEM;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200297 }
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200298
299 err = stat(abspath, &st);
300 if (err < 0) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200301 err = -errno;
302 DBG(ctx, "stat %s: %s\n", path, strerror(errno));
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200303 free(abspath);
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200304 return err;
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200305 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200306
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200307 if (path_to_modname(path, name, &namelen) == NULL) {
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200308 DBG(ctx, "could not get modname from path %s\n", path);
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200309 free(abspath);
310 return -ENOENT;
311 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200312
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200313 m = kmod_pool_get_module(ctx, name);
314 if (m != NULL) {
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200315 if (m->path == NULL)
316 m->path = abspath;
317 else if (streq(m->path, abspath))
318 free(abspath);
319 else {
Lucas De Marchiebaa7be2011-12-27 18:10:19 -0200320 ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n",
321 name, abspath, m->path);
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200322 free(abspath);
323 return -EEXIST;
324 }
325
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200326 *mod = kmod_module_ref(m);
327 return 0;
328 }
329
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200330 m = malloc(sizeof(*m) + namelen + 1);
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200331 if (m == NULL)
332 return -errno;
333
Lucas De Marchi788ef0f2011-12-14 15:05:03 -0200334 memset(m, 0, sizeof(*m));
335
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200336 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200337 m->name = (char *)m + sizeof(*m);
Lucas De Marchi9dec2442011-12-18 15:12:19 -0200338 memcpy(m->name, name, namelen + 1);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200339 m->path = abspath;
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200340 m->hashkey = m->name;
Gustavo Sverzut Barbieri87ca03b2011-12-04 12:34:02 -0200341 m->refcount = 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200342
Lucas De Marchi8bdeca12011-12-15 13:11:51 -0200343 kmod_pool_add_module(ctx, m, m->hashkey);
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200344
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200345 *mod = m;
346
347 return 0;
348}
349
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200350/**
351 * kmod_module_unref:
352 * @mod: kmod module
353 *
354 * Drop a reference of the kmod module. If the refcount reaches zero, its
355 * resources are released.
356 *
357 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
358 * returns the passed @mod with its refcount decremented.
359 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200360KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
361{
362 if (mod == NULL)
363 return NULL;
364
365 if (--mod->refcount > 0)
366 return mod;
367
368 DBG(mod->ctx, "kmod_module %p released\n", mod);
369
Lucas De Marchi4084c172011-12-15 13:43:22 -0200370 kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200371 kmod_module_unref_list(mod->dep);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200372 kmod_unref(mod->ctx);
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200373 free(mod->options);
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -0200374 free(mod->path);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200375 free(mod);
376 return NULL;
377}
378
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200379/**
380 * kmod_module_ref:
381 * @mod: kmod module
382 *
383 * Take a reference of the kmod module, incrementing its refcount.
384 *
385 * Returns: the passed @module with its refcount incremented.
386 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200387KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
388{
389 if (mod == NULL)
390 return NULL;
391
392 mod->refcount++;
393
394 return mod;
395}
396
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200397#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
398 do { \
399 if ((_err) < 0) \
400 goto _label_err; \
401 if (*(_list) != NULL) \
402 goto finish; \
403 } while (0)
404
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200405/**
406 * kmod_module_new_from_lookup:
407 * @ctx: kmod library context
408 * @given_alias: alias to look for
409 * @list: an empty list where to save the list of modules matching
410 * @given_alias
411 *
412 * Create a new list of kmod modules using an alias or module name and lookup
413 * libkmod's configuration files and indexes in order to find the module.
414 * Once it's found in one of the places, it stops searching and create the
415 * list of modules that is saved in @list.
416 *
417 * The search order is: 1. aliases in configuration file; 2. module names in
418 * modules.dep index; 3. symbol aliases in modules.symbols index; 4. aliases
419 * in modules.alias index.
420 *
421 * The initial refcount is 1, and needs to be decremented to release the
422 * resources of the kmod_module. The returned @list must be released by
423 * calling kmod_module_unref_list(). Since libkmod keeps track of all
424 * kmod_modules created, they are all released upon @ctx destruction too. Do
425 * not unref @ctx before all the desired operations with the returned list are
426 * completed.
427 *
428 * Returns: 0 on success or < 0 otherwise. It fails if any of the lookup
429 * methods failed, which is basically due to memory allocation fail. If module
430 * is not found, it still returns 0, but @list is an empty list.
431 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200432KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200433 const char *given_alias,
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200434 struct kmod_list **list)
435{
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200436 int err;
Lucas De Marchi6daceb22012-01-08 01:02:29 -0200437 char alias[PATH_MAX];
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200438
Lucas De Marchi4308b172011-12-13 10:26:04 -0200439 if (ctx == NULL || given_alias == NULL)
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200440 return -ENOENT;
441
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200442 if (list == NULL || *list != NULL) {
443 ERR(ctx, "An empty list is needed to create lookup\n");
444 return -ENOSYS;
445 }
446
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200447 if (alias_normalize(given_alias, alias, NULL) < 0) {
448 DBG(ctx, "invalid alias: %s\n", given_alias);
Lucas De Marchid470db12011-12-13 10:28:00 -0200449 return -EINVAL;
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200450 }
451
452 DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200453
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200454 /* Aliases from config file override all the others */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200455 err = kmod_lookup_alias_from_config(ctx, alias, list);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200456 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200457
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200458 DBG(ctx, "lookup modules.dep %s\n", alias);
Lucas De Marchi64700e42011-12-01 15:57:53 -0200459 err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
460 CHECK_ERR_AND_FINISH(err, fail, list, finish);
461
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200462 DBG(ctx, "lookup modules.symbols %s\n", alias);
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200463 err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
464 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200465
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200466 DBG(ctx, "lookup install and remove commands %s\n", alias);
Lucas De Marchif4fc5522011-12-16 03:57:12 -0200467 err = kmod_lookup_alias_from_commands(ctx, alias, list);
468 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200469
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200470 DBG(ctx, "lookup modules.aliases %s\n", alias);
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200471 err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
472 CHECK_ERR_AND_FINISH(err, fail, list, finish);
473
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200474finish:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200475 DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200476 return err;
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200477fail:
Gustavo Sverzut Barbierib55df2e2011-12-20 13:04:10 -0200478 DBG(ctx, "Failed to lookup %s\n", alias);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200479 kmod_module_unref_list(*list);
480 *list = NULL;
Lucas De Marchi84f42202011-12-02 10:03:34 -0200481 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200482}
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200483#undef CHECK_ERR_AND_FINISH
484
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200485/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200486 * kmod_module_unref_list:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200487 * @list: list of kmod modules
488 *
489 * Drop a reference of each kmod module in @list and releases the resources
490 * taken by the list itself.
491 *
492 * Returns: NULL if @mod is NULL or if the module was released. Otherwise it
493 * returns the passed @mod with its refcount decremented.
494 */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200495KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
496{
497 for (; list != NULL; list = kmod_list_remove(list))
498 kmod_module_unref(list->data);
499
500 return 0;
501}
502
Lucas De Marchi0d467432011-12-31 11:15:52 -0200503/**
504 * kmod_module_get_filtered_blacklist:
505 * @ctx: kmod library context
506 * @input: list of kmod_module to be filtered with blacklist
507 * @output: where to save the new list
508 *
509 * Given a list @input, this function filter it out with config's blacklist
510 * ans save it in @output.
511 *
512 * Returns: 0 on success or < 0 otherwise. @output is saved with the updated
513 * list.
514 */
515KMOD_EXPORT int kmod_module_get_filtered_blacklist(const struct kmod_ctx *ctx,
516 const struct kmod_list *input,
517 struct kmod_list **output)
518{
519 const struct kmod_list *li;
520 const struct kmod_list *blacklist;
521
522 if (ctx == NULL || output == NULL)
523 return -ENOENT;
524
525 *output = NULL;
526 if (input == NULL)
527 return 0;
528
529 blacklist = kmod_get_blacklists(ctx);
530 kmod_list_foreach(li, input) {
531 struct kmod_module *mod = li->data;
532 const struct kmod_list *lb;
533 struct kmod_list *node;
534 bool filtered = false;
535
536 kmod_list_foreach(lb, blacklist) {
537 const char *name = lb->data;
538
Lucas De Marchi4926cb52011-12-31 11:21:52 -0200539 if (streq(name, mod->name)) {
Lucas De Marchi0d467432011-12-31 11:15:52 -0200540 filtered = true;
541 break;
542 }
543 }
544
545 if (filtered)
546 continue;
547
548 node = kmod_list_append(*output, mod);
549 if (node == NULL)
550 goto fail;
551
552 *output = node;
553 kmod_module_ref(mod);
554 }
555
556 return 0;
557
558fail:
559 kmod_module_unref_list(*output);
560 *output = NULL;
561 return -ENOMEM;
562}
563
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200564static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
565{
566 if (!mod->init.dep) {
567 /* lazy init */
568 char *line = kmod_search_moddep(mod->ctx, mod->name);
569
570 if (line == NULL)
571 return NULL;
572
573 kmod_module_parse_depline((struct kmod_module *)mod, line);
574 free(line);
575
576 if (!mod->init.dep)
577 return NULL;
578 }
579
580 return mod->dep;
581}
582
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200583/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200584 * kmod_module_get_dependencies:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200585 * @mod: kmod module
586 *
587 * Search the modules.dep index to find the dependencies of the given @mod.
588 * The result is cached in @mod, so subsequent calls to this function will
589 * return the already searched list of modules.
590 *
591 * Returns: NULL on failure or if there are any dependencies. Otherwise it
592 * returns a list of kmod modules that can be released by calling
593 * kmod_module_unref_list().
594 */
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200595KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200596{
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200597 struct kmod_list *l, *l_new, *list_new = NULL;
598
599 if (mod == NULL)
600 return NULL;
601
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200602 module_get_dependencies_noref(mod);
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200603
604 kmod_list_foreach(l, mod->dep) {
605 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
606 if (l_new == NULL) {
607 kmod_module_unref(l->data);
608 goto fail;
609 }
610
611 list_new = l_new;
612 }
613
614 return list_new;
615
616fail:
617 ERR(mod->ctx, "out of memory\n");
618 kmod_module_unref_list(list_new);
619 return NULL;
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200620}
621
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200622/**
623 * kmod_module_get_module:
624 * @entry: an entry in a list of kmod modules.
625 *
626 * Get the kmod module of this @entry in the list, increasing its refcount.
627 * After it's used, unref it. Since the refcount is incremented upon return,
628 * you still have to call kmod_module_unref_list() to release the list of kmod
629 * modules.
630 *
631 * Returns: NULL on failure or the kmod_module contained in this list entry
632 * with its refcount incremented.
633 */
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200634KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200635{
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200636 if (entry == NULL)
637 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200638
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200639 return kmod_module_ref(entry->data);
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200640}
641
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200642/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200643 * kmod_module_get_name:
644 * @mod: kmod module
645 *
646 * Get the name of this kmod module. Name is always available, independently
647 * if it was created by kmod_module_new_from_name() or another function and
648 * it's always normalized (dashes are replaced with underscores).
649 *
650 * Returns: the name of this kmod module.
651 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200652KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200653{
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200654 if (mod == NULL)
655 return NULL;
656
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200657 return mod->name;
658}
659
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200660/**
661 * kmod_module_get_path:
662 * @mod: kmod module
663 *
664 * Get the path of this kmod module. If this kmod module was not created by
665 * path, it can search the modules.dep index in order to find out the module
666 * under context's dirname (see kmod_get_dirname()).
667 *
668 * Returns: the path of this kmod module or NULL if such information is not
669 * available.
670 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200671KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200672{
Lucas De Marchie005fac2011-12-08 10:42:34 -0200673 char *line;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200674
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200675 if (mod == NULL)
676 return NULL;
677
Gustavo Sverzut Barbierid01c67e2011-12-11 19:42:02 -0200678 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200679
Lucas De Marchie005fac2011-12-08 10:42:34 -0200680 if (mod->path != NULL)
681 return mod->path;
682 if (mod->init.dep)
683 return NULL;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200684
Lucas De Marchie005fac2011-12-08 10:42:34 -0200685 /* lazy init */
686 line = kmod_search_moddep(mod->ctx, mod->name);
687 if (line == NULL)
688 return NULL;
689
690 kmod_module_parse_depline((struct kmod_module *) mod, line);
691 free(line);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200692
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200693 return mod->path;
694}
695
696
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200697extern long delete_module(const char *name, unsigned int flags);
698
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200699/**
700 * kmod_module_remove_module:
701 * @mod: kmod module
702 * @flags: flags to pass to Linux kernel when removing the module
703 *
704 * Remove a module from Linux kernel.
705 *
706 * Returns: 0 on success or < 0 on failure.
707 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200708KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
709 unsigned int flags)
710{
711 int err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200712
713 if (mod == NULL)
714 return -ENOENT;
715
716 /* Filter out other flags */
717 flags &= (KMOD_REMOVE_FORCE | KMOD_REMOVE_NOWAIT);
718
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200719 err = delete_module(mod->name, flags);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200720 if (err != 0) {
Dave Reisnerb787b562012-01-04 10:59:49 -0500721 ERR(mod->ctx, "could not remove '%s': %s\n", mod->name,
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200722 strerror(-err));
723 return err;
724 }
725
726 return 0;
727}
728
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200729extern long init_module(const void *mem, unsigned long len, const char *args);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200730
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200731/**
732 * kmod_module_insert_module:
733 * @mod: kmod module
Lucas De Marchi142db572011-12-20 23:39:30 -0200734 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
735 * behavior of this function.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200736 * @options: module's options to pass to Linux Kernel.
737 *
738 * Insert a module in Linux kernel. It opens the file pointed by @mod,
739 * mmap'ing it and passing to kernel.
740 *
Lucas De Marchibbf59322011-12-30 14:13:33 -0200741 * Returns: 0 on success or < 0 on failure. If module is already loaded it
742 * returns -EEXIST.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200743 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200744KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200745 unsigned int flags,
746 const char *options)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200747{
748 int err;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200749 const void *mem;
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200750 off_t size;
751 struct kmod_file *file;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200752 struct kmod_elf *elf = NULL;
753 const char *path;
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200754 const char *args = options ? options : "";
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200755
756 if (mod == NULL)
757 return -ENOENT;
758
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200759 path = kmod_module_get_path(mod);
760 if (path == NULL) {
Dave Reisnerb787b562012-01-04 10:59:49 -0500761 ERR(mod->ctx, "could not find module by name='%s'\n", mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200762 return -ENOSYS;
763 }
764
Lucas De Marchic68e92f2012-01-04 08:19:34 -0200765 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200766 if (file == NULL) {
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200767 err = -errno;
768 return err;
769 }
770
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200771 size = kmod_file_get_size(file);
772 mem = kmod_file_get_contents(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200773
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200774 if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
775 elf = kmod_elf_new(mem, size);
776 if (elf == NULL) {
777 err = -errno;
778 goto elf_failed;
779 }
780
781 if (flags & KMOD_INSERT_FORCE_MODVERSION) {
782 err = kmod_elf_strip_section(elf, "__versions");
783 if (err < 0)
784 INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
785 }
786
787 if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
788 err = kmod_elf_strip_vermagic(elf);
789 if (err < 0)
790 INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
791 }
792
793 mem = kmod_elf_get_memory(elf);
794 }
795
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200796 err = init_module(mem, size, args);
Lucas De Marchibbf59322011-12-30 14:13:33 -0200797 if (err < 0) {
798 err = -errno;
799 INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
800 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200801
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200802 if (elf != NULL)
803 kmod_elf_unref(elf);
804elf_failed:
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200805 kmod_file_unref(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200806
807 return err;
808}
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200809
Lucas De Marchiddbda022011-12-27 11:40:10 -0200810static bool module_is_blacklisted(struct kmod_module *mod)
811{
812 struct kmod_ctx *ctx = mod->ctx;
813 const struct kmod_list *bl = kmod_get_blacklists(ctx);
814 const struct kmod_list *l;
815
816 kmod_list_foreach(l, bl) {
817 const char *modname = kmod_blacklist_get_modname(l);
818
819 if (streq(modname, mod->name))
820 return true;
821 }
822
823 return false;
824}
825
826#define RECURSION_CHECK_STEP 10
827#define RET_CHECK_NOLOOP_OR_FAIL(_ret, _flags, _label) \
828 do { \
829 if (_ret < 0) { \
830 if (_ret == -ELOOP || _ret == -ENOMEM \
831 || (_flags & KMOD_PROBE_STOP_ON_FAILURE)) \
832 goto _label; \
833 } \
834 } while (0)
835
836struct probe_insert_cb {
837 int (*run_install)(struct kmod_module *m, const char *cmd, void *data);
838 void *data;
839};
840
841int module_probe_insert_module(struct kmod_module *mod,
842 unsigned int flags, const char *extra_options,
843 struct probe_insert_cb *cb,
844 struct kmod_list *rec, unsigned int reccount);
845
846static int command_do(struct kmod_module *mod, const char *type,
847 const char *cmd)
848{
849 const char *modname = kmod_module_get_name(mod);
850 int err;
851
852 DBG(mod->ctx, "%s %s\n", type, cmd);
853
854 setenv("MODPROBE_MODULE", modname, 1);
855 err = system(cmd);
856 unsetenv("MODPROBE_MODULE");
857
858 if (err == -1 || WEXITSTATUS(err)) {
859 ERR(mod->ctx, "Error running %s command for %s\n",
860 type, modname);
861 if (err != -1)
862 err = -WEXITSTATUS(err);
863 }
864
865 return err;
866}
867
868static int module_do_install_commands(struct kmod_module *mod,
869 const char *options,
870 struct probe_insert_cb *cb)
871{
872 const char *command = kmod_module_get_install_commands(mod);
873 char *p, *cmd;
874 int err;
875 size_t cmdlen, options_len, varlen;
876
877 assert(command);
878
879 if (options == NULL)
880 options = "";
881
882 options_len = strlen(options);
883 cmdlen = strlen(command);
884 varlen = sizeof("$CMDLINE_OPTS") - 1;
885
886 cmd = memdup(command, cmdlen + 1);
887 if (cmd == NULL)
888 return -ENOMEM;
889
890 while ((p = strstr(cmd, "$CMDLINE_OPTS")) != NULL) {
891 size_t prefixlen = p - cmd;
892 size_t suffixlen = cmdlen - prefixlen - varlen;
893 size_t slen = cmdlen - varlen + options_len;
894 char *suffix = p + varlen;
895 char *s = malloc(slen + 1);
896 if (s == NULL) {
897 free(cmd);
898 return -ENOMEM;
899 }
900 memcpy(s, cmd, p - cmd);
901 memcpy(s + prefixlen, options, options_len);
902 memcpy(s + prefixlen + options_len, suffix, suffixlen);
903 s[slen] = '\0';
904
905 free(cmd);
906 cmd = s;
907 cmdlen = slen;
908 }
909
910 if (cb->run_install != NULL)
911 err = cb->run_install(mod, cmd, cb->data);
912 else
913 err = command_do(mod, "install", cmd);
914
915 free(cmd);
916
917 return err;
918}
919
920static bool module_dep_has_loop(const struct kmod_list *deps,
921 struct kmod_list *rec,
922 unsigned int reccount)
923{
924 struct kmod_list *l;
925 struct kmod_module *mod;
926
927 if (reccount < RECURSION_CHECK_STEP || deps == NULL)
928 return false;
929
930 mod = deps->data;
931 reccount = 0;
932 kmod_list_foreach(l, rec) {
933 struct kmod_list *loop;
934
935 if (l->data != mod)
936 continue;
937
938 ERR(mod->ctx, "Dependency loop detected while inserting '%s'. Operation aborted\n",
939 mod->name);
940
941 for (loop = l; loop != NULL;
942 loop = kmod_list_next(rec, loop)) {
943 struct kmod_module *m = loop->data;
944 ERR(mod->ctx, "%s\n", m->name);
945 }
946
947 return true;
948 }
949
950 return false;
951}
952
953static int module_do_insmod_dep(const struct kmod_list *deps,
954 unsigned int flags, struct probe_insert_cb *cb,
955 struct kmod_list *rec, unsigned int reccount)
956{
957 const struct kmod_list *d;
958 int err = 0;
959
960 if (module_dep_has_loop(deps, rec, reccount))
961 return -ELOOP;
962
963 kmod_list_foreach(d, deps) {
964 struct kmod_module *dm = d->data;
965 struct kmod_list *tmp;
966
967 tmp = kmod_list_append(rec, dm);
968 if (tmp == NULL)
969 return -ENOMEM;
970 rec = tmp;
971
972 err = module_probe_insert_module(dm, flags, NULL, cb,
973 rec, reccount + 1);
974
975 rec = kmod_list_remove_n_latest(rec, 1);
976 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
977 }
978
979finish:
980 return err;
981}
982
983static char *module_options_concat(const char *opt, const char *xopt)
984{
985 // TODO: we might need to check if xopt overrides options on opt
986 size_t optlen = opt == NULL ? 0 : strlen(opt);
987 size_t xoptlen = xopt == NULL ? 0 : strlen(xopt);
988 char *r;
989
990 if (optlen == 0 && xoptlen == 0)
991 return NULL;
992
993 r = malloc(optlen + xoptlen + 2);
994
995 if (opt != NULL) {
996 memcpy(r, opt, optlen);
997 r[optlen] = ' ';
998 optlen++;
999 }
1000
1001 if (xopt != NULL)
1002 memcpy(r + optlen, xopt, xoptlen);
1003
1004 r[optlen + xoptlen] = '\0';
1005
1006 return r;
1007}
1008
1009/*
1010 * Do the probe_insert work recursively. We traverse the dependencies in
1011 * depth-first order, checking the following conditions:
1012 *
1013 * - Is blacklisted?
1014 * - Is install command?
1015 * - Is already loaded?
1016 *
1017 * Then we insert the modules (calling module_do_insmod_dep(), which will
1018 * re-enter this function) needed to load @mod in the following order:
1019 *
1020 * 1) pre-softdep
1021 * 2) dependency
1022 * 3) @mod
1023 * 4) post-softdep
1024 */
1025int module_probe_insert_module(struct kmod_module *mod,
1026 unsigned int flags, const char *extra_options,
1027 struct probe_insert_cb *cb,
1028 struct kmod_list *rec, unsigned int reccount)
1029{
1030 int err;
1031 const char *install_cmds;
1032 const struct kmod_list *dep;
1033 struct kmod_list *pre = NULL, *post = NULL;
1034 char *options;
1035
1036 if ((flags & KMOD_PROBE_STOP_ON_BLACKLIST)
1037 && module_is_blacklisted(mod)) {
1038 DBG(mod->ctx, "Stopping on '%s': blacklisted\n", mod->name);
1039 return -EINVAL;
1040 }
1041
1042 install_cmds = kmod_module_get_install_commands(mod);
1043 if (install_cmds != NULL) {
1044 if (flags & KMOD_PROBE_STOP_ON_COMMAND) {
1045 DBG(mod->ctx, "Stopping on '%s': install command\n",
1046 mod->name);
1047 return -EINVAL;
1048 }
1049 } else {
1050 int state = kmod_module_get_initstate(mod);
1051
1052 if (state == KMOD_MODULE_LIVE ||
1053 state == KMOD_MODULE_COMING ||
1054 state == KMOD_MODULE_BUILTIN)
1055 return 0;
1056 }
1057
1058 err = kmod_module_get_softdeps(mod, &pre, &post);
1059 if (err < 0)
1060 return err;
1061
1062 err = module_do_insmod_dep(pre, flags, cb, rec, reccount);
1063 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
1064
1065 dep = module_get_dependencies_noref(mod);
1066 err = module_do_insmod_dep(dep, flags, cb, rec, reccount);
1067 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
1068
1069 options = module_options_concat(kmod_module_get_options(mod),
1070 extra_options);
1071
1072 if (install_cmds != NULL)
1073 err = module_do_install_commands(mod, options, cb);
1074 else
1075 err = kmod_module_insert_module(mod, flags, options);
1076
1077 free(options);
1078
Lucas De Marchie47c6042011-12-30 14:15:40 -02001079 /*
1080 * Ignore "already loaded" error. We need to check here because of
1081 * race conditions. We checked first if module was already loaded but
1082 * it may have been loaded between the check and the moment we try to
1083 * insert it.
1084 */
1085 if (err < 0 && err != -EEXIST && (flags & KMOD_PROBE_STOP_ON_FAILURE))
1086 goto finish;
Lucas De Marchiddbda022011-12-27 11:40:10 -02001087
1088 err = module_do_insmod_dep(post, flags, cb, rec, reccount);
1089
1090finish:
1091 kmod_module_unref_list(pre);
1092 kmod_module_unref_list(post);
1093
1094 return err;
1095}
1096
1097/**
1098 * kmod_module_probe_insert_module:
1099 * @mod: kmod module
1100 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
1101 * behavior of this function.
1102 * @extra_options: module's options to pass to Linux Kernel.
1103 * @run_install: function to run when @mod is backed by a install command.
1104 * @data: data to give back to @run_install callback
1105 *
1106 * Insert a module in Linux kernel resolving dependencies, soft dependencies
1107 * install commands and applying blacklist.
1108 *
1109 * If @run_install is NULL, and the flag KMOD_PROBE_STOP_ON_COMMANDS is not
1110 * given, this function will fork and exec by calling system(3). If you need
1111 * control over the execution of an install command, give a callback function
1112 * in @run_install.
1113 *
1114 * Returns: 0 on success or < 0 on failure.
1115 */
1116KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
1117 unsigned int flags, const char *extra_options,
1118 int (*run_install)(struct kmod_module *m,
1119 const char *cmd, void *data),
1120 const void *data)
1121{
1122 struct probe_insert_cb cb;
1123
1124 cb.run_install = run_install;
1125 cb.data = (void *) data;
1126
1127 return module_probe_insert_module(mod, flags, extra_options, &cb,
1128 NULL, 0);
1129}
1130
1131#undef RECURSION_CHECK_STEP
1132#undef RET_CHECK_NOLOOP_OR_FAIL
1133
1134
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001135/**
1136 * kmod_module_get_options:
1137 * @mod: kmod module
1138 *
1139 * Get options of this kmod module. Options come from the configuration file
1140 * and are cached in @mod. The first call to this function will search for
1141 * this module in configuration and subsequent calls return the cached string.
1142 *
1143 * Returns: a string with all the options separated by spaces. This string is
1144 * owned by @mod, do not free it.
1145 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001146KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
1147{
1148 if (mod == NULL)
1149 return NULL;
1150
1151 if (!mod->init.options) {
1152 /* lazy init */
1153 struct kmod_module *m = (struct kmod_module *)mod;
1154 const struct kmod_list *l, *ctx_options;
1155 char *opts = NULL;
1156 size_t optslen = 0;
1157
1158 ctx_options = kmod_get_options(mod->ctx);
1159
1160 kmod_list_foreach(l, ctx_options) {
1161 const char *modname = kmod_option_get_modname(l);
1162 const char *str;
1163 size_t len;
1164 void *tmp;
1165
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001166 DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
1167 if (!(streq(modname, mod->name) || (mod->alias != NULL &&
1168 streq(modname, mod->alias))))
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001169 continue;
1170
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001171 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 -02001172 str = kmod_option_get_options(l);
1173 len = strlen(str);
1174 if (len < 1)
1175 continue;
1176
1177 tmp = realloc(opts, optslen + len + 2);
1178 if (tmp == NULL) {
1179 free(opts);
1180 goto failed;
1181 }
1182
1183 opts = tmp;
1184
1185 if (optslen > 0) {
1186 opts[optslen] = ' ';
1187 optslen++;
1188 }
1189
1190 memcpy(opts + optslen, str, len);
1191 optslen += len;
1192 opts[optslen] = '\0';
1193 }
1194
1195 m->init.options = true;
1196 m->options = opts;
1197 }
1198
1199 return mod->options;
1200
1201failed:
1202 ERR(mod->ctx, "out of memory\n");
1203 return NULL;
1204}
1205
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001206/**
1207 * kmod_module_get_install_commands:
1208 * @mod: kmod module
1209 *
1210 * Get install commands for this kmod module. Install commands come from the
1211 * configuration file and are cached in @mod. The first call to this function
1212 * will search for this module in configuration and subsequent calls return
1213 * the cached string. The install commands are returned as they were in the
1214 * configuration, concatenated by ';'. No other processing is made in this
1215 * string.
1216 *
1217 * Returns: a string with all install commands separated by semicolons. This
1218 * string is owned by @mod, do not free it.
1219 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001220KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
1221{
1222 if (mod == NULL)
1223 return NULL;
1224
1225 if (!mod->init.install_commands) {
1226 /* lazy init */
1227 struct kmod_module *m = (struct kmod_module *)mod;
1228 const struct kmod_list *l, *ctx_install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001229
1230 ctx_install_commands = kmod_get_install_commands(mod->ctx);
1231
1232 kmod_list_foreach(l, ctx_install_commands) {
1233 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001234
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001235 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001236 continue;
1237
Lucas De Marchi60f67602011-12-16 03:33:26 -02001238 m->install_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001239
Lucas De Marchi60f67602011-12-16 03:33:26 -02001240 /*
1241 * find only the first command, as modprobe from
1242 * module-init-tools does
1243 */
1244 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001245 }
1246
1247 m->init.install_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001248 }
1249
1250 return mod->install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001251}
1252
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001253void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
1254{
1255 mod->init.install_commands = true;
1256 mod->install_commands = cmd;
1257}
1258
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001259static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
1260{
1261 struct kmod_list *ret = NULL;
1262 unsigned i;
1263
1264 for (i = 0; i < count; i++) {
1265 const char *depname = array[i];
1266 struct kmod_list *lst = NULL;
1267 int err;
1268
1269 err = kmod_module_new_from_lookup(ctx, depname, &lst);
1270 if (err < 0) {
1271 ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
1272 continue;
1273 } else if (lst != NULL)
1274 ret = kmod_list_append_list(ret, lst);
1275 }
1276 return ret;
1277}
1278
1279/**
1280 * kmod_module_get_softdeps:
1281 * @mod: kmod module
1282 * @pre: where to save the list of preceding soft dependencies.
1283 * @post: where to save the list of post soft dependencies.
1284 *
1285 * Get soft dependencies for this kmod module. Soft dependencies come
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001286 * from configuration file and are not cached in @mod because it may include
1287 * dependency cycles that would make we leak kmod_module. Any call
1288 * to this function will search for this module in configuration, allocate a
1289 * list and return the result.
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001290 *
1291 * Both @pre and @post are newly created list of kmod_module and
1292 * should be unreferenced with kmod_module_unref_list().
1293 *
1294 * Returns: 0 on success or < 0 otherwise.
1295 */
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001296KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
1297 struct kmod_list **pre,
1298 struct kmod_list **post)
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001299{
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001300 const struct kmod_list *l, *ctx_softdeps;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001301
1302 if (mod == NULL || pre == NULL || post == NULL)
1303 return -ENOENT;
1304
1305 assert(*pre == NULL);
1306 assert(*post == NULL);
1307
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001308 ctx_softdeps = kmod_get_softdeps(mod->ctx);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001309
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001310 kmod_list_foreach(l, ctx_softdeps) {
1311 const char *modname = kmod_softdep_get_name(l);
1312 const char * const *array;
1313 unsigned count;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001314
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001315 if (fnmatch(modname, mod->name, 0) != 0)
1316 continue;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001317
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001318 array = kmod_softdep_get_pre(l, &count);
1319 *pre = lookup_softdep(mod->ctx, array, count);
1320 array = kmod_softdep_get_post(l, &count);
1321 *post = lookup_softdep(mod->ctx, array, count);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001322
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001323 /*
1324 * find only the first command, as modprobe from
1325 * module-init-tools does
1326 */
1327 break;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001328 }
1329
1330 return 0;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001331}
1332
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001333/**
1334 * kmod_module_get_remove_commands:
1335 * @mod: kmod module
1336 *
1337 * Get remove commands for this kmod module. Remove commands come from the
1338 * configuration file and are cached in @mod. The first call to this function
1339 * will search for this module in configuration and subsequent calls return
1340 * the cached string. The remove commands are returned as they were in the
1341 * configuration, concatenated by ';'. No other processing is made in this
1342 * string.
1343 *
1344 * Returns: a string with all remove commands separated by semicolons. This
1345 * string is owned by @mod, do not free it.
1346 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001347KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
1348{
1349 if (mod == NULL)
1350 return NULL;
1351
1352 if (!mod->init.remove_commands) {
1353 /* lazy init */
1354 struct kmod_module *m = (struct kmod_module *)mod;
1355 const struct kmod_list *l, *ctx_remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001356
1357 ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
1358
1359 kmod_list_foreach(l, ctx_remove_commands) {
1360 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001361
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001362 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001363 continue;
1364
Lucas De Marchi60f67602011-12-16 03:33:26 -02001365 m->remove_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001366
Lucas De Marchi60f67602011-12-16 03:33:26 -02001367 /*
1368 * find only the first command, as modprobe from
1369 * module-init-tools does
1370 */
1371 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001372 }
1373
1374 m->init.remove_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001375 }
1376
1377 return mod->remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001378}
1379
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001380void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
1381{
1382 mod->init.remove_commands = true;
1383 mod->remove_commands = cmd;
1384}
1385
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001386/**
1387 * SECTION:libkmod-loaded
1388 * @short_description: currently loaded modules
1389 *
1390 * Information about currently loaded modules, as reported by Linux kernel.
1391 * These information are not cached by libkmod and are always read from /sys
1392 * and /proc/modules.
1393 */
1394
1395/**
1396 * kmod_module_new_from_loaded:
1397 * @ctx: kmod library context
1398 * @list: where to save the list of loaded modules
1399 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001400 * Create a new list of kmod modules with all modules currently loaded in
1401 * kernel. It uses /proc/modules to get the names of loaded modules and to
1402 * create kmod modules by calling kmod_module_new_from_name() in each of them.
1403 * They are put are put in @list in no particular order.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001404 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001405 * The initial refcount is 1, and needs to be decremented to release the
1406 * resources of the kmod_module. The returned @list must be released by
1407 * calling kmod_module_unref_list(). Since libkmod keeps track of all
1408 * kmod_modules created, they are all released upon @ctx destruction too. Do
1409 * not unref @ctx before all the desired operations with the returned list are
1410 * completed.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001411 *
1412 * Returns: 0 on success or < 0 on error.
1413 */
1414KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
1415 struct kmod_list **list)
1416{
1417 struct kmod_list *l = NULL;
1418 FILE *fp;
1419 char line[4096];
1420
1421 if (ctx == NULL || list == NULL)
1422 return -ENOENT;
1423
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001424 fp = fopen("/proc/modules", "re");
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001425 if (fp == NULL) {
1426 int err = -errno;
1427 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
1428 return err;
1429 }
1430
1431 while (fgets(line, sizeof(line), fp)) {
1432 struct kmod_module *m;
1433 struct kmod_list *node;
1434 int err;
1435 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
1436
1437 err = kmod_module_new_from_name(ctx, name, &m);
1438 if (err < 0) {
1439 ERR(ctx, "could not get module from name '%s': %s\n",
1440 name, strerror(-err));
1441 continue;
1442 }
1443
1444 node = kmod_list_append(l, m);
1445 if (node)
1446 l = node;
1447 else {
1448 ERR(ctx, "out of memory\n");
1449 kmod_module_unref(m);
1450 }
1451 }
1452
1453 fclose(fp);
1454 *list = l;
1455
1456 return 0;
1457}
1458
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001459/**
1460 * kmod_module_initstate_str:
1461 * @state: the state as returned by kmod_module_get_initstate()
1462 *
1463 * Translate a initstate to a string.
1464 *
1465 * Returns: the string associated to the @state. This string is statically
1466 * allocated, do not free it.
1467 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001468KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
1469{
1470 switch (state) {
1471 case KMOD_MODULE_BUILTIN:
1472 return "builtin";
1473 case KMOD_MODULE_LIVE:
1474 return "live";
1475 case KMOD_MODULE_COMING:
1476 return "coming";
1477 case KMOD_MODULE_GOING:
1478 return "going";
1479 default:
1480 return NULL;
1481 }
1482}
1483
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001484/**
1485 * kmod_module_get_initstate:
1486 * @mod: kmod module
1487 *
1488 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
1489 * /sys filesystem.
1490 *
1491 * Returns: < 0 on error or enum kmod_initstate if module is found in kernel.
1492 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001493KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
1494{
1495 char path[PATH_MAX], buf[32];
1496 int fd, err, pathlen;
1497
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001498 if (mod == NULL)
1499 return -ENOENT;
1500
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001501 pathlen = snprintf(path, sizeof(path),
1502 "/sys/module/%s/initstate", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001503 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001504 if (fd < 0) {
1505 err = -errno;
1506
Lucas De Marchiddbda022011-12-27 11:40:10 -02001507 DBG(mod->ctx, "could not open '%s': %s\n",
1508 path, strerror(-err));
1509
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001510 if (pathlen > (int)sizeof("/initstate") - 1) {
1511 struct stat st;
1512 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
1513 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
1514 return KMOD_MODULE_BUILTIN;
1515 }
1516
Gustavo Sverzut Barbieri926f67a2011-12-11 19:33:03 -02001517 DBG(mod->ctx, "could not open '%s': %s\n",
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001518 path, strerror(-err));
1519 return err;
1520 }
1521
1522 err = read_str_safe(fd, buf, sizeof(buf));
1523 close(fd);
1524 if (err < 0) {
1525 ERR(mod->ctx, "could not read from '%s': %s\n",
1526 path, strerror(-err));
1527 return err;
1528 }
1529
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001530 if (streq(buf, "live\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001531 return KMOD_MODULE_LIVE;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001532 else if (streq(buf, "coming\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001533 return KMOD_MODULE_COMING;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001534 else if (streq(buf, "going\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001535 return KMOD_MODULE_GOING;
1536
1537 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
1538 return -EINVAL;
1539}
1540
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001541/**
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001542 * kmod_module_get_size:
1543 * @mod: kmod module
1544 *
1545 * Get the size of this kmod module as returned by Linux kernel. It reads the
1546 * file /proc/modules to search for this module and get its size.
1547 *
1548 * Returns: the size of this kmod module.
1549 */
1550KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
1551{
1552 // FIXME TODO: this should be available from /sys/module/foo
1553 FILE *fp;
1554 char line[4096];
1555 int lineno = 0;
1556 long size = -ENOENT;
1557
1558 if (mod == NULL)
1559 return -ENOENT;
1560
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001561 fp = fopen("/proc/modules", "re");
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001562 if (fp == NULL) {
1563 int err = -errno;
1564 ERR(mod->ctx,
1565 "could not open /proc/modules: %s\n", strerror(errno));
1566 return err;
1567 }
1568
1569 while (fgets(line, sizeof(line), fp)) {
1570 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
1571 long value;
1572
1573 lineno++;
1574 if (tok == NULL || !streq(tok, mod->name))
1575 continue;
1576
1577 tok = strtok_r(NULL, " \t", &saveptr);
1578 if (tok == NULL) {
1579 ERR(mod->ctx,
1580 "invalid line format at /proc/modules:%d\n", lineno);
1581 break;
1582 }
1583
1584 value = strtol(tok, &endptr, 10);
1585 if (endptr == tok || *endptr != '\0') {
1586 ERR(mod->ctx,
1587 "invalid line format at /proc/modules:%d\n", lineno);
1588 break;
1589 }
1590
1591 size = value;
1592 break;
1593 }
1594 fclose(fp);
1595 return size;
1596}
1597
1598/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001599 * kmod_module_get_refcnt:
1600 * @mod: kmod module
1601 *
1602 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
1603 * /sys filesystem.
1604 *
1605 * Returns: 0 on success or < 0 on failure.
1606 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001607KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
1608{
1609 char path[PATH_MAX];
1610 long refcnt;
1611 int fd, err;
1612
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001613 if (mod == NULL)
1614 return -ENOENT;
1615
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001616 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001617 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001618 if (fd < 0) {
1619 err = -errno;
1620 ERR(mod->ctx, "could not open '%s': %s\n",
1621 path, strerror(errno));
1622 return err;
1623 }
1624
1625 err = read_str_long(fd, &refcnt, 10);
1626 close(fd);
1627 if (err < 0) {
1628 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
1629 path, strerror(-err));
1630 return err;
1631 }
1632
1633 return (int)refcnt;
1634}
1635
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001636/**
1637 * kmod_module_get_holders:
1638 * @mod: kmod module
1639 *
1640 * Get a list of kmod modules that are holding this @mod, as returned by Linux
1641 * Kernel. After use, free the @list by calling kmod_module_unref_list().
1642 *
1643 * Returns: a new list of kmod modules on success or NULL on failure.
1644 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001645KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
1646{
1647 char dname[PATH_MAX];
1648 struct kmod_list *list = NULL;
1649 DIR *d;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001650
1651 if (mod == NULL)
1652 return NULL;
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001653
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001654 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
1655
1656 d = opendir(dname);
1657 if (d == NULL) {
1658 ERR(mod->ctx, "could not open '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001659 dname, strerror(errno));
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001660 return NULL;
1661 }
1662
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001663 for (;;) {
1664 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001665 struct kmod_module *holder;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001666 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001667 int err;
1668
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001669 err = readdir_r(d, &de, &entp);
1670 if (err != 0) {
1671 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1672 mod->name, strerror(-err));
1673 goto fail;
1674 }
1675
1676 if (entp == NULL)
1677 break;
1678
1679 if (de.d_name[0] == '.') {
1680 if (de.d_name[1] == '\0' ||
1681 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001682 continue;
1683 }
1684
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001685 err = kmod_module_new_from_name(mod->ctx, de.d_name, &holder);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001686 if (err < 0) {
1687 ERR(mod->ctx, "could not create module for '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001688 de.d_name, strerror(-err));
1689 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001690 }
1691
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001692 l = kmod_list_append(list, holder);
1693 if (l != NULL) {
1694 list = l;
1695 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001696 ERR(mod->ctx, "out of memory\n");
1697 kmod_module_unref(holder);
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001698 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001699 }
1700 }
1701
1702 closedir(d);
1703 return list;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001704
1705fail:
1706 closedir(d);
1707 kmod_module_unref_list(list);
1708 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001709}
1710
1711struct kmod_module_section {
1712 unsigned long address;
1713 char name[];
1714};
1715
1716static void kmod_module_section_free(struct kmod_module_section *section)
1717{
1718 free(section);
1719}
1720
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001721/**
1722 * kmod_module_get_sections:
1723 * @mod: kmod module
1724 *
1725 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
1726 * structure contained in this list is internal to libkmod and their fields
1727 * can be obtained by calling kmod_module_section_get_name() and
1728 * kmod_module_section_get_address().
1729 *
1730 * After use, free the @list by calling kmod_module_section_free_list().
1731 *
1732 * Returns: a new list of kmod module sections on success or NULL on failure.
1733 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001734KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1735{
1736 char dname[PATH_MAX];
1737 struct kmod_list *list = NULL;
1738 DIR *d;
1739 int dfd;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001740
1741 if (mod == NULL)
1742 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001743
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001744 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1745
1746 d = opendir(dname);
1747 if (d == NULL) {
1748 ERR(mod->ctx, "could not open '%s': %s\n",
1749 dname, strerror(errno));
1750 return NULL;
1751 }
1752
1753 dfd = dirfd(d);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001754
1755 for (;;) {
1756 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001757 struct kmod_module_section *section;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001758 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001759 unsigned long address;
1760 size_t namesz;
1761 int fd, err;
1762
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001763 err = readdir_r(d, &de, &entp);
1764 if (err != 0) {
1765 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1766 mod->name, strerror(-err));
1767 goto fail;
1768 }
1769
1770 if (de.d_name[0] == '.') {
1771 if (de.d_name[1] == '\0' ||
1772 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001773 continue;
1774 }
1775
Cristian Rodríguez8e3e5832011-12-16 14:46:52 -03001776 fd = openat(dfd, de.d_name, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001777 if (fd < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001778 ERR(mod->ctx, "could not open '%s/%s': %m\n",
1779 dname, de.d_name);
1780 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001781 }
1782
1783 err = read_str_ulong(fd, &address, 16);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001784 close(fd);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001785 if (err < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001786 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
1787 dname, de.d_name);
1788 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001789 }
1790
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001791 namesz = strlen(de.d_name) + 1;
1792 section = malloc(sizeof(*section) + namesz);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001793
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001794 if (section == NULL) {
1795 ERR(mod->ctx, "out of memory\n");
1796 goto fail;
1797 }
1798
1799 section->address = address;
1800 memcpy(section->name, de.d_name, namesz);
1801
1802 l = kmod_list_append(list, section);
1803 if (l != NULL) {
1804 list = l;
1805 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001806 ERR(mod->ctx, "out of memory\n");
1807 free(section);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001808 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001809 }
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001810 }
1811
1812 closedir(d);
1813 return list;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001814
1815fail:
1816 closedir(d);
1817 kmod_module_unref_list(list);
1818 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001819}
1820
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001821/**
1822 * kmod_module_section_get_module_name:
1823 * @entry: a list entry representing a kmod module section
1824 *
1825 * Get the name of a kmod module section.
1826 *
1827 * After use, free the @list by calling kmod_module_section_free_list().
1828 *
1829 * Returns: the name of this kmod module section on success or NULL on
1830 * failure. The string is owned by the section, do not free it.
1831 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001832KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
1833{
1834 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001835
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001836 if (entry == NULL)
1837 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001838
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001839 section = entry->data;
1840 return section->name;
1841}
1842
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001843/**
1844 * kmod_module_section_get_address:
1845 * @entry: a list entry representing a kmod module section
1846 *
1847 * Get the address of a kmod module section.
1848 *
1849 * After use, free the @list by calling kmod_module_section_free_list().
1850 *
1851 * Returns: the address of this kmod module section on success or ULONG_MAX
1852 * on failure.
1853 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001854KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
1855{
1856 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001857
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001858 if (entry == NULL)
1859 return (unsigned long)-1;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001860
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001861 section = entry->data;
1862 return section->address;
1863}
1864
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001865/**
1866 * kmod_module_section_free_list:
1867 * @list: kmod module section list
1868 *
1869 * Release the resources taken by @list
1870 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001871KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
1872{
1873 while (list) {
1874 kmod_module_section_free(list->data);
1875 list = kmod_list_remove(list);
1876 }
1877}
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001878
1879struct kmod_module_info {
1880 char *key;
1881 char value[];
1882};
1883
1884static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
1885{
1886 struct kmod_module_info *info;
1887
1888 info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
1889 if (info == NULL)
1890 return NULL;
1891
1892 info->key = (char *)info + sizeof(struct kmod_module_info)
1893 + valuelen + 1;
1894 memcpy(info->key, key, keylen);
1895 info->key[keylen] = '\0';
1896 memcpy(info->value, value, valuelen);
1897 info->value[valuelen] = '\0';
1898 return info;
1899}
1900
1901static void kmod_module_info_free(struct kmod_module_info *info)
1902{
1903 free(info);
1904}
1905
1906/**
1907 * kmod_module_get_info:
1908 * @mod: kmod module
1909 * @list: where to return list of module information. Use
1910 * kmod_module_info_get_key() and
1911 * kmod_module_info_get_value(). Release this list with
1912 * kmod_module_info_unref_list()
1913 *
1914 * Get a list of entries in ELF section ".modinfo", these contain
1915 * alias, license, depends, vermagic and other keys with respective
1916 * values.
1917 *
1918 * After use, free the @list by calling kmod_module_info_free_list().
1919 *
1920 * Returns: 0 on success or < 0 otherwise.
1921 */
1922KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
1923{
1924 struct kmod_file *file;
1925 struct kmod_elf *elf;
1926 const char *path;
1927 const void *mem;
1928 char **strings;
1929 size_t size;
1930 int i, count, ret = 0;
1931
1932 if (mod == NULL || list == NULL)
1933 return -ENOENT;
1934
1935 assert(*list == NULL);
1936
1937 path = kmod_module_get_path(mod);
1938 if (path == NULL)
1939 return -ENOENT;
1940
Lucas De Marchic68e92f2012-01-04 08:19:34 -02001941 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001942 if (file == NULL)
1943 return -errno;
1944
1945 size = kmod_file_get_size(file);
1946 mem = kmod_file_get_contents(file);
1947
1948 elf = kmod_elf_new(mem, size);
1949 if (elf == NULL) {
1950 ret = -errno;
1951 goto elf_open_error;
1952 }
1953
1954 count = kmod_elf_get_strings(elf, ".modinfo", &strings);
1955 if (count < 0) {
1956 ret = count;
1957 goto get_strings_error;
1958 }
1959
1960 for (i = 0; i < count; i++) {
1961 struct kmod_module_info *info;
1962 struct kmod_list *n;
1963 const char *key, *value;
1964 size_t keylen, valuelen;
1965
1966 key = strings[i];
1967 value = strchr(key, '=');
1968 if (value == NULL) {
1969 keylen = strlen(key);
1970 valuelen = 0;
1971 } else {
1972 keylen = value - key;
1973 value++;
1974 valuelen = strlen(value);
1975 }
1976
1977 info = kmod_module_info_new(key, keylen, value, valuelen);
1978 if (info == NULL) {
1979 ret = -errno;
1980 kmod_module_info_free_list(*list);
1981 *list = NULL;
1982 goto list_error;
1983 }
1984
1985 n = kmod_list_append(*list, info);
1986 if (n != NULL)
1987 *list = n;
1988 else {
1989 kmod_module_info_free(info);
1990 kmod_module_info_free_list(*list);
1991 *list = NULL;
1992 ret = -ENOMEM;
1993 goto list_error;
1994 }
1995 }
1996 ret = count;
1997
1998list_error:
1999 free(strings);
2000get_strings_error:
2001 kmod_elf_unref(elf);
2002elf_open_error:
2003 kmod_file_unref(file);
2004
2005 return ret;
2006}
2007
2008/**
2009 * kmod_module_info_get_key:
2010 * @entry: a list entry representing a kmod module info
2011 *
2012 * Get the key of a kmod module info.
2013 *
2014 * Returns: the key of this kmod module info on success or NULL on
2015 * failure. The string is owned by the info, do not free it.
2016 */
2017KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
2018{
2019 struct kmod_module_info *info;
2020
2021 if (entry == NULL)
2022 return NULL;
2023
2024 info = entry->data;
2025 return info->key;
2026}
2027
2028/**
2029 * kmod_module_info_get_value:
2030 * @entry: a list entry representing a kmod module info
2031 *
2032 * Get the value of a kmod module info.
2033 *
2034 * Returns: the value of this kmod module info on success or NULL on
2035 * failure. The string is owned by the info, do not free it.
2036 */
2037KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
2038{
2039 struct kmod_module_info *info;
2040
2041 if (entry == NULL)
2042 return NULL;
2043
2044 info = entry->data;
2045 return info->value;
2046}
2047
2048/**
2049 * kmod_module_info_free_list:
2050 * @list: kmod module info list
2051 *
2052 * Release the resources taken by @list
2053 */
2054KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
2055{
2056 while (list) {
2057 kmod_module_info_free(list->data);
2058 list = kmod_list_remove(list);
2059 }
2060}
2061
2062struct kmod_module_version {
2063 uint64_t crc;
2064 char symbol[];
2065};
2066
2067static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
2068{
2069 struct kmod_module_version *mv;
2070 size_t symbollen = strlen(symbol) + 1;
2071
2072 mv = malloc(sizeof(struct kmod_module_version) + symbollen);
2073 if (mv == NULL)
2074 return NULL;
2075
2076 mv->crc = crc;
2077 memcpy(mv->symbol, symbol, symbollen);
2078 return mv;
2079}
2080
2081static void kmod_module_version_free(struct kmod_module_version *version)
2082{
2083 free(version);
2084}
2085
2086/**
2087 * kmod_module_get_versions:
2088 * @mod: kmod module
2089 * @list: where to return list of module versions. Use
2090 * kmod_module_versions_get_symbol() and
2091 * kmod_module_versions_get_crc(). Release this list with
2092 * kmod_module_versions_unref_list()
2093 *
2094 * Get a list of entries in ELF section "__versions".
2095 *
2096 * After use, free the @list by calling kmod_module_versions_free_list().
2097 *
2098 * Returns: 0 on success or < 0 otherwise.
2099 */
2100KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
2101{
2102 struct kmod_file *file;
2103 struct kmod_elf *elf;
2104 const char *path;
2105 const void *mem;
2106 struct kmod_modversion *versions;
2107 size_t size;
2108 int i, count, ret = 0;
2109
2110 if (mod == NULL || list == NULL)
2111 return -ENOENT;
2112
2113 assert(*list == NULL);
2114
2115 path = kmod_module_get_path(mod);
2116 if (path == NULL)
2117 return -ENOENT;
2118
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002119 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02002120 if (file == NULL)
2121 return -errno;
2122
2123 size = kmod_file_get_size(file);
2124 mem = kmod_file_get_contents(file);
2125
2126 elf = kmod_elf_new(mem, size);
2127 if (elf == NULL) {
2128 ret = -errno;
2129 goto elf_open_error;
2130 }
2131
2132 count = kmod_elf_get_modversions(elf, &versions);
2133 if (count < 0) {
2134 ret = count;
2135 goto get_strings_error;
2136 }
2137
2138 for (i = 0; i < count; i++) {
2139 struct kmod_module_version *mv;
2140 struct kmod_list *n;
2141
2142 mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
2143 if (mv == NULL) {
2144 ret = -errno;
2145 kmod_module_versions_free_list(*list);
2146 *list = NULL;
2147 goto list_error;
2148 }
2149
2150 n = kmod_list_append(*list, mv);
2151 if (n != NULL)
2152 *list = n;
2153 else {
2154 kmod_module_version_free(mv);
2155 kmod_module_versions_free_list(*list);
2156 *list = NULL;
2157 ret = -ENOMEM;
2158 goto list_error;
2159 }
2160 }
2161 ret = count;
2162
2163list_error:
2164 free(versions);
2165get_strings_error:
2166 kmod_elf_unref(elf);
2167elf_open_error:
2168 kmod_file_unref(file);
2169
2170 return ret;
2171}
2172
2173/**
2174 * kmod_module_versions_get_symbol:
2175 * @entry: a list entry representing a kmod module versions
2176 *
2177 * Get the symbol of a kmod module versions.
2178 *
2179 * Returns: the symbol of this kmod module versions on success or NULL
2180 * on failure. The string is owned by the versions, do not free it.
2181 */
2182KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
2183{
2184 struct kmod_module_version *version;
2185
2186 if (entry == NULL)
2187 return NULL;
2188
2189 version = entry->data;
2190 return version->symbol;
2191}
2192
2193/**
2194 * kmod_module_version_get_crc:
2195 * @entry: a list entry representing a kmod module version
2196 *
2197 * Get the crc of a kmod module version.
2198 *
2199 * Returns: the crc of this kmod module version on success or NULL on
2200 * failure. The string is owned by the version, do not free it.
2201 */
2202KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
2203{
2204 struct kmod_module_version *version;
2205
2206 if (entry == NULL)
2207 return 0;
2208
2209 version = entry->data;
2210 return version->crc;
2211}
2212
2213/**
2214 * kmod_module_versions_free_list:
2215 * @list: kmod module versions list
2216 *
2217 * Release the resources taken by @list
2218 */
2219KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
2220{
2221 while (list) {
2222 kmod_module_version_free(list->data);
2223 list = kmod_list_remove(list);
2224 }
2225}
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002226
2227struct kmod_module_symbol {
2228 uint64_t crc;
2229 char symbol[];
2230};
2231
2232static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
2233{
2234 struct kmod_module_symbol *mv;
2235 size_t symbollen = strlen(symbol) + 1;
2236
2237 mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
2238 if (mv == NULL)
2239 return NULL;
2240
2241 mv->crc = crc;
2242 memcpy(mv->symbol, symbol, symbollen);
2243 return mv;
2244}
2245
2246static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
2247{
2248 free(symbol);
2249}
2250
2251/**
2252 * kmod_module_get_symbols:
2253 * @mod: kmod module
2254 * @list: where to return list of module symbols. Use
2255 * kmod_module_symbols_get_symbol() and
2256 * kmod_module_symbols_get_crc(). Release this list with
2257 * kmod_module_symbols_unref_list()
2258 *
2259 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2260 *
2261 * After use, free the @list by calling kmod_module_symbols_free_list().
2262 *
2263 * Returns: 0 on success or < 0 otherwise.
2264 */
2265KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
2266{
2267 struct kmod_file *file;
2268 struct kmod_elf *elf;
2269 const char *path;
2270 const void *mem;
2271 struct kmod_modversion *symbols;
2272 size_t size;
2273 int i, count, ret = 0;
2274
2275 if (mod == NULL || list == NULL)
2276 return -ENOENT;
2277
2278 assert(*list == NULL);
2279
2280 path = kmod_module_get_path(mod);
2281 if (path == NULL)
2282 return -ENOENT;
2283
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002284 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002285 if (file == NULL)
2286 return -errno;
2287
2288 size = kmod_file_get_size(file);
2289 mem = kmod_file_get_contents(file);
2290
2291 elf = kmod_elf_new(mem, size);
2292 if (elf == NULL) {
2293 ret = -errno;
2294 goto elf_open_error;
2295 }
2296
2297 count = kmod_elf_get_symbols(elf, &symbols);
2298 if (count < 0) {
2299 ret = count;
2300 goto get_strings_error;
2301 }
2302
2303 for (i = 0; i < count; i++) {
2304 struct kmod_module_symbol *mv;
2305 struct kmod_list *n;
2306
2307 mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
2308 if (mv == NULL) {
2309 ret = -errno;
2310 kmod_module_symbols_free_list(*list);
2311 *list = NULL;
2312 goto list_error;
2313 }
2314
2315 n = kmod_list_append(*list, mv);
2316 if (n != NULL)
2317 *list = n;
2318 else {
2319 kmod_module_symbol_free(mv);
2320 kmod_module_symbols_free_list(*list);
2321 *list = NULL;
2322 ret = -ENOMEM;
2323 goto list_error;
2324 }
2325 }
2326 ret = count;
2327
2328list_error:
2329 free(symbols);
2330get_strings_error:
2331 kmod_elf_unref(elf);
2332elf_open_error:
2333 kmod_file_unref(file);
2334
2335 return ret;
2336}
2337
2338/**
2339 * kmod_module_symbols_get_symbol:
2340 * @entry: a list entry representing a kmod module symbols
2341 *
2342 * Get the symbol of a kmod module symbols.
2343 *
2344 * Returns: the symbol of this kmod module symbols on success or NULL
2345 * on failure. The string is owned by the symbols, do not free it.
2346 */
2347KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
2348{
2349 struct kmod_module_symbol *symbol;
2350
2351 if (entry == NULL)
2352 return NULL;
2353
2354 symbol = entry->data;
2355 return symbol->symbol;
2356}
2357
2358/**
2359 * kmod_module_symbol_get_crc:
2360 * @entry: a list entry representing a kmod module symbol
2361 *
2362 * Get the crc of a kmod module symbol.
2363 *
2364 * Returns: the crc of this kmod module symbol on success or NULL on
2365 * failure. The string is owned by the symbol, do not free it.
2366 */
2367KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
2368{
2369 struct kmod_module_symbol *symbol;
2370
2371 if (entry == NULL)
2372 return 0;
2373
2374 symbol = entry->data;
2375 return symbol->crc;
2376}
2377
2378/**
2379 * kmod_module_symbols_free_list:
2380 * @list: kmod module symbols list
2381 *
2382 * Release the resources taken by @list
2383 */
2384KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
2385{
2386 while (list) {
2387 kmod_module_symbol_free(list->data);
2388 list = kmod_list_remove(list);
2389 }
2390}
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002391
2392struct kmod_module_dependency_symbol {
2393 uint64_t crc;
2394 uint8_t bind;
2395 char symbol[];
2396};
2397
2398static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
2399{
2400 struct kmod_module_dependency_symbol *mv;
2401 size_t symbollen = strlen(symbol) + 1;
2402
2403 mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
2404 if (mv == NULL)
2405 return NULL;
2406
2407 mv->crc = crc;
2408 mv->bind = bind;
2409 memcpy(mv->symbol, symbol, symbollen);
2410 return mv;
2411}
2412
2413static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
2414{
2415 free(dependency_symbol);
2416}
2417
2418/**
2419 * kmod_module_get_dependency_symbols:
2420 * @mod: kmod module
2421 * @list: where to return list of module dependency_symbols. Use
2422 * kmod_module_dependency_symbol_get_symbol() and
2423 * kmod_module_dependency_symbol_get_crc(). Release this list with
2424 * kmod_module_dependency_symbols_free_list()
2425 *
2426 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2427 *
2428 * After use, free the @list by calling
2429 * kmod_module_dependency_symbols_free_list().
2430 *
2431 * Returns: 0 on success or < 0 otherwise.
2432 */
2433KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
2434{
2435 struct kmod_file *file;
2436 struct kmod_elf *elf;
2437 const char *path;
2438 const void *mem;
2439 struct kmod_modversion *symbols;
2440 size_t size;
2441 int i, count, ret = 0;
2442
2443 if (mod == NULL || list == NULL)
2444 return -ENOENT;
2445
2446 assert(*list == NULL);
2447
2448 path = kmod_module_get_path(mod);
2449 if (path == NULL)
2450 return -ENOENT;
2451
Lucas De Marchic68e92f2012-01-04 08:19:34 -02002452 file = kmod_file_open(mod->ctx, path);
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002453 if (file == NULL)
2454 return -errno;
2455
2456 size = kmod_file_get_size(file);
2457 mem = kmod_file_get_contents(file);
2458
2459 elf = kmod_elf_new(mem, size);
2460 if (elf == NULL) {
2461 ret = -errno;
2462 goto elf_open_error;
2463 }
2464
2465 count = kmod_elf_get_dependency_symbols(elf, &symbols);
2466 if (count < 0) {
2467 ret = count;
2468 goto get_strings_error;
2469 }
2470
2471 for (i = 0; i < count; i++) {
2472 struct kmod_module_dependency_symbol *mv;
2473 struct kmod_list *n;
2474
2475 mv = kmod_module_dependency_symbols_new(symbols[i].crc,
2476 symbols[i].bind,
2477 symbols[i].symbol);
2478 if (mv == NULL) {
2479 ret = -errno;
2480 kmod_module_dependency_symbols_free_list(*list);
2481 *list = NULL;
2482 goto list_error;
2483 }
2484
2485 n = kmod_list_append(*list, mv);
2486 if (n != NULL)
2487 *list = n;
2488 else {
2489 kmod_module_dependency_symbol_free(mv);
2490 kmod_module_dependency_symbols_free_list(*list);
2491 *list = NULL;
2492 ret = -ENOMEM;
2493 goto list_error;
2494 }
2495 }
2496 ret = count;
2497
2498list_error:
2499 free(symbols);
2500get_strings_error:
2501 kmod_elf_unref(elf);
2502elf_open_error:
2503 kmod_file_unref(file);
2504
2505 return ret;
2506}
2507
2508/**
2509 * kmod_module_dependency_symbol_get_symbol:
2510 * @entry: a list entry representing a kmod module dependency_symbols
2511 *
2512 * Get the dependency symbol of a kmod module
2513 *
2514 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
2515 * on failure. The string is owned by the dependency_symbols, do not free it.
2516 */
2517KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
2518{
2519 struct kmod_module_dependency_symbol *dependency_symbol;
2520
2521 if (entry == NULL)
2522 return NULL;
2523
2524 dependency_symbol = entry->data;
2525 return dependency_symbol->symbol;
2526}
2527
2528/**
2529 * kmod_module_dependency_symbol_get_crc:
2530 * @entry: a list entry representing a kmod module dependency_symbol
2531 *
2532 * Get the crc of a kmod module dependency_symbol.
2533 *
2534 * Returns: the crc of this kmod module dependency_symbol on success or NULL on
2535 * failure. The string is owned by the dependency_symbol, do not free it.
2536 */
2537KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
2538{
2539 struct kmod_module_dependency_symbol *dependency_symbol;
2540
2541 if (entry == NULL)
2542 return 0;
2543
2544 dependency_symbol = entry->data;
2545 return dependency_symbol->crc;
2546}
2547
2548/**
2549 * kmod_module_dependency_symbol_get_bind:
2550 * @entry: a list entry representing a kmod module dependency_symbol
2551 *
2552 * Get the bind type of a kmod module dependency_symbol.
2553 *
2554 * Returns: the bind of this kmod module dependency_symbol on success
2555 * or < 0 on failure.
2556 */
2557KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
2558{
2559 struct kmod_module_dependency_symbol *dependency_symbol;
2560
2561 if (entry == NULL)
2562 return 0;
2563
2564 dependency_symbol = entry->data;
2565 return dependency_symbol->bind;
2566}
2567
2568/**
2569 * kmod_module_dependency_symbols_free_list:
2570 * @list: kmod module dependency_symbols list
2571 *
2572 * Release the resources taken by @list
2573 */
2574KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
2575{
2576 while (list) {
2577 kmod_module_dependency_symbol_free(list->data);
2578 list = kmod_list_remove(list);
2579 }
2580}