From: Ilya Dryomov Date: Fri, 12 Aug 2022 09:10:45 +0000 (+0200) Subject: rbd: find_action() should sort actions first X-Git-Tag: v17.2.4~82^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a9776fd652bd1c0f6de15f413e2dc7b409c4b472;p=ceph.git rbd: find_action() should sort actions first The order in which objects with static storage duration in different TUs are initialized is undefined. If the compiler chooses to initialize Shell::Action objects in action/Trash.cc before Shell::Action objects in action/TrashPurgeSchedule.cc, all "rbd trash purge schedule ..." commands get shadowed by "rbd trash purge" command: $ rbd trash purge schedule list rbd: too many arguments The confusing error arises because "rbd trash purge" takes a single positional argument. "schedule" gets interpreted as and "list" generates an error. Fixes: https://tracker.ceph.com/issues/57107 Signed-off-by: Ilya Dryomov (cherry picked from commit e0b428a87a48f2132c825ffde4629709a57b76d6) --- diff --git a/src/tools/rbd/Shell.cc b/src/tools/rbd/Shell.cc index c7d07657403b..209568265443 100644 --- a/src/tools/rbd/Shell.cc +++ b/src/tools/rbd/Shell.cc @@ -301,8 +301,14 @@ void Shell::get_command_spec(const std::vector &arguments, Shell::Action *Shell::find_action(const CommandSpec &command_spec, CommandSpec **matching_spec, bool *is_alias) { - for (size_t i = 0; i < get_actions().size(); ++i) { - Action *action = get_actions()[i]; + // sort such that all "trash purge schedule ..." actions come before + // "trash purge" + std::vector actions(get_actions()); + std::sort(actions.begin(), actions.end(), [](auto lhs, auto rhs) { + return lhs->command_spec.size() > rhs->command_spec.size(); + }); + + for (Action *action : actions) { if (action->command_spec.size() <= command_spec.size()) { if (std::includes(action->command_spec.begin(), action->command_spec.end(),