Skip to content

Commit

Permalink
Merge pull request #8754 from kmroz/wip-backport-fix-run-dir-chown
Browse files Browse the repository at this point in the history
jewel: global-init: fixup chown of the run directory along with log and asok files

Reviewed-by: Sage Weil <sage@redhat.com>
  • Loading branch information
liewegas committed Jun 27, 2016
2 parents 2cf8d58 + 6c1163c commit e16830c
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/common/admin_socket.cc
Expand Up @@ -290,7 +290,7 @@ void* AdminSocket::entry()
void AdminSocket::chown(uid_t uid, gid_t gid)
{
if (m_sock_fd >= 0) {
int r = ::fchown(m_sock_fd, uid, gid);
int r = ::chown(m_path.c_str(), uid, gid);
if (r < 0) {
r = -errno;
lderr(m_cct) << "AdminSocket: failed to chown socket: "
Expand Down
5 changes: 5 additions & 0 deletions src/common/ceph_context.cc
Expand Up @@ -641,6 +641,11 @@ uint32_t CephContext::get_module_type() const
return _module_type;
}

void CephContext::set_init_flags(int flags)
{
_init_flags = flags;
}

int CephContext::get_init_flags() const
{
return _init_flags;
Expand Down
1 change: 1 addition & 0 deletions src/common/ceph_context.h
Expand Up @@ -84,6 +84,7 @@ class CephContext {
/* Get the module type (client, mon, osd, mds, etc.) */
uint32_t get_module_type() const;

void set_init_flags(int flags);
int get_init_flags() const;

/* Get the PerfCountersCollection of this CephContext */
Expand Down
9 changes: 8 additions & 1 deletion src/common/common_init.cc
Expand Up @@ -12,6 +12,7 @@
*
*/

#include "common/admin_socket.h"
#include "common/ceph_argparse.h"
#include "common/ceph_context.h"
#include "common/ceph_crypto.h"
Expand Down Expand Up @@ -123,6 +124,12 @@ void common_init_finish(CephContext *cct)
{
cct->init_crypto();

if (!(cct->get_init_flags() & CINIT_FLAG_NO_DAEMON_ACTIONS))
int flags = cct->get_init_flags();
if (!(flags & CINIT_FLAG_NO_DAEMON_ACTIONS))
cct->start_service_thread();

if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) &&
(cct->get_set_uid() || cct->get_set_gid())) {
cct->get_admin_socket()->chown(cct->get_set_uid(), cct->get_set_gid());
}
}
72 changes: 58 additions & 14 deletions src/global/global_init.cc
Expand Up @@ -60,6 +60,26 @@ static const char* c_str_or_null(const std::string &str)
return str.c_str();
}

static int chown_path(const std::string &pathname, const uid_t owner, const gid_t group,
const std::string &uid_str, const std::string &gid_str)
{
const char *pathname_cstr = c_str_or_null(pathname);

if (!pathname_cstr) {
return 0;
}

int r = ::chown(pathname_cstr, owner, group);

if (r < 0) {
r = -errno;
cerr << "warning: unable to chown() " << pathname << " as "
<< uid_str << ":" << gid_str << ": " << cpp_strerror(r) << std::endl;
}

return r;
}

void global_pre_init(std::vector < const char * > *alt_def_args,
std::vector < const char* >& args,
uint32_t module_type, code_environment_t code_env,
Expand Down Expand Up @@ -128,6 +148,12 @@ void global_init(std::vector < const char * > *alt_def_args,
}
first_run = false;

// Verify flags have not changed if global_pre_init() has been called
// manually. If they have, update them.
if (g_ceph_context->get_init_flags() != flags) {
g_ceph_context->set_init_flags(flags);
}

// signal stuff
int siglist[] = { SIGPIPE, 0 };
block_signals(siglist, NULL);
Expand Down Expand Up @@ -265,16 +291,21 @@ void global_init(std::vector < const char * > *alt_def_args,

if (priv_ss.str().length()) {
dout(0) << priv_ss.str() << dendl;
}

if (g_ceph_context->get_set_uid() || g_ceph_context->get_set_gid()) {
// fix ownership on log, asok files. this is sadly a bit of a hack :(
g_ceph_context->_log->chown_log_file(
g_ceph_context->get_set_uid(),
g_ceph_context->get_set_gid());
g_ceph_context->get_admin_socket()->chown(
g_ceph_context->get_set_uid(),
g_ceph_context->get_set_gid());
}
if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) &&
(g_ceph_context->get_set_uid() || g_ceph_context->get_set_gid())) {
// Fix ownership on log files and run directories if needed.
// Admin socket files are chown()'d during the common init path _after_
// the service thread has been started. This is sadly a bit of a hack :(
chown_path(g_conf->run_dir,
g_ceph_context->get_set_uid(),
g_ceph_context->get_set_gid(),
g_ceph_context->get_set_uid_string(),
g_ceph_context->get_set_gid_string());
g_ceph_context->_log->chown_log_file(
g_ceph_context->get_set_uid(),
g_ceph_context->get_set_gid());
}

// Now we're ready to complain about config file parse errors
Expand Down Expand Up @@ -305,15 +336,21 @@ int global_init_prefork(CephContext *cct)
const md_config_t *conf = cct->_conf;
if (!conf->daemonize) {

if (pidfile_write(g_conf) < 0)
if (pidfile_write(conf) < 0)
exit(1);

if ((cct->get_init_flags() & CINIT_FLAG_DEFER_DROP_PRIVILEGES) &&
(cct->get_set_uid() || cct->get_set_gid())) {
chown_path(conf->pid_file, cct->get_set_uid(), cct->get_set_gid(),
cct->get_set_uid_string(), cct->get_set_gid_string());
}

return -1;
}

// stop log thread
g_ceph_context->_log->flush();
g_ceph_context->_log->stop();
cct->_log->flush();
cct->_log->stop();
return 0;
}

Expand Down Expand Up @@ -341,7 +378,7 @@ void global_init_daemonize(CephContext *cct)
void global_init_postfork_start(CephContext *cct)
{
// restart log thread
g_ceph_context->_log->start();
cct->_log->start();

/* This is the old trick where we make file descriptors 0, 1, and possibly 2
* point to /dev/null.
Expand All @@ -366,8 +403,15 @@ void global_init_postfork_start(CephContext *cct)
exit(1);
}

if (pidfile_write(g_conf) < 0)
const md_config_t *conf = cct->_conf;
if (pidfile_write(conf) < 0)
exit(1);

if ((cct->get_init_flags() & CINIT_FLAG_DEFER_DROP_PRIVILEGES) &&
(cct->get_set_uid() || cct->get_set_gid())) {
chown_path(conf->pid_file, cct->get_set_uid(), cct->get_set_gid(),
cct->get_set_uid_string(), cct->get_set_gid_string());
}
}

void global_init_postfork_finish(CephContext *cct)
Expand Down

0 comments on commit e16830c

Please sign in to comment.