Skip to content

Commit

Permalink
time,ns: add --time to set specific clocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Snaipe committed May 13, 2020
1 parent db7311e commit f622041
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 9 deletions.
8 changes: 8 additions & 0 deletions bst.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ Users of bst may choose to opt-out of some of the isolation.

You cannot use this option with _--share=uts_.

\--time <name-or-id>=<seconds>[.<nanoseconds>]
Set the value of the specified clock for the inner process' time namespace.

Valid clock names are the same as the ones described in *time_namespaces*(7).
Alternatively, the numerical clock IDs can be supplied.

You cannot use this option with _--share=time_.

# SEE ALSO

*namespaces*(7), *mount*(1), *setarch*(1)
60 changes: 60 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
* in the LICENSE file.
*/

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <signal.h>
Expand All @@ -28,6 +30,7 @@ enum {
OPTION_ARGV0,
OPTION_HOSTNAME,
OPTION_DOMAIN,
OPTION_TIME,
};

/* Usage is generated from usage.txt. Note that the array is not null-terminated,
Expand Down Expand Up @@ -69,10 +72,16 @@ int main(int argc, char *argv[], char *envp[])
{ "argv0", required_argument, NULL, OPTION_ARGV0 },
{ "hostname", required_argument, NULL, OPTION_HOSTNAME },
{ "domainname", required_argument, NULL, OPTION_DOMAIN },
{ "time", required_argument, NULL, OPTION_TIME },

{ 0, 0, 0, 0 }
};

static const char *clocknames[MAX_CLOCK + 1] = {
[CLOCK_MONOTONIC] = "monotonic",
[CLOCK_BOOTTIME] = "boottime",
};

char *argv0 = NULL;

int error = 0;
Expand Down Expand Up @@ -147,6 +156,57 @@ int main(int argc, char *argv[], char *envp[])
opts.domainname = optarg;
break;

case OPTION_TIME:
{
const char *name = strtok(optarg, "=");
const char *secs = strtok(NULL, ".");
const char *nsecs = strtok(NULL, "");

clockid_t clock = -1;
for (clockid_t id = 0; id < MAX_CLOCK + 1; ++id) {
if (clocknames[id] && strcmp(clocknames[id], name) == 0) {
clock = id;
break;
}
}

if (clock == -1 && isdigit(name[0])) {
errno = 0;
clock = strtol(name, NULL, 10);
if (errno != 0) {
clock = -1;
}
}

if (clock < 0 || clock > MAX_CLOCK) {
errx(2, "%s is not a valid clock ID or name", name);
}

struct timespec ts = {0, 0};
errno = 0;
ts.tv_sec = strtol(secs, NULL, 10);
if (errno != 0) {
err(2, "%s is not a valid number of seconds", secs);
}
if (ts.tv_sec < 0) {
errx(2, "%s must be a positive number of seconds", secs);
}
if (nsecs && nsecs[0] != '\0') {
errno = 0;
ts.tv_nsec = strtol(nsecs, NULL, 10);
if (errno != 0) {
err(2, "%s is not a valid number of nanoseconds", nsecs);
}
if (ts.tv_nsec < 0 || ts.tv_nsec >= SEC_IN_NS) {
errx(2, "%s as nanoseconds is out of range (must be "
"between 0 and 999.999.999)", nsecs);
}
}

opts.clockspecs[clock] = ts;
break;
}

case 'r':
opts.root = optarg;
break;
Expand Down
10 changes: 3 additions & 7 deletions timens.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
#include <time.h>
#include "timens.h"

enum {
GIGA = 1000000000,
};

void init_clocks(int fd, const struct timespec *times, size_t nclocks)
{
FILE *clocks = fdopen(fd, "w");
Expand All @@ -37,10 +33,10 @@ void init_clocks(int fd, const struct timespec *times, size_t nclocks)
}

tp.tv_sec = times[clock].tv_sec - tp.tv_sec - 1;
tp.tv_nsec = GIGA - tp.tv_nsec + times[clock].tv_nsec;
while (tp.tv_nsec > GIGA) {
tp.tv_nsec = SEC_IN_NS - tp.tv_nsec + times[clock].tv_nsec;
while (tp.tv_nsec > SEC_IN_NS) {
tp.tv_sec += 1;
tp.tv_nsec -= GIGA;
tp.tv_nsec -= SEC_IN_NS;
}

fprintf(clocks, "%d %ld %ld\n", clock, tp.tv_sec, tp.tv_nsec);
Expand Down
2 changes: 2 additions & 0 deletions timens.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

enum {
MAX_CLOCK = 11, // CLOCK_TAI

SEC_IN_NS = 1000000000,
};

typedef long clockspecs[MAX_CLOCK];
Expand Down
9 changes: 7 additions & 2 deletions usage.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ unsigned char usage_txt[] = {
0x68, 0x20, 0x3c, 0x61, 0x72, 0x63, 0x68, 0x3e, 0x3a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x65, 0x74, 0x20, 0x74,
0x68, 0x65, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x0a
0x20, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x09, 0x2d, 0x2d,
0x74, 0x69, 0x6d, 0x65, 0x20, 0x3c, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x3d,
0x3c, 0x73, 0x3e, 0x5b, 0x2e, 0x6e, 0x73, 0x5d, 0x3a, 0x20, 0x53, 0x65,
0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
0x66, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63,
0x20, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x0a
};
unsigned int usage_txt_len = 849;
unsigned int usage_txt_len = 908;
1 change: 1 addition & 0 deletions usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Options:
--gid <gid>: Set group ID.
--groups <gid,gid,...>: Set additional groups.
--arch <arch>: Set the execution domain.
--time <name>=<s>[.ns]: Set the time of a specific clock.

0 comments on commit f622041

Please sign in to comment.