2011-03-02 16:20:36 +00:00
|
|
|
// (c) 2011 Thomas Schoebel-Theuer / 1&1 Internet AG
|
|
|
|
|
|
|
|
//#define BRICK_DEBUGGING
|
|
|
|
//#define MARS_DEBUGGING
|
|
|
|
//#define IO_DEBUGGING
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
|
|
|
|
#include <linux/sysctl.h>
|
|
|
|
#include <linux/uaccess.h>
|
|
|
|
|
2011-07-22 10:43:40 +00:00
|
|
|
#include "strategy.h"
|
2011-03-02 16:20:36 +00:00
|
|
|
#include "mars_proc.h"
|
2012-10-15 14:35:36 +00:00
|
|
|
#include "../mars_bio.h"
|
|
|
|
#include "../mars_aio.h"
|
2012-08-07 12:07:12 +00:00
|
|
|
#include "../mars_client.h"
|
|
|
|
#include "../mars_server.h"
|
2012-09-26 09:22:36 +00:00
|
|
|
#include "../mars_trans_logger.h"
|
2011-03-02 16:20:36 +00:00
|
|
|
|
|
|
|
mars_info_fn mars_info = NULL;
|
|
|
|
|
|
|
|
static
|
2012-02-02 10:16:06 +00:00
|
|
|
int trigger_sysctl_handler(
|
|
|
|
ctl_table *table,
|
|
|
|
int write,
|
|
|
|
void __user *buffer,
|
|
|
|
size_t *length,
|
|
|
|
loff_t *ppos)
|
2011-03-02 16:20:36 +00:00
|
|
|
{
|
|
|
|
ssize_t res = 0;
|
|
|
|
size_t len = *length;
|
|
|
|
|
|
|
|
MARS_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos);
|
|
|
|
|
|
|
|
if (!len || *ppos > 0) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (write) {
|
|
|
|
char tmp[8] = {};
|
|
|
|
int code = 0;
|
|
|
|
|
|
|
|
res = len; // fake consumption of all data
|
|
|
|
|
|
|
|
if (len > 7)
|
|
|
|
len = 7;
|
|
|
|
if (!copy_from_user(tmp, buffer, len)) {
|
|
|
|
sscanf(tmp, "%d", &code);
|
|
|
|
if (code) {
|
|
|
|
mars_trigger();
|
2012-01-25 13:38:45 +00:00
|
|
|
mars_remote_trigger();
|
2011-03-02 16:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char *answer = "MARS module not loaded\n";
|
|
|
|
char *tmp = NULL;
|
|
|
|
int mylen;
|
|
|
|
|
|
|
|
if (mars_info) {
|
|
|
|
answer = "internal error while determining mars_info\n";
|
|
|
|
tmp = mars_info();
|
|
|
|
if (tmp)
|
|
|
|
answer = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
mylen = strlen(answer);
|
|
|
|
if (len > mylen)
|
|
|
|
len = mylen;
|
|
|
|
res = len;
|
|
|
|
if (copy_to_user(buffer, answer, len)) {
|
|
|
|
MARS_ERR("write %ld bytes at %p failed\n", len, buffer);
|
|
|
|
res = -EFAULT;
|
|
|
|
}
|
2011-08-12 11:09:48 +00:00
|
|
|
brick_string_free(tmp);
|
2011-03-02 16:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
MARS_DBG("res = %ld\n", res);
|
|
|
|
*length = res;
|
|
|
|
if (res >= 0) {
|
|
|
|
*ppos += res;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-02-02 10:16:06 +00:00
|
|
|
static
|
|
|
|
int _proc_sysctl_handler(
|
|
|
|
int class,
|
|
|
|
int write,
|
|
|
|
void __user *buffer,
|
|
|
|
size_t *length,
|
|
|
|
loff_t *ppos)
|
|
|
|
{
|
|
|
|
ssize_t res = 0;
|
|
|
|
size_t len = *length;
|
|
|
|
|
|
|
|
MARS_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos);
|
|
|
|
|
|
|
|
if (!len || *ppos > 0) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (write) {
|
|
|
|
res = len; // fake consumption of all data
|
|
|
|
} else {
|
|
|
|
int len;
|
|
|
|
const char *answer = proc_say_get(class, &len);
|
|
|
|
|
|
|
|
if (answer) {
|
|
|
|
res = len;
|
|
|
|
if (copy_to_user(buffer, answer, len)) {
|
|
|
|
MARS_ERR("write %d bytes at %p failed\n", len, answer);
|
|
|
|
res = -EFAULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
MARS_DBG("res = %ld\n", res);
|
|
|
|
*length = res;
|
|
|
|
if (res >= 0) {
|
|
|
|
*ppos += res;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
int warnings_sysctl_handler(
|
|
|
|
ctl_table *table,
|
|
|
|
int write,
|
|
|
|
void __user *buffer,
|
|
|
|
size_t *length,
|
|
|
|
loff_t *ppos)
|
|
|
|
{
|
2012-10-11 06:25:41 +00:00
|
|
|
return _proc_sysctl_handler(SAY_WARN, write, buffer, length, ppos);
|
2012-02-02 10:16:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
int errors_sysctl_handler(
|
|
|
|
ctl_table *table,
|
|
|
|
int write,
|
|
|
|
void __user *buffer,
|
|
|
|
size_t *length,
|
|
|
|
loff_t *ppos)
|
|
|
|
{
|
2012-10-11 06:25:41 +00:00
|
|
|
return _proc_sysctl_handler(SAY_ERROR, write, buffer, length, ppos);
|
2012-02-02 10:16:06 +00:00
|
|
|
}
|
|
|
|
|
2012-02-08 18:12:57 +00:00
|
|
|
#ifdef CONFIG_MARS_LOADAVG_LIMIT
|
2012-02-14 13:27:12 +00:00
|
|
|
int mars_max_loadavg = 0;
|
2012-02-08 18:12:57 +00:00
|
|
|
EXPORT_SYMBOL_GPL(mars_max_loadavg);
|
|
|
|
#endif
|
|
|
|
|
2012-09-18 06:13:33 +00:00
|
|
|
#ifdef CTL_UNNUMBERED
|
|
|
|
#define _CTL_NAME .ctl_name = CTL_UNNUMBERED,
|
|
|
|
#define _CTL_STRATEGY(handler) .strategy = &handler,
|
|
|
|
#else
|
|
|
|
#define _CTL_NAME /*empty*/
|
|
|
|
#define _CTL_STRATEGY(handler) /*empty*/
|
|
|
|
#endif
|
|
|
|
|
2012-10-15 14:35:36 +00:00
|
|
|
#define INT_ENTRY(NAME,VAR,MODE) \
|
|
|
|
{ \
|
|
|
|
_CTL_NAME \
|
|
|
|
.procname = NAME, \
|
|
|
|
.data = &(VAR), \
|
|
|
|
.maxlen = sizeof(int), \
|
|
|
|
.mode = MODE, \
|
|
|
|
.proc_handler = &proc_dointvec, \
|
|
|
|
_CTL_STRATEGY(sysctl_intvec) \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define LIMITER_ENTRIES(VAR, PREFIX, SUFFIX) \
|
|
|
|
INT_ENTRY(PREFIX "_limit_" SUFFIX, (VAR)->lim_max_rate, 0600), \
|
|
|
|
INT_ENTRY(PREFIX "_rate_" SUFFIX, (VAR)->lim_rate, 0600) \
|
|
|
|
|
|
|
|
#define THRESHOLD_ENTRIES(VAR, PREFIX) \
|
|
|
|
INT_ENTRY(PREFIX "_threshold_us", (VAR)->thr_limit, 0600), \
|
|
|
|
INT_ENTRY(PREFIX "_factor_percent", (VAR)->thr_factor, 0600), \
|
|
|
|
INT_ENTRY(PREFIX "_plus_us", (VAR)->thr_plus, 0600), \
|
|
|
|
INT_ENTRY(PREFIX "_triggered", (VAR)->thr_triggered, 0600), \
|
|
|
|
INT_ENTRY(PREFIX "_true_hit", (VAR)->thr_true_hit, 0600) \
|
|
|
|
|
|
|
|
static
|
|
|
|
ctl_table tuning_table[] = {
|
|
|
|
LIMITER_ENTRIES(&client_limiter, "network_traffic", "kb"),
|
|
|
|
LIMITER_ENTRIES(&server_limiter, "server_io", "kb"),
|
|
|
|
LIMITER_ENTRIES(&global_writeback.limiter, "writeback", "kb"),
|
|
|
|
INT_ENTRY("writeback_until_percent", global_writeback.until_percent, 0600),
|
|
|
|
THRESHOLD_ENTRIES(&bio_submit_threshold, "bio_submit"),
|
|
|
|
THRESHOLD_ENTRIES(&bio_io_threshold[0], "bio_io_r"),
|
|
|
|
THRESHOLD_ENTRIES(&bio_io_threshold[1], "bio_io_w"),
|
|
|
|
THRESHOLD_ENTRIES(&aio_submit_threshold, "aio_submit"),
|
|
|
|
THRESHOLD_ENTRIES(&aio_io_threshold[0], "aio_io_r"),
|
|
|
|
THRESHOLD_ENTRIES(&aio_io_threshold[1], "aio_io_w"),
|
|
|
|
THRESHOLD_ENTRIES(&aio_sync_threshold, "aio_sync"),
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2011-03-02 16:20:36 +00:00
|
|
|
static
|
|
|
|
ctl_table mars_table[] = {
|
2012-01-23 16:27:44 +00:00
|
|
|
{
|
2012-09-18 06:13:33 +00:00
|
|
|
_CTL_NAME
|
2012-01-23 16:27:44 +00:00
|
|
|
.procname = "trigger",
|
|
|
|
.mode = 0200,
|
|
|
|
.proc_handler = &trigger_sysctl_handler,
|
|
|
|
},
|
2012-02-02 10:16:06 +00:00
|
|
|
{
|
2012-09-18 06:13:33 +00:00
|
|
|
_CTL_NAME
|
2012-02-02 10:16:06 +00:00
|
|
|
.procname = "warnings",
|
|
|
|
.mode = 0400,
|
|
|
|
.proc_handler = &warnings_sysctl_handler,
|
|
|
|
},
|
|
|
|
{
|
2012-09-18 06:13:33 +00:00
|
|
|
_CTL_NAME
|
2012-02-02 10:16:06 +00:00
|
|
|
.procname = "errors",
|
|
|
|
.mode = 0400,
|
|
|
|
.proc_handler = &errors_sysctl_handler,
|
|
|
|
},
|
2012-10-15 14:35:36 +00:00
|
|
|
INT_ENTRY("percent_mem_limit_kb", mars_mem_percent, 0600),
|
|
|
|
INT_ENTRY("mem_used_kb", trans_logger_mem_usage, 0400),
|
|
|
|
INT_ENTRY("logrot_auto_gb", global_logrot_auto, 0600),
|
|
|
|
INT_ENTRY("logdel_auto_gb", global_logdel_auto, 0600),
|
|
|
|
INT_ENTRY("free_space_mb", global_free_space, 0600),
|
2012-02-08 18:12:57 +00:00
|
|
|
#ifdef CONFIG_MARS_LOADAVG_LIMIT
|
2012-10-15 14:35:36 +00:00
|
|
|
INT_ENTRY("loadavg_limit", mars_max_loadavg, 0600),
|
2012-02-08 18:12:57 +00:00
|
|
|
#endif
|
2012-10-15 14:35:36 +00:00
|
|
|
INT_ENTRY("network_io_timeout", global_net_io_timeout, 0600),
|
2012-08-21 11:43:56 +00:00
|
|
|
{
|
2012-09-18 06:13:33 +00:00
|
|
|
_CTL_NAME
|
2012-10-15 14:35:36 +00:00
|
|
|
.procname = "tuning",
|
|
|
|
.mode = 0500,
|
|
|
|
.child = tuning_table,
|
2012-09-26 09:29:18 +00:00
|
|
|
},
|
2012-01-23 16:27:44 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
static
|
|
|
|
ctl_table mars_root_table[] = {
|
2011-03-02 16:20:36 +00:00
|
|
|
{
|
2012-09-18 06:13:33 +00:00
|
|
|
_CTL_NAME
|
2011-03-02 16:20:36 +00:00
|
|
|
.procname = "mars",
|
2012-01-23 16:27:44 +00:00
|
|
|
.mode = 0500,
|
|
|
|
.child = mars_table,
|
2011-03-02 16:20:36 +00:00
|
|
|
},
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////// module init stuff /////////////////////////
|
|
|
|
|
|
|
|
static struct ctl_table_header *header = NULL;
|
|
|
|
|
2011-08-25 10:16:32 +00:00
|
|
|
int __init init_mars_proc(void)
|
2011-03-02 16:20:36 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
MARS_INF("init_proc()\n");
|
2011-08-26 10:31:56 +00:00
|
|
|
|
2012-01-23 16:27:44 +00:00
|
|
|
header = register_sysctl_table(mars_root_table);
|
2011-03-02 16:20:36 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-08-25 10:16:32 +00:00
|
|
|
void __exit exit_mars_proc(void)
|
2011-03-02 16:20:36 +00:00
|
|
|
{
|
|
|
|
MARS_INF("exit_proc()\n");
|
|
|
|
if (header) {
|
|
|
|
unregister_sysctl_table(header);
|
|
|
|
header = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-25 10:16:32 +00:00
|
|
|
#ifndef CONFIG_MARS_HAVE_BIGMODULE
|
2011-03-02 16:20:36 +00:00
|
|
|
MODULE_DESCRIPTION("MARS /proc/ infrastructure");
|
|
|
|
MODULE_AUTHOR("Thomas Schoebel-Theuer <tst@1und1.de>");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
2011-08-25 10:16:32 +00:00
|
|
|
module_init(init_mars_proc);
|
|
|
|
module_exit(exit_mars_proc);
|
|
|
|
#endif
|