mirror of
https://github.com/schoebel/mars
synced 2025-03-11 07:47:41 +00:00
proc: new trigger interface
Necessary for kernels >= 5.8.x. It should also work with old kernels.
This commit is contained in:
parent
f92a44ecfa
commit
c3cf062fb6
@ -46,6 +46,8 @@
|
|||||||
|
|
||||||
#include "../buildtag.h"
|
#include "../buildtag.h"
|
||||||
|
|
||||||
|
#define USE_NEW_TRIGGER
|
||||||
|
|
||||||
const char mars_version_string[] = BUILDTAG " (" BUILDHOST " " BUILDDATE ") "
|
const char mars_version_string[] = BUILDTAG " (" BUILDHOST " " BUILDDATE ") "
|
||||||
#ifndef CONFIG_MARS_DEBUG
|
#ifndef CONFIG_MARS_DEBUG
|
||||||
"production"
|
"production"
|
||||||
@ -176,6 +178,153 @@ void interpret_user_message(char *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_NEW_TRIGGER
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(trigger_buf_mutex);
|
||||||
|
static char trigger_buffer[PAGE_SIZE];
|
||||||
|
|
||||||
|
/* Compatible to old behaviour.
|
||||||
|
* Please use the new "t" codes instead.
|
||||||
|
* HOPEFULLY this can vanish some day :(
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int work_trigger_old(void)
|
||||||
|
{
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
sscanf(trigger_buffer, "%d", &code);
|
||||||
|
if (code >= 8) {
|
||||||
|
mars_remote_trigger(MARS_TRIGGER_LOCAL | MARS_TRIGGER_FROM_REMOTE | MARS_TRIGGER_TO_REMOTE_ALL | MARS_TRIGGER_FULL);
|
||||||
|
} else if (code >= 3) {
|
||||||
|
mars_remote_trigger(MARS_TRIGGER_LOCAL | MARS_TRIGGER_FROM_REMOTE | MARS_TRIGGER_TO_REMOTE_ALL);
|
||||||
|
} else if (code >= 2) {
|
||||||
|
mars_remote_trigger(MARS_TRIGGER_LOCAL | MARS_TRIGGER_TO_REMOTE);
|
||||||
|
} else if (code >= 1) {
|
||||||
|
mars_remote_trigger(MARS_TRIGGER_LOCAL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int work_trigger(void)
|
||||||
|
{
|
||||||
|
/* Deprecated, to disappear */
|
||||||
|
if (trigger_buffer[0] == ' ' ||
|
||||||
|
(trigger_buffer[0] >= '0' && trigger_buffer[0] <= '9'))
|
||||||
|
return work_trigger_old();
|
||||||
|
|
||||||
|
if (!trigger_buffer[0] || !trigger_buffer[1])
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
interpret_user_message(trigger_buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int trigger_answer(void)
|
||||||
|
{
|
||||||
|
char *answer = "MARS module not operational\n";
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
if (mars_info) {
|
||||||
|
answer = "internal error while determining mars_info\n";
|
||||||
|
tmp = mars_info();
|
||||||
|
if (tmp)
|
||||||
|
answer = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(trigger_buffer, answer, sizeof(trigger_buffer));
|
||||||
|
|
||||||
|
brick_string_free(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mars_dotrigger(struct ctl_table *table, int write,
|
||||||
|
void *buffer, size_t *lenp, loff_t *ppos)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&trigger_buf_mutex);
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
err = trigger_answer();
|
||||||
|
if (err < 0)
|
||||||
|
goto done_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = proc_dostring(table, write, buffer, lenp, ppos);
|
||||||
|
|
||||||
|
if (write && err >= 0) {
|
||||||
|
int status = work_trigger();
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
goto done_unlock;
|
||||||
|
}
|
||||||
|
done_unlock:
|
||||||
|
mutex_unlock(&trigger_buf_mutex);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LAMPORT_BUF_LEN 128
|
||||||
|
|
||||||
|
/* NO rw-mutex, to enforce strictness of results.
|
||||||
|
* This will deliberately limit the userspace parallelism ;)
|
||||||
|
* In short, userspace should not overload a long-distance
|
||||||
|
* Distributed System as represented by a Lamport Clock.
|
||||||
|
* As explained elsewhere, a Lamport Clock should act as
|
||||||
|
* a _singleton_ as seen from a local perspective.
|
||||||
|
* Nevertheless, a local nesting hierarchy remains possible
|
||||||
|
* for improved performance, but suchalike is deliberately _not_
|
||||||
|
* exported to userspace.
|
||||||
|
* Hopefully this will protect the kernel from intrusion-like
|
||||||
|
* misbehaviour.
|
||||||
|
* When necessary, some msleep() limitations may be added in future.
|
||||||
|
*/
|
||||||
|
static DEFINE_MUTEX(lamport_buf_mutex);
|
||||||
|
atomic_t lamport_calls = ATOMIC_INIT(0);
|
||||||
|
static char lamport_buffer[LAMPORT_BUF_LEN];
|
||||||
|
|
||||||
|
int proc_dolamport(struct ctl_table *table, int write,
|
||||||
|
void *buffer, size_t *lenp, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct lamport_time know;
|
||||||
|
struct lamport_time lnow;
|
||||||
|
int calls;
|
||||||
|
int len;
|
||||||
|
int err = -EINVAL;
|
||||||
|
|
||||||
|
/* also count any tries or failures */
|
||||||
|
calls = atomic_inc_return(&lamport_calls);
|
||||||
|
|
||||||
|
if (write)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
mutex_lock(&lamport_buf_mutex);
|
||||||
|
|
||||||
|
get_lamport(&know, &lnow);
|
||||||
|
|
||||||
|
len = scnprintf(lamport_buffer, LAMPORT_BUF_LEN,
|
||||||
|
"CURRENT_TIME=%lld.%09ld\n"
|
||||||
|
"lamport_now=%lld.%09ld\n"
|
||||||
|
"CALLS=%u",
|
||||||
|
(s64)know.tv_sec, know.tv_nsec,
|
||||||
|
(s64)lnow.tv_sec, lnow.tv_nsec,
|
||||||
|
/* may overflow */
|
||||||
|
(unsigned)calls);
|
||||||
|
if (unlikely(len <= 0 || len >= LAMPORT_BUF_LEN - 1))
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
err = proc_dostring(table, write, buffer, lenp, ppos);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&lamport_buf_mutex);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(proc_dolamport);
|
||||||
|
|
||||||
|
#else /* USE_NEW_TRIGGER */
|
||||||
|
|
||||||
static
|
static
|
||||||
int trigger_sysctl_handler(
|
int trigger_sysctl_handler(
|
||||||
struct ctl_table *table,
|
struct ctl_table *table,
|
||||||
@ -311,6 +460,8 @@ done:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* USE_NEW_TRIGGER */
|
||||||
|
|
||||||
#ifdef CTL_UNNUMBERED
|
#ifdef CTL_UNNUMBERED
|
||||||
#define _CTL_NAME .ctl_name = CTL_UNNUMBERED,
|
#define _CTL_NAME .ctl_name = CTL_UNNUMBERED,
|
||||||
#define _CTL_STRATEGY(handler) .strategy = &handler,
|
#define _CTL_STRATEGY(handler) .strategy = &handler,
|
||||||
@ -419,19 +570,37 @@ struct ctl_table mars_table[] = {
|
|||||||
_CTL_NAME
|
_CTL_NAME
|
||||||
.procname = "trigger",
|
.procname = "trigger",
|
||||||
.mode = 0200,
|
.mode = 0200,
|
||||||
|
#ifdef USE_NEW_TRIGGER
|
||||||
|
.data = trigger_buffer,
|
||||||
|
.maxlen = sizeof(trigger_buffer),
|
||||||
|
.proc_handler = &mars_dotrigger,
|
||||||
|
#else
|
||||||
.proc_handler = &trigger_sysctl_handler,
|
.proc_handler = &trigger_sysctl_handler,
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_CTL_NAME
|
_CTL_NAME
|
||||||
.procname = "info",
|
.procname = "info",
|
||||||
.mode = 0400,
|
.mode = 0400,
|
||||||
|
#ifdef USE_NEW_TRIGGER
|
||||||
|
.data = trigger_buffer,
|
||||||
|
.maxlen = sizeof(trigger_buffer),
|
||||||
|
.proc_handler = &mars_dotrigger,
|
||||||
|
#else
|
||||||
.proc_handler = &trigger_sysctl_handler,
|
.proc_handler = &trigger_sysctl_handler,
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_CTL_NAME
|
_CTL_NAME
|
||||||
.procname = "lamport_clock",
|
.procname = "lamport_clock",
|
||||||
.mode = 0400,
|
.mode = 0400,
|
||||||
|
#ifdef USE_NEW_TRIGGER
|
||||||
|
.data = lamport_buffer,
|
||||||
|
.maxlen = LAMPORT_BUF_LEN,
|
||||||
|
.proc_handler = &proc_dolamport,
|
||||||
|
#else
|
||||||
.proc_handler = &lamport_sysctl_handler,
|
.proc_handler = &lamport_sysctl_handler,
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
INT_ENTRY("min_update_seconds", mars_min_update, 0600),
|
INT_ENTRY("min_update_seconds", mars_min_update, 0600),
|
||||||
INT_ENTRY("max_lamport_future", max_lamport_future, 0600),
|
INT_ENTRY("max_lamport_future", max_lamport_future, 0600),
|
||||||
|
Loading…
Reference in New Issue
Block a user