return ret;
}
-static int rmmod_do_soft_dependencies(struct kmod_module *mod)
-{
- ERR("TODO - implement soft dependencies!\n");
- /* remember to reverse soft dependencies! */
- return 0;
-}
+static int rmmod_do_dependencies(struct kmod_module *parent);
+static int rmmod_do_soft_dependencies(struct kmod_module *mod, struct kmod_list *deps);
-static int rmmod_do_dependencies(struct kmod_module *parent)
+static int rmmod_do_deps_list(struct kmod_module *parent, struct kmod_list *deps, unsigned stop_on_errors)
{
+ struct kmod_list *d;
int err = 0;
- struct kmod_list *d, *deps = kmod_module_get_holders(parent);
- kmod_list_foreach(d, deps) {
+
+ kmod_list_foreach_reverse(d, deps) {
struct kmod_module *dm = kmod_module_get_module(d);
+ struct kmod_list *pre = NULL, *post = NULL;
const char *cmd, *dmname = kmod_module_get_name(dm);
int r;
goto dep_error;
}
- if (!ignore_loaded) {
- int state = kmod_module_get_initstate(dm);
- if (state != KMOD_MODULE_LIVE &&
- state != KMOD_MODULE_COMING)
- goto dep_done;
+ r = kmod_module_get_softdeps(dm, &pre, &post);
+ if (r < 0) {
+ WRN("could not get softdeps of '%s': %s\n",
+ dmname, strerror(-r));
+ goto dep_done;
}
- r = rmmod_do_soft_dependencies(dm);
+ r = rmmod_do_soft_dependencies(dm, post);
if (r < 0) {
- WRN("could not remove soft dependencies of '%s': %s\n",
+ WRN("could not remove post soft softdeps of '%s': %s\n",
dmname, strerror(-r));
goto dep_error;
}
+ if (!ignore_loaded) {
+ int state = kmod_module_get_initstate(dm);
+ if (state != KMOD_MODULE_LIVE &&
+ state != KMOD_MODULE_COMING)
+ goto dep_done;
+ }
+
cmd = kmod_module_get_remove_commands(dm);
if (cmd) {
r = command_do(dm, "remove", cmd, NULL);
}
dep_done:
+ r = rmmod_do_soft_dependencies(dm, pre);
+ if (r < 0) {
+ WRN("could not remove pre softdeps of '%s': %s\n",
+ dmname, strerror(-r));
+ goto dep_error;
+ }
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
kmod_module_unref(dm);
continue;
+
dep_error:
err = r;
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
kmod_module_unref(dm);
- continue;
+ if (stop_on_errors)
+ break;
+ else
+ continue;
}
+
+ return err;
+}
+
+static int rmmod_do_soft_dependencies(struct kmod_module *mod, struct kmod_list *deps)
+{
+ return rmmod_do_deps_list(mod, deps, 0);
+}
+
+static int rmmod_do_dependencies(struct kmod_module *parent)
+{
+ struct kmod_list *deps = kmod_module_get_holders(parent);
+ int err = rmmod_do_deps_list(parent, deps, 1);
kmod_module_unref_list(deps);
return err;
}
static int rmmod_do(struct kmod_module *mod)
{
const char *modname = kmod_module_get_name(mod);
+ struct kmod_list *pre = NULL, *post = NULL;
int err;
if (!ignore_loaded) {
if (!ignore_commands) {
const char *cmd;
- err = rmmod_do_soft_dependencies(mod);
- if (err < 0)
+ err = kmod_module_get_softdeps(mod, &pre, &post);
+ if (err < 0) {
+ WRN("could not get softdeps of '%s': %s\n",
+ modname, strerror(-err));
return err;
+ }
+
+ err = rmmod_do_soft_dependencies(mod, post);
+ if (err < 0) {
+ WRN("could not remove post softdeps of '%s': %s\n",
+ modname, strerror(-err));
+ goto error;
+ }
cmd = kmod_module_get_remove_commands(mod);
- if (cmd)
- return command_do(mod, "remove", cmd, NULL);
+ if (cmd != NULL) {
+ err = command_do(mod, "remove", cmd, NULL);
+ goto done;
+ }
}
if (!ignore_loaded) {
int usage = kmod_module_get_refcnt(mod);
if (usage > 0) {
LOG("Module %s is in use.\n", modname);
- return -EBUSY;
+ err = -EBUSY;
+ goto error;
}
}
LOG("Module %s is not in kernel.\n", modname);
}
}
+
+done:
+ if (!ignore_commands) {
+ err = rmmod_do_soft_dependencies(mod, pre);
+ if (err < 0) {
+ WRN("could not remove pre softdeps of '%s': %s\n",
+ modname, strerror(-err));
+ goto error;
+ }
+ }
+
+error:
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
return err;
}
return err;
}
-static int insmod_do_soft_dependencies(struct kmod_module *mod)
-{
- ERR("TODO - implement soft dependencies!\n");
- return 0;
-}
+static int insmod_do_dependencies(struct kmod_module *parent);
+static int insmod_do_soft_dependencies(struct kmod_module *mod, struct kmod_list *deps);
-static int insmod_do_dependencies(struct kmod_module *parent)
+static int insmod_do_deps_list(struct kmod_module *parent, struct kmod_list *deps, unsigned stop_on_errors)
{
+ struct kmod_list *d;
int err = 0;
- struct kmod_list *d, *deps = kmod_module_get_dependencies(parent);
+
kmod_list_foreach(d, deps) {
struct kmod_module *dm = kmod_module_get_module(d);
+ struct kmod_list *pre = NULL, *post = NULL;
const char *cmd, *opts, *dmname = kmod_module_get_name(dm);
int r;
goto dep_error;
}
+ r = kmod_module_get_softdeps(dm, &pre, &post);
+ if (r < 0) {
+ WRN("could not get softdeps of '%s': %s\n",
+ dmname, strerror(-r));
+ goto dep_done;
+ }
+
+ r = insmod_do_soft_dependencies(dm, pre);
+ if (r < 0) {
+ WRN("could not insert pre softdeps of '%s': %s\n",
+ dmname, strerror(-r));
+ goto dep_error;
+ }
+
if (!ignore_loaded) {
int state = kmod_module_get_initstate(dm);
if (state == KMOD_MODULE_LIVE ||
goto dep_done;
}
- r = insmod_do_soft_dependencies(dm);
- if (r < 0) {
- WRN("could not insert soft dependencies of '%s': %s\n",
- dmname, strerror(-r));
- goto dep_error;
- }
-
cmd = kmod_module_get_install_commands(dm);
if (cmd) {
r = command_do(dm, "install", cmd, NULL);
}
dep_done:
+ r = insmod_do_soft_dependencies(dm, post);
+ if (r < 0) {
+ WRN("could not insert post softdeps of '%s': %s\n",
+ dmname, strerror(-r));
+ goto dep_error;
+ }
+
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
kmod_module_unref(dm);
continue;
+
dep_error:
err = r;
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
kmod_module_unref(dm);
- continue;
+ if (stop_on_errors)
+ break;
+ else
+ continue;
}
+
+ return err;
+}
+
+static int insmod_do_soft_dependencies(struct kmod_module *mod, struct kmod_list *deps)
+{
+ return insmod_do_deps_list(mod, deps, 0);
+}
+
+static int insmod_do_dependencies(struct kmod_module *parent)
+{
+ struct kmod_list *deps = kmod_module_get_dependencies(parent);
+ int err = insmod_do_deps_list(parent, deps, 1);
kmod_module_unref_list(deps);
return err;
}
{
const char *modname = kmod_module_get_name(mod);
const char *conf_opts = kmod_module_get_options(mod);
+ struct kmod_list *pre = NULL, *post = NULL;
char *opts = NULL;
int err;
if (!ignore_commands) {
const char *cmd;
- err = insmod_do_soft_dependencies(mod);
- if (err < 0)
+ err = kmod_module_get_softdeps(mod, &pre, &post);
+ if (err < 0) {
+ WRN("could not get softdeps of '%s': %s\n",
+ modname, strerror(-err));
return err;
+ }
+
+ err = insmod_do_soft_dependencies(mod, pre);
+ if (err < 0) {
+ WRN("could not insert pre softdeps of '%s': %s\n",
+ modname, strerror(-err));
+ goto error;
+ }
cmd = kmod_module_get_install_commands(mod);
- if (cmd)
- return command_do(mod, "install", cmd, extra_opts);
+ if (cmd != NULL) {
+ err = command_do(mod, "install", cmd, extra_opts);
+ goto done;
+ }
}
if (conf_opts || extra_opts) {
else if (asprintf(&opts, "%s %s", conf_opts, extra_opts) < 0)
opts = NULL;
- if (opts == NULL)
- return -ENOMEM;
+ if (opts == NULL) {
+ err = -ENOMEM;
+ goto error;
+ }
}
SHOW("insmod %s %s\n", kmod_module_get_path(mod), opts ? opts : "");
kmod_module_get_name(mod));
}
}
+
+done:
+ if (!ignore_commands) {
+ err = insmod_do_soft_dependencies(mod, post);
+ if (err < 0) {
+ WRN("could not insert post softdeps of '%s': %s\n",
+ modname, strerror(-err));
+ goto error;
+ }
+ }
+
+error:
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
free(opts);
return err;
}