]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/osd: do not pass ceph options to seastar
authorKefu Chai <kchai@redhat.com>
Thu, 14 Mar 2019 10:53:36 +0000 (18:53 +0800)
committerKefu Chai <kchai@redhat.com>
Wed, 20 Mar 2019 06:20:33 +0000 (14:20 +0800)
the program_option parser used by seastar::app_template does not allow
unrecognized options. but ceph options can be specfied by being passed
to ceph applications as command line options, for instance, we can
specify the "key" or "keyfile" when creating an objectstore using
"--mkfs", like:

  ceph-osd --mkfs --key <key>

in this change, all options known by seastar's app_template are
enumerated and stored into a separated vector. so it can be passed to
"app". and the unknown ones are passed to ceph functions.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/osd/main.cc

index 04a0c97dfc8f30515b22d5ccf7801d9e2ead78de..49d4b03e5e3ec00809472244146fb5f7b944205b 100644 (file)
@@ -21,10 +21,49 @@ void usage(const char* prog) {
   generic_server_usage();
 }
 
+auto partition_args(seastar::app_template& app, int argc, char* argv[])
+{
+  namespace bpo = boost::program_options;
+  // collect all options consumed by seastar::app_template
+  auto parsed = bpo::command_line_parser(argc, argv)
+    .options(app.get_options_description()).allow_unregistered().run();
+  const auto unknown_args = bpo::collect_unrecognized(parsed.options,
+                                                      bpo::include_positional);
+  std::vector<const char*> ceph_args, app_args;
+  bool consume_next_arg = false;
+  std::partition_copy(
+    argv, argv + argc,
+    std::back_inserter(ceph_args),
+    std::back_inserter(app_args),
+    [begin=unknown_args.begin(),
+     end=unknown_args.end(),
+     &consume_next_arg](const char* arg) {
+      if (std::find(begin, end, arg) != end) {
+        return true;
+      } else if (std::strcmp(arg, "-c") == 0) {
+        // ceph_argparse_early_args() and
+        // seastar::smp::get_options_description() use "-c" for different
+        // options. and ceph wins
+        consume_next_arg = true;
+        return true;
+      } else if (consume_next_arg) {
+        consume_next_arg = false;
+        return true;
+      } else {
+        return false;
+      }
+    });
+  return make_pair(std::move(ceph_args), std::move(app_args));
+}
+
 int main(int argc, char* argv[])
 {
-  std::vector<const char*> args{argv + 1, argv + argc};
-  if (ceph_argparse_need_usage(args)) {
+  seastar::app_template app;
+  app.add_options()
+    ("mkfs", "create a [new] data directory");
+
+  auto [ceph_args, app_args] = partition_args(app, argc, argv);
+  if (ceph_argparse_need_usage(ceph_args)) {
     usage(argv[0]);
     return EXIT_SUCCESS;
   }
@@ -32,22 +71,16 @@ int main(int argc, char* argv[])
   std::string conf_file_list;
   // ceph_argparse_early_args() could _exit(), while local_conf() won't ready
   // until it's started. so do the boilerplate-settings parsing here.
-  auto init_params = ceph_argparse_early_args(args,
+  auto init_params = ceph_argparse_early_args(ceph_args,
                                               CEPH_ENTITY_TYPE_OSD,
                                               &cluster,
                                               &conf_file_list);
-  seastar::app_template app;
-  app.add_options()
-    ("mkfs", "create a [new] data directory");
   seastar::sharded<OSD> osd;
-
   using ceph::common::sharded_conf;
   using ceph::common::sharded_perf_coll;
   using ceph::common::local_conf;
-
-  args.insert(begin(args), argv[0]);
   try {
-    return app.run_deprecated(args.size(), const_cast<char**>(args.data()), [&] {
+    return app.run_deprecated(app_args.size(), const_cast<char**>(app_args.data()), [&] {
       auto& config = app.configuration();
       seastar::engine().at_exit([] {
         return sharded_conf().stop();