blob: 0390250d0af50747ecbf861cf9bf0efdd9681145 [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 Marchi4f2bb7c2011-12-06 02:46:22 -0200188 char name_norm[NAME_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 Marchi113c66a2011-12-14 15:21:10 -0200240 char key[NAME_MAX];
241 size_t namelen = strlen(name);
242 size_t aliaslen = strlen(alias);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200243
Lucas De Marchi113c66a2011-12-14 15:21:10 -0200244 if (namelen + aliaslen + 2 > NAME_MAX)
245 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 Marchid753b8c2011-12-05 18:14:51 -0200286 char name[NAME_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;
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200437 char alias[NAME_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 Marchib72f74b2011-12-27 04:51:05 -0200503static const struct kmod_list *module_get_dependencies_noref(const struct kmod_module *mod)
504{
505 if (!mod->init.dep) {
506 /* lazy init */
507 char *line = kmod_search_moddep(mod->ctx, mod->name);
508
509 if (line == NULL)
510 return NULL;
511
512 kmod_module_parse_depline((struct kmod_module *)mod, line);
513 free(line);
514
515 if (!mod->init.dep)
516 return NULL;
517 }
518
519 return mod->dep;
520}
521
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200522/**
Lucas De Marchi91428ae2011-12-15 13:09:46 -0200523 * kmod_module_get_dependencies:
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200524 * @mod: kmod module
525 *
526 * Search the modules.dep index to find the dependencies of the given @mod.
527 * The result is cached in @mod, so subsequent calls to this function will
528 * return the already searched list of modules.
529 *
530 * Returns: NULL on failure or if there are any dependencies. Otherwise it
531 * returns a list of kmod modules that can be released by calling
532 * kmod_module_unref_list().
533 */
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200534KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200535{
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200536 struct kmod_list *l, *l_new, *list_new = NULL;
537
538 if (mod == NULL)
539 return NULL;
540
Lucas De Marchib72f74b2011-12-27 04:51:05 -0200541 module_get_dependencies_noref(mod);
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200542
543 kmod_list_foreach(l, mod->dep) {
544 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
545 if (l_new == NULL) {
546 kmod_module_unref(l->data);
547 goto fail;
548 }
549
550 list_new = l_new;
551 }
552
553 return list_new;
554
555fail:
556 ERR(mod->ctx, "out of memory\n");
557 kmod_module_unref_list(list_new);
558 return NULL;
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200559}
560
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200561/**
562 * kmod_module_get_module:
563 * @entry: an entry in a list of kmod modules.
564 *
565 * Get the kmod module of this @entry in the list, increasing its refcount.
566 * After it's used, unref it. Since the refcount is incremented upon return,
567 * you still have to call kmod_module_unref_list() to release the list of kmod
568 * modules.
569 *
570 * Returns: NULL on failure or the kmod_module contained in this list entry
571 * with its refcount incremented.
572 */
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200573KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200574{
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200575 if (entry == NULL)
576 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200577
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200578 return kmod_module_ref(entry->data);
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200579}
580
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200581/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200582 * kmod_module_get_name:
583 * @mod: kmod module
584 *
585 * Get the name of this kmod module. Name is always available, independently
586 * if it was created by kmod_module_new_from_name() or another function and
587 * it's always normalized (dashes are replaced with underscores).
588 *
589 * Returns: the name of this kmod module.
590 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200591KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200592{
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200593 if (mod == NULL)
594 return NULL;
595
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200596 return mod->name;
597}
598
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200599/**
600 * kmod_module_get_path:
601 * @mod: kmod module
602 *
603 * Get the path of this kmod module. If this kmod module was not created by
604 * path, it can search the modules.dep index in order to find out the module
605 * under context's dirname (see kmod_get_dirname()).
606 *
607 * Returns: the path of this kmod module or NULL if such information is not
608 * available.
609 */
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200610KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200611{
Lucas De Marchie005fac2011-12-08 10:42:34 -0200612 char *line;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200613
Lucas De Marchi818f8e82011-12-15 13:35:40 -0200614 if (mod == NULL)
615 return NULL;
616
Gustavo Sverzut Barbierid01c67e2011-12-11 19:42:02 -0200617 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200618
Lucas De Marchie005fac2011-12-08 10:42:34 -0200619 if (mod->path != NULL)
620 return mod->path;
621 if (mod->init.dep)
622 return NULL;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200623
Lucas De Marchie005fac2011-12-08 10:42:34 -0200624 /* lazy init */
625 line = kmod_search_moddep(mod->ctx, mod->name);
626 if (line == NULL)
627 return NULL;
628
629 kmod_module_parse_depline((struct kmod_module *) mod, line);
630 free(line);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200631
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200632 return mod->path;
633}
634
635
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200636extern long delete_module(const char *name, unsigned int flags);
637
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200638/**
639 * kmod_module_remove_module:
640 * @mod: kmod module
641 * @flags: flags to pass to Linux kernel when removing the module
642 *
643 * Remove a module from Linux kernel.
644 *
645 * Returns: 0 on success or < 0 on failure.
646 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200647KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
648 unsigned int flags)
649{
650 int err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200651
652 if (mod == NULL)
653 return -ENOENT;
654
655 /* Filter out other flags */
656 flags &= (KMOD_REMOVE_FORCE | KMOD_REMOVE_NOWAIT);
657
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200658 err = delete_module(mod->name, flags);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200659 if (err != 0) {
Lucas De Marchi63af0612011-12-14 12:07:37 -0200660 ERR(mod->ctx, "Could not remove '%s': %s\n", mod->name,
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200661 strerror(-err));
662 return err;
663 }
664
665 return 0;
666}
667
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200668extern long init_module(const void *mem, unsigned long len, const char *args);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200669
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200670/**
671 * kmod_module_insert_module:
672 * @mod: kmod module
Lucas De Marchi142db572011-12-20 23:39:30 -0200673 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
674 * behavior of this function.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200675 * @options: module's options to pass to Linux Kernel.
676 *
677 * Insert a module in Linux kernel. It opens the file pointed by @mod,
678 * mmap'ing it and passing to kernel.
679 *
Lucas De Marchibbf59322011-12-30 14:13:33 -0200680 * Returns: 0 on success or < 0 on failure. If module is already loaded it
681 * returns -EEXIST.
Lucas De Marchi7afc98a2011-12-14 12:06:18 -0200682 */
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200683KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200684 unsigned int flags,
685 const char *options)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200686{
687 int err;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200688 const void *mem;
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200689 off_t size;
690 struct kmod_file *file;
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200691 struct kmod_elf *elf = NULL;
692 const char *path;
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200693 const char *args = options ? options : "";
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200694
695 if (mod == NULL)
696 return -ENOENT;
697
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200698 path = kmod_module_get_path(mod);
699 if (path == NULL) {
Lucas De Marchif304afe2011-12-20 23:39:56 -0200700 ERR(mod->ctx, "Could not find module by name='%s'\n", mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200701 return -ENOSYS;
702 }
703
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200704 file = kmod_file_open(path);
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200705 if (file == NULL) {
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200706 err = -errno;
707 return err;
708 }
709
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200710 size = kmod_file_get_size(file);
711 mem = kmod_file_get_contents(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200712
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200713 if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
714 elf = kmod_elf_new(mem, size);
715 if (elf == NULL) {
716 err = -errno;
717 goto elf_failed;
718 }
719
720 if (flags & KMOD_INSERT_FORCE_MODVERSION) {
721 err = kmod_elf_strip_section(elf, "__versions");
722 if (err < 0)
723 INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
724 }
725
726 if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
727 err = kmod_elf_strip_vermagic(elf);
728 if (err < 0)
729 INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
730 }
731
732 mem = kmod_elf_get_memory(elf);
733 }
734
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200735 err = init_module(mem, size, args);
Lucas De Marchibbf59322011-12-30 14:13:33 -0200736 if (err < 0) {
737 err = -errno;
738 INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
739 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200740
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -0200741 if (elf != NULL)
742 kmod_elf_unref(elf);
743elf_failed:
Gustavo Sverzut Barbieri3d8226e2011-12-16 16:08:53 -0200744 kmod_file_unref(file);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200745
746 return err;
747}
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200748
Lucas De Marchiddbda022011-12-27 11:40:10 -0200749static bool module_is_blacklisted(struct kmod_module *mod)
750{
751 struct kmod_ctx *ctx = mod->ctx;
752 const struct kmod_list *bl = kmod_get_blacklists(ctx);
753 const struct kmod_list *l;
754
755 kmod_list_foreach(l, bl) {
756 const char *modname = kmod_blacklist_get_modname(l);
757
758 if (streq(modname, mod->name))
759 return true;
760 }
761
762 return false;
763}
764
765#define RECURSION_CHECK_STEP 10
766#define RET_CHECK_NOLOOP_OR_FAIL(_ret, _flags, _label) \
767 do { \
768 if (_ret < 0) { \
769 if (_ret == -ELOOP || _ret == -ENOMEM \
770 || (_flags & KMOD_PROBE_STOP_ON_FAILURE)) \
771 goto _label; \
772 } \
773 } while (0)
774
775struct probe_insert_cb {
776 int (*run_install)(struct kmod_module *m, const char *cmd, void *data);
777 void *data;
778};
779
780int module_probe_insert_module(struct kmod_module *mod,
781 unsigned int flags, const char *extra_options,
782 struct probe_insert_cb *cb,
783 struct kmod_list *rec, unsigned int reccount);
784
785static int command_do(struct kmod_module *mod, const char *type,
786 const char *cmd)
787{
788 const char *modname = kmod_module_get_name(mod);
789 int err;
790
791 DBG(mod->ctx, "%s %s\n", type, cmd);
792
793 setenv("MODPROBE_MODULE", modname, 1);
794 err = system(cmd);
795 unsetenv("MODPROBE_MODULE");
796
797 if (err == -1 || WEXITSTATUS(err)) {
798 ERR(mod->ctx, "Error running %s command for %s\n",
799 type, modname);
800 if (err != -1)
801 err = -WEXITSTATUS(err);
802 }
803
804 return err;
805}
806
807static int module_do_install_commands(struct kmod_module *mod,
808 const char *options,
809 struct probe_insert_cb *cb)
810{
811 const char *command = kmod_module_get_install_commands(mod);
812 char *p, *cmd;
813 int err;
814 size_t cmdlen, options_len, varlen;
815
816 assert(command);
817
818 if (options == NULL)
819 options = "";
820
821 options_len = strlen(options);
822 cmdlen = strlen(command);
823 varlen = sizeof("$CMDLINE_OPTS") - 1;
824
825 cmd = memdup(command, cmdlen + 1);
826 if (cmd == NULL)
827 return -ENOMEM;
828
829 while ((p = strstr(cmd, "$CMDLINE_OPTS")) != NULL) {
830 size_t prefixlen = p - cmd;
831 size_t suffixlen = cmdlen - prefixlen - varlen;
832 size_t slen = cmdlen - varlen + options_len;
833 char *suffix = p + varlen;
834 char *s = malloc(slen + 1);
835 if (s == NULL) {
836 free(cmd);
837 return -ENOMEM;
838 }
839 memcpy(s, cmd, p - cmd);
840 memcpy(s + prefixlen, options, options_len);
841 memcpy(s + prefixlen + options_len, suffix, suffixlen);
842 s[slen] = '\0';
843
844 free(cmd);
845 cmd = s;
846 cmdlen = slen;
847 }
848
849 if (cb->run_install != NULL)
850 err = cb->run_install(mod, cmd, cb->data);
851 else
852 err = command_do(mod, "install", cmd);
853
854 free(cmd);
855
856 return err;
857}
858
859static bool module_dep_has_loop(const struct kmod_list *deps,
860 struct kmod_list *rec,
861 unsigned int reccount)
862{
863 struct kmod_list *l;
864 struct kmod_module *mod;
865
866 if (reccount < RECURSION_CHECK_STEP || deps == NULL)
867 return false;
868
869 mod = deps->data;
870 reccount = 0;
871 kmod_list_foreach(l, rec) {
872 struct kmod_list *loop;
873
874 if (l->data != mod)
875 continue;
876
877 ERR(mod->ctx, "Dependency loop detected while inserting '%s'. Operation aborted\n",
878 mod->name);
879
880 for (loop = l; loop != NULL;
881 loop = kmod_list_next(rec, loop)) {
882 struct kmod_module *m = loop->data;
883 ERR(mod->ctx, "%s\n", m->name);
884 }
885
886 return true;
887 }
888
889 return false;
890}
891
892static int module_do_insmod_dep(const struct kmod_list *deps,
893 unsigned int flags, struct probe_insert_cb *cb,
894 struct kmod_list *rec, unsigned int reccount)
895{
896 const struct kmod_list *d;
897 int err = 0;
898
899 if (module_dep_has_loop(deps, rec, reccount))
900 return -ELOOP;
901
902 kmod_list_foreach(d, deps) {
903 struct kmod_module *dm = d->data;
904 struct kmod_list *tmp;
905
906 tmp = kmod_list_append(rec, dm);
907 if (tmp == NULL)
908 return -ENOMEM;
909 rec = tmp;
910
911 err = module_probe_insert_module(dm, flags, NULL, cb,
912 rec, reccount + 1);
913
914 rec = kmod_list_remove_n_latest(rec, 1);
915 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
916 }
917
918finish:
919 return err;
920}
921
922static char *module_options_concat(const char *opt, const char *xopt)
923{
924 // TODO: we might need to check if xopt overrides options on opt
925 size_t optlen = opt == NULL ? 0 : strlen(opt);
926 size_t xoptlen = xopt == NULL ? 0 : strlen(xopt);
927 char *r;
928
929 if (optlen == 0 && xoptlen == 0)
930 return NULL;
931
932 r = malloc(optlen + xoptlen + 2);
933
934 if (opt != NULL) {
935 memcpy(r, opt, optlen);
936 r[optlen] = ' ';
937 optlen++;
938 }
939
940 if (xopt != NULL)
941 memcpy(r + optlen, xopt, xoptlen);
942
943 r[optlen + xoptlen] = '\0';
944
945 return r;
946}
947
948/*
949 * Do the probe_insert work recursively. We traverse the dependencies in
950 * depth-first order, checking the following conditions:
951 *
952 * - Is blacklisted?
953 * - Is install command?
954 * - Is already loaded?
955 *
956 * Then we insert the modules (calling module_do_insmod_dep(), which will
957 * re-enter this function) needed to load @mod in the following order:
958 *
959 * 1) pre-softdep
960 * 2) dependency
961 * 3) @mod
962 * 4) post-softdep
963 */
964int module_probe_insert_module(struct kmod_module *mod,
965 unsigned int flags, const char *extra_options,
966 struct probe_insert_cb *cb,
967 struct kmod_list *rec, unsigned int reccount)
968{
969 int err;
970 const char *install_cmds;
971 const struct kmod_list *dep;
972 struct kmod_list *pre = NULL, *post = NULL;
973 char *options;
974
975 if ((flags & KMOD_PROBE_STOP_ON_BLACKLIST)
976 && module_is_blacklisted(mod)) {
977 DBG(mod->ctx, "Stopping on '%s': blacklisted\n", mod->name);
978 return -EINVAL;
979 }
980
981 install_cmds = kmod_module_get_install_commands(mod);
982 if (install_cmds != NULL) {
983 if (flags & KMOD_PROBE_STOP_ON_COMMAND) {
984 DBG(mod->ctx, "Stopping on '%s': install command\n",
985 mod->name);
986 return -EINVAL;
987 }
988 } else {
989 int state = kmod_module_get_initstate(mod);
990
991 if (state == KMOD_MODULE_LIVE ||
992 state == KMOD_MODULE_COMING ||
993 state == KMOD_MODULE_BUILTIN)
994 return 0;
995 }
996
997 err = kmod_module_get_softdeps(mod, &pre, &post);
998 if (err < 0)
999 return err;
1000
1001 err = module_do_insmod_dep(pre, flags, cb, rec, reccount);
1002 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
1003
1004 dep = module_get_dependencies_noref(mod);
1005 err = module_do_insmod_dep(dep, flags, cb, rec, reccount);
1006 RET_CHECK_NOLOOP_OR_FAIL(err, flags, finish);
1007
1008 options = module_options_concat(kmod_module_get_options(mod),
1009 extra_options);
1010
1011 if (install_cmds != NULL)
1012 err = module_do_install_commands(mod, options, cb);
1013 else
1014 err = kmod_module_insert_module(mod, flags, options);
1015
1016 free(options);
1017
1018 if (err < 0 && (flags & KMOD_PROBE_STOP_ON_FAILURE))
1019 return err;
1020
1021 err = module_do_insmod_dep(post, flags, cb, rec, reccount);
1022
1023finish:
1024 kmod_module_unref_list(pre);
1025 kmod_module_unref_list(post);
1026
1027 return err;
1028}
1029
1030/**
1031 * kmod_module_probe_insert_module:
1032 * @mod: kmod module
1033 * @flags: flags are not passed to Linux Kernel, but instead they dictate the
1034 * behavior of this function.
1035 * @extra_options: module's options to pass to Linux Kernel.
1036 * @run_install: function to run when @mod is backed by a install command.
1037 * @data: data to give back to @run_install callback
1038 *
1039 * Insert a module in Linux kernel resolving dependencies, soft dependencies
1040 * install commands and applying blacklist.
1041 *
1042 * If @run_install is NULL, and the flag KMOD_PROBE_STOP_ON_COMMANDS is not
1043 * given, this function will fork and exec by calling system(3). If you need
1044 * control over the execution of an install command, give a callback function
1045 * in @run_install.
1046 *
1047 * Returns: 0 on success or < 0 on failure.
1048 */
1049KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
1050 unsigned int flags, const char *extra_options,
1051 int (*run_install)(struct kmod_module *m,
1052 const char *cmd, void *data),
1053 const void *data)
1054{
1055 struct probe_insert_cb cb;
1056
1057 cb.run_install = run_install;
1058 cb.data = (void *) data;
1059
1060 return module_probe_insert_module(mod, flags, extra_options, &cb,
1061 NULL, 0);
1062}
1063
1064#undef RECURSION_CHECK_STEP
1065#undef RET_CHECK_NOLOOP_OR_FAIL
1066
1067
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001068/**
1069 * kmod_module_get_options:
1070 * @mod: kmod module
1071 *
1072 * Get options of this kmod module. Options come from the configuration file
1073 * and are cached in @mod. The first call to this function will search for
1074 * this module in configuration and subsequent calls return the cached string.
1075 *
1076 * Returns: a string with all the options separated by spaces. This string is
1077 * owned by @mod, do not free it.
1078 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001079KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
1080{
1081 if (mod == NULL)
1082 return NULL;
1083
1084 if (!mod->init.options) {
1085 /* lazy init */
1086 struct kmod_module *m = (struct kmod_module *)mod;
1087 const struct kmod_list *l, *ctx_options;
1088 char *opts = NULL;
1089 size_t optslen = 0;
1090
1091 ctx_options = kmod_get_options(mod->ctx);
1092
1093 kmod_list_foreach(l, ctx_options) {
1094 const char *modname = kmod_option_get_modname(l);
1095 const char *str;
1096 size_t len;
1097 void *tmp;
1098
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001099 DBG(mod->ctx, "modname=%s mod->name=%s mod->alias=%s\n", modname, mod->name, mod->alias);
1100 if (!(streq(modname, mod->name) || (mod->alias != NULL &&
1101 streq(modname, mod->alias))))
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001102 continue;
1103
Lucas De Marchi07b8c822011-12-13 14:21:24 -02001104 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 -02001105 str = kmod_option_get_options(l);
1106 len = strlen(str);
1107 if (len < 1)
1108 continue;
1109
1110 tmp = realloc(opts, optslen + len + 2);
1111 if (tmp == NULL) {
1112 free(opts);
1113 goto failed;
1114 }
1115
1116 opts = tmp;
1117
1118 if (optslen > 0) {
1119 opts[optslen] = ' ';
1120 optslen++;
1121 }
1122
1123 memcpy(opts + optslen, str, len);
1124 optslen += len;
1125 opts[optslen] = '\0';
1126 }
1127
1128 m->init.options = true;
1129 m->options = opts;
1130 }
1131
1132 return mod->options;
1133
1134failed:
1135 ERR(mod->ctx, "out of memory\n");
1136 return NULL;
1137}
1138
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001139/**
1140 * kmod_module_get_install_commands:
1141 * @mod: kmod module
1142 *
1143 * Get install commands for this kmod module. Install commands come from the
1144 * configuration file and are cached in @mod. The first call to this function
1145 * will search for this module in configuration and subsequent calls return
1146 * the cached string. The install commands are returned as they were in the
1147 * configuration, concatenated by ';'. No other processing is made in this
1148 * string.
1149 *
1150 * Returns: a string with all install commands separated by semicolons. This
1151 * string is owned by @mod, do not free it.
1152 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001153KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
1154{
1155 if (mod == NULL)
1156 return NULL;
1157
1158 if (!mod->init.install_commands) {
1159 /* lazy init */
1160 struct kmod_module *m = (struct kmod_module *)mod;
1161 const struct kmod_list *l, *ctx_install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001162
1163 ctx_install_commands = kmod_get_install_commands(mod->ctx);
1164
1165 kmod_list_foreach(l, ctx_install_commands) {
1166 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001167
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001168 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001169 continue;
1170
Lucas De Marchi60f67602011-12-16 03:33:26 -02001171 m->install_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001172
Lucas De Marchi60f67602011-12-16 03:33:26 -02001173 /*
1174 * find only the first command, as modprobe from
1175 * module-init-tools does
1176 */
1177 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001178 }
1179
1180 m->init.install_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001181 }
1182
1183 return mod->install_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001184}
1185
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001186void kmod_module_set_install_commands(struct kmod_module *mod, const char *cmd)
1187{
1188 mod->init.install_commands = true;
1189 mod->install_commands = cmd;
1190}
1191
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001192static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const * array, unsigned int count)
1193{
1194 struct kmod_list *ret = NULL;
1195 unsigned i;
1196
1197 for (i = 0; i < count; i++) {
1198 const char *depname = array[i];
1199 struct kmod_list *lst = NULL;
1200 int err;
1201
1202 err = kmod_module_new_from_lookup(ctx, depname, &lst);
1203 if (err < 0) {
1204 ERR(ctx, "failed to lookup soft dependency '%s', continuing anyway.\n", depname);
1205 continue;
1206 } else if (lst != NULL)
1207 ret = kmod_list_append_list(ret, lst);
1208 }
1209 return ret;
1210}
1211
1212/**
1213 * kmod_module_get_softdeps:
1214 * @mod: kmod module
1215 * @pre: where to save the list of preceding soft dependencies.
1216 * @post: where to save the list of post soft dependencies.
1217 *
1218 * Get soft dependencies for this kmod module. Soft dependencies come
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001219 * from configuration file and are not cached in @mod because it may include
1220 * dependency cycles that would make we leak kmod_module. Any call
1221 * to this function will search for this module in configuration, allocate a
1222 * list and return the result.
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001223 *
1224 * Both @pre and @post are newly created list of kmod_module and
1225 * should be unreferenced with kmod_module_unref_list().
1226 *
1227 * Returns: 0 on success or < 0 otherwise.
1228 */
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001229KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
1230 struct kmod_list **pre,
1231 struct kmod_list **post)
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001232{
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001233 const struct kmod_list *l, *ctx_softdeps;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001234
1235 if (mod == NULL || pre == NULL || post == NULL)
1236 return -ENOENT;
1237
1238 assert(*pre == NULL);
1239 assert(*post == NULL);
1240
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001241 ctx_softdeps = kmod_get_softdeps(mod->ctx);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001242
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001243 kmod_list_foreach(l, ctx_softdeps) {
1244 const char *modname = kmod_softdep_get_name(l);
1245 const char * const *array;
1246 unsigned count;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001247
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001248 if (fnmatch(modname, mod->name, 0) != 0)
1249 continue;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001250
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001251 array = kmod_softdep_get_pre(l, &count);
1252 *pre = lookup_softdep(mod->ctx, array, count);
1253 array = kmod_softdep_get_post(l, &count);
1254 *post = lookup_softdep(mod->ctx, array, count);
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001255
Lucas De Marchi2bd7cbf2011-12-27 10:15:40 -02001256 /*
1257 * find only the first command, as modprobe from
1258 * module-init-tools does
1259 */
1260 break;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001261 }
1262
1263 return 0;
Gustavo Sverzut Barbieri1c522602011-12-16 21:18:10 -02001264}
1265
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001266/**
1267 * kmod_module_get_remove_commands:
1268 * @mod: kmod module
1269 *
1270 * Get remove commands for this kmod module. Remove commands come from the
1271 * configuration file and are cached in @mod. The first call to this function
1272 * will search for this module in configuration and subsequent calls return
1273 * the cached string. The remove commands are returned as they were in the
1274 * configuration, concatenated by ';'. No other processing is made in this
1275 * string.
1276 *
1277 * Returns: a string with all remove commands separated by semicolons. This
1278 * string is owned by @mod, do not free it.
1279 */
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001280KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
1281{
1282 if (mod == NULL)
1283 return NULL;
1284
1285 if (!mod->init.remove_commands) {
1286 /* lazy init */
1287 struct kmod_module *m = (struct kmod_module *)mod;
1288 const struct kmod_list *l, *ctx_remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001289
1290 ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
1291
1292 kmod_list_foreach(l, ctx_remove_commands) {
1293 const char *modname = kmod_command_get_modname(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001294
Gustavo Sverzut Barbieria6bf2492011-12-16 22:43:04 -02001295 if (fnmatch(modname, mod->name, 0) != 0)
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001296 continue;
1297
Lucas De Marchi60f67602011-12-16 03:33:26 -02001298 m->remove_commands = kmod_command_get_command(l);
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001299
Lucas De Marchi60f67602011-12-16 03:33:26 -02001300 /*
1301 * find only the first command, as modprobe from
1302 * module-init-tools does
1303 */
1304 break;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001305 }
1306
1307 m->init.remove_commands = true;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001308 }
1309
1310 return mod->remove_commands;
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001311}
1312
Lucas De Marchif4fc5522011-12-16 03:57:12 -02001313void kmod_module_set_remove_commands(struct kmod_module *mod, const char *cmd)
1314{
1315 mod->init.remove_commands = true;
1316 mod->remove_commands = cmd;
1317}
1318
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001319/**
1320 * SECTION:libkmod-loaded
1321 * @short_description: currently loaded modules
1322 *
1323 * Information about currently loaded modules, as reported by Linux kernel.
1324 * These information are not cached by libkmod and are always read from /sys
1325 * and /proc/modules.
1326 */
1327
1328/**
1329 * kmod_module_new_from_loaded:
1330 * @ctx: kmod library context
1331 * @list: where to save the list of loaded modules
1332 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001333 * Create a new list of kmod modules with all modules currently loaded in
1334 * kernel. It uses /proc/modules to get the names of loaded modules and to
1335 * create kmod modules by calling kmod_module_new_from_name() in each of them.
1336 * They are put are put in @list in no particular order.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001337 *
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001338 * The initial refcount is 1, and needs to be decremented to release the
1339 * resources of the kmod_module. The returned @list must be released by
1340 * calling kmod_module_unref_list(). Since libkmod keeps track of all
1341 * kmod_modules created, they are all released upon @ctx destruction too. Do
1342 * not unref @ctx before all the desired operations with the returned list are
1343 * completed.
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001344 *
1345 * Returns: 0 on success or < 0 on error.
1346 */
1347KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
1348 struct kmod_list **list)
1349{
1350 struct kmod_list *l = NULL;
1351 FILE *fp;
1352 char line[4096];
1353
1354 if (ctx == NULL || list == NULL)
1355 return -ENOENT;
1356
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001357 fp = fopen("/proc/modules", "re");
Lucas De Marchi49ce6d02011-12-12 13:56:47 -02001358 if (fp == NULL) {
1359 int err = -errno;
1360 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
1361 return err;
1362 }
1363
1364 while (fgets(line, sizeof(line), fp)) {
1365 struct kmod_module *m;
1366 struct kmod_list *node;
1367 int err;
1368 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
1369
1370 err = kmod_module_new_from_name(ctx, name, &m);
1371 if (err < 0) {
1372 ERR(ctx, "could not get module from name '%s': %s\n",
1373 name, strerror(-err));
1374 continue;
1375 }
1376
1377 node = kmod_list_append(l, m);
1378 if (node)
1379 l = node;
1380 else {
1381 ERR(ctx, "out of memory\n");
1382 kmod_module_unref(m);
1383 }
1384 }
1385
1386 fclose(fp);
1387 *list = l;
1388
1389 return 0;
1390}
1391
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001392/**
1393 * kmod_module_initstate_str:
1394 * @state: the state as returned by kmod_module_get_initstate()
1395 *
1396 * Translate a initstate to a string.
1397 *
1398 * Returns: the string associated to the @state. This string is statically
1399 * allocated, do not free it.
1400 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001401KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
1402{
1403 switch (state) {
1404 case KMOD_MODULE_BUILTIN:
1405 return "builtin";
1406 case KMOD_MODULE_LIVE:
1407 return "live";
1408 case KMOD_MODULE_COMING:
1409 return "coming";
1410 case KMOD_MODULE_GOING:
1411 return "going";
1412 default:
1413 return NULL;
1414 }
1415}
1416
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001417/**
1418 * kmod_module_get_initstate:
1419 * @mod: kmod module
1420 *
1421 * Get the initstate of this @mod, as returned by Linux Kernel, by reading
1422 * /sys filesystem.
1423 *
1424 * Returns: < 0 on error or enum kmod_initstate if module is found in kernel.
1425 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001426KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
1427{
1428 char path[PATH_MAX], buf[32];
1429 int fd, err, pathlen;
1430
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001431 if (mod == NULL)
1432 return -ENOENT;
1433
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001434 pathlen = snprintf(path, sizeof(path),
1435 "/sys/module/%s/initstate", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001436 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001437 if (fd < 0) {
1438 err = -errno;
1439
Lucas De Marchiddbda022011-12-27 11:40:10 -02001440 DBG(mod->ctx, "could not open '%s': %s\n",
1441 path, strerror(-err));
1442
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001443 if (pathlen > (int)sizeof("/initstate") - 1) {
1444 struct stat st;
1445 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
1446 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
1447 return KMOD_MODULE_BUILTIN;
1448 }
1449
Gustavo Sverzut Barbieri926f67a2011-12-11 19:33:03 -02001450 DBG(mod->ctx, "could not open '%s': %s\n",
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001451 path, strerror(-err));
1452 return err;
1453 }
1454
1455 err = read_str_safe(fd, buf, sizeof(buf));
1456 close(fd);
1457 if (err < 0) {
1458 ERR(mod->ctx, "could not read from '%s': %s\n",
1459 path, strerror(-err));
1460 return err;
1461 }
1462
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001463 if (streq(buf, "live\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001464 return KMOD_MODULE_LIVE;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001465 else if (streq(buf, "coming\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001466 return KMOD_MODULE_COMING;
Lucas De Marchi877e80c2011-12-07 02:26:31 -02001467 else if (streq(buf, "going\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001468 return KMOD_MODULE_GOING;
1469
1470 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
1471 return -EINVAL;
1472}
1473
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001474/**
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001475 * kmod_module_get_size:
1476 * @mod: kmod module
1477 *
1478 * Get the size of this kmod module as returned by Linux kernel. It reads the
1479 * file /proc/modules to search for this module and get its size.
1480 *
1481 * Returns: the size of this kmod module.
1482 */
1483KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
1484{
1485 // FIXME TODO: this should be available from /sys/module/foo
1486 FILE *fp;
1487 char line[4096];
1488 int lineno = 0;
1489 long size = -ENOENT;
1490
1491 if (mod == NULL)
1492 return -ENOENT;
1493
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001494 fp = fopen("/proc/modules", "re");
Lucas De Marchi2d7bab52011-12-14 12:10:02 -02001495 if (fp == NULL) {
1496 int err = -errno;
1497 ERR(mod->ctx,
1498 "could not open /proc/modules: %s\n", strerror(errno));
1499 return err;
1500 }
1501
1502 while (fgets(line, sizeof(line), fp)) {
1503 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
1504 long value;
1505
1506 lineno++;
1507 if (tok == NULL || !streq(tok, mod->name))
1508 continue;
1509
1510 tok = strtok_r(NULL, " \t", &saveptr);
1511 if (tok == NULL) {
1512 ERR(mod->ctx,
1513 "invalid line format at /proc/modules:%d\n", lineno);
1514 break;
1515 }
1516
1517 value = strtol(tok, &endptr, 10);
1518 if (endptr == tok || *endptr != '\0') {
1519 ERR(mod->ctx,
1520 "invalid line format at /proc/modules:%d\n", lineno);
1521 break;
1522 }
1523
1524 size = value;
1525 break;
1526 }
1527 fclose(fp);
1528 return size;
1529}
1530
1531/**
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001532 * kmod_module_get_refcnt:
1533 * @mod: kmod module
1534 *
1535 * Get the ref count of this @mod, as returned by Linux Kernel, by reading
1536 * /sys filesystem.
1537 *
1538 * Returns: 0 on success or < 0 on failure.
1539 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001540KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
1541{
1542 char path[PATH_MAX];
1543 long refcnt;
1544 int fd, err;
1545
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001546 if (mod == NULL)
1547 return -ENOENT;
1548
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001549 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
Cristian Rodríguez79e5ea92011-12-16 02:49:54 -03001550 fd = open(path, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001551 if (fd < 0) {
1552 err = -errno;
1553 ERR(mod->ctx, "could not open '%s': %s\n",
1554 path, strerror(errno));
1555 return err;
1556 }
1557
1558 err = read_str_long(fd, &refcnt, 10);
1559 close(fd);
1560 if (err < 0) {
1561 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
1562 path, strerror(-err));
1563 return err;
1564 }
1565
1566 return (int)refcnt;
1567}
1568
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001569/**
1570 * kmod_module_get_holders:
1571 * @mod: kmod module
1572 *
1573 * Get a list of kmod modules that are holding this @mod, as returned by Linux
1574 * Kernel. After use, free the @list by calling kmod_module_unref_list().
1575 *
1576 * Returns: a new list of kmod modules on success or NULL on failure.
1577 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001578KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
1579{
1580 char dname[PATH_MAX];
1581 struct kmod_list *list = NULL;
1582 DIR *d;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001583
1584 if (mod == NULL)
1585 return NULL;
Lucas De Marchi818f8e82011-12-15 13:35:40 -02001586
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001587 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
1588
1589 d = opendir(dname);
1590 if (d == NULL) {
1591 ERR(mod->ctx, "could not open '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001592 dname, strerror(errno));
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001593 return NULL;
1594 }
1595
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001596 for (;;) {
1597 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001598 struct kmod_module *holder;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001599 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001600 int err;
1601
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001602 err = readdir_r(d, &de, &entp);
1603 if (err != 0) {
1604 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1605 mod->name, strerror(-err));
1606 goto fail;
1607 }
1608
1609 if (entp == NULL)
1610 break;
1611
1612 if (de.d_name[0] == '.') {
1613 if (de.d_name[1] == '\0' ||
1614 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001615 continue;
1616 }
1617
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001618 err = kmod_module_new_from_name(mod->ctx, de.d_name, &holder);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001619 if (err < 0) {
1620 ERR(mod->ctx, "could not create module for '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001621 de.d_name, strerror(-err));
1622 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001623 }
1624
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001625 l = kmod_list_append(list, holder);
1626 if (l != NULL) {
1627 list = l;
1628 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001629 ERR(mod->ctx, "out of memory\n");
1630 kmod_module_unref(holder);
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001631 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001632 }
1633 }
1634
1635 closedir(d);
1636 return list;
Lucas De Marchi53886dd2011-12-05 13:24:23 -02001637
1638fail:
1639 closedir(d);
1640 kmod_module_unref_list(list);
1641 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001642}
1643
1644struct kmod_module_section {
1645 unsigned long address;
1646 char name[];
1647};
1648
1649static void kmod_module_section_free(struct kmod_module_section *section)
1650{
1651 free(section);
1652}
1653
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001654/**
1655 * kmod_module_get_sections:
1656 * @mod: kmod module
1657 *
1658 * Get a list of kmod sections of this @mod, as returned by Linux Kernel. The
1659 * structure contained in this list is internal to libkmod and their fields
1660 * can be obtained by calling kmod_module_section_get_name() and
1661 * kmod_module_section_get_address().
1662 *
1663 * After use, free the @list by calling kmod_module_section_free_list().
1664 *
1665 * Returns: a new list of kmod module sections on success or NULL on failure.
1666 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001667KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1668{
1669 char dname[PATH_MAX];
1670 struct kmod_list *list = NULL;
1671 DIR *d;
1672 int dfd;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001673
1674 if (mod == NULL)
1675 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001676
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001677 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1678
1679 d = opendir(dname);
1680 if (d == NULL) {
1681 ERR(mod->ctx, "could not open '%s': %s\n",
1682 dname, strerror(errno));
1683 return NULL;
1684 }
1685
1686 dfd = dirfd(d);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001687
1688 for (;;) {
1689 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001690 struct kmod_module_section *section;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001691 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001692 unsigned long address;
1693 size_t namesz;
1694 int fd, err;
1695
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001696 err = readdir_r(d, &de, &entp);
1697 if (err != 0) {
1698 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1699 mod->name, strerror(-err));
1700 goto fail;
1701 }
1702
1703 if (de.d_name[0] == '.') {
1704 if (de.d_name[1] == '\0' ||
1705 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001706 continue;
1707 }
1708
Cristian Rodríguez8e3e5832011-12-16 14:46:52 -03001709 fd = openat(dfd, de.d_name, O_RDONLY|O_CLOEXEC);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001710 if (fd < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001711 ERR(mod->ctx, "could not open '%s/%s': %m\n",
1712 dname, de.d_name);
1713 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001714 }
1715
1716 err = read_str_ulong(fd, &address, 16);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001717 close(fd);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001718 if (err < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001719 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
1720 dname, de.d_name);
1721 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001722 }
1723
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001724 namesz = strlen(de.d_name) + 1;
1725 section = malloc(sizeof(*section) + namesz);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001726
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001727 if (section == NULL) {
1728 ERR(mod->ctx, "out of memory\n");
1729 goto fail;
1730 }
1731
1732 section->address = address;
1733 memcpy(section->name, de.d_name, namesz);
1734
1735 l = kmod_list_append(list, section);
1736 if (l != NULL) {
1737 list = l;
1738 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001739 ERR(mod->ctx, "out of memory\n");
1740 free(section);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001741 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001742 }
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001743 }
1744
1745 closedir(d);
1746 return list;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001747
1748fail:
1749 closedir(d);
1750 kmod_module_unref_list(list);
1751 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001752}
1753
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001754/**
1755 * kmod_module_section_get_module_name:
1756 * @entry: a list entry representing a kmod module section
1757 *
1758 * Get the name of a kmod module section.
1759 *
1760 * After use, free the @list by calling kmod_module_section_free_list().
1761 *
1762 * Returns: the name of this kmod module section on success or NULL on
1763 * failure. The string is owned by the section, do not free it.
1764 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001765KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
1766{
1767 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001768
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001769 if (entry == NULL)
1770 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001771
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001772 section = entry->data;
1773 return section->name;
1774}
1775
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001776/**
1777 * kmod_module_section_get_address:
1778 * @entry: a list entry representing a kmod module section
1779 *
1780 * Get the address of a kmod module section.
1781 *
1782 * After use, free the @list by calling kmod_module_section_free_list().
1783 *
1784 * Returns: the address of this kmod module section on success or ULONG_MAX
1785 * on failure.
1786 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001787KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
1788{
1789 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001790
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001791 if (entry == NULL)
1792 return (unsigned long)-1;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001793
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001794 section = entry->data;
1795 return section->address;
1796}
1797
Lucas De Marchi7afc98a2011-12-14 12:06:18 -02001798/**
1799 * kmod_module_section_free_list:
1800 * @list: kmod module section list
1801 *
1802 * Release the resources taken by @list
1803 */
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001804KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
1805{
1806 while (list) {
1807 kmod_module_section_free(list->data);
1808 list = kmod_list_remove(list);
1809 }
1810}
Gustavo Sverzut Barbieri708624a2011-12-18 01:25:06 -02001811
1812struct kmod_module_info {
1813 char *key;
1814 char value[];
1815};
1816
1817static struct kmod_module_info *kmod_module_info_new(const char *key, size_t keylen, const char *value, size_t valuelen)
1818{
1819 struct kmod_module_info *info;
1820
1821 info = malloc(sizeof(struct kmod_module_info) + keylen + valuelen + 2);
1822 if (info == NULL)
1823 return NULL;
1824
1825 info->key = (char *)info + sizeof(struct kmod_module_info)
1826 + valuelen + 1;
1827 memcpy(info->key, key, keylen);
1828 info->key[keylen] = '\0';
1829 memcpy(info->value, value, valuelen);
1830 info->value[valuelen] = '\0';
1831 return info;
1832}
1833
1834static void kmod_module_info_free(struct kmod_module_info *info)
1835{
1836 free(info);
1837}
1838
1839/**
1840 * kmod_module_get_info:
1841 * @mod: kmod module
1842 * @list: where to return list of module information. Use
1843 * kmod_module_info_get_key() and
1844 * kmod_module_info_get_value(). Release this list with
1845 * kmod_module_info_unref_list()
1846 *
1847 * Get a list of entries in ELF section ".modinfo", these contain
1848 * alias, license, depends, vermagic and other keys with respective
1849 * values.
1850 *
1851 * After use, free the @list by calling kmod_module_info_free_list().
1852 *
1853 * Returns: 0 on success or < 0 otherwise.
1854 */
1855KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
1856{
1857 struct kmod_file *file;
1858 struct kmod_elf *elf;
1859 const char *path;
1860 const void *mem;
1861 char **strings;
1862 size_t size;
1863 int i, count, ret = 0;
1864
1865 if (mod == NULL || list == NULL)
1866 return -ENOENT;
1867
1868 assert(*list == NULL);
1869
1870 path = kmod_module_get_path(mod);
1871 if (path == NULL)
1872 return -ENOENT;
1873
1874 file = kmod_file_open(path);
1875 if (file == NULL)
1876 return -errno;
1877
1878 size = kmod_file_get_size(file);
1879 mem = kmod_file_get_contents(file);
1880
1881 elf = kmod_elf_new(mem, size);
1882 if (elf == NULL) {
1883 ret = -errno;
1884 goto elf_open_error;
1885 }
1886
1887 count = kmod_elf_get_strings(elf, ".modinfo", &strings);
1888 if (count < 0) {
1889 ret = count;
1890 goto get_strings_error;
1891 }
1892
1893 for (i = 0; i < count; i++) {
1894 struct kmod_module_info *info;
1895 struct kmod_list *n;
1896 const char *key, *value;
1897 size_t keylen, valuelen;
1898
1899 key = strings[i];
1900 value = strchr(key, '=');
1901 if (value == NULL) {
1902 keylen = strlen(key);
1903 valuelen = 0;
1904 } else {
1905 keylen = value - key;
1906 value++;
1907 valuelen = strlen(value);
1908 }
1909
1910 info = kmod_module_info_new(key, keylen, value, valuelen);
1911 if (info == NULL) {
1912 ret = -errno;
1913 kmod_module_info_free_list(*list);
1914 *list = NULL;
1915 goto list_error;
1916 }
1917
1918 n = kmod_list_append(*list, info);
1919 if (n != NULL)
1920 *list = n;
1921 else {
1922 kmod_module_info_free(info);
1923 kmod_module_info_free_list(*list);
1924 *list = NULL;
1925 ret = -ENOMEM;
1926 goto list_error;
1927 }
1928 }
1929 ret = count;
1930
1931list_error:
1932 free(strings);
1933get_strings_error:
1934 kmod_elf_unref(elf);
1935elf_open_error:
1936 kmod_file_unref(file);
1937
1938 return ret;
1939}
1940
1941/**
1942 * kmod_module_info_get_key:
1943 * @entry: a list entry representing a kmod module info
1944 *
1945 * Get the key of a kmod module info.
1946 *
1947 * Returns: the key of this kmod module info on success or NULL on
1948 * failure. The string is owned by the info, do not free it.
1949 */
1950KMOD_EXPORT const char *kmod_module_info_get_key(const struct kmod_list *entry)
1951{
1952 struct kmod_module_info *info;
1953
1954 if (entry == NULL)
1955 return NULL;
1956
1957 info = entry->data;
1958 return info->key;
1959}
1960
1961/**
1962 * kmod_module_info_get_value:
1963 * @entry: a list entry representing a kmod module info
1964 *
1965 * Get the value of a kmod module info.
1966 *
1967 * Returns: the value of this kmod module info on success or NULL on
1968 * failure. The string is owned by the info, do not free it.
1969 */
1970KMOD_EXPORT const char *kmod_module_info_get_value(const struct kmod_list *entry)
1971{
1972 struct kmod_module_info *info;
1973
1974 if (entry == NULL)
1975 return NULL;
1976
1977 info = entry->data;
1978 return info->value;
1979}
1980
1981/**
1982 * kmod_module_info_free_list:
1983 * @list: kmod module info list
1984 *
1985 * Release the resources taken by @list
1986 */
1987KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
1988{
1989 while (list) {
1990 kmod_module_info_free(list->data);
1991 list = kmod_list_remove(list);
1992 }
1993}
1994
1995struct kmod_module_version {
1996 uint64_t crc;
1997 char symbol[];
1998};
1999
2000static struct kmod_module_version *kmod_module_versions_new(uint64_t crc, const char *symbol)
2001{
2002 struct kmod_module_version *mv;
2003 size_t symbollen = strlen(symbol) + 1;
2004
2005 mv = malloc(sizeof(struct kmod_module_version) + symbollen);
2006 if (mv == NULL)
2007 return NULL;
2008
2009 mv->crc = crc;
2010 memcpy(mv->symbol, symbol, symbollen);
2011 return mv;
2012}
2013
2014static void kmod_module_version_free(struct kmod_module_version *version)
2015{
2016 free(version);
2017}
2018
2019/**
2020 * kmod_module_get_versions:
2021 * @mod: kmod module
2022 * @list: where to return list of module versions. Use
2023 * kmod_module_versions_get_symbol() and
2024 * kmod_module_versions_get_crc(). Release this list with
2025 * kmod_module_versions_unref_list()
2026 *
2027 * Get a list of entries in ELF section "__versions".
2028 *
2029 * After use, free the @list by calling kmod_module_versions_free_list().
2030 *
2031 * Returns: 0 on success or < 0 otherwise.
2032 */
2033KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
2034{
2035 struct kmod_file *file;
2036 struct kmod_elf *elf;
2037 const char *path;
2038 const void *mem;
2039 struct kmod_modversion *versions;
2040 size_t size;
2041 int i, count, ret = 0;
2042
2043 if (mod == NULL || list == NULL)
2044 return -ENOENT;
2045
2046 assert(*list == NULL);
2047
2048 path = kmod_module_get_path(mod);
2049 if (path == NULL)
2050 return -ENOENT;
2051
2052 file = kmod_file_open(path);
2053 if (file == NULL)
2054 return -errno;
2055
2056 size = kmod_file_get_size(file);
2057 mem = kmod_file_get_contents(file);
2058
2059 elf = kmod_elf_new(mem, size);
2060 if (elf == NULL) {
2061 ret = -errno;
2062 goto elf_open_error;
2063 }
2064
2065 count = kmod_elf_get_modversions(elf, &versions);
2066 if (count < 0) {
2067 ret = count;
2068 goto get_strings_error;
2069 }
2070
2071 for (i = 0; i < count; i++) {
2072 struct kmod_module_version *mv;
2073 struct kmod_list *n;
2074
2075 mv = kmod_module_versions_new(versions[i].crc, versions[i].symbol);
2076 if (mv == NULL) {
2077 ret = -errno;
2078 kmod_module_versions_free_list(*list);
2079 *list = NULL;
2080 goto list_error;
2081 }
2082
2083 n = kmod_list_append(*list, mv);
2084 if (n != NULL)
2085 *list = n;
2086 else {
2087 kmod_module_version_free(mv);
2088 kmod_module_versions_free_list(*list);
2089 *list = NULL;
2090 ret = -ENOMEM;
2091 goto list_error;
2092 }
2093 }
2094 ret = count;
2095
2096list_error:
2097 free(versions);
2098get_strings_error:
2099 kmod_elf_unref(elf);
2100elf_open_error:
2101 kmod_file_unref(file);
2102
2103 return ret;
2104}
2105
2106/**
2107 * kmod_module_versions_get_symbol:
2108 * @entry: a list entry representing a kmod module versions
2109 *
2110 * Get the symbol of a kmod module versions.
2111 *
2112 * Returns: the symbol of this kmod module versions on success or NULL
2113 * on failure. The string is owned by the versions, do not free it.
2114 */
2115KMOD_EXPORT const char *kmod_module_version_get_symbol(const struct kmod_list *entry)
2116{
2117 struct kmod_module_version *version;
2118
2119 if (entry == NULL)
2120 return NULL;
2121
2122 version = entry->data;
2123 return version->symbol;
2124}
2125
2126/**
2127 * kmod_module_version_get_crc:
2128 * @entry: a list entry representing a kmod module version
2129 *
2130 * Get the crc of a kmod module version.
2131 *
2132 * Returns: the crc of this kmod module version on success or NULL on
2133 * failure. The string is owned by the version, do not free it.
2134 */
2135KMOD_EXPORT uint64_t kmod_module_version_get_crc(const struct kmod_list *entry)
2136{
2137 struct kmod_module_version *version;
2138
2139 if (entry == NULL)
2140 return 0;
2141
2142 version = entry->data;
2143 return version->crc;
2144}
2145
2146/**
2147 * kmod_module_versions_free_list:
2148 * @list: kmod module versions list
2149 *
2150 * Release the resources taken by @list
2151 */
2152KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
2153{
2154 while (list) {
2155 kmod_module_version_free(list->data);
2156 list = kmod_list_remove(list);
2157 }
2158}
Gustavo Sverzut Barbieri45e6db92011-12-19 21:23:13 -02002159
2160struct kmod_module_symbol {
2161 uint64_t crc;
2162 char symbol[];
2163};
2164
2165static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
2166{
2167 struct kmod_module_symbol *mv;
2168 size_t symbollen = strlen(symbol) + 1;
2169
2170 mv = malloc(sizeof(struct kmod_module_symbol) + symbollen);
2171 if (mv == NULL)
2172 return NULL;
2173
2174 mv->crc = crc;
2175 memcpy(mv->symbol, symbol, symbollen);
2176 return mv;
2177}
2178
2179static void kmod_module_symbol_free(struct kmod_module_symbol *symbol)
2180{
2181 free(symbol);
2182}
2183
2184/**
2185 * kmod_module_get_symbols:
2186 * @mod: kmod module
2187 * @list: where to return list of module symbols. Use
2188 * kmod_module_symbols_get_symbol() and
2189 * kmod_module_symbols_get_crc(). Release this list with
2190 * kmod_module_symbols_unref_list()
2191 *
2192 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2193 *
2194 * After use, free the @list by calling kmod_module_symbols_free_list().
2195 *
2196 * Returns: 0 on success or < 0 otherwise.
2197 */
2198KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
2199{
2200 struct kmod_file *file;
2201 struct kmod_elf *elf;
2202 const char *path;
2203 const void *mem;
2204 struct kmod_modversion *symbols;
2205 size_t size;
2206 int i, count, ret = 0;
2207
2208 if (mod == NULL || list == NULL)
2209 return -ENOENT;
2210
2211 assert(*list == NULL);
2212
2213 path = kmod_module_get_path(mod);
2214 if (path == NULL)
2215 return -ENOENT;
2216
2217 file = kmod_file_open(path);
2218 if (file == NULL)
2219 return -errno;
2220
2221 size = kmod_file_get_size(file);
2222 mem = kmod_file_get_contents(file);
2223
2224 elf = kmod_elf_new(mem, size);
2225 if (elf == NULL) {
2226 ret = -errno;
2227 goto elf_open_error;
2228 }
2229
2230 count = kmod_elf_get_symbols(elf, &symbols);
2231 if (count < 0) {
2232 ret = count;
2233 goto get_strings_error;
2234 }
2235
2236 for (i = 0; i < count; i++) {
2237 struct kmod_module_symbol *mv;
2238 struct kmod_list *n;
2239
2240 mv = kmod_module_symbols_new(symbols[i].crc, symbols[i].symbol);
2241 if (mv == NULL) {
2242 ret = -errno;
2243 kmod_module_symbols_free_list(*list);
2244 *list = NULL;
2245 goto list_error;
2246 }
2247
2248 n = kmod_list_append(*list, mv);
2249 if (n != NULL)
2250 *list = n;
2251 else {
2252 kmod_module_symbol_free(mv);
2253 kmod_module_symbols_free_list(*list);
2254 *list = NULL;
2255 ret = -ENOMEM;
2256 goto list_error;
2257 }
2258 }
2259 ret = count;
2260
2261list_error:
2262 free(symbols);
2263get_strings_error:
2264 kmod_elf_unref(elf);
2265elf_open_error:
2266 kmod_file_unref(file);
2267
2268 return ret;
2269}
2270
2271/**
2272 * kmod_module_symbols_get_symbol:
2273 * @entry: a list entry representing a kmod module symbols
2274 *
2275 * Get the symbol of a kmod module symbols.
2276 *
2277 * Returns: the symbol of this kmod module symbols on success or NULL
2278 * on failure. The string is owned by the symbols, do not free it.
2279 */
2280KMOD_EXPORT const char *kmod_module_symbol_get_symbol(const struct kmod_list *entry)
2281{
2282 struct kmod_module_symbol *symbol;
2283
2284 if (entry == NULL)
2285 return NULL;
2286
2287 symbol = entry->data;
2288 return symbol->symbol;
2289}
2290
2291/**
2292 * kmod_module_symbol_get_crc:
2293 * @entry: a list entry representing a kmod module symbol
2294 *
2295 * Get the crc of a kmod module symbol.
2296 *
2297 * Returns: the crc of this kmod module symbol on success or NULL on
2298 * failure. The string is owned by the symbol, do not free it.
2299 */
2300KMOD_EXPORT uint64_t kmod_module_symbol_get_crc(const struct kmod_list *entry)
2301{
2302 struct kmod_module_symbol *symbol;
2303
2304 if (entry == NULL)
2305 return 0;
2306
2307 symbol = entry->data;
2308 return symbol->crc;
2309}
2310
2311/**
2312 * kmod_module_symbols_free_list:
2313 * @list: kmod module symbols list
2314 *
2315 * Release the resources taken by @list
2316 */
2317KMOD_EXPORT void kmod_module_symbols_free_list(struct kmod_list *list)
2318{
2319 while (list) {
2320 kmod_module_symbol_free(list->data);
2321 list = kmod_list_remove(list);
2322 }
2323}
Gustavo Sverzut Barbieri674f8592011-12-20 11:54:53 -02002324
2325struct kmod_module_dependency_symbol {
2326 uint64_t crc;
2327 uint8_t bind;
2328 char symbol[];
2329};
2330
2331static struct kmod_module_dependency_symbol *kmod_module_dependency_symbols_new(uint64_t crc, uint8_t bind, const char *symbol)
2332{
2333 struct kmod_module_dependency_symbol *mv;
2334 size_t symbollen = strlen(symbol) + 1;
2335
2336 mv = malloc(sizeof(struct kmod_module_dependency_symbol) + symbollen);
2337 if (mv == NULL)
2338 return NULL;
2339
2340 mv->crc = crc;
2341 mv->bind = bind;
2342 memcpy(mv->symbol, symbol, symbollen);
2343 return mv;
2344}
2345
2346static void kmod_module_dependency_symbol_free(struct kmod_module_dependency_symbol *dependency_symbol)
2347{
2348 free(dependency_symbol);
2349}
2350
2351/**
2352 * kmod_module_get_dependency_symbols:
2353 * @mod: kmod module
2354 * @list: where to return list of module dependency_symbols. Use
2355 * kmod_module_dependency_symbol_get_symbol() and
2356 * kmod_module_dependency_symbol_get_crc(). Release this list with
2357 * kmod_module_dependency_symbols_free_list()
2358 *
2359 * Get a list of entries in ELF section ".symtab" or "__ksymtab_strings".
2360 *
2361 * After use, free the @list by calling
2362 * kmod_module_dependency_symbols_free_list().
2363 *
2364 * Returns: 0 on success or < 0 otherwise.
2365 */
2366KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
2367{
2368 struct kmod_file *file;
2369 struct kmod_elf *elf;
2370 const char *path;
2371 const void *mem;
2372 struct kmod_modversion *symbols;
2373 size_t size;
2374 int i, count, ret = 0;
2375
2376 if (mod == NULL || list == NULL)
2377 return -ENOENT;
2378
2379 assert(*list == NULL);
2380
2381 path = kmod_module_get_path(mod);
2382 if (path == NULL)
2383 return -ENOENT;
2384
2385 file = kmod_file_open(path);
2386 if (file == NULL)
2387 return -errno;
2388
2389 size = kmod_file_get_size(file);
2390 mem = kmod_file_get_contents(file);
2391
2392 elf = kmod_elf_new(mem, size);
2393 if (elf == NULL) {
2394 ret = -errno;
2395 goto elf_open_error;
2396 }
2397
2398 count = kmod_elf_get_dependency_symbols(elf, &symbols);
2399 if (count < 0) {
2400 ret = count;
2401 goto get_strings_error;
2402 }
2403
2404 for (i = 0; i < count; i++) {
2405 struct kmod_module_dependency_symbol *mv;
2406 struct kmod_list *n;
2407
2408 mv = kmod_module_dependency_symbols_new(symbols[i].crc,
2409 symbols[i].bind,
2410 symbols[i].symbol);
2411 if (mv == NULL) {
2412 ret = -errno;
2413 kmod_module_dependency_symbols_free_list(*list);
2414 *list = NULL;
2415 goto list_error;
2416 }
2417
2418 n = kmod_list_append(*list, mv);
2419 if (n != NULL)
2420 *list = n;
2421 else {
2422 kmod_module_dependency_symbol_free(mv);
2423 kmod_module_dependency_symbols_free_list(*list);
2424 *list = NULL;
2425 ret = -ENOMEM;
2426 goto list_error;
2427 }
2428 }
2429 ret = count;
2430
2431list_error:
2432 free(symbols);
2433get_strings_error:
2434 kmod_elf_unref(elf);
2435elf_open_error:
2436 kmod_file_unref(file);
2437
2438 return ret;
2439}
2440
2441/**
2442 * kmod_module_dependency_symbol_get_symbol:
2443 * @entry: a list entry representing a kmod module dependency_symbols
2444 *
2445 * Get the dependency symbol of a kmod module
2446 *
2447 * Returns: the symbol of this kmod module dependency_symbols on success or NULL
2448 * on failure. The string is owned by the dependency_symbols, do not free it.
2449 */
2450KMOD_EXPORT const char *kmod_module_dependency_symbol_get_symbol(const struct kmod_list *entry)
2451{
2452 struct kmod_module_dependency_symbol *dependency_symbol;
2453
2454 if (entry == NULL)
2455 return NULL;
2456
2457 dependency_symbol = entry->data;
2458 return dependency_symbol->symbol;
2459}
2460
2461/**
2462 * kmod_module_dependency_symbol_get_crc:
2463 * @entry: a list entry representing a kmod module dependency_symbol
2464 *
2465 * Get the crc of a kmod module dependency_symbol.
2466 *
2467 * Returns: the crc of this kmod module dependency_symbol on success or NULL on
2468 * failure. The string is owned by the dependency_symbol, do not free it.
2469 */
2470KMOD_EXPORT uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry)
2471{
2472 struct kmod_module_dependency_symbol *dependency_symbol;
2473
2474 if (entry == NULL)
2475 return 0;
2476
2477 dependency_symbol = entry->data;
2478 return dependency_symbol->crc;
2479}
2480
2481/**
2482 * kmod_module_dependency_symbol_get_bind:
2483 * @entry: a list entry representing a kmod module dependency_symbol
2484 *
2485 * Get the bind type of a kmod module dependency_symbol.
2486 *
2487 * Returns: the bind of this kmod module dependency_symbol on success
2488 * or < 0 on failure.
2489 */
2490KMOD_EXPORT int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry)
2491{
2492 struct kmod_module_dependency_symbol *dependency_symbol;
2493
2494 if (entry == NULL)
2495 return 0;
2496
2497 dependency_symbol = entry->data;
2498 return dependency_symbol->bind;
2499}
2500
2501/**
2502 * kmod_module_dependency_symbols_free_list:
2503 * @list: kmod module dependency_symbols list
2504 *
2505 * Release the resources taken by @list
2506 */
2507KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list)
2508{
2509 while (list) {
2510 kmod_module_dependency_symbol_free(list->data);
2511 list = kmod_list_remove(list);
2512 }
2513}