]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-conf: fix client's admin socket parsing 37785/head
authorXiubo Li <xiubli@redhat.com>
Wed, 25 Nov 2020 05:54:04 +0000 (13:54 +0800)
committerXiubo Li <xiubli@redhat.com>
Wed, 9 Dec 2020 11:36:24 +0000 (19:36 +0800)
For the 'admin socket' in ceph.conf, if the "$pid" is specified, it
will be expanded with the current process's PID.

For the ceph-conf command, if we specify the "--name" with a value
that have contained a socket daemon's PID, likes:

$ ceph-conf --name client.admin.133423 --show-config-value admin_socket

It will return a sockpath like:

/tmp/user/1000/ceph-asok.EZQumU/client.admin.133423.324523.asok

But the following is expected:

/tmp/user/1000/ceph-asok.EZQumU/client.admin.133423.asok

Stick "$name.$id" for mon/osd/mds/mgr daemons and for other try to
tripe the "$pid" from the name option's value and set a "PID" env.

Fixes: https://tracker.ceph.com/issues/47977
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/common/config.cc
src/test/cli/ceph-conf/show-config-value.t
src/tools/ceph_conf.cc

index 9cd42c6a5d8a8e93ca266fc0fec67400d2275074..1815c9ff4e7f365bc1cfead9ace79c7b84d0ec73 100644 (file)
@@ -1218,7 +1218,12 @@ Option::value_t md_config_t::_expand_meta(
       } else if (var == "id") {
        out += values.name.get_id();
       } else if (var == "pid") {
-       out += stringify(getpid());
+        char *_pid = getenv("PID");
+        if (_pid) {
+          out += _pid;
+        } else {
+          out += stringify(getpid());
+        }
         if (o) {
           may_reexpand_meta.push_back(o->name);
         }
index 5750de8e5a59014c5b9d8c3c050a11e6769fb511..a0ab4cbdfce26d44ae316e9467de6defb5302163 100644 (file)
@@ -8,9 +8,12 @@
   $ ceph-conf -n osd.0 --show-config-value INVALID -c /dev/null
   failed to get config option 'INVALID': option not found
   [1]
-  $ echo '[global]' > $TESTDIR/ceph.conf
-  $ echo 'mon_host=$public_network' >> $TESTDIR/ceph.conf
-  $ echo 'public_network=$mon_host' >> $TESTDIR/ceph.conf
+
+  $ cat > $TESTDIR/ceph.conf <<EOF
+  > [global]
+  >     mon_host = \$public_network
+  >     public_network = \$mon_host
+  > EOF
   $ ceph-conf --show-config-value mon_host -c $TESTDIR/ceph.conf
   variable expansion loop at mon_host=$public_network
   expansion stack:
   mon_host=$public_network
   $mon_host
   $ rm $TESTDIR/ceph.conf
+
+Name option test to strip the PID
+=================================
+  $ cat > $TESTDIR/ceph.conf <<EOF
+  > [client]
+  >     admin socket = \$name.\$pid.asok
+  > [global]
+  >     admin socket = \$name.asok
+  > EOF
+  $ ceph-conf --name client.admin.133423 --show-config-value admin_socket -c $TESTDIR/ceph.conf
+  client.admin.133423.asok
+  $ ceph-conf --name mds.a --show-config-value admin_socket -c $TESTDIR/ceph.conf
+  mds.a.asok
+  $ ceph-conf --name osd.0 --show-config-value admin_socket -c $TESTDIR/ceph.conf
+  osd.0.asok
+  $ rm $TESTDIR/ceph.conf
index df5384a9e91d05a32ee7c4732a79187f09993aae..755bb90233aa49adf2be429d3e3c844f05588413 100644 (file)
@@ -163,6 +163,47 @@ static int dump_all(const string& format)
   }
 }
 
+bool is_name_pid(std::string name, std::string& id)
+{
+  if (id.empty()) {
+    return false;
+  }
+  static const char* daemon_types[] = {"mon", "osd", "mds", "mgr"};
+  if (std::find(std::begin(daemon_types), std::end(daemon_types), name) !=
+      std::end(daemon_types)) {
+    // only override name and pid for non-daemon names
+    return false;
+  }
+  try {
+    std::stoi(id);
+  } catch (const std::logic_error&) {
+    // only override pid for $id which looks like pid
+    return false;
+  }
+  return true;
+}
+
+std::pair<std::string, std::string>
+maybe_override_name_pid(vector<const char*> args)
+{
+  for (auto i = args.begin(); i != args.end(); ++i) {
+    string val;
+    if (ceph_argparse_witharg(args, i, &val, "--name", "-n", (char*)NULL)) {
+      size_t dot_pos = val.rfind('.');
+      if (dot_pos != val.npos) {
+       string name = val.substr(0, dot_pos);
+       string id = val.substr(dot_pos + 1);
+        if (is_name_pid(name, id)) {
+          // override name
+          return {name, id};
+        }
+      }
+      return {val, ""};
+    }
+  }
+  return {};
+}
+
 int main(int argc, const char **argv)
 {
   vector<const char*> args;
@@ -176,8 +217,19 @@ int main(int argc, const char **argv)
   std::string dump_format;
 
   argv_to_vec(argc, argv, args);
+
   auto orig_args = args;
   auto cct = [&args] {
+    // override the name and PID for non-daemon names
+    auto [name, pid] = maybe_override_name_pid(args);
+    if (!name.empty()) {
+      // push the name option back
+      args.push_back("--name");
+      args.push_back(name.c_str());
+    }
+    if (!pid.empty()) {
+      setenv("PID", pid.c_str(), 1);
+    }
     std::map<std::string,std::string> defaults = {{"log_to_file", "false"}};
     return global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
                       CODE_ENVIRONMENT_DAEMON,