Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for VOMS mapfile #1572

Merged
merged 11 commits into from
Mar 1, 2022
Merged
112 changes: 28 additions & 84 deletions src/XrdVoms/XrdVomsMapfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,6 @@ XrdVomsMapfile::XrdVomsMapfile(XrdSysError *erp,
const std::string &mapfile)
: m_mapfile(mapfile), m_edest(erp)
{
// Setup communication pipes; we write one byte to the child to tell it to shutdown;
// it'll write one byte back to acknowledge before our destructor exits.
int pipes[2];
if (-1 == XrdSysFD_Pipe(pipes)) {
m_edest->Emsg("XrdVomsMapfile", "Failed to create communication pipes", strerror(errno));
return;
}
if (-1 == XrdSysFD_Pipe(pipes)) {
m_edest->Emsg("XrdVomsMapfile", "Failed to create communication pipes", strerror(errno));
return;
}

struct stat statbuf;
if (-1 == stat(m_mapfile.c_str(), &statbuf)) {
m_edest->Emsg("XrdVomsMapfile", errno, "Error checking the mapfile", m_mapfile.c_str());
Expand All @@ -93,42 +81,19 @@ XrdVomsMapfile::XrdVomsMapfile(XrdSysError *erp,

if (!ParseMapfile(m_mapfile)) {return;}

m_maintenance_pipe_r = pipes[0];
m_maintenance_pipe_w = pipes[1];
m_maintenance_thread_pipe_r = pipes[0];
m_maintenance_thread_pipe_w = pipes[1];

pthread_t tid;
auto rc = XrdSysThread::Run(&tid, XrdVomsMapfile::MaintenanceThread,
static_cast<void*>(this), 0, "VOMS Mapfile refresh");
if (rc) {
m_edest->Emsg("XrdVomsMapfile", "Failed to launch VOMS mapfile monitoring thread");
close(m_maintenance_pipe_r); m_maintenance_pipe_r = -1;
close(m_maintenance_pipe_w); m_maintenance_pipe_w = -1;
close(m_maintenance_thread_pipe_r); m_maintenance_thread_pipe_r = -1;
close(m_maintenance_thread_pipe_w); m_maintenance_thread_pipe_w = -1;
return;
}
m_is_valid = true;
}


XrdVomsMapfile::~XrdVomsMapfile()
{
char indicator[1];
if (m_maintenance_pipe_w >= 0) {
indicator[0] = '1';
int rval;
do {rval = write(m_maintenance_pipe_w, indicator, 1);} while (rval != -1 || errno == EINTR);
if (m_maintenance_thread_pipe_r >= 0) {
do {rval = read(m_maintenance_thread_pipe_r, indicator, 1);} while (rval != -1 || errno == EINTR);
close(m_maintenance_thread_pipe_r);
close(m_maintenance_thread_pipe_w);
}
close(m_maintenance_pipe_r);
close(m_maintenance_pipe_w);
}
}
{}


bool
Expand Down Expand Up @@ -420,54 +385,33 @@ XrdVomsMapfile::MaintenanceThread(void *myself_raw)
while (true) {
now = monotonic_time_s();
auto remaining = next_update - now;
struct pollfd fds;
fds.fd = myself->m_maintenance_pipe_r;
fds.events = POLLIN;
auto rval = poll(&fds, 1, remaining*1000);
if (rval == -1) {
if (rval == EINTR) continue;
else break;
} else if (rval == 0) { // timeout! Let's run maintenance.
struct stat statbuf;
if (-1 == stat(myself->m_mapfile.c_str(), &statbuf)) {
myself->m_edest->Emsg("XrdVomsMapfile", errno, "Error checking the mapfile",
myself->m_mapfile.c_str());
next_update = monotonic_time_s() + m_update_interval_failure;
myself->m_mapfile_ctime.tv_sec = 0;
myself->m_mapfile_ctime.tv_nsec = 0;
myself->m_is_valid = false;
continue;
}
if ((myself->m_mapfile_ctime.tv_sec == statbuf.st_ctim.tv_sec) &&
(myself->m_mapfile_ctime.tv_nsec == statbuf.st_ctim.tv_nsec))
{
myself->m_edest->Log(LogMask::Debug, "Maintenance", "Not reloading VOMS mapfile; "
"no changes detected.");
next_update = monotonic_time_s() + m_update_interval;
continue;
}
memcpy(&myself->m_mapfile_ctime, &statbuf.st_ctim, sizeof(decltype(statbuf.st_ctim)));

myself->m_edest->Log(LogMask::Debug, "Maintenance", "Reloading VOMS mapfile now");
if ( (myself->m_is_valid = myself->ParseMapfile(myself->m_mapfile)) ) {
next_update = monotonic_time_s() + m_update_interval;
} else {
next_update = monotonic_time_s() + m_update_interval_failure;
}
} else { // FD ready; let's shutdown
if (fds.revents & POLLIN) {
char indicator[1];
do {rval = read(myself->m_maintenance_pipe_r, indicator, 1);} while (rval != -1 || errno == EINTR);
}
auto rval = sleep(remaining);
if (rval > 0) {
// Woke up early due to a signal; re-run prior logic.
continue;
}
}
if (errno) {
myself->m_edest->Emsg("Maintenance", "Failed to poll for events from parent object");
}
char indicator = '1';
int rval;
do {rval = write(myself->m_maintenance_thread_pipe_w, &indicator, 1);} while (rval != -1 || errno == EINTR);

next_update = monotonic_time_s() + m_update_interval;
struct stat statbuf;
if (-1 == stat(myself->m_mapfile.c_str(), &statbuf)) {
myself->m_edest->Emsg("XrdVomsMapfile", errno, "Error checking the mapfile",
myself->m_mapfile.c_str());
myself->m_mapfile_ctime.tv_sec = 0;
myself->m_mapfile_ctime.tv_nsec = 0;
myself->m_is_valid = false;
continue;
}
if ((myself->m_mapfile_ctime.tv_sec == statbuf.st_ctim.tv_sec) &&
(myself->m_mapfile_ctime.tv_nsec == statbuf.st_ctim.tv_nsec))
bbockelm marked this conversation as resolved.
Show resolved Hide resolved
{
myself->m_edest->Log(LogMask::Debug, "Maintenance", "Not reloading VOMS mapfile; "
"no changes detected.");
continue;
}
memcpy(&myself->m_mapfile_ctime, &statbuf.st_ctim, sizeof(decltype(statbuf.st_ctim)));

return nullptr;
bbockelm marked this conversation as resolved.
Show resolved Hide resolved
myself->m_edest->Log(LogMask::Debug, "Maintenance", "Reloading VOMS mapfile now");
if ( !(myself->m_is_valid = myself->ParseMapfile(myself->m_mapfile)) ) {
myself->m_edest->Log(LogMask::Error, "Maintenance", "Failed to reload VOMS mapfile");
}
}
bbockelm marked this conversation as resolved.
Show resolved Hide resolved
}
9 changes: 0 additions & 9 deletions src/XrdVoms/XrdVomsMapfile.hh
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,8 @@ private:
std::shared_ptr<const std::vector<MapfileEntry>> m_entries;
XrdSysError *m_edest{nullptr};

// Pipes to allow the main thread to communicate shutdown events to the maintenance
// thread, allowing for a clean shutdown.
int m_maintenance_pipe_r{-1};
int m_maintenance_pipe_w{-1};
int m_maintenance_thread_pipe_r{-1};
int m_maintenance_thread_pipe_w{-1};

// After success, how long to wait until the next mapfile check.
static constexpr unsigned m_update_interval = 30;
bbockelm marked this conversation as resolved.
Show resolved Hide resolved
// After failure, how long to wait until the next mapfile check.
static constexpr unsigned m_update_interval_failure = 3;

// Singleton
static std::unique_ptr<XrdVomsMapfile> mapper;
Expand Down