]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: find_action() should sort actions first
authorIlya Dryomov <idryomov@gmail.com>
Fri, 12 Aug 2022 09:10:45 +0000 (11:10 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 12 Aug 2022 09:10:45 +0000 (11:10 +0200)
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 <pool-spec> and
"list" generates an error.

Fixes: https://tracker.ceph.com/issues/57107
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/tools/rbd/Shell.cc

index c7d07657403b128923ba89244db627b1dd9bd391..2095682654430250852be4769269dfaec917f707 100644 (file)
@@ -301,8 +301,14 @@ void Shell::get_command_spec(const std::vector<std::string> &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<Action *> 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(),