Commit d88a251b authored by Lennart Poettering's avatar Lennart Poettering

util: introduce a proper nsec_t and make use of it where appropriate

parent 256425cc
...@@ -581,16 +581,17 @@ ...@@ -581,16 +581,17 @@
<term><varname>TimerSlackNSec=</varname></term> <term><varname>TimerSlackNSec=</varname></term>
<listitem><para>Sets the timer slack <listitem><para>Sets the timer slack
in nanoseconds for the executed in nanoseconds for the executed
processes. The timer slack controls the processes. The timer slack controls
accuracy of wake-ups triggered by the accuracy of wake-ups triggered by
timers. See timers. See
<citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
for more information. Note that in for more information. Note that in
contrast to most other time span contrast to most other time span
definitions this parameter takes an definitions this parameter takes an
integer value in nano-seconds and does integer value in nano-seconds if no
not understand any other unit is specified. The usual time
units.</para></listitem> units are understood
too.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
......
...@@ -216,7 +216,7 @@ int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property ...@@ -216,7 +216,7 @@ int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property
assert(property); assert(property);
assert(c); assert(c);
if (c->timer_slack_nsec_set) if (c->timer_slack_nsec != (nsec_t) -1)
u = (uint64_t) c->timer_slack_nsec; u = (uint64_t) c->timer_slack_nsec;
else else
u = (uint64_t) prctl(PR_GET_TIMERSLACK); u = (uint64_t) prctl(PR_GET_TIMERSLACK);
......
...@@ -1183,7 +1183,7 @@ int exec_spawn(ExecCommand *command, ...@@ -1183,7 +1183,7 @@ int exec_spawn(ExecCommand *command,
goto fail_child; goto fail_child;
} }
if (context->timer_slack_nsec_set) if (context->timer_slack_nsec != (nsec_t) -1)
if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
err = -errno; err = -errno;
r = EXIT_TIMERSLACK; r = EXIT_TIMERSLACK;
...@@ -1494,6 +1494,7 @@ void exec_context_init(ExecContext *c) { ...@@ -1494,6 +1494,7 @@ void exec_context_init(ExecContext *c) {
c->send_sigkill = true; c->send_sigkill = true;
c->control_group_persistent = -1; c->control_group_persistent = -1;
c->ignore_sigpipe = true; c->ignore_sigpipe = true;
c->timer_slack_nsec = (nsec_t) -1;
} }
void exec_context_done(ExecContext *c) { void exec_context_done(ExecContext *c) {
...@@ -1739,7 +1740,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { ...@@ -1739,7 +1740,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
fputs("\n", f); fputs("\n", f);
} }
if (c->timer_slack_nsec_set) if (c->timer_slack_nsec != (nsec_t) -1)
fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, c->timer_slack_nsec); fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, c->timer_slack_nsec);
fprintf(f, fprintf(f,
......
...@@ -118,7 +118,7 @@ struct ExecContext { ...@@ -118,7 +118,7 @@ struct ExecContext {
ExecOutput std_output; ExecOutput std_output;
ExecOutput std_error; ExecOutput std_error;
unsigned long timer_slack_nsec; nsec_t timer_slack_nsec;
char *tcpwrap_name; char *tcpwrap_name;
...@@ -178,7 +178,6 @@ struct ExecContext { ...@@ -178,7 +178,6 @@ struct ExecContext {
bool nice_set:1; bool nice_set:1;
bool ioprio_set:1; bool ioprio_set:1;
bool cpu_sched_set:1; bool cpu_sched_set:1;
bool timer_slack_nsec_set:1;
}; };
int exec_spawn(ExecCommand *command, int exec_spawn(ExecCommand *command,
......
...@@ -47,7 +47,7 @@ $1.SyslogLevelPrefix, config_parse_bool, 0, ...@@ -47,7 +47,7 @@ $1.SyslogLevelPrefix, config_parse_bool, 0,
$1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context) $1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context)
$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) $1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context)
$1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop) $1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop)
$1.TimerSlackNSec, config_parse_exec_timer_slack_nsec, 0, offsetof($1, exec_context) $1.TimerSlackNSec, config_parse_nsec, 0, offsetof($1, exec_context.timer_slack_nsec)
$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) $1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit)
$1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) $1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit)
$1.LimitDATA, config_parse_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit) $1.LimitDATA, config_parse_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit)
......
...@@ -991,34 +991,6 @@ int config_parse_bounding_set( ...@@ -991,34 +991,6 @@ int config_parse_bounding_set(
return 0; return 0;
} }
int config_parse_exec_timer_slack_nsec(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
ExecContext *c = data;
unsigned long u;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (safe_atolu(rvalue, &u) < 0) {
log_error("[%s:%u] Failed to parse time slack value, ignoring: %s", filename, line, rvalue);
return 0;
}
c->timer_slack_nsec = u;
return 0;
}
int config_parse_limit( int config_parse_limit(
const char *filename, const char *filename,
unsigned line, unsigned line,
...@@ -2449,7 +2421,6 @@ void unit_dump_config_items(FILE *f) { ...@@ -2449,7 +2421,6 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_exec_capabilities, "CAPABILITIES" }, { config_parse_exec_capabilities, "CAPABILITIES" },
{ config_parse_exec_secure_bits, "SECUREBITS" }, { config_parse_exec_secure_bits, "SECUREBITS" },
{ config_parse_bounding_set, "BOUNDINGSET" }, { config_parse_bounding_set, "BOUNDINGSET" },
{ config_parse_exec_timer_slack_nsec, "TIMERSLACK" },
{ config_parse_limit, "LIMIT" }, { config_parse_limit, "LIMIT" },
{ config_parse_unit_cgroup, "CGROUP [...]" }, { config_parse_unit_cgroup, "CGROUP [...]" },
{ config_parse_unit_deps, "UNIT [...]" }, { config_parse_unit_deps, "UNIT [...]" },
...@@ -2468,6 +2439,7 @@ void unit_dump_config_items(FILE *f) { ...@@ -2468,6 +2439,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_socket_bind, "SOCKETBIND" }, { config_parse_socket_bind, "SOCKETBIND" },
{ config_parse_socket_bindtodevice, "NETWORKINTERFACE" }, { config_parse_socket_bindtodevice, "NETWORKINTERFACE" },
{ config_parse_usec, "SECONDS" }, { config_parse_usec, "SECONDS" },
{ config_parse_nsec, "NANOSECONDS" },
{ config_parse_path_strv, "PATH [...]" }, { config_parse_path_strv, "PATH [...]" },
{ config_parse_unit_requires_mounts_for, "PATH [...]" }, { config_parse_unit_requires_mounts_for, "PATH [...]" },
{ config_parse_exec_mount_flags, "MOUNTFLAG [...]" }, { config_parse_exec_mount_flags, "MOUNTFLAG [...]" },
......
...@@ -57,7 +57,6 @@ int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const ch ...@@ -57,7 +57,6 @@ int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const ch
int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_timer_slack_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_sysv_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_sysv_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
......
...@@ -817,6 +817,31 @@ int config_parse_usec( ...@@ -817,6 +817,31 @@ int config_parse_usec(
return 0; return 0;
} }
int config_parse_nsec(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
nsec_t *nsec = data;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (parse_nsec(rvalue, nsec) < 0) {
log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue);
return 0;
}
return 0;
}
int config_parse_mode( int config_parse_mode(
const char *filename, const char *filename,
unsigned line, unsigned line,
......
...@@ -102,6 +102,7 @@ int config_parse_path(const char *filename, unsigned line, const char *section, ...@@ -102,6 +102,7 @@ int config_parse_path(const char *filename, unsigned line, const char *section,
int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
......
...@@ -2707,7 +2707,7 @@ int parse_usec(const char *t, usec_t *usec) { ...@@ -2707,7 +2707,7 @@ int parse_usec(const char *t, usec_t *usec) {
{ "m", USEC_PER_MINUTE }, { "m", USEC_PER_MINUTE },
{ "usec", 1ULL }, { "usec", 1ULL },
{ "us", 1ULL }, { "us", 1ULL },
{ "", USEC_PER_SEC }, { "", USEC_PER_SEC }, /* default is sec */
}; };
const char *p; const char *p;
...@@ -2753,6 +2753,71 @@ int parse_usec(const char *t, usec_t *usec) { ...@@ -2753,6 +2753,71 @@ int parse_usec(const char *t, usec_t *usec) {
return 0; return 0;
} }
int parse_nsec(const char *t, nsec_t *nsec) {
static const struct {
const char *suffix;
nsec_t nsec;
} table[] = {
{ "sec", NSEC_PER_SEC },
{ "s", NSEC_PER_SEC },
{ "min", NSEC_PER_MINUTE },
{ "hr", NSEC_PER_HOUR },
{ "h", NSEC_PER_HOUR },
{ "d", NSEC_PER_DAY },
{ "w", NSEC_PER_WEEK },
{ "msec", NSEC_PER_MSEC },
{ "ms", NSEC_PER_MSEC },
{ "m", NSEC_PER_MINUTE },
{ "usec", NSEC_PER_USEC },
{ "us", NSEC_PER_USEC },
{ "nsec", 1ULL },
{ "ns", 1ULL },
{ "", 1ULL }, /* default is nsec */
};
const char *p;
nsec_t r = 0;
assert(t);
assert(nsec);
p = t;
do {
long long l;
char *e;
unsigned i;
errno = 0;
l = strtoll(p, &e, 10);
if (errno != 0)
return -errno;
if (l < 0)
return -ERANGE;
if (e == p)
return -EINVAL;
e += strspn(e, WHITESPACE);
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
r += (nsec_t) l * table[i].nsec;
p = e + strlen(table[i].suffix);
break;
}
if (i >= ELEMENTSOF(table))
return -EINVAL;
} while (*p != 0);
*nsec = r;
return 0;
}
int parse_bytes(const char *t, off_t *bytes) { int parse_bytes(const char *t, off_t *bytes) {
static const struct { static const struct {
const char *suffix; const char *suffix;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "macro.h" #include "macro.h"
typedef uint64_t usec_t; typedef uint64_t usec_t;
typedef unsigned long nsec_t;
typedef struct dual_timestamp { typedef struct dual_timestamp {
usec_t realtime; usec_t realtime;
...@@ -53,11 +54,17 @@ typedef struct dual_timestamp { ...@@ -53,11 +54,17 @@ typedef struct dual_timestamp {
#define NSEC_PER_USEC 1000ULL #define NSEC_PER_USEC 1000ULL
#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC) #define USEC_PER_MINUTE (60ULL*USEC_PER_SEC)
#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC)
#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE) #define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE)
#define USEC_PER_DAY (24ULL*USEC_PER_HOUR) #define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR)
#define USEC_PER_WEEK (7ULL*USEC_PER_DAY) #define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY)
#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC) #define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC)
#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC) #define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC)
/* What is interpreted as whitespace? */ /* What is interpreted as whitespace? */
#define WHITESPACE " \t\n\r" #define WHITESPACE " \t\n\r"
...@@ -139,6 +146,7 @@ void close_many(const int fds[], unsigned n_fd); ...@@ -139,6 +146,7 @@ void close_many(const int fds[], unsigned n_fd);
int parse_boolean(const char *v); int parse_boolean(const char *v);
int parse_usec(const char *t, usec_t *usec); int parse_usec(const char *t, usec_t *usec);
int parse_nsec(const char *t, nsec_t *nsec);
int parse_bytes(const char *t, off_t *bytes); int parse_bytes(const char *t, off_t *bytes);
int parse_pid(const char *s, pid_t* ret_pid); int parse_pid(const char *s, pid_t* ret_pid);
int parse_uid(const char *s, uid_t* ret_uid); int parse_uid(const char *s, uid_t* ret_uid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment