Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'mariux/issues/issue23'
Browse files Browse the repository at this point in the history
resolves mariux64#23

* mariux/issues/issue23:
  mxqd: Set MXQ_HOSTID to bootid-hex(starttime)-pid
  mxqd: set MXQ_HOSTNAME and MXQ_SERVERID
  mx_util: Add mx_proc_pid_stat()
  mx_util: Add mx_strscan_ull() and mx_strscan_ll()
  mx_util: Add mx_read_first_line_from_file()
mariux committed Sep 24, 2015
2 parents 881ce84 + 4f2859e commit 05a1509
Showing 5 changed files with 366 additions and 1 deletion.
188 changes: 188 additions & 0 deletions mx_util.c
Original file line number Diff line number Diff line change
@@ -752,6 +752,194 @@ int mx_open_newfile(char *fname)
return fh;
}

int mx_read_first_line_from_file(char *fname, char **line)
{
_mx_cleanup_fclose_ FILE *fp;
char *buf = NULL;
size_t n = 0;
ssize_t res;

fp = fopen(fname, "r");
if (!fp)
return -errno;

res = getline(&buf, &n, fp);
if (res == -1)
return -errno;

*line = buf;

if (!res)
return res;

res--;

if (buf[res] == '\n')
buf[res] = 0;

return res;
}

int mx_strscan_ull(char **str, unsigned long long int *to)
{
unsigned long long int l;
char *s;
char *p;
char o = 0;
int res;

s = *str;

p = strchr(s, ' ');
if (p) {
o = *p;
*p = 0;
p++;
} else {
p = s + strlen(s);
}

res = mx_strtoull(s, &l);
if (o)
*(p-1) = o;

if (res == 0) {
*to = l;
*str = p;
}

return res;
}

int mx_strscan_ll(char **str, long long int *to)
{
long long int l;
char *s;
char *p;
char o = 0;
int res;

s = *str;

p = strchr(s, ' ');
if (p) {
o = *p;
*p = 0;
p++;
} else {
p = s + strlen(s);
}

res = mx_strtoll(s, &l);
if (o)
*(p-1) = o;

if (res == 0) {
*to = l;
*str = p;
}

return res;
}

int mx_strscan_proc_pid_stat(char *str, struct proc_pid_stat *pps)
{
size_t res = 0;
char *p;
char *s;

pps->comm = NULL;

s = str;

res += mx_strscan_ll(&s, &(pps->pid));

p = strrchr(s, ')');
if (!p)
return -(errno=EINVAL);

*p = 0;
s++;

pps->comm = mx_strdup_forever(s);
s = p + 2;

pps->state = *s;
res += !(*(s+1) == ' ');
s += 2;

res += mx_strscan_ll(&s, &(pps->ppid));
res += mx_strscan_ll(&s, &(pps->pgrp));
res += mx_strscan_ll(&s, &(pps->session));
res += mx_strscan_ll(&s, &(pps->tty_nr));
res += mx_strscan_ll(&s, &(pps->tpgid));
res += mx_strscan_ull(&s, &(pps->flags));
res += mx_strscan_ull(&s, &(pps->minflt));
res += mx_strscan_ull(&s, &(pps->cminflt));
res += mx_strscan_ull(&s, &(pps->majflt));
res += mx_strscan_ull(&s, &(pps->cmajflt));
res += mx_strscan_ull(&s, &(pps->utime));
res += mx_strscan_ull(&s, &(pps->stime));
res += mx_strscan_ll(&s, &(pps->cutime));
res += mx_strscan_ll(&s, &(pps->cstime));
res += mx_strscan_ll(&s, &(pps->priority));
res += mx_strscan_ll(&s, &(pps->nice));
res += mx_strscan_ll(&s, &(pps->num_threads));
res += mx_strscan_ll(&s, &(pps->itrealvalue));
res += mx_strscan_ull(&s, &(pps->starttime));
res += mx_strscan_ull(&s, &(pps->vsize));
res += mx_strscan_ll(&s, &(pps->rss));
res += mx_strscan_ull(&s, &(pps->rsslim));
res += mx_strscan_ull(&s, &(pps->startcode));
res += mx_strscan_ull(&s, &(pps->endcode));
res += mx_strscan_ull(&s, &(pps->startstack));
res += mx_strscan_ull(&s, &(pps->kstkesp));
res += mx_strscan_ull(&s, &(pps->kstkeip));
res += mx_strscan_ull(&s, &(pps->signal));
res += mx_strscan_ull(&s, &(pps->blocked));
res += mx_strscan_ull(&s, &(pps->sigignore));
res += mx_strscan_ull(&s, &(pps->sigcatch));
res += mx_strscan_ull(&s, &(pps->wchan));
res += mx_strscan_ull(&s, &(pps->nswap));
res += mx_strscan_ull(&s, &(pps->cnswap));
res += mx_strscan_ll(&s, &(pps->exit_signal));
res += mx_strscan_ll(&s, &(pps->processor));
res += mx_strscan_ull(&s, &(pps->rt_priority));
res += mx_strscan_ull(&s, &(pps->policy));
res += mx_strscan_ull(&s, &(pps->delayacct_blkio_ticks));
res += mx_strscan_ull(&s, &(pps->guest_time));
res += mx_strscan_ll(&s, &(pps->cguest_time));

if (res != 0)
return -(errno=EINVAL);

return 0;
}

int mx_proc_pid_stat(struct proc_pid_stat *pps, pid_t pid)
{
_mx_cleanup_free_ char *fname = NULL;
_mx_cleanup_free_ char *line = NULL;
int res;

mx_asprintf_forever(&fname, "/proc/%d/stat", pid);

res = mx_read_first_line_from_file(fname, &line);
if (res < 0)
return res;

res = mx_strscan_proc_pid_stat(line, pps);
if (res < 0)
return res;

return 0;
}

void mx_proc_pid_stat_free(struct proc_pid_stat *pps)
{
mx_free_null(pps->comm);
}

int mx_sleep(unsigned int seconds)
{
if (seconds)
65 changes: 65 additions & 0 deletions mx_util.h
Original file line number Diff line number Diff line change
@@ -5,9 +5,57 @@
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include "mx_log.h"

struct proc_pid_stat {
long long int pid; /* 1 */
char *comm; /* 2 (comm) */
char state; /* 3 "RSDZTW" */
long long int ppid; /* 4 */
long long int pgrp; /* 5 */
long long int session; /* 6 */
long long int tty_nr; /* 7 */
long long int tpgid; /* 8 */
unsigned long long int flags; /* 9 */
unsigned long long int minflt; /* 10 */
unsigned long long int cminflt; /* 11 */
unsigned long long int majflt; /* 12 */
unsigned long long int cmajflt; /* 13 */
unsigned long long int utime; /* 14 */
unsigned long long int stime; /* 15 */
long long int cutime; /* 16 */
long long int cstime; /* 17 */
long long int priority; /* 18 */
long long int nice; /* 19 */
long long int num_threads; /* 20 */
long long int itrealvalue; /* 21 */
unsigned long long int starttime; /* 22 */
unsigned long long int vsize; /* 23 */
long long int rss; /* 24 */
unsigned long long int rsslim; /* 25 */
unsigned long long int startcode; /* 26 */
unsigned long long int endcode; /* 27 */
unsigned long long int startstack; /* 28 */
unsigned long long int kstkesp; /* 29 */
unsigned long long int kstkeip; /* 30 */
unsigned long long int signal; /* 31 */
unsigned long long int blocked; /* 32 */
unsigned long long int sigignore; /* 33 */
unsigned long long int sigcatch; /* 34 */
unsigned long long int wchan; /* 35 */
unsigned long long int nswap; /* 36 */
unsigned long long int cnswap; /* 37 */
long long int exit_signal; /* 38 */
long long int processor; /* 39 */
unsigned long long int rt_priority; /* 40 */
unsigned long long int policy; /* 41 */
unsigned long long int delayacct_blkio_ticks; /* 42 */
unsigned long long int guest_time; /* 43 */
long long int cguest_time; /* 44 */
};

#ifdef MX_NDEBUG
# include <assert.h>
# define mx_assert_return_minus_errno(test, eno) \
@@ -46,9 +94,17 @@ static inline void __mx_free(void *ptr) {
free(*(void **)ptr);
}

static inline void __mx_fclose(FILE **ptr) {
if (*ptr)
fclose(*ptr);
}

#undef _mx_cleanup_free_
#define _mx_cleanup_free_ _mx_cleanup_(__mx_free)

#undef _mx_cleanup_fclose_
#define _mx_cleanup_fclose_ _mx_cleanup_(__mx_fclose)

#undef likely
#define likely(x) __builtin_expect((x),1)

@@ -106,6 +162,15 @@ int mx_setenvf_forever(const char *name, char *fmt, ...) __attribute__ ((format(

int mx_open_newfile(char *fname);

int mx_read_first_line_from_file(char *fname, char **line);

int mx_strscan_ull(char **str, unsigned long long int *to);
int mx_strscan_ll(char **str, long long int *to);
int mx_strscan_proc_pid_stat(char *str, struct proc_pid_stat *pps);

int mx_proc_pid_stat(struct proc_pid_stat *pps, pid_t pid);
void mx_proc_pid_stat_free(struct proc_pid_stat *pps);

int mx_sleep(unsigned int seconds);
int mx_sleep_nofail(unsigned int seconds);

23 changes: 22 additions & 1 deletion mxqd.c
Original file line number Diff line number Diff line change
@@ -203,11 +203,13 @@ int server_init(struct mxq_server *server, int argc, char *argv[])
char *arg_initial_tmpdir;
char arg_daemonize = 0;
char arg_nolog = 0;
char *str_bootid;
int opt;
unsigned long threads_total = 1;
unsigned long memory_total = 2048;
unsigned long memory_max = 0;
int i;
struct proc_pid_stat pps = {0};

struct mx_getopt_ctl optctl;
struct mx_option opts[] = {
@@ -409,6 +411,20 @@ int server_init(struct mxq_server *server, int argc, char *argv[])
}
}

res = mx_read_first_line_from_file("/proc/sys/kernel/random/boot_id", &str_bootid);
assert(res == 36);
assert(str_bootid);

server->boot_id = str_bootid;

res = mx_proc_pid_stat(&pps, getpid());
assert(res == 0);

server->starttime = pps.starttime;
mx_proc_pid_stat_free(&pps);

mx_asprintf_forever(&server->host_id, "%s-%llx-%x", server->boot_id, server->starttime, getpid());

server->slots = threads_total;;
server->memory_total = memory_total;
server->memory_max_per_slot = memory_max;
@@ -807,7 +823,9 @@ static int init_child_process(struct mxq_group_list *group, struct mxq_job *j)
mx_setenvf_forever("MXQ_SLOTS", "%lu", group->slots_per_job);
mx_setenvf_forever("MXQ_MEMORY", "%lu", g->job_memory);
mx_setenvf_forever("MXQ_TIME", "%d", g->job_time);
mx_setenvf_forever("MXQ_HOSTID", "%s::%s", s->hostname, s->server_id);
mx_setenv_forever("MXQ_HOSTID", s->host_id);
mx_setenv_forever("MXQ_HOSTNAME", s->hostname);
mx_setenv_forever("MXQ_SERVERID", s->server_id);

fh = open("/proc/self/loginuid", O_WRONLY|O_TRUNC);
if (fh == -1) {
@@ -1349,6 +1367,8 @@ void server_close(struct mxq_server *server)
unlink(server->pidfilename);

mx_funlock(server->flock);

mx_free_null(server->boot_id);
}

int killall(struct mxq_server *server, int sig, unsigned int pgrp)
@@ -1691,6 +1711,7 @@ int main(int argc, char *argv[])
mx_log_info(" by Marius Tolzmann <tolzmann@molgen.mpg.de> " MXQ_VERSIONDATE);
mx_log_info(" Max Planck Institute for Molecular Genetics - Berlin Dahlem");
mx_log_info("hostname=%s server_id=%s :: MXQ server started.", server.hostname, server.server_id);
mx_log_info(" host_id=%s", server.host_id);
mx_log_info("slots=%lu memory_total=%lu memory_avg_per_slot=%.0Lf memory_max_per_slot=%ld :: server initialized.",
server.slots, server.memory_total, server.memory_avg_per_slot, server.memory_max_per_slot);

3 changes: 3 additions & 0 deletions mxqd.h
Original file line number Diff line number Diff line change
@@ -70,6 +70,9 @@ struct mxq_server {

struct mx_mysql *mysql;

char *boot_id;
unsigned long long int starttime;
char *host_id;
char *hostname;
char *server_id;
char *lockfilename;
88 changes: 88 additions & 0 deletions test_mx_util.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@

#define _GNU_SOURCE

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "mx_util.h"

@@ -44,6 +48,7 @@ static void test_mx_strtoul(void)
assert(mx_strtoul("-1", &l) == -ERANGE);
assert(mx_strtoul(" -1", &l) == -ERANGE);

assert(mx_strtoul("123 123", &l) == -EINVAL);
assert(mx_strtoul("123s", &l) == -EINVAL);
assert(mx_strtoul("0888", &l) == -EINVAL);
assert(mx_strtoul("1.2", &l) == -EINVAL);
@@ -271,6 +276,87 @@ static void test_mx_strtobytes(void)
assert(mx_strtobytes("test", &l) == -EINVAL);
}

static void test_mx_read_first_line_from_file(void)
{
char *str;
long long int l;

assert(mx_read_first_line_from_file("/proc/sys/kernel/random/boot_id", &str) == 36);
assert(str);
mx_free_null(str);

assert(mx_read_first_line_from_file("/proc/sys/kernel/random/uuid", &str) == 36);
assert(str);
mx_free_null(str);

assert(mx_read_first_line_from_file("/proc/no_such_file", &str) == -ENOENT);
assert(str == NULL);

assert(mx_read_first_line_from_file("/proc/self/stat", &str) > 0);
assert(str);
mx_strtoll(str, &l);
mx_free_null(str);
}

static void test_mx_strscan(void)
{
_mx_cleanup_free_ char *s = NULL;
char *str;
unsigned long long int ull;
long long int ll;
_mx_cleanup_free_ char *line = NULL;
struct proc_pid_stat pps = {0};
struct proc_pid_stat pps2 = {0};

assert(s = strdup("123 456 -789 246 abc"));
str = s;

assert(mx_strscan_ull(&str, &ull) == 0);
assert(ull == 123);

assert(mx_strscan_ull(&str, &ull) == 0);
assert(ull == 456);

assert(mx_strscan_ull(&str, &ull) == -ERANGE);
assert(mx_streq(str, "-789 246 abc"));

assert(mx_strscan_ll(&str, &ll) == 0);
assert(ll == -789);
assert(mx_streq(str, "246 abc"));

assert(mx_strscan_ll(&str, &ll) == 0);
assert(ll == 246);
assert(mx_streq(str, "abc"));

assert(mx_strscan_ull(&str, &ull) == -EINVAL);
assert(mx_streq(str, "abc"));
assert(mx_streq(s, "123 456 -789 246 abc"));
mx_free_null(s);

assert(s = strdup("123"));
str = s;
assert(mx_strscan_ull(&str, &ull) == 0);
assert(ull == 123);
assert(mx_streq(str, ""));
assert(mx_streq(s, "123"));

assert(mx_read_first_line_from_file("/proc/self/stat", &line) > 0);
assert(mx_strscan_proc_pid_stat(line, &pps) == 0);
assert(pps.pid == getpid());
assert(pps.ppid == getppid());
assert(pps.state == 'R');
assert(mx_streq(pps.comm, program_invocation_short_name) || mx_streq(pps.comm, "memcheck-amd64-"));
mx_proc_pid_stat_free(&pps);

assert(mx_proc_pid_stat(&pps2, getpid()) == 0);
assert(pps2.pid == getpid());
assert(pps2.ppid == getppid());
assert(pps2.state == 'R');
assert(mx_streq(pps2.comm, program_invocation_short_name) || mx_streq(pps2.comm, "memcheck-amd64-"));
mx_proc_pid_stat_free(&pps2);
}


int main(int argc, char *argv[])
{
test_mx_strskipwhitespaces();
@@ -284,5 +370,7 @@ int main(int argc, char *argv[])
test_mx_strtoseconds();
test_mx_strtominutes();
test_mx_strtobytes();
test_mx_read_first_line_from_file();
test_mx_strscan();
return 0;
}

0 comments on commit 05a1509

Please sign in to comment.