Configuration Management System

The configuration management system exists to provide every daemon with the proper configuration information. The configuration can be viewed as a set of key-value pairs.

How can the configuration be set? Well, there are several sources:

  • the ceph configuration file, usually named ceph.conf

  • command line arguments:

    --debug-ms=1
    --debug-monc=10
    

    etc.

  • arguments injected at runtime using injectargs or config set

The Configuration File

Most configuration settings originate in the Ceph configuration file.

How do we find the configuration file? Well, in order, we check:

  • the default locations

  • the environment variable CEPH_CONF

  • the command line argument -c

Each stanza of the configuration file describes the key-value pairs that will be in effect for a particular subset of the daemons. The “global” stanza applies to everything. The “mon”, “osd”, and “mds” stanzas specify settings to take effect for all monitors, all OSDs, and all mds servers, respectively. A stanza of the form mon.$name, osd.$name, or mds.$name gives settings for the monitor, OSD, or MDS of that name, respectively. Configuration values that appear later in the file win over earlier ones.

A sample configuration file can be found in src/sample.ceph.conf.

Metavariables

The configuration system allows any configuration value to be substituted into another value using the $varname syntax, similar to how bash shell expansion works.

A few additional special metavariables are also defined:

  • $host: expands to the current hostname

  • $type: expands to one of “mds”, “osd”, “mon”, or “client”

  • $id: expands to the daemon identifier. For osd.0, this would be 0; for mds.a, it would be a; for client.admin, it would be admin.

  • $num: same as $id

  • $name: expands to $type.$id

Reading configuration values

There are two ways for Ceph code to get configuration values. One way is to read it directly from a variable named g_conf, or equivalently, g_ceph_ctx->_conf. The other is to register an observer that will be called every time the relevant configuration values change. This observer will be called soon after the initial configuration is read, and every time after that when one of the relevant values changes. Each observer tracks a set of keys and is invoked only when one of the relevant keys changes.

The interface to implement is found in common/config_obs.h.

The observer method should be preferred in new code because

  • It is more flexible, allowing the code to do whatever reinitialization needs to be done to implement the new configuration value.

  • It is the only way to create a std::string configuration variable that can be changed by injectargs.

  • Even for int-valued configuration options, changing the values in one thread while another thread is reading them can lead to subtle and impossible-to-diagnose bugs.

For these reasons, reading directly from g_conf should be considered deprecated and not done in new code. Do not ever alter g_conf.

Changing configuration values

Configuration values can be changed by calling g_conf()->set_val. After changing the configuration, you should call g_conf()->apply_changes to re-run all the affected configuration observers. For convenience, you can call g_conf()->set_val_or_die to make a configuration change which you think should never fail.

injectargs, parse_argv, and parse_env are three other functions which modify the configuration. Just like with set_val, you should call apply_changes after calling these functions to make sure your changes get applied.

Defining config options

Config options are defined in common/options/*.yaml.in. The options are categorized by their consumers. If an option is only used by ceph-osd, it should go to osd.yaml.in. All the .yaml.in files are translated into .cc and .h files at build time by y2c.py.

Each option is represented using a YAML mapping (dictionary). A typical option looks like

- name: public_addr
  type: addr
  level: basic
  desc: public-facing address to bind to
  long_desc: The IP address for the public (front-side) network.
    Set for each daemon.
  services:
  - mon
  - mds
  - osd
  - mgr
  flags:
  - startup
  with_legacy: true

In which, following keys are allowed:

level

The level property of an option is an indicator for the probability the option is adjusted by an operator or a developer:

basic

for basic config options that a normal operator is likely to adjust.

advanced

for options that an operator can adjust, but should not touch unless they understand what they are doing. Adjusting advanced options poorly can lead to problems (performance or even data loss) if done incorrectly.

dev

for options in place for use by developers only, either for testing purposes, or to describe constants that no user should adjust but we prefer not to compile into the code.

desc, long_desc and fmt_desc

desc

Short description of the option. Sentence fragment. e.g.

desc: Default checksum algorithm to use
long_desc

The long description is complete sentences, perhaps even multiple paragraphs, and may include other detailed information or notes. e.g.

long_desc: crc32c, xxhash32, and xxhash64 are available.  The _16 and _8 variants use
  only a subset of the bits for more compact (but less reliable) checksumming.
fmt_desc

The description formatted using reStructuredText. This property is only used by the confval directive to render an option in the document. e.g.:

fmt_desc: The interval for "deep" scrubbing (fully reading all data). The
  ``osd_scrub_load_threshold`` does not affect this setting.

Default values

There is a default value for every config option. In some cases, there may also be a daemon default that only applies to code that declares itself as a daemon (in this case, the regular default only applies to non-daemons). Like:

default: crc32c

Some literal postfixes are allowed when options with type of float, size and secs, like:

- name: mon_scrub_interval
  type: secs
  default: 1_day
- name: osd_journal_size
  type: size
  default: 5_K

For better readability, it is encouraged to use these literal postfixes when adding or updating the default value for an option.

Service

Service is a component name, like “common”, “osd”, “rgw”, “mds”, etc. It may be a list of components, like:

services:
- mon
- mds
- osd
- mgr

For example, the rocksdb options affect both the osd and mon. If an option is put into a service specific .yaml.in file, the corresponding service is added to its services property automatically. For instance, osd_scrub_begin_hour option is located in osd.yaml.in, even its services is not specified explicitly in this file, this property still contains osd.

Tags

Tags identify options across services that relate in some way. For example:

network

options affecting network configuration

mkfs

options that only matter at mkfs time

Like:

tags:
- network

Enums

For options with a defined set of allowed values:

enum_values:
- none
- crc32c
- crc32c_16
- crc32c_8
- xxhash32
- xxhash64

Flags

runtime

the value can be updated at runtime

no_mon_update

Daemons/clients do not pull this value from the monitor config database. We disallow setting this option via ceph config set .... This option should be configured via ceph.conf or via the command line.

startup

option takes effect only during daemon startup

cluster_create

option only affects cluster creation

create

option only affects daemon creation