]>
Commit | Line | Data |
---|---|---|
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2010-2011 Dreamhost | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #include "common/admin_socket.h" | |
16 | #include "common/ceph_argparse.h" | |
17 | #include "common/common_init.h" | |
18 | #include "common/valgrind.h" | |
19 | #include "common/zipkin_trace.h" | |
20 | ||
21 | #define dout_subsys ceph_subsys_ | |
22 | ||
23 | #define _STR(x) #x | |
24 | #define STRINGIFY(x) _STR(x) | |
25 | ||
26 | CephContext *common_preinit(const CephInitParameters &iparams, | |
27 | enum code_environment_t code_env, int flags, | |
28 | const char *data_dir_option) | |
29 | { | |
30 | // set code environment | |
31 | ANNOTATE_BENIGN_RACE_SIZED(&g_code_env, sizeof(g_code_env), "g_code_env"); | |
32 | g_code_env = code_env; | |
33 | ||
34 | // Create a configuration object | |
35 | CephContext *cct = new CephContext(iparams.module_type, flags); | |
36 | ||
37 | md_config_t *conf = cct->_conf; | |
38 | // add config observers here | |
39 | ||
40 | // Set up our entity name. | |
41 | conf->name = iparams.name; | |
42 | ||
43 | if (data_dir_option) | |
44 | conf->data_dir_option = data_dir_option; | |
45 | ||
46 | // Set some defaults based on code type | |
47 | switch (code_env) { | |
48 | case CODE_ENVIRONMENT_DAEMON: | |
49 | conf->set_val_or_die("daemonize", "true"); | |
50 | conf->set_val_or_die("log_to_stderr", "false"); | |
51 | conf->set_val_or_die("err_to_stderr", "true"); | |
52 | ||
53 | // different default keyring locations for osd and mds. this is | |
54 | // for backward compatibility. moving forward, we want all keyrings | |
55 | // in these locations. the mon already forces $mon_data/keyring. | |
56 | if (conf->name.is_mds()) | |
57 | conf->set_val("keyring", "$mds_data/keyring", false); | |
58 | else if (conf->name.is_osd()) | |
59 | conf->set_val("keyring", "$osd_data/keyring", false); | |
60 | break; | |
61 | ||
62 | case CODE_ENVIRONMENT_UTILITY_NODOUT: | |
63 | case CODE_ENVIRONMENT_LIBRARY: | |
64 | conf->set_val_or_die("log_to_stderr", "false"); | |
65 | conf->set_val_or_die("err_to_stderr", "false"); | |
66 | conf->set_val_or_die("log_flush_on_exit", "false"); | |
67 | break; | |
68 | ||
69 | default: | |
70 | break; | |
71 | } | |
72 | ||
73 | if (flags & CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS) { | |
74 | // do nothing special! we used to do no default log, pid_file, | |
75 | // admin_socket, but changed our minds. let's make ceph-fuse | |
76 | // and radosgw use the same defaults as ceph-{osd,mon,mds,...} | |
77 | } else if (code_env != CODE_ENVIRONMENT_DAEMON) { | |
78 | // no default log, pid_file, admin_socket | |
79 | conf->set_val_or_die("pid_file", ""); | |
80 | conf->set_val_or_die("admin_socket", ""); | |
81 | conf->set_val_or_die("log_file", ""); | |
82 | // use less memory for logs | |
83 | conf->set_val_or_die("log_max_recent", "500"); | |
84 | } | |
85 | ||
86 | return cct; | |
87 | } | |
88 | ||
89 | void complain_about_parse_errors(CephContext *cct, | |
90 | std::deque<std::string> *parse_errors) | |
91 | { | |
92 | if (parse_errors->empty()) | |
93 | return; | |
94 | lderr(cct) << "Errors while parsing config file!" << dendl; | |
95 | int cur_err = 0; | |
96 | static const int MAX_PARSE_ERRORS = 20; | |
97 | for (std::deque<std::string>::const_iterator p = parse_errors->begin(); | |
98 | p != parse_errors->end(); ++p) | |
99 | { | |
100 | lderr(cct) << *p << dendl; | |
101 | if (cur_err == MAX_PARSE_ERRORS) { | |
102 | lderr(cct) << "Suppressed " << (parse_errors->size() - MAX_PARSE_ERRORS) | |
103 | << " more errors." << dendl; | |
104 | break; | |
105 | } | |
106 | ++cur_err; | |
107 | } | |
108 | } | |
109 | ||
110 | /* Please be sure that this can safely be called multiple times by the | |
111 | * same application. */ | |
112 | void common_init_finish(CephContext *cct) | |
113 | { | |
114 | cct->init_crypto(); | |
115 | ZTracer::ztrace_init(); | |
116 | ||
117 | int flags = cct->get_init_flags(); | |
118 | if (!(flags & CINIT_FLAG_NO_DAEMON_ACTIONS)) | |
119 | cct->start_service_thread(); | |
120 | ||
121 | if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) && | |
122 | (cct->get_set_uid() || cct->get_set_gid())) { | |
123 | cct->get_admin_socket()->chown(cct->get_set_uid(), cct->get_set_gid()); | |
124 | } | |
125 | ||
126 | md_config_t *conf = cct->_conf; | |
127 | ||
128 | if (!conf->admin_socket.empty() && !conf->admin_socket_mode.empty()) { | |
129 | int ret = 0; | |
130 | std::string err; | |
131 | ||
132 | ret = strict_strtol(conf->admin_socket_mode.c_str(), 8, &err); | |
133 | if (err.empty()) { | |
134 | if (!(ret & (~ACCESSPERMS))) { | |
135 | cct->get_admin_socket()->chmod(static_cast<mode_t>(ret)); | |
136 | } else { | |
137 | lderr(cct) << "Invalid octal permissions string: " | |
138 | << conf->admin_socket_mode << dendl; | |
139 | } | |
140 | } else { | |
141 | lderr(cct) << "Invalid octal string: " << err << dendl; | |
142 | } | |
143 | } | |
144 | } |