blob: 074e368e83e9a0c283f91cdaecacb16096ba9336 [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>
37
38#include "libkmod.h"
39#include "libkmod-private.h"
40
41/**
42 * kmod_module:
43 *
44 * Opaque object representing a module.
45 */
46struct kmod_module {
47 struct kmod_ctx *ctx;
Lucas De Marchi219f9c32011-12-13 13:07:40 -020048 char *name;
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -020049 char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -020050 struct kmod_list *dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020051 char *options;
52 char *install_commands;
53 char *remove_commands;
Lucas De Marchi6ad5f262011-12-13 14:12:50 -020054 char *alias; /* only set if this module was created from an alias */
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -020055 int n_dep;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020056 int refcount;
Lucas De Marchi7636e722011-12-01 17:56:03 -020057 struct {
58 bool dep : 1;
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -020059 bool options : 1;
60 bool install_commands : 1;
61 bool remove_commands : 1;
Lucas De Marchi7636e722011-12-01 17:56:03 -020062 } init;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020063};
64
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -020065inline char *modname_normalize(const char *modname, char buf[NAME_MAX],
Lucas De Marchi6c343b12011-12-06 09:01:01 -020066 size_t *len)
Lucas De Marchi8f788d52011-11-25 01:22:56 -020067{
Lucas De Marchid753b8c2011-12-05 18:14:51 -020068 size_t s;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020069
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020070 for (s = 0; s < NAME_MAX - 1; s++) {
71 const char c = modname[s];
72 if (c == '-')
73 buf[s] = '_';
74 else if (c == '\0' || c == '.')
75 break;
76 else
77 buf[s] = c;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020078 }
Lucas De Marchi28c175e2011-12-12 11:52:59 -020079
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020080 buf[s] = '\0';
Lucas De Marchid753b8c2011-12-05 18:14:51 -020081
82 if (len)
83 *len = s;
84
Gustavo Sverzut Barbierie1a6b302011-12-08 04:10:49 -020085 return buf;
Lucas De Marchi8f788d52011-11-25 01:22:56 -020086}
87
Lucas De Marchi6c343b12011-12-06 09:01:01 -020088static char *path_to_modname(const char *path, char buf[NAME_MAX], size_t *len)
89{
90 char *modname;
91
92 modname = basename(path);
93 if (modname == NULL || modname[0] == '\0')
94 return NULL;
95
96 return modname_normalize(modname, buf, len);
97}
98
Lucas De Marchic35347f2011-12-12 10:48:02 -020099static inline const char *path_join(const char *path, size_t prefixlen,
100 char buf[PATH_MAX])
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200101{
102 size_t pathlen;
103
104 if (path[0] == '/')
105 return path;
106
107 pathlen = strlen(path);
108 if (prefixlen + pathlen + 1 >= PATH_MAX)
109 return NULL;
110
111 memcpy(buf + prefixlen, path, pathlen + 1);
112 return buf;
113}
114
Lucas De Marchi671d4892011-12-05 20:23:05 -0200115int kmod_module_parse_depline(struct kmod_module *mod, char *line)
Lucas De Marchi7636e722011-12-01 17:56:03 -0200116{
117 struct kmod_ctx *ctx = mod->ctx;
118 struct kmod_list *list = NULL;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200119 const char *dirname;
120 char buf[PATH_MAX];
Lucas De Marchi7636e722011-12-01 17:56:03 -0200121 char *p, *saveptr;
Lucas De Marchi45f27782011-12-12 17:23:04 -0200122 int err = 0, n = 0;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200123 size_t dirnamelen;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200124
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200125 if (mod->init.dep)
126 return mod->n_dep;
127 assert(mod->dep == NULL);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200128 mod->init.dep = true;
129
130 p = strchr(line, ':');
131 if (p == NULL)
132 return 0;
133
Lucas De Marchi671d4892011-12-05 20:23:05 -0200134 *p = '\0';
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200135 dirname = kmod_get_dirname(mod->ctx);
136 dirnamelen = strlen(dirname);
137 if (dirnamelen + 2 >= PATH_MAX)
138 return 0;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200139
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200140 memcpy(buf, dirname, dirnamelen);
141 buf[dirnamelen] = '/';
142 dirnamelen++;
143 buf[dirnamelen] = '\0';
144
145 if (mod->path == NULL) {
146 const char *str = path_join(line, dirnamelen, buf);
147 if (str == NULL)
148 return 0;
149 mod->path = strdup(str);
150 if (mod->path == NULL)
151 return 0;
152 }
Lucas De Marchi671d4892011-12-05 20:23:05 -0200153
Lucas De Marchi7636e722011-12-01 17:56:03 -0200154 p++;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200155 for (p = strtok_r(p, " \t", &saveptr); p != NULL;
156 p = strtok_r(NULL, " \t", &saveptr)) {
Lucas De Marchi1fc1c9a2011-12-02 10:00:03 -0200157 struct kmod_module *depmod;
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200158 const char *path;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200159
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200160 path = path_join(p, dirnamelen, buf);
161 if (path == NULL) {
162 ERR(ctx, "could not join path '%s' and '%s'.\n",
163 dirname, p);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200164 goto fail;
165 }
166
Gustavo Sverzut Barbierie18ad352011-12-08 04:44:03 -0200167 err = kmod_module_new_from_path(ctx, path, &depmod);
168 if (err < 0) {
169 ERR(ctx, "ctx=%p path=%s error=%s\n",
170 ctx, path, strerror(-err));
171 goto fail;
172 }
173
174 DBG(ctx, "add dep: %s\n", path);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200175
Lucas De Marchi1fc1c9a2011-12-02 10:00:03 -0200176 list = kmod_list_append(list, depmod);
Lucas De Marchi7636e722011-12-01 17:56:03 -0200177 n++;
178 }
179
180 DBG(ctx, "%d dependencies for %s\n", n, mod->name);
181
182 mod->dep = list;
Gustavo Sverzut Barbierib6a534f2011-12-10 20:36:22 -0200183 mod->n_dep = n;
Lucas De Marchi7636e722011-12-01 17:56:03 -0200184 return n;
185
186fail:
187 kmod_module_unref_list(list);
188 mod->init.dep = false;
189 return err;
190}
191
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200192KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
193 const char *name,
194 struct kmod_module **mod)
195{
196 struct kmod_module *m;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200197 size_t namelen;
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200198 char name_norm[NAME_MAX];
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200199
200 if (ctx == NULL || name == NULL)
201 return -ENOENT;
202
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200203 alias_normalize(name, name_norm, &namelen);
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200204
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200205 m = kmod_pool_get_module(ctx, name_norm);
206 if (m != NULL) {
207 *mod = kmod_module_ref(m);
208 return 0;
209 }
210
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200211 m = calloc(1, sizeof(*m) + namelen + 1);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200212 if (m == NULL) {
213 free(m);
214 return -ENOMEM;
215 }
216
217 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200218 m->name = (char *)m + sizeof(*m);
Lucas De Marchi4f2bb7c2011-12-06 02:46:22 -0200219 memcpy(m->name, name_norm, namelen + 1);
Gustavo Sverzut Barbieri87ca03b2011-12-04 12:34:02 -0200220 m->refcount = 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200221
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200222 kmod_pool_add_module(ctx, m);
223
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200224 *mod = m;
225
226 return 0;
227}
228
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200229int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
230 const char *name, struct kmod_module **mod)
231{
232 int err;
233 struct kmod_module *m;
234
235 err = kmod_module_new_from_name(ctx, alias, mod);
236 if (err < 0)
237 return err;
238
239 m = *mod;
240
241 /* if module did not came from pool */
242 if (m->alias == NULL) {
243 m->alias = m->name;
244 m->name = strdup(name);
245 if (m->name == NULL)
246 goto fail_oom;
247 }
248
249 return 0;
250
251fail_oom:
252 ERR(ctx, "out of memory\n");
253 kmod_module_unref(m);
254 *mod = NULL;
255 return err;
256}
257
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200258KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
259 const char *path,
260 struct kmod_module **mod)
261{
262 struct kmod_module *m;
263 int err;
264 struct stat st;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200265 char name[NAME_MAX];
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200266 char *abspath;
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200267 size_t namelen;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200268
269 if (ctx == NULL || path == NULL)
270 return -ENOENT;
271
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200272 abspath = path_make_absolute_cwd(path);
273 if (abspath == NULL)
274 return -ENOMEM;
275
276 err = stat(abspath, &st);
277 if (err < 0) {
278 free(abspath);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200279 return -errno;
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200280 }
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200281
Gustavo Sverzut Barbieri973c80b2011-12-12 18:28:52 -0200282 if (path_to_modname(path, name, &namelen) == NULL) {
283 free(abspath);
284 return -ENOENT;
285 }
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200286
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200287 m = kmod_pool_get_module(ctx, name);
288 if (m != NULL) {
Lucas De Marchi6bd0b8d2011-12-07 14:08:01 -0200289 if (m->path == NULL)
290 m->path = abspath;
291 else if (streq(m->path, abspath))
292 free(abspath);
293 else {
294 ERR(ctx, "kmod_module '%s' already exists with different path\n",
295 name);
296 free(abspath);
297 return -EEXIST;
298 }
299
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200300 *mod = kmod_module_ref(m);
301 return 0;
302 }
303
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200304 m = calloc(1, sizeof(*m) + namelen + 1);
305 if (m == NULL)
306 return -errno;
307
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200308 m->ctx = kmod_ref(ctx);
Lucas De Marchi219f9c32011-12-13 13:07:40 -0200309 m->name = (char *)m + sizeof(*m);
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200310 memcpy(m->name, name, namelen);
Lucas De Marchi71e975c2011-12-07 13:53:53 -0200311 m->path = abspath;
Gustavo Sverzut Barbieri87ca03b2011-12-04 12:34:02 -0200312 m->refcount = 1;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200313
Lucas De Marchifd186ae2011-12-06 03:38:37 -0200314 kmod_pool_add_module(ctx, m);
315
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200316 *mod = m;
317
318 return 0;
319}
320
321KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
322{
323 if (mod == NULL)
324 return NULL;
325
326 if (--mod->refcount > 0)
327 return mod;
328
329 DBG(mod->ctx, "kmod_module %p released\n", mod);
330
Lucas De Marchi7636e722011-12-01 17:56:03 -0200331 kmod_module_unref_list(mod->dep);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200332 kmod_unref(mod->ctx);
Gustavo Sverzut Barbieribd3f5532011-12-10 20:47:01 -0200333 free(mod->options);
334 free(mod->install_commands);
335 free(mod->remove_commands);
Gustavo Sverzut Barbierif1fb6f82011-12-08 04:44:03 -0200336 free(mod->path);
Lucas De Marchi6ad5f262011-12-13 14:12:50 -0200337 if (mod->alias != NULL)
338 free(mod->name);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200339 free(mod);
340 return NULL;
341}
342
343KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
344{
345 if (mod == NULL)
346 return NULL;
347
348 mod->refcount++;
349
350 return mod;
351}
352
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200353#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
354 do { \
355 if ((_err) < 0) \
356 goto _label_err; \
357 if (*(_list) != NULL) \
358 goto finish; \
359 } while (0)
360
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200361KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200362 const char *given_alias,
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200363 struct kmod_list **list)
364{
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200365 int err;
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200366 char alias[NAME_MAX];
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200367
Lucas De Marchi4308b172011-12-13 10:26:04 -0200368 if (ctx == NULL || given_alias == NULL)
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200369 return -ENOENT;
370
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200371 if (list == NULL || *list != NULL) {
372 ERR(ctx, "An empty list is needed to create lookup\n");
373 return -ENOSYS;
374 }
375
Lucas De Marchid470db12011-12-13 10:28:00 -0200376 if (alias_normalize(given_alias, alias, NULL) < 0)
377 return -EINVAL;
Gustavo Sverzut Barbierid917f272011-12-10 21:00:19 -0200378
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200379 /* Aliases from config file override all the others */
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200380 err = kmod_lookup_alias_from_config(ctx, alias, list);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200381 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200382
Lucas De Marchi64700e42011-12-01 15:57:53 -0200383 err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
384 CHECK_ERR_AND_FINISH(err, fail, list, finish);
385
Lucas De Marchi9ba6f572011-11-30 20:31:45 -0200386 err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
387 CHECK_ERR_AND_FINISH(err, fail, list, finish);
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200388
Lucas De Marchi49e61ca2011-12-01 16:27:04 -0200389 err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
390 CHECK_ERR_AND_FINISH(err, fail, list, finish);
391
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200392finish:
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200393
394 return err;
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200395fail:
396 kmod_module_unref_list(*list);
397 *list = NULL;
Lucas De Marchi84f42202011-12-02 10:03:34 -0200398 return err;
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200399}
Lucas De Marchib14dcfd2011-11-30 20:29:51 -0200400#undef CHECK_ERR_AND_FINISH
401
Lucas De Marchi7f3eb0c2011-11-30 19:03:41 -0200402
403KMOD_EXPORT int kmod_module_unref_list(struct kmod_list *list)
404{
405 for (; list != NULL; list = kmod_list_remove(list))
406 kmod_module_unref(list->data);
407
408 return 0;
409}
410
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200411KMOD_EXPORT struct kmod_list *kmod_module_get_dependencies(const struct kmod_module *mod)
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200412{
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200413 struct kmod_list *l, *l_new, *list_new = NULL;
414
415 if (mod == NULL)
416 return NULL;
417
Lucas De Marchi671d4892011-12-05 20:23:05 -0200418 if (!mod->init.dep) {
419 /* lazy init */
420 char *line = kmod_search_moddep(mod->ctx, mod->name);
421
422 if (line == NULL)
423 return NULL;
424
425 kmod_module_parse_depline((struct kmod_module *)mod, line);
426 free(line);
427
428 if (!mod->init.dep)
429 return NULL;
430 }
Lucas De Marchif1cd7992011-12-05 19:40:45 -0200431
432 kmod_list_foreach(l, mod->dep) {
433 l_new = kmod_list_append(list_new, kmod_module_ref(l->data));
434 if (l_new == NULL) {
435 kmod_module_unref(l->data);
436 goto fail;
437 }
438
439 list_new = l_new;
440 }
441
442 return list_new;
443
444fail:
445 ERR(mod->ctx, "out of memory\n");
446 kmod_module_unref_list(list_new);
447 return NULL;
Lucas De Marchi0835fc32011-12-01 20:06:08 -0200448}
449
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200450KMOD_EXPORT struct kmod_module *kmod_module_get_module(const struct kmod_list *entry)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200451{
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200452 if (entry == NULL)
453 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -0200454
Gustavo Sverzut Barbieriad4d1ae2011-12-04 13:14:11 -0200455 return kmod_module_ref(entry->data);
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200456}
457
Gustavo Sverzut Barbieri69f9dd42011-12-04 14:02:30 -0200458KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
459{
460 // FIXME TODO: this should be available from /sys/module/foo
461 FILE *fp;
462 char line[4096];
463 int lineno = 0;
464 long size = -ENOENT;
465
466 if (mod == NULL)
467 return -ENOENT;
468
469 fp = fopen("/proc/modules", "r");
470 if (fp == NULL) {
471 int err = -errno;
472 ERR(mod->ctx,
473 "could not open /proc/modules: %s\n", strerror(errno));
474 return err;
475 }
476
477 while (fgets(line, sizeof(line), fp)) {
478 char *saveptr, *endptr, *tok = strtok_r(line, " \t", &saveptr);
479 long value;
480
481 lineno++;
Lucas De Marchi877e80c2011-12-07 02:26:31 -0200482 if (tok == NULL || !streq(tok, mod->name))
Gustavo Sverzut Barbieri69f9dd42011-12-04 14:02:30 -0200483 continue;
484
485 tok = strtok_r(NULL, " \t", &saveptr);
486 if (tok == NULL) {
487 ERR(mod->ctx,
488 "invalid line format at /proc/modules:%d\n", lineno);
489 break;
490 }
491
492 value = strtol(tok, &endptr, 10);
493 if (endptr == tok || *endptr != '\0') {
494 ERR(mod->ctx,
495 "invalid line format at /proc/modules:%d\n", lineno);
496 break;
497 }
498
499 size = value;
500 break;
501 }
502 fclose(fp);
503 return size;
504}
505
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200506KMOD_EXPORT const char *kmod_module_get_name(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200507{
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200508 return mod->name;
509}
510
Gustavo Sverzut Barbieri1ce08a52011-12-02 20:24:07 -0200511KMOD_EXPORT const char *kmod_module_get_path(const struct kmod_module *mod)
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200512{
Lucas De Marchie005fac2011-12-08 10:42:34 -0200513 char *line;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200514
Gustavo Sverzut Barbierid01c67e2011-12-11 19:42:02 -0200515 DBG(mod->ctx, "name='%s' path='%s'\n", mod->name, mod->path);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200516
Lucas De Marchie005fac2011-12-08 10:42:34 -0200517 if (mod->path != NULL)
518 return mod->path;
519 if (mod->init.dep)
520 return NULL;
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200521
Lucas De Marchie005fac2011-12-08 10:42:34 -0200522 /* lazy init */
523 line = kmod_search_moddep(mod->ctx, mod->name);
524 if (line == NULL)
525 return NULL;
526
527 kmod_module_parse_depline((struct kmod_module *) mod, line);
528 free(line);
Lucas De Marchic5e7b1f2011-12-05 20:28:13 -0200529
Lucas De Marchi6e869df2011-11-30 19:01:01 -0200530 return mod->path;
531}
532
533
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200534extern long delete_module(const char *name, unsigned int flags);
535
536KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
537 unsigned int flags)
538{
539 int err;
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200540
541 if (mod == NULL)
542 return -ENOENT;
543
544 /* Filter out other flags */
545 flags &= (KMOD_REMOVE_FORCE | KMOD_REMOVE_NOWAIT);
546
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200547 err = delete_module(mod->name, flags);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200548 if (err != 0) {
Lucas De Marchid753b8c2011-12-05 18:14:51 -0200549 ERR(mod->ctx, "Removing '%s': %s\n", mod->name,
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200550 strerror(-err));
551 return err;
552 }
553
554 return 0;
555}
556
557extern long init_module(void *mem, unsigned long len, const char *args);
558
559KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200560 unsigned int flags,
561 const char *options)
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200562{
563 int err;
564 void *mmaped_file;
565 struct stat st;
566 int fd;
Gustavo Sverzut Barbieri3a721bb2011-12-10 21:02:39 -0200567 const char *args = options ? options : "";
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200568
569 if (mod == NULL)
570 return -ENOENT;
571
572 if (mod->path == NULL) {
Lucas De Marchi1b2e26a2011-11-25 01:28:39 -0200573 ERR(mod->ctx, "Not supported to load a module by name yet\n");
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200574 return -ENOSYS;
575 }
576
577 if (flags != 0)
Lucas De Marchi1b2e26a2011-11-25 01:28:39 -0200578 INFO(mod->ctx, "Flags are not implemented yet\n");
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200579
580 if ((fd = open(mod->path, O_RDONLY)) < 0) {
581 err = -errno;
582 return err;
583 }
584
Lucas De Marchib418a822011-12-01 23:13:27 -0200585 fstat(fd, &st);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200586
587 if ((mmaped_file = mmap(0, st.st_size, PROT_READ,
588 MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
589 close(fd);
590 return -errno;
591 }
592
593 err = init_module(mmaped_file, st.st_size, args);
594 if (err < 0)
Lucas De Marchi1b2e26a2011-11-25 01:28:39 -0200595 ERR(mod->ctx, "Failed to insert module '%s'\n", mod->path);
Lucas De Marchi8f788d52011-11-25 01:22:56 -0200596
597 munmap(mmaped_file, st.st_size);
598 close(fd);
599
600 return err;
601}
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200602
Lucas De Marchi49ce6d02011-12-12 13:56:47 -0200603KMOD_EXPORT const char *kmod_module_get_options(const struct kmod_module *mod)
604{
605 if (mod == NULL)
606 return NULL;
607
608 if (!mod->init.options) {
609 /* lazy init */
610 struct kmod_module *m = (struct kmod_module *)mod;
611 const struct kmod_list *l, *ctx_options;
612 char *opts = NULL;
613 size_t optslen = 0;
614
615 ctx_options = kmod_get_options(mod->ctx);
616
617 kmod_list_foreach(l, ctx_options) {
618 const char *modname = kmod_option_get_modname(l);
619 const char *str;
620 size_t len;
621 void *tmp;
622
623 if (strcmp(modname, mod->name) != 0)
624 continue;
625
626 str = kmod_option_get_options(l);
627 len = strlen(str);
628 if (len < 1)
629 continue;
630
631 tmp = realloc(opts, optslen + len + 2);
632 if (tmp == NULL) {
633 free(opts);
634 goto failed;
635 }
636
637 opts = tmp;
638
639 if (optslen > 0) {
640 opts[optslen] = ' ';
641 optslen++;
642 }
643
644 memcpy(opts + optslen, str, len);
645 optslen += len;
646 opts[optslen] = '\0';
647 }
648
649 m->init.options = true;
650 m->options = opts;
651 }
652
653 return mod->options;
654
655failed:
656 ERR(mod->ctx, "out of memory\n");
657 return NULL;
658}
659
660KMOD_EXPORT const char *kmod_module_get_install_commands(const struct kmod_module *mod)
661{
662 if (mod == NULL)
663 return NULL;
664
665 if (!mod->init.install_commands) {
666 /* lazy init */
667 struct kmod_module *m = (struct kmod_module *)mod;
668 const struct kmod_list *l, *ctx_install_commands;
669 char *cmds = NULL;
670 size_t cmdslen = 0;
671
672 ctx_install_commands = kmod_get_install_commands(mod->ctx);
673
674 kmod_list_foreach(l, ctx_install_commands) {
675 const char *modname = kmod_command_get_modname(l);
676 const char *str;
677 size_t len;
678 void *tmp;
679
680 if (strcmp(modname, mod->name) != 0)
681 continue;
682
683 str = kmod_command_get_command(l);
684 len = strlen(str);
685 if (len < 1)
686 continue;
687
688 tmp = realloc(cmds, cmdslen + len + 2);
689 if (tmp == NULL) {
690 free(cmds);
691 goto failed;
692 }
693
694 cmds = tmp;
695
696 if (cmdslen > 0) {
697 cmds[cmdslen] = ';';
698 cmdslen++;
699 }
700
701 memcpy(cmds + cmdslen, str, len);
702 cmdslen += len;
703 cmds[cmdslen] = '\0';
704 }
705
706 m->init.install_commands = true;
707 m->install_commands = cmds;
708 }
709
710 return mod->install_commands;
711
712failed:
713 ERR(mod->ctx, "out of memory\n");
714 return NULL;
715}
716
717KMOD_EXPORT const char *kmod_module_get_remove_commands(const struct kmod_module *mod)
718{
719 if (mod == NULL)
720 return NULL;
721
722 if (!mod->init.remove_commands) {
723 /* lazy init */
724 struct kmod_module *m = (struct kmod_module *)mod;
725 const struct kmod_list *l, *ctx_remove_commands;
726 char *cmds = NULL;
727 size_t cmdslen = 0;
728
729 ctx_remove_commands = kmod_get_remove_commands(mod->ctx);
730
731 kmod_list_foreach(l, ctx_remove_commands) {
732 const char *modname = kmod_command_get_modname(l);
733 const char *str;
734 size_t len;
735 void *tmp;
736
737 if (strcmp(modname, mod->name) != 0)
738 continue;
739
740 str = kmod_command_get_command(l);
741 len = strlen(str);
742 if (len < 1)
743 continue;
744
745 tmp = realloc(cmds, cmdslen + len + 2);
746 if (tmp == NULL) {
747 free(cmds);
748 goto failed;
749 }
750
751 cmds = tmp;
752
753 if (cmdslen > 0) {
754 cmds[cmdslen] = ';';
755 cmdslen++;
756 }
757
758 memcpy(cmds + cmdslen, str, len);
759 cmdslen += len;
760 cmds[cmdslen] = '\0';
761 }
762
763 m->init.remove_commands = true;
764 m->remove_commands = cmds;
765 }
766
767 return mod->remove_commands;
768
769failed:
770 ERR(mod->ctx, "out of memory\n");
771 return NULL;
772}
773
774/**
775 * SECTION:libkmod-loaded
776 * @short_description: currently loaded modules
777 *
778 * Information about currently loaded modules, as reported by Linux kernel.
779 * These information are not cached by libkmod and are always read from /sys
780 * and /proc/modules.
781 */
782
783/**
784 * kmod_module_new_from_loaded:
785 * @ctx: kmod library context
786 * @list: where to save the list of loaded modules
787 *
788 * Get a list of all modules currently loaded in kernel. It uses /proc/modules
789 * to get the names of loaded modules and to create kmod_module objects by
790 * calling kmod_module_new_from_name() in each of them. They are put are put
791 * in @list in no particular order.
792 *
793 * All the returned modules get their refcount incremented (or are created if
794 * they do not exist yet). After using the list, release the resources by
795 * calling kmod_module_unref_list().
796 *
797 * Returns: 0 on success or < 0 on error.
798 */
799KMOD_EXPORT int kmod_module_new_from_loaded(struct kmod_ctx *ctx,
800 struct kmod_list **list)
801{
802 struct kmod_list *l = NULL;
803 FILE *fp;
804 char line[4096];
805
806 if (ctx == NULL || list == NULL)
807 return -ENOENT;
808
809 fp = fopen("/proc/modules", "r");
810 if (fp == NULL) {
811 int err = -errno;
812 ERR(ctx, "could not open /proc/modules: %s\n", strerror(errno));
813 return err;
814 }
815
816 while (fgets(line, sizeof(line), fp)) {
817 struct kmod_module *m;
818 struct kmod_list *node;
819 int err;
820 char *saveptr, *name = strtok_r(line, " \t", &saveptr);
821
822 err = kmod_module_new_from_name(ctx, name, &m);
823 if (err < 0) {
824 ERR(ctx, "could not get module from name '%s': %s\n",
825 name, strerror(-err));
826 continue;
827 }
828
829 node = kmod_list_append(l, m);
830 if (node)
831 l = node;
832 else {
833 ERR(ctx, "out of memory\n");
834 kmod_module_unref(m);
835 }
836 }
837
838 fclose(fp);
839 *list = l;
840
841 return 0;
842}
843
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200844KMOD_EXPORT const char *kmod_module_initstate_str(enum kmod_module_initstate state)
845{
846 switch (state) {
847 case KMOD_MODULE_BUILTIN:
848 return "builtin";
849 case KMOD_MODULE_LIVE:
850 return "live";
851 case KMOD_MODULE_COMING:
852 return "coming";
853 case KMOD_MODULE_GOING:
854 return "going";
855 default:
856 return NULL;
857 }
858}
859
860KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
861{
862 char path[PATH_MAX], buf[32];
863 int fd, err, pathlen;
864
865 pathlen = snprintf(path, sizeof(path),
866 "/sys/module/%s/initstate", mod->name);
867 fd = open(path, O_RDONLY);
868 if (fd < 0) {
869 err = -errno;
870
871 if (pathlen > (int)sizeof("/initstate") - 1) {
872 struct stat st;
873 path[pathlen - (sizeof("/initstate") - 1)] = '\0';
874 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
875 return KMOD_MODULE_BUILTIN;
876 }
877
Gustavo Sverzut Barbieri926f67a2011-12-11 19:33:03 -0200878 DBG(mod->ctx, "could not open '%s': %s\n",
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200879 path, strerror(-err));
880 return err;
881 }
882
883 err = read_str_safe(fd, buf, sizeof(buf));
884 close(fd);
885 if (err < 0) {
886 ERR(mod->ctx, "could not read from '%s': %s\n",
887 path, strerror(-err));
888 return err;
889 }
890
Lucas De Marchi877e80c2011-12-07 02:26:31 -0200891 if (streq(buf, "live\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200892 return KMOD_MODULE_LIVE;
Lucas De Marchi877e80c2011-12-07 02:26:31 -0200893 else if (streq(buf, "coming\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200894 return KMOD_MODULE_COMING;
Lucas De Marchi877e80c2011-12-07 02:26:31 -0200895 else if (streq(buf, "going\n"))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200896 return KMOD_MODULE_GOING;
897
898 ERR(mod->ctx, "unknown %s: '%s'\n", path, buf);
899 return -EINVAL;
900}
901
902KMOD_EXPORT int kmod_module_get_refcnt(const struct kmod_module *mod)
903{
904 char path[PATH_MAX];
905 long refcnt;
906 int fd, err;
907
908 snprintf(path, sizeof(path), "/sys/module/%s/refcnt", mod->name);
909 fd = open(path, O_RDONLY);
910 if (fd < 0) {
911 err = -errno;
912 ERR(mod->ctx, "could not open '%s': %s\n",
913 path, strerror(errno));
914 return err;
915 }
916
917 err = read_str_long(fd, &refcnt, 10);
918 close(fd);
919 if (err < 0) {
920 ERR(mod->ctx, "could not read integer from '%s': '%s'\n",
921 path, strerror(-err));
922 return err;
923 }
924
925 return (int)refcnt;
926}
927
928KMOD_EXPORT struct kmod_list *kmod_module_get_holders(const struct kmod_module *mod)
929{
930 char dname[PATH_MAX];
931 struct kmod_list *list = NULL;
932 DIR *d;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200933
934 if (mod == NULL)
935 return NULL;
936 snprintf(dname, sizeof(dname), "/sys/module/%s/holders", mod->name);
937
938 d = opendir(dname);
939 if (d == NULL) {
940 ERR(mod->ctx, "could not open '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200941 dname, strerror(errno));
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200942 return NULL;
943 }
944
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200945 for (;;) {
946 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200947 struct kmod_module *holder;
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200948 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200949 int err;
950
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200951 err = readdir_r(d, &de, &entp);
952 if (err != 0) {
953 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
954 mod->name, strerror(-err));
955 goto fail;
956 }
957
958 if (entp == NULL)
959 break;
960
961 if (de.d_name[0] == '.') {
962 if (de.d_name[1] == '\0' ||
963 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200964 continue;
965 }
966
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200967 err = kmod_module_new_from_name(mod->ctx, de.d_name, &holder);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200968 if (err < 0) {
969 ERR(mod->ctx, "could not create module for '%s': %s\n",
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200970 de.d_name, strerror(-err));
971 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200972 }
973
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200974 l = kmod_list_append(list, holder);
975 if (l != NULL) {
976 list = l;
977 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200978 ERR(mod->ctx, "out of memory\n");
979 kmod_module_unref(holder);
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200980 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200981 }
982 }
983
984 closedir(d);
985 return list;
Lucas De Marchi53886dd2011-12-05 13:24:23 -0200986
987fail:
988 closedir(d);
989 kmod_module_unref_list(list);
990 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -0200991}
992
993struct kmod_module_section {
994 unsigned long address;
995 char name[];
996};
997
998static void kmod_module_section_free(struct kmod_module_section *section)
999{
1000 free(section);
1001}
1002
1003KMOD_EXPORT struct kmod_list *kmod_module_get_sections(const struct kmod_module *mod)
1004{
1005 char dname[PATH_MAX];
1006 struct kmod_list *list = NULL;
1007 DIR *d;
1008 int dfd;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001009
1010 if (mod == NULL)
1011 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001012
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001013 snprintf(dname, sizeof(dname), "/sys/module/%s/sections", mod->name);
1014
1015 d = opendir(dname);
1016 if (d == NULL) {
1017 ERR(mod->ctx, "could not open '%s': %s\n",
1018 dname, strerror(errno));
1019 return NULL;
1020 }
1021
1022 dfd = dirfd(d);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001023
1024 for (;;) {
1025 struct dirent de, *entp;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001026 struct kmod_module_section *section;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001027 struct kmod_list *l;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001028 unsigned long address;
1029 size_t namesz;
1030 int fd, err;
1031
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001032 err = readdir_r(d, &de, &entp);
1033 if (err != 0) {
1034 ERR(mod->ctx, "could not iterate for module '%s': %s\n",
1035 mod->name, strerror(-err));
1036 goto fail;
1037 }
1038
1039 if (de.d_name[0] == '.') {
1040 if (de.d_name[1] == '\0' ||
1041 (de.d_name[1] == '.' && de.d_name[2] == '\0'))
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001042 continue;
1043 }
1044
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001045 fd = openat(dfd, de.d_name, O_RDONLY);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001046 if (fd < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001047 ERR(mod->ctx, "could not open '%s/%s': %m\n",
1048 dname, de.d_name);
1049 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001050 }
1051
1052 err = read_str_ulong(fd, &address, 16);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001053 close(fd);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001054 if (err < 0) {
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001055 ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
1056 dname, de.d_name);
1057 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001058 }
1059
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001060 namesz = strlen(de.d_name) + 1;
1061 section = malloc(sizeof(*section) + namesz);
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001062
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001063 if (section == NULL) {
1064 ERR(mod->ctx, "out of memory\n");
1065 goto fail;
1066 }
1067
1068 section->address = address;
1069 memcpy(section->name, de.d_name, namesz);
1070
1071 l = kmod_list_append(list, section);
1072 if (l != NULL) {
1073 list = l;
1074 } else {
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001075 ERR(mod->ctx, "out of memory\n");
1076 free(section);
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001077 goto fail;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001078 }
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001079 }
1080
1081 closedir(d);
1082 return list;
Lucas De Marchi40923bd2011-12-05 13:40:16 -02001083
1084fail:
1085 closedir(d);
1086 kmod_module_unref_list(list);
1087 return NULL;
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001088}
1089
1090KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
1091{
1092 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001093
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001094 if (entry == NULL)
1095 return NULL;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001096
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001097 section = entry->data;
1098 return section->name;
1099}
1100
1101KMOD_EXPORT unsigned long kmod_module_section_get_address(const struct kmod_list *entry)
1102{
1103 struct kmod_module_section *section;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001104
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001105 if (entry == NULL)
1106 return (unsigned long)-1;
Lucas De Marchi28c175e2011-12-12 11:52:59 -02001107
Gustavo Sverzut Barbierif12ae3c2011-12-04 12:40:00 -02001108 section = entry->data;
1109 return section->address;
1110}
1111
1112KMOD_EXPORT void kmod_module_section_free_list(struct kmod_list *list)
1113{
1114 while (list) {
1115 kmod_module_section_free(list->data);
1116 list = kmod_list_remove(list);
1117 }
1118}