From: Ilya Dryomov Date: Fri, 12 Aug 2022 09:10:45 +0000 (+0200) Subject: rbd: find_action() should sort actions first X-Git-Tag: v16.2.11~354^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=391856b48e80030896a16ba854e93a08ab70b890;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 b3d33e9c81f6..9a544080e50f 100644 --- a/src/tools/rbd/Shell.cc +++ b/src/tools/rbd/Shell.cc @@ -302,8 +302,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(),