diff --git a/doc/man/8/ceph-conf.rst b/doc/man/8/ceph-conf.rst index 3743813e119..b8b99c2aab1 100644 --- a/doc/man/8/ceph-conf.rst +++ b/doc/man/8/ceph-conf.rst @@ -84,6 +84,13 @@ Options For example, if we specify ``--name osd.0``, the following sections will be searched: [osd.0], [osd], [global] +.. option:: --pid *pid* + + override the ``$pid`` when expanding options. For example, if an option is + configured like ``/var/log/$name.$pid.log``, the ``$pid`` portion in its + value will be substituded using the PID of **ceph-conf** instead of the + PID of the process specfied using the ``--name`` option. + .. option:: -r, --resolve-search search for the first file that exists and can be opened in the resulted diff --git a/src/ceph.in b/src/ceph.in index 9d535eb842a..1714ae931bb 100755 --- a/src/ceph.in +++ b/src/ceph.in @@ -20,11 +20,11 @@ Foundation. See file COPYING. """ from time import sleep -import codecs import grp import os import pwd import shutil +import stat import sys import time import platform @@ -495,7 +495,7 @@ def format_help(cmddict, partial=None): return fullusage -def ceph_conf(parsed_args, field, name): +def ceph_conf(parsed_args, field, name, pid=None): cmd = 'ceph-conf' bindir = os.path.dirname(__file__) if shutil.which(cmd): @@ -507,6 +507,8 @@ def ceph_conf(parsed_args, field, name): if name: args.extend(['--name', name]) + if pid: + args.extend(['--pid', pid]) # add any args in GLOBAL_ARGS for key, val in GLOBAL_ARGS.items(): @@ -526,6 +528,7 @@ def ceph_conf(parsed_args, field, name): raise RuntimeError('unable to get conf option %s for %s: %s' % (field, name, errdata)) return outdata.rstrip() + PROMPT = 'ceph> ' if sys.stdin.isatty(): @@ -730,6 +733,23 @@ def ping_monitor(cluster_handle, name, timeout): return 0 +def get_admin_socket(parsed_args, name): + path = ceph_conf(parsed_args, 'admin_socket', name) + try: + if stat.S_ISSOCK(os.stat(path).st_mode): + return path + except OSError: + pass + # try harder, probably the "name" option is in the form of + # "${name}.${pid}"? + parts = name.rsplit('.', 1) + if len(parts) > 1 and parts[-1].isnumeric(): + name, pid = parts + return ceph_conf(parsed_args, 'admin_socket', name, pid) + else: + return path + + def maybe_daemon_command(parsed_args, childargs): """ Check if --admin-socket, daemon, or daemonperf command @@ -751,8 +771,7 @@ def maybe_daemon_command(parsed_args, childargs): else: # try resolve daemon name try: - sockpath = ceph_conf(parsed_args, 'admin_socket', - childargs[1]) + sockpath = get_admin_socket(parsed_args, childargs[1]) except Exception as e: print('Can\'t get admin socket path: ' + str(e), file=sys.stderr) return True, errno.EINVAL diff --git a/src/test/cli/ceph-conf/help.t b/src/test/cli/ceph-conf/help.t index 8fa2152d394..751b3a54ae9 100644 --- a/src/test/cli/ceph-conf/help.t +++ b/src/test/cli/ceph-conf/help.t @@ -28,6 +28,7 @@ [--format plain|json|json-pretty] dump variables in plain text, json or pretty json + [--pid ] Override the $pid when expanding options If there is no action given, the action will default to --lookup. diff --git a/src/test/cli/ceph-conf/show-config-value.t b/src/test/cli/ceph-conf/show-config-value.t index a0ab4cbdfce..2e0528e9390 100644 --- a/src/test/cli/ceph-conf/show-config-value.t +++ b/src/test/cli/ceph-conf/show-config-value.t @@ -30,7 +30,7 @@ Name option test to strip the PID > [global] > admin socket = \$name.asok > EOF - $ ceph-conf --name client.admin.133423 --show-config-value admin_socket -c $TESTDIR/ceph.conf + $ ceph-conf --name client.admin --pid 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 diff --git a/src/tools/ceph_conf.cc b/src/tools/ceph_conf.cc index 755bb90233a..d26cbb03994 100644 --- a/src/tools/ceph_conf.cc +++ b/src/tools/ceph_conf.cc @@ -55,6 +55,7 @@ FLAGS [--format plain|json|json-pretty] dump variables in plain text, json or pretty json + [--pid ] Override the $pid when expanding options If there is no action given, the action will default to --lookup. @@ -163,45 +164,15 @@ 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 -maybe_override_name_pid(vector args) +static void maybe_override_pid(vector& 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, ""}; + if (ceph_argparse_witharg(args, i, &val, "--pid", (char*)NULL)) { + setenv("PID", val.c_str(), 1); + break; } } - return {}; } int main(int argc, const char **argv) @@ -220,16 +191,8 @@ int main(int argc, const char **argv) 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); - } + // override the PID before options are expanded + maybe_override_pid(args); std::map defaults = {{"log_to_file", "false"}}; return global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON,