[RFC 28/32] mars: add new module mars_proc
Signed-off-by: Thomas Schoebel-Theuer--- drivers/staging/mars/mars/mars_proc.c | 389 ++ drivers/staging/mars/mars/mars_proc.h | 34 +++ 2 files changed, 423 insertions(+) create mode 100644 drivers/staging/mars/mars/mars_proc.c create mode 100644 drivers/staging/mars/mars/mars_proc.h diff --git a/drivers/staging/mars/mars/mars_proc.c b/drivers/staging/mars/mars/mars_proc.c new file mode 100644 index ..84b4dfc82211 --- /dev/null +++ b/drivers/staging/mars/mars/mars_proc.c @@ -0,0 +1,389 @@ +/* + * MARS Long Distance Replication Software + * + * Copyright (C) 2010-2014 Thomas Schoebel-Theuer + * Copyright (C) 2011-2014 1&1 Internet AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include + +#include "strategy.h" +#include "mars_proc.h" +#include +#include +#include +#include +#include +#include +#include + +xio_info_fn xio_info; + +static +int trigger_sysctl_handler( + struct ctl_table *table, + int write, + void __user *buffer, + size_t *length, + loff_t *ppos) +{ + ssize_t res = 0; + size_t len = *length; + + XIO_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos); + + if (!len || *ppos > 0) + goto done; + + if (write) { + char tmp[8] = {}; + + res = len; /* fake consumption of all data */ + + if (len > 7) + len = 7; + if (!copy_from_user(tmp, buffer, len)) { + int code = 0; + int status = kstrtoint(tmp, 10, ); + + /* the return value from ssanf() does not matter */ + (void)status; + if (code > 0) + local_trigger(); + if (code > 1) + remote_trigger(); + } + } else { + char *answer = "MARS module not operational\n"; + char *tmp = NULL; + int mylen; + + if (xio_info) { + answer = "internal error while determining xio_info\n"; + tmp = xio_info(); + if (tmp) + answer = tmp; + } + + mylen = strlen(answer); + if (len > mylen) + len = mylen; + res = len; + if (copy_to_user(buffer, answer, len)) { + XIO_ERR("write %ld bytes at %p failed\n", len, buffer); + res = -EFAULT; + } + brick_string_free(tmp); + } + +done: + XIO_DBG("res = %ld\n", res); + *length = res; + if (res >= 0) { + *ppos += res; + return 0; + } + return res; +} + +static +int lamport_sysctl_handler( + struct ctl_table *table, + int write, + void __user *buffer, + size_t *length, + loff_t *ppos) +{ + ssize_t res = 0; + size_t len = *length; + int my_len = 128; + char *tmp = brick_string_alloc(my_len); + struct timespec know = CURRENT_TIME; + struct timespec lnow; + + XIO_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos); + + if (!len || *ppos > 0) + goto done; + + if (write) + return -EINVAL; + + get_lamport(); + + res = scnprintf( + tmp, + my_len, + "CURRENT_TIME=%ld.%09ld\nlamport_now=%ld.%09ld\n", + know.tv_sec, know.tv_nsec, + lnow.tv_sec, lnow.tv_nsec + ); + + if (copy_to_user(buffer, tmp, res)) { + XIO_ERR("write %ld bytes at %p failed\n", res, buffer); + res = -EFAULT; + } + brick_string_free(tmp); + +done: + XIO_DBG("res = %ld\n", res); + *length = res; + if (res >= 0) { + *ppos += res; + return 0; + } + return res; +} + +#ifdef CTL_UNNUMBERED +#define _CTL_NAME .ctl_name = CTL_UNNUMBERED, +#define _CTL_STRATEGY(handler) .strategy = , +#else +#define _CTL_NAME /*empty*/ +#define _CTL_STRATEGY(handler) /*empty*/ +#endif + +#define VEC_ENTRY(NAME, VAR, MODE, COUNT) \ + {
[RFC 28/32] mars: add new module mars_proc
Signed-off-by: Thomas Schoebel-Theuer --- drivers/staging/mars/mars/mars_proc.c | 389 ++ drivers/staging/mars/mars/mars_proc.h | 34 +++ 2 files changed, 423 insertions(+) create mode 100644 drivers/staging/mars/mars/mars_proc.c create mode 100644 drivers/staging/mars/mars/mars_proc.h diff --git a/drivers/staging/mars/mars/mars_proc.c b/drivers/staging/mars/mars/mars_proc.c new file mode 100644 index ..84b4dfc82211 --- /dev/null +++ b/drivers/staging/mars/mars/mars_proc.c @@ -0,0 +1,389 @@ +/* + * MARS Long Distance Replication Software + * + * Copyright (C) 2010-2014 Thomas Schoebel-Theuer + * Copyright (C) 2011-2014 1&1 Internet AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include + +#include "strategy.h" +#include "mars_proc.h" +#include +#include +#include +#include +#include +#include +#include + +xio_info_fn xio_info; + +static +int trigger_sysctl_handler( + struct ctl_table *table, + int write, + void __user *buffer, + size_t *length, + loff_t *ppos) +{ + ssize_t res = 0; + size_t len = *length; + + XIO_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos); + + if (!len || *ppos > 0) + goto done; + + if (write) { + char tmp[8] = {}; + + res = len; /* fake consumption of all data */ + + if (len > 7) + len = 7; + if (!copy_from_user(tmp, buffer, len)) { + int code = 0; + int status = kstrtoint(tmp, 10, ); + + /* the return value from ssanf() does not matter */ + (void)status; + if (code > 0) + local_trigger(); + if (code > 1) + remote_trigger(); + } + } else { + char *answer = "MARS module not operational\n"; + char *tmp = NULL; + int mylen; + + if (xio_info) { + answer = "internal error while determining xio_info\n"; + tmp = xio_info(); + if (tmp) + answer = tmp; + } + + mylen = strlen(answer); + if (len > mylen) + len = mylen; + res = len; + if (copy_to_user(buffer, answer, len)) { + XIO_ERR("write %ld bytes at %p failed\n", len, buffer); + res = -EFAULT; + } + brick_string_free(tmp); + } + +done: + XIO_DBG("res = %ld\n", res); + *length = res; + if (res >= 0) { + *ppos += res; + return 0; + } + return res; +} + +static +int lamport_sysctl_handler( + struct ctl_table *table, + int write, + void __user *buffer, + size_t *length, + loff_t *ppos) +{ + ssize_t res = 0; + size_t len = *length; + int my_len = 128; + char *tmp = brick_string_alloc(my_len); + struct timespec know = CURRENT_TIME; + struct timespec lnow; + + XIO_DBG("write = %d len = %ld pos = %lld\n", write, len, *ppos); + + if (!len || *ppos > 0) + goto done; + + if (write) + return -EINVAL; + + get_lamport(); + + res = scnprintf( + tmp, + my_len, + "CURRENT_TIME=%ld.%09ld\nlamport_now=%ld.%09ld\n", + know.tv_sec, know.tv_nsec, + lnow.tv_sec, lnow.tv_nsec + ); + + if (copy_to_user(buffer, tmp, res)) { + XIO_ERR("write %ld bytes at %p failed\n", res, buffer); + res = -EFAULT; + } + brick_string_free(tmp); + +done: + XIO_DBG("res = %ld\n", res); + *length = res; + if (res >= 0) { + *ppos += res; + return 0; + } + return res; +} + +#ifdef CTL_UNNUMBERED +#define _CTL_NAME .ctl_name = CTL_UNNUMBERED, +#define _CTL_STRATEGY(handler) .strategy = , +#else +#define _CTL_NAME /*empty*/ +#define _CTL_STRATEGY(handler) /*empty*/ +#endif + +#define VEC_ENTRY(NAME, VAR, MODE, COUNT) \ + { \ +