From patchwork Tue Mar 29 09:05:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 12794588 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B10BC433F5 for ; Tue, 29 Mar 2022 09:06:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234371AbiC2JH4 (ORCPT ); Tue, 29 Mar 2022 05:07:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234437AbiC2JHl (ORCPT ); Tue, 29 Mar 2022 05:07:41 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39ABD241B7C for ; Tue, 29 Mar 2022 02:05:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648544758; x=1680080758; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=a7ZF5XjqShb5VZnzS09pEe8sn4Z0kAmNbRW3SbLYsak=; b=oFlROxUtLW55FZUIHjLfyzC++LU5cyt4loal1crxg9rCiRizgrmZrqLI VSH70KgOP00iHR9X7KuTI7eVXQqO0DLJD3xYvfHxizjey0vTY1a+ObAtQ ygxMsgtpTS1E9AaSlEJ8h0+bp7shGVD/1mO57TNwr+T2RHREqEA0jD8HX iX39XBV+TmXzWlA6c0c0qdOwot99EB0RjaHCRHGWT/hhg7b8GJ9BTRR9N kpeAQTomcpQK59ztd3DA9OAZH0bPsC4huMKP2ns2kup37FV4hKnaLs5f4 j3XmxMQ9NTcDM9e8H8LKGSCR6Blc0J3qxwD1y++jttsrhXxYFaEEFu9Am Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10300"; a="239134284" X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="239134284" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:56 -0700 X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="585502837" Received: from mlopezja-mobl.amr.corp.intel.com (HELO ldmartin-desk2.intel.com) ([10.255.231.179]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:55 -0700 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 1/4] modprobe: Rename rmmod_do_deps_list Date: Tue, 29 Mar 2022 02:05:35 -0700 Message-Id: <20220329090540.38255-2-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220329090540.38255-1-lucas.demarchi@intel.com> References: <20220329090540.38255-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: It's used not only for dependencies, but also for pre and post softdep. Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain --- tools/modprobe.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/modprobe.c b/tools/modprobe.c index 9387537..eed951f 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -357,7 +357,8 @@ static int rmmod_do_remove_module(struct kmod_module *mod) #define RMMOD_FLAG_IGNORE_BUILTIN 0x2 static int rmmod_do_module(struct kmod_module *mod, int flags); -static int rmmod_do_deps_list(struct kmod_list *list, bool stop_on_errors) +/* Remove modules in reverse order */ +static int rmmod_do_modlist(struct kmod_list *list, bool stop_on_errors) { struct kmod_list *l; @@ -413,12 +414,12 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) } } - rmmod_do_deps_list(post, false); + rmmod_do_modlist(post, false); if ((flags & RMMOD_FLAG_DO_DEPENDENCIES) && remove_dependencies) { struct kmod_list *deps = kmod_module_get_dependencies(mod); - err = rmmod_do_deps_list(deps, true); + err = rmmod_do_modlist(deps, true); if (err < 0) goto error; } @@ -443,7 +444,7 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) if (err < 0) goto error; - rmmod_do_deps_list(pre, false); + rmmod_do_modlist(pre, false); error: kmod_module_unref_list(pre); From patchwork Tue Mar 29 09:05:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 12794593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9130BC433FE for ; Tue, 29 Mar 2022 09:06:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234424AbiC2JH6 (ORCPT ); Tue, 29 Mar 2022 05:07:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234439AbiC2JHl (ORCPT ); Tue, 29 Mar 2022 05:07:41 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 906B4242200 for ; Tue, 29 Mar 2022 02:05:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648544759; x=1680080759; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pOfuYLD3+WIqgBXyekrwMeTleCTPVI4Hjm+Qr82QKO4=; b=bnzTH7/IQL+ZW5caD6BTjHITF5u2IKogyaKaWNpnHvqrXiZb/vLJFfzf pPo19q6Jmjv65UiG9vFJKu/15bPi3L9jP7siIVHstmQlsPHPo8g8U4LMh 73M/WGnMY+9aIuVQmyxmILJDiSJ8yaJzIPbbYgVR3XJJ6mjo5oHq4QZiE 6FdEeXV48/nF4M4pPsIlFJ2JTPV+BVaXZGsNnHTKsPDpmPetSoy1bfEKK O4trdB6acYi6M8+o2S+eQpIhSkserjUFM2oNESnk/ufKn5x+ZOcgoBZ37 gYN3/jjMDz4FcIsO7KU3itRdcjgmdsO+hfr3W8Jc4e9xkBvu1bM0fI7lE w==; X-IronPort-AV: E=McAfee;i="6200,9189,10300"; a="239134288" X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="239134288" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:57 -0700 X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="585502844" Received: from mlopezja-mobl.amr.corp.intel.com (HELO ldmartin-desk2.intel.com) ([10.255.231.179]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:55 -0700 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 2/4] modprobe: Fix holders removal Date: Tue, 29 Mar 2022 02:05:37 -0700 Message-Id: <20220329090540.38255-4-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220329090540.38255-1-lucas.demarchi@intel.com> References: <20220329090540.38255-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: The idea behind --remove-dependencies was to remove other modules that depend on the current module being removed. It's the reverse dependency list, not the dependency list of the current module: that never works since the current module would still hold a ref on it. Fix it by replacing the call to kmod_module_get_dependencies() with kmod_module_get_holders() when using that option. Also try to cleanup the confusion by renaming the option to --remove-holders: "holder" is the name used in sysfs and by libkmod to refer to a "live" reverse dependency like what we are interested in. Before: ./tools/modprobe -D -r --remove-dependencies video rmmod video After: ./tools/modprobe -D -r --remove-holders video rmmod i915 rmmod thinkpad_acpi rmmod video Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain --- tools/modprobe.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/modprobe.c b/tools/modprobe.c index eed951f..ceb4ff6 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -54,7 +54,7 @@ static int use_blacklist = 0; static int force = 0; static int strip_modversion = 0; static int strip_vermagic = 0; -static int remove_dependencies = 0; +static int remove_holders = 0; static int quiet_inuse = 0; static const char cmdopts_s[] = "arRibfDcnC:d:S:sqvVh"; @@ -62,6 +62,7 @@ static const struct option cmdopts[] = { {"all", no_argument, 0, 'a'}, {"remove", no_argument, 0, 'r'}, {"remove-dependencies", no_argument, 0, 5}, + {"remove-holders", no_argument, 0, 5}, {"resolve-alias", no_argument, 0, 'R'}, {"first-time", no_argument, 0, 3}, {"ignore-install", no_argument, 0, 'i'}, @@ -107,7 +108,8 @@ static void help(void) "\t be a module name to be inserted\n" "\t or removed (-r)\n" "\t-r, --remove Remove modules instead of inserting\n" - "\t --remove-dependencies Also remove modules depending on it\n" + "\t --remove-dependencies Deprecated: use --remove-holders\n" + "\t --remove-holders Also remove module holders (use together with -r)\n" "\t-R, --resolve-alias Only lookup and print alias and exit\n" "\t --first-time Fail if module already inserted or removed\n" "\t-i, --ignore-install Ignore install commands\n" @@ -353,7 +355,7 @@ static int rmmod_do_remove_module(struct kmod_module *mod) return err; } -#define RMMOD_FLAG_DO_DEPENDENCIES 0x1 +#define RMMOD_FLAG_REMOVE_HOLDERS 0x1 #define RMMOD_FLAG_IGNORE_BUILTIN 0x2 static int rmmod_do_module(struct kmod_module *mod, int flags); @@ -416,10 +418,10 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) rmmod_do_modlist(post, false); - if ((flags & RMMOD_FLAG_DO_DEPENDENCIES) && remove_dependencies) { - struct kmod_list *deps = kmod_module_get_dependencies(mod); + if ((flags & RMMOD_FLAG_REMOVE_HOLDERS) && remove_holders) { + struct kmod_list *holders = kmod_module_get_holders(mod); - err = rmmod_do_modlist(deps, true); + err = rmmod_do_modlist(holders, true); if (err < 0) goto error; } @@ -469,7 +471,7 @@ static int rmmod(struct kmod_ctx *ctx, const char *alias) kmod_list_foreach(l, list) { struct kmod_module *mod = kmod_module_get_module(l); - err = rmmod_do_module(mod, RMMOD_FLAG_DO_DEPENDENCIES); + err = rmmod_do_module(mod, RMMOD_FLAG_REMOVE_HOLDERS); kmod_module_unref(mod); if (err < 0) break; @@ -787,7 +789,7 @@ static int do_modprobe(int argc, char **orig_argv) do_remove = 1; break; case 5: - remove_dependencies = 1; + remove_holders = 1; break; case 'R': lookup_only = 1; From patchwork Tue Mar 29 09:05:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 12794591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4636C43217 for ; Tue, 29 Mar 2022 09:06:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234427AbiC2JIB (ORCPT ); Tue, 29 Mar 2022 05:08:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234441AbiC2JHm (ORCPT ); Tue, 29 Mar 2022 05:07:42 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A95B8242202 for ; Tue, 29 Mar 2022 02:05:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648544759; x=1680080759; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SX6Rb/HKFg/+JyY0RR92+nOatpAw4Y6382LxugLc99s=; b=VPOcHVfWTLy06vvy20RAQ+GF/9GwX5RYV7KMN9RE4JHK9IwOtCzNEqpl hDUSyDKb1s5LE1FhmVFaAUEnpoJL901IxgyoFwmSOGM4n4ksBZJx79Y6n zh7D070dUhNhj8/a245QVtWHINxGsKFhNn1Vo26Ek1B9/plWea/C51U0+ 3feUK5CSNQyMPIUSvbaU6Lxplrmn4Z94Dp7AicJ+4BcOCG6LJjKYHYSUu MwoG6w1PKsJHQLx1dctCYbUureJCcUBOd2GO5ya1SM2yd6jmON2Wagzfi kNgISxVE7eeZ/7wp7TFo1UR2xjKcq7RAisS34Hp1AUfxBVM9yYnVGYl8v A==; X-IronPort-AV: E=McAfee;i="6200,9189,10300"; a="239134293" X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="239134293" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:57 -0700 X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="585502850" Received: from mlopezja-mobl.amr.corp.intel.com (HELO ldmartin-desk2.intel.com) ([10.255.231.179]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:55 -0700 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 3/4] modprobe: move check for remove_holders to caller Date: Tue, 29 Mar 2022 02:05:39 -0700 Message-Id: <20220329090540.38255-6-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220329090540.38255-1-lucas.demarchi@intel.com> References: <20220329090540.38255-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: Do not mix the flags with and additional boolean from arguments. Signed-off-by: Lucas De Marchi --- tools/modprobe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/modprobe.c b/tools/modprobe.c index ceb4ff6..0d9b805 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -418,7 +418,7 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) rmmod_do_modlist(post, false); - if ((flags & RMMOD_FLAG_REMOVE_HOLDERS) && remove_holders) { + if (flags & RMMOD_FLAG_REMOVE_HOLDERS) { struct kmod_list *holders = kmod_module_get_holders(mod); err = rmmod_do_modlist(holders, true); @@ -471,7 +471,9 @@ static int rmmod(struct kmod_ctx *ctx, const char *alias) kmod_list_foreach(l, list) { struct kmod_module *mod = kmod_module_get_module(l); - err = rmmod_do_module(mod, RMMOD_FLAG_REMOVE_HOLDERS); + int flags = remove_holders ? RMMOD_FLAG_REMOVE_HOLDERS : 0; + + err = rmmod_do_module(mod, flags); kmod_module_unref(mod); if (err < 0) break; From patchwork Tue Mar 29 09:05:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas De Marchi X-Patchwork-Id: 12794590 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DBD2C43219 for ; Tue, 29 Mar 2022 09:06:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234431AbiC2JIB (ORCPT ); Tue, 29 Mar 2022 05:08:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234443AbiC2JHm (ORCPT ); Tue, 29 Mar 2022 05:07:42 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C4F2241B7A for ; Tue, 29 Mar 2022 02:06:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648544760; x=1680080760; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rNkYydc8uQlz0RjN4RZ/kbh1OjvRCz/lyzzKXzruYRk=; b=HcojgQi+aI4Ru1n4Awfy1sItomgLfBsKUZg84D06Bou7SGhfmlm9zJRS rAwwA4/UodY/1UUkFj5hkdT2ogwZp887kz6uUOYzTrJ2596lpJ2+VuTzs vbB83skNNbwx0ccZJOL+uWy2m7PyRhaYY2oMLv3CjSIV/cbYAIvQrsKCL wxYNy/c8KJLjRf74CkTPhTSlYuqNmlUBBkD5wKhcgFXdjSvjbZb4zF8H3 FRRpO+eA9+5ek8kX4IU4wPZteoo7V7ejA9AURATzqV4qLK7f0Ug8l0Lju bA4dJcGRhNY7tVA+lpwpx8NoK/QsJpcyZbxLuOIBowiT9q8HJjEZCgpZI g==; X-IronPort-AV: E=McAfee;i="6200,9189,10300"; a="239134294" X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="239134294" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:57 -0700 X-IronPort-AV: E=Sophos;i="5.90,219,1643702400"; d="scan'208";a="585502853" Received: from mlopezja-mobl.amr.corp.intel.com (HELO ldmartin-desk2.intel.com) ([10.255.231.179]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Mar 2022 02:05:56 -0700 From: Lucas De Marchi To: linux-modules@vger.kernel.org Cc: Luis Chamberlain , Lucas De Marchi Subject: [PATCH 4/4] modprobe: Make rmmod_do_module() contain all the removal sequence Date: Tue, 29 Mar 2022 02:05:40 -0700 Message-Id: <20220329090540.38255-7-lucas.demarchi@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220329090540.38255-1-lucas.demarchi@intel.com> References: <20220329090540.38255-1-lucas.demarchi@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: Move the remaining part of the removal sequence dangling in rmmod_do_remove_module() to rmmod_do_module() so we can consider this function is the one controlling all the module removals. While at it, add some comments about the removal order and normalize coding style in this function. Signed-off-by: Lucas De Marchi Reviewed-by: Luis Chamberlain --- tools/modprobe.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/tools/modprobe.c b/tools/modprobe.c index 0d9b805..34ef8da 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -322,7 +322,6 @@ end: static int rmmod_do_remove_module(struct kmod_module *mod) { const char *modname = kmod_module_get_name(mod); - struct kmod_list *deps, *itr; int flags = 0, err; SHOW("rmmod %s\n", kmod_module_get_name(mod)); @@ -341,17 +340,6 @@ static int rmmod_do_remove_module(struct kmod_module *mod) LOG("Module %s is not in kernel.\n", modname); } - deps = kmod_module_get_dependencies(mod); - if (deps != NULL) { - kmod_list_foreach(itr, deps) { - struct kmod_module *dep = kmod_module_get_module(itr); - if (kmod_module_get_refcnt(dep) == 0) - rmmod_do_remove_module(dep); - kmod_module_unref(dep); - } - kmod_module_unref_list(deps); - } - return err; } @@ -394,7 +382,8 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) cmd = kmod_module_get_remove_commands(mod); } - if (cmd == NULL && !ignore_loaded) { + /* Quick check if module is loaded, otherwise there's nothing to do */ + if (!cmd && !ignore_loaded) { int state = kmod_module_get_initstate(mod); if (state < 0) { @@ -416,8 +405,10 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) } } + /* 1. @mod's post-softdeps in reverse order */ rmmod_do_modlist(post, false); + /* 2. Other modules holding @mod */ if (flags & RMMOD_FLAG_REMOVE_HOLDERS) { struct kmod_list *holders = kmod_module_get_holders(mod); @@ -426,7 +417,8 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) goto error; } - if (!ignore_loaded && !cmd) { + /* 3. @mod itself, but check for refcnt first */ + if (!cmd && !ignore_loaded) { int usage = kmod_module_get_refcnt(mod); if (usage > 0) { @@ -438,7 +430,7 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) } } - if (cmd == NULL) + if (!cmd) err = rmmod_do_remove_module(mod); else err = command_do(mod, "remove", cmd, NULL); @@ -446,6 +438,21 @@ static int rmmod_do_module(struct kmod_module *mod, int flags) if (err < 0) goto error; + /* 4. Other modules that became unused: errors are non-fatal */ + if (!cmd) { + struct kmod_list *deps, *itr; + + deps = kmod_module_get_dependencies(mod); + kmod_list_foreach(itr, deps) { + struct kmod_module *dep = kmod_module_get_module(itr); + if (kmod_module_get_refcnt(dep) == 0) + rmmod_do_remove_module(dep); + kmod_module_unref(dep); + } + kmod_module_unref_list(deps); + } + + /* 5. @mod's pre-softdeps in reverse order: errors are non-fatal */ rmmod_do_modlist(pre, false); error: