-
Jan David Mol authoredJan David Mol authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
IOPriority.h 4.52 KiB
//# IOPriority.h: define some Linux specific IO priority macro's
//# Copyright (C) 2011-2013 ASTRON (Netherlands Institute for Radio Astronomy)
//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
//#
//# This file is part of the LOFAR software suite.
//# The LOFAR software suite is free software: you can redistribute it and/or
//# modify it under the terms of the GNU General Public License as published
//# by the Free Software Foundation, either version 3 of the License, or
//# (at your option) any later version.
//#
//# The LOFAR software suite is distributed in the hope that it will be useful,
//# but WITHOUT ANY WARRANTY; without even the implied warranty of
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//# GNU General Public License for more details.
//#
//# You should have received a copy of the GNU General Public License along
//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
//#
//# $Id$
#ifndef LOFAR_STORAGE_IOPRIORITY_H
#define LOFAR_STORAGE_IOPRIORITY_H
#define IOPRIO_BITS (16)
#define IOPRIO_CLASS_SHIFT (13)
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
#define IOPRIO_PRIO_VALUE(class, data) (((class ) << IOPRIO_CLASS_SHIFT) | data)
#include <pwd.h>
#include <sched.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
#include <sys/resource.h>
#if defined __linux__
#include <linux/version.h>
#endif
enum {
IOPRIO_WHO_PROCESS = 1,
IOPRIO_WHO_PGRP,
IOPRIO_WHO_USER,
};
enum {
IOPRIO_CLASS_NONE,
IOPRIO_CLASS_RT,
IOPRIO_CLASS_BE,
IOPRIO_CLASS_IDLE,
};
inline int ioprio_set(int which, int who, int ioprio)
{
#if defined __linux__
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
return syscall(SYS_ioprio_set, which, who, ioprio);
#else
return -1;
#endif
#else
return -1;
#endif
}
inline int ioprio_get(int which, int who)
{
#if defined __linux__
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
return syscall(SYS_ioprio_get, which, who);
#else
return -1;
#endif
#else
return -1;
#endif
}
inline void setIOpriority()
{
if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT,7)) != 0) {
switch (errno) {
case EPERM:
{
struct passwd *user = getpwnam("lofarsys");
if ((user != NULL) && (getuid() != user->pw_uid))
LOG_WARN_STR("Failed to set IO priority, permission denied");
else
LOG_ERROR_STR("Failed to set IO priority, capability CAP_SYS_ADMIN not set?");
} break;
case EINVAL:
case ESRCH:
default:
LOG_ERROR_STR("Failed to set IO priority: " << errno);
}
}
}
inline void setRTpriority()
{
int priority = sched_get_priority_min(SCHED_RR);
struct sched_param sp;
sp.sched_priority = priority;
if (sched_setscheduler(0, SCHED_RR, &sp) < 0) {
switch (errno) {
case EPERM:
{
struct passwd *user = getpwnam("lofarsys");
if ((user != NULL) && (getuid() != user->pw_uid))
LOG_WARN_STR("Failed to set RT priority, permission denied");
else
LOG_ERROR_STR("Failed to set RT priority, capability CAP_SYS_NICE not set?");
} break;
case EINVAL:
case ESRCH:
default:
LOG_ERROR_STR("Failed to set RT priority: " << errno);
}
}
}
inline void lockInMemory(rlim_t memLockLimit = RLIM_INFINITY)
{
struct passwd *user = getpwnam("lofarsys");
bool am_lofarsys = (user != NULL) && (getuid() == user->pw_uid);
if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
switch (errno) {
case ENOMEM:
case EPERM:
{
if (am_lofarsys)
LOG_ERROR_STR("Failed to lock application in memory, capability CAP_IPC_LOCK not set?");
else
LOG_WARN_STR("Failed to lock application in memory, permission denied");
} break;
case EINVAL:
default:
LOG_ERROR_STR("Failed to lock application in memory: flags invalid");
}
}
const struct rlimit limit = { memLockLimit, memLockLimit };
// Set MEMLOCK limit
if (setrlimit(RLIMIT_MEMLOCK, &limit) < 0) {
if (am_lofarsys)
LOG_ERROR_STR("Failed to set MEMLOCK limit");
else
LOG_WARN_STR("Failed to set MEMLOCK limit");
}
// Set DATA limit
if (setrlimit(RLIMIT_DATA, &limit) < 0) {
if (am_lofarsys)
LOG_ERROR_STR("Failed to set DATA limit");
else
LOG_WARN_STR("Failed to set DATA limit");
}
}
#endif