import mars-68.tgz

This commit is contained in:
Thomas Schoebel-Theuer 2011-03-03 10:02:10 +01:00
parent 7dec70085d
commit bbff01d71f
7 changed files with 190 additions and 138 deletions

11
mars.h
View File

@ -332,17 +332,16 @@ extern int mars_kill_brick(struct mars_brick *brick);
// mid-level brick instantiation (identity is based on path strings) // mid-level brick instantiation (identity is based on path strings)
extern char *vpath_make(struct mars_dent *parent, const char *fmt, va_list *args); extern char *vpath_make(const char *fmt, va_list *args);
extern char *path_make(struct mars_dent *parent, const char *fmt, ...); extern char *path_make(const char *fmt, ...);
extern struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, struct mars_dent *parent, const char *fmt, ...); extern struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, const char *fmt, ...);
/* Create a new brick and connect its inputs to a set of predecessors. /* Create a new brick and connect its inputs to a set of predecessors.
* When @timeout > 0, switch on the brick as well as its predecessors. * When @timeout > 0, switch on the brick as well as its predecessors.
*/ */
extern struct mars_brick *make_brick_all( extern struct mars_brick *make_brick_all(
struct mars_global *global, struct mars_global *global,
struct mars_dent *parent,
struct mars_dent *belongs, struct mars_dent *belongs,
int timeout, int timeout,
const char *new_name, const char *new_name,
@ -375,8 +374,8 @@ extern int mars_lchown(const char *path, uid_t uid);
* from the main instantiation logic (separate modprobe for mars_server * from the main instantiation logic (separate modprobe for mars_server
* is possible). * is possible).
*/ */
extern struct generic_brick_type *_client_brick_type; extern const struct generic_brick_type *_client_brick_type;
extern struct generic_brick_type *_aio_brick_type; extern const struct generic_brick_type *_aio_brick_type;
/* Kludge: our kernel threads will have no mm context, but need one /* Kludge: our kernel threads will have no mm context, but need one
* for stuff like ioctx_alloc() / aio_setup_ring() etc * for stuff like ioctx_alloc() / aio_setup_ring() etc

View File

@ -43,19 +43,20 @@ static int _connect(struct client_output *output, const char *str)
struct sockaddr_storage sockaddr = {}; struct sockaddr_storage sockaddr = {};
int status; int status;
if (!output->host) { if (!output->path) {
output->host = kstrdup(str, GFP_MARS); output->path = kstrdup(str, GFP_MARS);
status = -ENOMEM; status = -ENOMEM;
if (!output->host) if (!output->path)
goto done; goto done;
status = -EINVAL; status = -EINVAL;
output->path = strchr(output->host, '+'); output->host = strchr(output->path, '@');
if (!output->path) { if (!output->host) {
kfree(output->host); kfree(output->path);
output->host = NULL; output->path = NULL;
MARS_ERR("parameter string '%s' contains no remote specifier with '@'-syntax\n", str);
goto done; goto done;
} }
*output->path++ = '\0'; *output->host++ = '\0';
} }
status = mars_create_sockaddr(&sockaddr, output->host); status = mars_create_sockaddr(&sockaddr, output->host);
@ -270,7 +271,7 @@ done:
if (output->socket) { if (output->socket) {
MARS_INF("shutting down socket\n"); MARS_INF("shutting down socket\n");
kernel_sock_shutdown(output->socket, SHUT_WR); kernel_sock_shutdown(output->socket, SHUT_WR);
//msleep(1000); msleep(1000);
output->socket = NULL; output->socket = NULL;
} }
return status; return status;
@ -432,8 +433,10 @@ static int client_output_construct(struct client_output *output)
static int client_output_destruct(struct client_output *output) static int client_output_destruct(struct client_output *output)
{ {
if (output->host) if (output->path) {
kfree(output->host); kfree(output->path);
output->path = NULL;
}
return 0; return 0;
} }

View File

@ -14,6 +14,8 @@
#define _STRATEGY #define _STRATEGY
#include "mars.h" #include "mars.h"
#include "mars_client.h"
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/kthread.h> #include <linux/kthread.h>
@ -117,7 +119,7 @@ EXPORT_SYMBOL_GPL(mars_mkdir);
int mars_symlink(const char *oldpath, const char *newpath, const struct timespec *stamp, uid_t uid) int mars_symlink(const char *oldpath, const char *newpath, const struct timespec *stamp, uid_t uid)
{ {
char *tmp = path_make(NULL, "%s.tmp", newpath); char *tmp = path_make("%s.tmp", newpath);
mm_segment_t oldfs; mm_segment_t oldfs;
int status = -ENOMEM; int status = -ENOMEM;
@ -914,39 +916,37 @@ EXPORT_SYMBOL_GPL(mars_kill_brick);
// mid-level brick instantiation (identity is based on path strings) // mid-level brick instantiation (identity is based on path strings)
char *vpath_make(struct mars_dent *parent, const char *fmt, va_list *args) char *vpath_make(const char *fmt, va_list *args)
{ {
int len = parent ? parent->d_pathlen : 0; int len = strlen(fmt);
char *res = kmalloc(len + MARS_PATH_MAX, GFP_MARS); char *res = kmalloc(len + MARS_PATH_MAX, GFP_MARS);
if (likely(res)) { if (likely(res)) {
if (parent) vsnprintf(res, MARS_PATH_MAX, fmt, *args);
memcpy(res, parent->d_path, len);
vsnprintf(res + len, MARS_PATH_MAX, fmt, *args);
} }
return res; return res;
} }
EXPORT_SYMBOL_GPL(vpath_make); EXPORT_SYMBOL_GPL(vpath_make);
char *path_make(struct mars_dent *parent, const char *fmt, ...) char *path_make(const char *fmt, ...)
{ {
va_list args; va_list args;
char *res; char *res;
va_start(args, fmt); va_start(args, fmt);
res = vpath_make(parent, fmt, &args); res = vpath_make(fmt, &args);
va_end(args); va_end(args);
return res; return res;
} }
EXPORT_SYMBOL_GPL(path_make); EXPORT_SYMBOL_GPL(path_make);
struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, struct mars_dent *parent, const char *fmt, ...) struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, const char *fmt, ...)
{ {
va_list args; va_list args;
char *fullpath; char *fullpath;
struct mars_brick *res; struct mars_brick *res;
va_start(args, fmt); va_start(args, fmt);
fullpath = vpath_make(parent, fmt, &args); fullpath = vpath_make(fmt, &args);
va_end(args); va_end(args);
if (!fullpath) { if (!fullpath) {
@ -959,14 +959,13 @@ struct mars_brick *path_find_brick(struct mars_global *global, const void *brick
} }
EXPORT_SYMBOL_GPL(path_find_brick); EXPORT_SYMBOL_GPL(path_find_brick);
struct generic_brick_type *_client_brick_type = NULL; const struct generic_brick_type *_client_brick_type = NULL;
EXPORT_SYMBOL_GPL(_client_brick_type); EXPORT_SYMBOL_GPL(_client_brick_type);
struct generic_brick_type *_aio_brick_type = NULL; const struct generic_brick_type *_aio_brick_type = NULL;
EXPORT_SYMBOL_GPL(_aio_brick_type); EXPORT_SYMBOL_GPL(_aio_brick_type);
struct mars_brick *make_brick_all( struct mars_brick *make_brick_all(
struct mars_global *global, struct mars_global *global,
struct mars_dent *parent,
struct mars_dent *belongs, struct mars_dent *belongs,
int timeout, int timeout,
const char *new_name, const char *new_name,
@ -979,7 +978,8 @@ struct mars_brick *make_brick_all(
) )
{ {
va_list args; va_list args;
char *new_path; const char *new_path;
const char *_new_path = NULL;
struct mars_brick *brick = NULL; struct mars_brick *brick = NULL;
char *paths[prev_count]; char *paths[prev_count];
struct mars_brick *prev[prev_count]; struct mars_brick *prev[prev_count];
@ -987,9 +987,13 @@ struct mars_brick *make_brick_all(
// treat variable arguments // treat variable arguments
va_start(args, prev_count); va_start(args, prev_count);
new_path = vpath_make(parent, new_fmt, &args); if (new_fmt) {
new_path = _new_path = vpath_make(new_fmt, &args);
} else {
new_path = new_name;
}
for (i = 0; i < prev_count; i++) { for (i = 0; i < prev_count; i++) {
paths[i] = vpath_make(parent, prev_fmt[i], &args); paths[i] = vpath_make(prev_fmt[i], &args);
} }
va_end(args); va_end(args);
@ -999,11 +1003,13 @@ struct mars_brick *make_brick_all(
} }
// don't do anything if brick already exists // don't do anything if brick already exists
brick = mars_find_brick(global, new_brick_type, new_path); brick = mars_find_brick(global, new_brick_type != _aio_brick_type ? new_brick_type : NULL, new_path);
if (brick) { if (brick) {
MARS_DBG("found brick '%s'\n", new_path); MARS_DBG("found brick '%s'\n", new_path);
goto done; goto done;
} }
if (!new_name)
new_name = new_path;
MARS_DBG("----> new brick type = '%s' path = '%s' name = '%s'\n", new_brick_type->type_name, new_path, new_name); MARS_DBG("----> new brick type = '%s' path = '%s' name = '%s'\n", new_brick_type->type_name, new_path, new_name);
@ -1028,15 +1034,16 @@ struct mars_brick *make_brick_all(
// create it... // create it...
brick = NULL; brick = NULL;
if (new_brick_type == _aio_brick_type && _client_brick_type != NULL) { if (new_brick_type == _aio_brick_type && _client_brick_type != NULL) {
char *remote = strchr(new_path, '@'); char *remote = strchr(new_name, '@');
if (remote) { if (remote) {
new_path[remote-new_path] = '\0';
remote++; remote++;
brick = mars_make_brick(global, NULL, _client_brick_type, new_path, remote); MARS_DBG("substitute by remote brick '%s' on peer '%s'\n", new_name, remote);
brick = mars_make_brick(global, belongs, _client_brick_type, new_path, new_name);
} }
} }
if (!brick) if (!brick)
brick = mars_make_brick(global, NULL, new_brick_type, new_path, new_name); brick = mars_make_brick(global, belongs, new_brick_type, new_path, new_name);
if (unlikely(!brick)) { if (unlikely(!brick)) {
MARS_DBG("creation failed '%s' '%s'\n", new_path, new_name); MARS_DBG("creation failed '%s' '%s'\n", new_path, new_name);
goto err; goto err;
@ -1075,8 +1082,8 @@ done:
kfree(paths[i]); kfree(paths[i]);
} }
} }
if (new_path) if (_new_path)
kfree(new_path); kfree(_new_path);
return brick; return brick;
} }

View File

@ -131,37 +131,46 @@ char *_backskip_replace(const char *path, char delim, bool insert, const char *f
static static
int __make_copy( int __make_copy(
struct mars_global *global, struct mars_global *global,
struct mars_dent *parent,
struct mars_dent *belongs, struct mars_dent *belongs,
const char *path, const char *path,
const char *parent,
const char *argv[], const char *argv[],
loff_t start_pos, loff_t start_pos,
struct copy_brick **__copy) struct copy_brick **__copy)
{ {
struct mars_brick *copy; struct mars_brick *copy;
struct copy_brick *_copy; struct copy_brick *_copy;
const char *fullpath[2] = {};
struct mars_output *output[2] = {}; struct mars_output *output[2] = {};
struct mars_info info[2] = {}; struct mars_info info[2] = {};
int i; int i;
int status = -1; int status = -1;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
const char *target = argv[i];
struct mars_brick *aio; struct mars_brick *aio;
if (parent) {
fullpath[i] = path_make("%s/%s", parent, argv[i]);
if (!fullpath[i]) {
MARS_ERR("cannot make path '%s/%s'\n", parent, argv[i]);
goto done;
}
} else {
fullpath[i] = argv[i];
}
aio = aio =
make_brick_all(global, make_brick_all(global,
parent, NULL,
parent,
10 * HZ, 10 * HZ,
target, NULL,
(const struct generic_brick_type*)&device_aio_brick_type, (const struct generic_brick_type*)&device_aio_brick_type,
(const struct generic_brick_type*[]){}, (const struct generic_brick_type*[]){},
"/%s", fullpath[i],
(const char *[]){}, (const char *[]){},
0, 0);
target);
if (!aio) { if (!aio) {
MARS_DBG("cannot instantiate '%s'\n", target); MARS_DBG("cannot instantiate '%s'\n", fullpath[i]);
goto done; goto done;
} }
output[i] = aio->outputs[0]; output[i] = aio->outputs[0];
@ -169,17 +178,19 @@ int __make_copy(
copy = copy =
make_brick_all(global, make_brick_all(global,
parent,
belongs, belongs,
1, 0,
path, path,
(const struct generic_brick_type*)&copy_brick_type, (const struct generic_brick_type*)&copy_brick_type,
(const struct generic_brick_type*[]){NULL,NULL,NULL,NULL}, (const struct generic_brick_type*[]){NULL,NULL,NULL,NULL},
"/copy%s", "%s",
(const char *[]){"/%s", "/%s", "/%s", "/%s"}, (const char *[]){"%s", "%s", "%s", "%s"},
4, 4,
path, path,
argv[0], argv[0], argv[1], argv[1]); fullpath[0],
fullpath[0],
fullpath[1],
fullpath[1]);
if (!copy) { if (!copy) {
MARS_DBG("fail '%s'\n", path); MARS_DBG("fail '%s'\n", path);
goto done; goto done;
@ -203,12 +214,12 @@ int __make_copy(
if (start_pos != -1) { if (start_pos != -1) {
_copy->copy_start = start_pos; _copy->copy_start = start_pos;
if (unlikely(info[0].current_size != info[1].current_size)) { if (unlikely(info[0].current_size != info[1].current_size)) {
MARS_ERR("oops, devices have different size %lld != %lld at '%s'\n", info[0].current_size, info[1].current_size, parent->d_path); MARS_ERR("oops, devices have different size %lld != %lld at '%s'\n", info[0].current_size, info[1].current_size, path);
status = -EINVAL; status = -EINVAL;
goto done; goto done;
} }
if (unlikely(start_pos > info[0].current_size)) { if (unlikely(start_pos > info[0].current_size)) {
MARS_ERR("bad start position %lld is larger than actual size %lld on '%s'\n", start_pos, info[0].current_size, parent->d_path); MARS_ERR("bad start position %lld is larger than actual size %lld on '%s'\n", start_pos, info[0].current_size, path);
status = -EINVAL; status = -EINVAL;
goto done; goto done;
} }
@ -225,6 +236,10 @@ int __make_copy(
done: done:
MARS_DBG("status = %d\n", status); MARS_DBG("status = %d\n", status);
for (i = 0; i < 2; i++) {
if (fullpath[i] && fullpath[i] != argv[i])
kfree(fullpath[i]);
}
return status; return status;
} }
@ -244,19 +259,21 @@ struct mars_peerinfo {
}; };
static static
int _update_file(struct mars_global *global, struct mars_dent *parent, const char *peer, const char *path) int _update_file(struct mars_global *global, const char *path, const char *peer)
{ {
char *tmp = path_make(NULL, "%s@%s", path, peer); const char *tmp = path_make("%s@%s", path, peer);
const char *argv[2] = { tmp, path}; const char *argv[2] = { tmp, path };
int status = -ENOMEM; int status = -ENOMEM;
if (unlikely(!tmp)) if (unlikely(!tmp))
goto done; goto done;
status = __make_copy(global, parent, parent, tmp, argv, -1, NULL); MARS_DBG("tmp = '%s' path = '%s'\n", tmp, path);
kfree(tmp); status = __make_copy(global, NULL, path, NULL, argv, -1, NULL);
done: done:
if (tmp)
kfree(tmp);
return status; return status;
} }
@ -347,13 +364,15 @@ int run_bones(void *buf, struct mars_dent *dent)
if (!stat_ok || local_stat.size < src_size) { if (!stat_ok || local_stat.size < src_size) {
// check whether connect is allowed // check whether connect is allowed
char *connect_path = _backskip_replace(dent->d_path, '/', false, "/connect-%d", my_id()); char *connect_path = _backskip_replace(dent->d_path, '/', false, "/connect-%s", my_id());
if (likely(connect_path)) { if (likely(connect_path)) {
struct kstat connect_stat = {}; struct kstat connect_stat = {};
status = mars_lstat(connect_path, &connect_stat); status = mars_lstat(connect_path, &connect_stat);
MARS_DBG("connect_path = '%s' stat status = %d uid = %d\n", connect_path, status, connect_stat.uid);
kfree(connect_path); kfree(connect_path);
if (status >= 0 && !connect_stat.uid) { if (status >= 0 && !connect_stat.uid) {
status = _update_file(peer->global, dent->d_parent, peer->peer, dent->d_name); // parent is not available here
status = _update_file(peer->global, dent->d_path, peer->peer);
MARS_DBG("update '%s' from peer '%s' status = %d\n", dent->d_path, peer->peer, status); MARS_DBG("update '%s' from peer '%s' status = %d\n", dent->d_path, peer->peer, status);
if (status >= 0) { if (status >= 0) {
char *tmp = _backskip_replace(dent->d_path, '-', false, "-%s", my_id()); char *tmp = _backskip_replace(dent->d_path, '-', false, "-%s", my_id());
@ -643,9 +662,11 @@ void _create_new_logfile(char *path)
set_fs(get_ds()); set_fs(get_ds());
f = filp_open(path, flags, prot); f = filp_open(path, flags, prot);
set_fs(oldfs); set_fs(oldfs);
if (f) { if (IS_ERR(f)) {
filp_close(f, NULL); MARS_ERR("could not create logfile '%s' status = %d\n", path, (int)PTR_ERR(f));
} else {
MARS_DBG("created empty logfile '%s'\n", path); MARS_DBG("created empty logfile '%s'\n", path);
filp_close(f, NULL);
mars_trigger(); mars_trigger();
} }
} }
@ -658,10 +679,10 @@ int _update_link(struct mars_rotate *rot, struct mars_dent *parent, int sequence
char *new; char *new;
int status = -ENOMEM; int status = -ENOMEM;
old = path_make(NULL, "log-%09d-%s,%lld", sequence, my_id(), pos); old = path_make("log-%09d-%s,%lld", sequence, my_id(), pos);
if (!old) if (!old)
goto out_old; goto out_old;
new = path_make(parent, "/replay-%s", my_id()); new = path_make("%s/replay-%s", parent->d_path, my_id());
if (!new) if (!new)
goto out_new; goto out_new;
@ -723,7 +744,7 @@ int make_log_init(void *buf, struct mars_dent *parent)
/* Fetch the replay status symlink. /* Fetch the replay status symlink.
* It must exist, and its value will control everything. * It must exist, and its value will control everything.
*/ */
replay_path = path_make(parent, "/replay-%s", my_id()); replay_path = path_make("%s/replay-%s", parent->d_path, my_id());
if (unlikely(!replay_path)) { if (unlikely(!replay_path)) {
MARS_ERR("cannot make path\n"); MARS_ERR("cannot make path\n");
status = -ENOMEM; status = -ENOMEM;
@ -745,7 +766,7 @@ int make_log_init(void *buf, struct mars_dent *parent)
/* Fetch the referenced AIO dentry. /* Fetch the referenced AIO dentry.
*/ */
aio_path = path_make(parent, "/%s", replay_link->d_argv[0]); aio_path = path_make("%s/%s", parent->d_path, replay_link->d_argv[0]);
if (unlikely(!aio_path)) { if (unlikely(!aio_path)) {
MARS_ERR("cannot make path\n"); MARS_ERR("cannot make path\n");
status = -ENOMEM; status = -ENOMEM;
@ -767,7 +788,6 @@ int make_log_init(void *buf, struct mars_dent *parent)
*/ */
aio_brick = aio_brick =
make_brick_all(global, make_brick_all(global,
NULL,
aio_dent, aio_dent,
10 * HZ, 10 * HZ,
aio_path, aio_path,
@ -802,15 +822,16 @@ int make_log_init(void *buf, struct mars_dent *parent)
*/ */
trans_brick = trans_brick =
make_brick_all(global, make_brick_all(global,
parent,
parent, parent,
0, 0,
aio_path, aio_path,
(const struct generic_brick_type*)&trans_logger_brick_type, (const struct generic_brick_type*)&trans_logger_brick_type,
(const struct generic_brick_type*[]){(const struct generic_brick_type*)&device_aio_brick_type}, (const struct generic_brick_type*[]){(const struct generic_brick_type*)&device_aio_brick_type},
"/logger", "%s/logger",
(const char *[]){"/data-%s"}, (const char *[]){"%s/data-%s"},
1, 1,
parent->d_path,
parent->d_path,
my_id()); my_id());
status = -ENOENT; status = -ENOENT;
if (!trans_brick) { if (!trans_brick) {
@ -1032,7 +1053,6 @@ int _start_trans(struct mars_rotate *rot)
*/ */
rot->relevant_brick = rot->relevant_brick =
make_brick_all(rot->global, make_brick_all(rot->global,
NULL,
rot->relevant_log, rot->relevant_log,
10 * HZ, 10 * HZ,
rot->relevant_log->d_path, rot->relevant_log->d_path,
@ -1136,7 +1156,7 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *parent)
* normally userspace should control what happens in MARS. * normally userspace should control what happens in MARS.
*/ */
if (!rot->relevant_log && rot->is_primary && !rot->has_error && rot->max_sequence > 0 && !rot->create_once) { // try to create an empty logfile if (!rot->relevant_log && rot->is_primary && !rot->has_error && rot->max_sequence > 0 && !rot->create_once) { // try to create an empty logfile
char *tmp = path_make(parent, "/log-%09d-%s", rot->max_sequence + 1, my_id()); char *tmp = path_make("%s/log-%09d-%s", parent->d_path, rot->max_sequence + 1, my_id());
if (likely(tmp)) { if (likely(tmp)) {
_create_new_logfile(tmp); _create_new_logfile(tmp);
kfree(tmp); kfree(tmp);
@ -1210,7 +1230,6 @@ int make_aio(void *buf, struct mars_dent *dent)
dent->d_kill_inactive = true; dent->d_kill_inactive = true;
brick = brick =
make_brick_all(global, make_brick_all(global,
NULL,
dent, dent,
10 * HZ, 10 * HZ,
dent->d_path, dent->d_path,
@ -1269,16 +1288,17 @@ static int make_dev(void *buf, struct mars_dent *dent)
dev_brick = dev_brick =
make_brick_all(global, make_brick_all(global,
dent->d_parent,
dent, dent,
10 * HZ, 10 * HZ,
dent->d_argv[0], dent->d_argv[0],
(const struct generic_brick_type*)&if_device_brick_type, (const struct generic_brick_type*)&if_device_brick_type,
(const struct generic_brick_type*[]){(const struct generic_brick_type*)&trans_logger_brick_type}, (const struct generic_brick_type*[]){(const struct generic_brick_type*)&trans_logger_brick_type},
"/linuxdev-%s", "%s/linuxdev-%s",
(const char *[]){"/logger"}, (const char *[]){"%s/logger"},
1, 1,
dent->d_argv[0]); dent->d_parent->d_path,
dent->d_argv[0],
dent->d_parent->d_path);
if (!dev_brick) { if (!dev_brick) {
MARS_DBG("fail\n"); MARS_DBG("fail\n");
return -1; return -1;
@ -1304,15 +1324,15 @@ static int _make_direct(void *buf, struct mars_dent *dent)
} }
brick = brick =
make_brick_all(global, make_brick_all(global,
dent->d_parent,
dent, dent,
10 * HZ, 10 * HZ,
dent->d_argv[0], dent->d_argv[0],
(const struct generic_brick_type*)&device_aio_brick_type, (const struct generic_brick_type*)&device_aio_brick_type,
(const struct generic_brick_type*[]){}, (const struct generic_brick_type*[]){},
"/%s", "%s/%s",
(const char *[]){}, (const char *[]){},
0, 0,
dent->d_parent->d_path,
dent->d_argv[0]); dent->d_argv[0]);
status = -1; status = -1;
if (!brick) { if (!brick) {
@ -1322,16 +1342,18 @@ static int _make_direct(void *buf, struct mars_dent *dent)
brick = brick =
make_brick_all(global, make_brick_all(global,
dent->d_parent,
dent, dent,
10 * HZ, 10 * HZ,
dent->d_argv[1], dent->d_argv[1],
(const struct generic_brick_type*)&if_device_brick_type, (const struct generic_brick_type*)&if_device_brick_type,
(const struct generic_brick_type*[]){NULL}, (const struct generic_brick_type*[]){NULL},
"/linuxdev-%s", "%s/linuxdev-%s",
(const char *[]){dent->d_argv[0]}, (const char *[]){ "%s/%s" },
1, 1,
dent->d_argv[1]), dent->d_parent->d_path,
dent->d_argv[1],
dent->d_parent->d_path,
dent->d_argv[0]),
status = -1; status = -1;
if (!brick) { if (!brick) {
MARS_DBG("fail\n"); MARS_DBG("fail\n");
@ -1357,7 +1379,7 @@ static int _make_copy(void *buf, struct mars_dent *dent)
goto done; goto done;
} }
status = __make_copy(global, dent->d_parent, dent, dent->d_path, (const char**)dent->d_argv, -1, NULL); status = __make_copy(global, dent, dent->d_path, dent->d_parent->d_path, (const char**)dent->d_argv, -1, NULL);
done: done:
MARS_DBG("status = %d\n", status); MARS_DBG("status = %d\n", status);
@ -1392,7 +1414,7 @@ static int make_sync(void *buf, struct mars_dent *dent)
/* Determine peer /* Determine peer
*/ */
tmp = path_make(dent->d_parent, "/connect-%s", my_id()); tmp = path_make("%s/connect-%s", dent->d_parent->d_path, my_id());
status = -ENOMEM; status = -ENOMEM;
if (unlikely(!tmp)) if (unlikely(!tmp))
goto done; goto done;
@ -1412,8 +1434,8 @@ static int make_sync(void *buf, struct mars_dent *dent)
/* Start copy /* Start copy
*/ */
src = path_make(NULL, "data-%s@%s", peer, peer); src = path_make("data-%s@%s", peer, peer);
dst = path_make(NULL, "data-%s", my_id()); dst = path_make("data-%s", my_id());
status = -ENOMEM; status = -ENOMEM;
if (unlikely(!src || !dst)) if (unlikely(!src || !dst))
goto done; goto done;
@ -1422,7 +1444,7 @@ static int make_sync(void *buf, struct mars_dent *dent)
{ {
const char *argv[2] = { src, dst }; const char *argv[2] = { src, dst };
status = __make_copy(global, dent->d_parent, dent, dent->d_path, argv, start_pos, &copy); status = __make_copy(global, dent, dent->d_path, dent->d_parent->d_path, argv, start_pos, &copy);
} }
/* Update syncstatus symlink /* Update syncstatus symlink
@ -1430,8 +1452,8 @@ static int make_sync(void *buf, struct mars_dent *dent)
if (status >= 0 && copy && copy->power.button && copy->power.led_on) { if (status >= 0 && copy && copy->power.button && copy->power.led_on) {
kfree(src); kfree(src);
kfree(dst); kfree(dst);
src = path_make(NULL, "%lld", copy->copy_last); src = path_make("%lld", copy->copy_last);
dst = path_make(dent->d_parent, "/syncstatus-%s", my_id()); dst = path_make("%s/syncstatus-%s", dent->d_parent->d_path, my_id());
status = -ENOMEM; status = -ENOMEM;
if (unlikely(!src || !dst)) if (unlikely(!src || !dst))
goto done; goto done;
@ -1825,7 +1847,7 @@ void _show_status(struct mars_global *global)
MARS_DBG("status symlink '%s' -> '%s' status = %d\n", dst, src, status); MARS_DBG("status symlink '%s' -> '%s' status = %d\n", dst, src, status);
if (test->status_level > 1) { if (test->status_level > 1) {
char perc[8]; char perc[8];
char *dst2 = path_make(NULL, "%s.percent", dst); char *dst2 = path_make("%s.percent", dst);
if (likely(dst2)) { if (likely(dst2)) {
snprintf(perc, sizeof(perc), "%d", test->power.percent_done); snprintf(perc, sizeof(perc), "%d", test->power.percent_done);
status = mars_symlink(perc, dst2, NULL, 0); status = mars_symlink(perc, dst2, NULL, 0);
@ -1838,6 +1860,44 @@ void _show_status(struct mars_global *global)
up(&global->mutex); up(&global->mutex);
} }
#ifdef STAT_DEBUGGING
static
void _show_statist(struct mars_global *global)
{
struct list_head *tmp;
int dent_count = 0;
int brick_count = 0;
down(&global->mutex);
MARS_STAT("----------- lists:\n");
for (tmp = global->dent_anchor.next; tmp != &global->dent_anchor; tmp = tmp->next) {
struct mars_dent *dent;
dent = container_of(tmp, struct mars_dent, dent_link);
MARS_STAT("dent '%s'\n", dent->d_path);
dent_count++;
}
for (tmp = global->brick_anchor.next; tmp != &global->brick_anchor; tmp = tmp->next) {
struct mars_brick *test;
int i;
test = container_of(tmp, struct mars_brick, global_brick_link);
MARS_STAT("brick type = %s path = '%s' name = '%s' level = %d button = %d off = %d on = %d\n", test->type->type_name, test->brick_path, test->brick_name, test->status_level, test->power.button, test->power.led_off, test->power.led_on);
brick_count++;
for (i = 0; i < test->nr_inputs; i++) {
struct mars_input *input = test->inputs[i];
struct mars_output *output = input ? input->connect : NULL;
if (output) {
MARS_STAT(" input %d connected with %s path = '%s' name = '%s'\n", i, output->brick->type->type_name, output->brick->brick_path, output->brick->brick_name);
} else {
MARS_STAT(" input %d not connected\n", i);
}
}
}
up(&global->mutex);
MARS_INF("----------- STATISTICS: %d dents, %d bricks\n", dent_count, brick_count);
}
#endif
static int light_thread(void *data) static int light_thread(void *data)
{ {
char *id = my_id(); char *id = my_id();
@ -1871,36 +1931,14 @@ static int light_thread(void *data)
MARS_DBG("worker status = %d\n", status); MARS_DBG("worker status = %d\n", status);
_show_status(&global); _show_status(&global);
#ifdef STAT_DEBUGGING
_show_statist(&global);
#endif
msleep(1000);
wait_event_interruptible_timeout(global.main_event, global.main_trigger, 30 * HZ); wait_event_interruptible_timeout(global.main_event, global.main_trigger, 30 * HZ);
global.main_trigger = false; global.main_trigger = false;
#ifdef STAT_DEBUGGING
{
struct list_head *tmp;
int dent_count = 0;
int brick_count = 0;
down(&global.mutex);
MARS_STAT("----------- lists:\n");
for (tmp = global.dent_anchor.next; tmp != &global.dent_anchor; tmp = tmp->next) {
struct mars_dent *dent;
dent = container_of(tmp, struct mars_dent, dent_link);
MARS_STAT("dent '%s'\n", dent->d_path);
dent_count++;
}
for (tmp = global.brick_anchor.next; tmp != &global.brick_anchor; tmp = tmp->next) {
struct mars_brick *test;
test = container_of(tmp, struct mars_brick, global_brick_link);
MARS_STAT("brick type = %s path = '%s' name = '%s' level = %d button = %d on = %d off = %d\n", test->type->type_name, test->brick_path, test->brick_name, test->status_level, test->power.button, test->power.led_on, test->power.led_off);
brick_count++;
}
up(&global.mutex);
MARS_INF("----------- STATISTICS: %d dents, %d bricks\n", dent_count, brick_count);
}
msleep(500);
#endif
} }
done: done:
@ -1944,6 +1982,10 @@ static int __init init_light(void)
return 0; return 0;
} }
// force module loading
const void *dummy1 = &client_brick_type;
const void *dummy2 = &server_brick_type;
MODULE_DESCRIPTION("MARS Light"); MODULE_DESCRIPTION("MARS Light");
MODULE_AUTHOR("Thomas Schoebel-Theuer <tst@1und1.de>"); MODULE_AUTHOR("Thomas Schoebel-Theuer <tst@1und1.de>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -47,7 +47,7 @@ char *mars_translate_hostname(struct mars_global *global, const char *name)
if (unlikely(!global)) { if (unlikely(!global)) {
goto done; goto done;
} }
tmp = path_make(NULL, "/mars/ips/ip-%s", name); tmp = path_make("/mars/ips/ip-%s", name);
if (unlikely(!tmp)) { if (unlikely(!tmp)) {
goto done; goto done;
} }
@ -192,18 +192,13 @@ int mars_send(struct socket **sock, void *buf, int len)
//MARS_IO("buf = %p, len = %d\n", buf, len); //MARS_IO("buf = %p, len = %d\n", buf, len);
while (sent < len) { while (sent < len) {
mm_segment_t oldfs;
if (unlikely(!*sock)) { if (unlikely(!*sock)) {
MARS_ERR("socket has disappeared\n"); MARS_ERR("socket has disappeared\n");
status = -EIDRM; status = -EIDRM;
goto done; goto done;
} }
oldfs = get_fs();
set_fs(get_ds());
status = kernel_sendmsg(*sock, &msg, &iov, 1, len); status = kernel_sendmsg(*sock, &msg, &iov, 1, len);
set_fs(oldfs);
if (status == -EAGAIN) { if (status == -EAGAIN) {
msleep(50); msleep(50);
@ -248,7 +243,6 @@ int mars_recv(struct socket **sock, void *buf, int minlen, int maxlen)
} }
while (done < minlen) { while (done < minlen) {
mm_segment_t oldfs;
struct kvec iov = { struct kvec iov = {
.iov_base = buf + done, .iov_base = buf + done,
.iov_len = maxlen - done, .iov_len = maxlen - done,
@ -267,10 +261,7 @@ int mars_recv(struct socket **sock, void *buf, int minlen, int maxlen)
MARS_IO("done %d, fetching %d bytes\n", done, maxlen-done); MARS_IO("done %d, fetching %d bytes\n", done, maxlen-done);
oldfs = get_fs();
set_fs(get_ds());
status = kernel_recvmsg(*sock, &msg, &iov, 1, maxlen-done, msg.msg_flags); status = kernel_recvmsg(*sock, &msg, &iov, 1, maxlen-done, msg.msg_flags);
set_fs(oldfs);
if (status == -EAGAIN) { if (status == -EAGAIN) {
#if 0 #if 0

View File

@ -29,6 +29,7 @@ static struct task_struct *server_thread = NULL;
///////////////////////// own helper functions //////////////////////// ///////////////////////// own helper functions ////////////////////////
static int server_checker(const char *path, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial) static int server_checker(const char *path, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial)
{ {
return 0; return 0;
@ -55,6 +56,7 @@ static void server_endio(struct generic_callback *cb)
CHECK_PTR(brick, err); CHECK_PTR(brick, err);
sock = mref_a->sock; sock = mref_a->sock;
CHECK_PTR(sock, err); CHECK_PTR(sock, err);
CHECK_PTR(*sock, err);
down(&brick->socket_sem); down(&brick->socket_sem);
status = mars_send_cb(sock, mref); status = mars_send_cb(sock, mref);
@ -90,7 +92,7 @@ static int handler_thread(void *data)
status = mars_recv_struct(sock, &cmd, mars_cmd_meta); status = mars_recv_struct(sock, &cmd, mars_cmd_meta);
if (status < 0) { if (status < 0) {
MARS_ERR("command status = %d\n", status); MARS_ERR("bad command status = %d\n", status);
break; break;
} }
@ -161,7 +163,6 @@ static int handler_thread(void *data)
//prev = mars_find_brick(mars_global, NULL, cmd.cmd_str1); //prev = mars_find_brick(mars_global, NULL, cmd.cmd_str1);
prev = prev =
make_brick_all(mars_global, make_brick_all(mars_global,
NULL,
NULL, NULL,
10 * HZ, 10 * HZ,
path, path,
@ -231,16 +232,19 @@ static int handler_thread(void *data)
break; break;
} }
//kernel_sock_shutdown(*sock, SHUT_WR); kernel_sock_shutdown(*sock, SHUT_WR);
sock_release(*sock); //sock_release(*sock);
//cleanup_mm(); //cleanup_mm();
done: done:
MARS_DBG("handler_thread terminating, status = %d\n", status); MARS_DBG("handler_thread terminating, status = %d\n", status);
do { do {
int status = mars_kill_brick((void*)brick); int status = mars_kill_brick((void*)brick);
if (status >= 0) if (status >= 0) {
//if(*sock)
//sock_release(*sock);
break; break;
}
if (status >= 0 || max_round-- < 0) { if (status >= 0 || max_round-- < 0) {
MARS_INF("not dead, giving up....\n"); MARS_INF("not dead, giving up....\n");
break; break;
@ -444,8 +448,9 @@ static int _server_thread(void *data)
err: err:
if (new_socket) { if (new_socket) {
kernel_sock_shutdown(new_socket, SHUT_WR); kernel_sock_shutdown(new_socket, SHUT_WR);
sock_release(new_socket); //sock_release(new_socket);
} }
msleep(3000);
} }
MARS_INF("-------- cleaning up ----------\n"); MARS_INF("-------- cleaning up ----------\n");
@ -500,7 +505,7 @@ static void __exit exit_server(void)
} }
kthread_stop(server_thread); kthread_stop(server_thread);
if (server_socket && !server_thread) { if (server_socket && !server_thread) {
sock_release(server_socket); //sock_release(server_socket);
server_socket = NULL; server_socket = NULL;
} }
} }

View File

@ -59,6 +59,10 @@ sub get_size {
# helpers # helpers
sub _trigger {
system("echo 1 > /proc/sys/mars 2>/dev/null");
}
sub _switch { sub _switch {
my ($path, $on) = @_; my ($path, $on) = @_;
@ -369,3 +373,4 @@ if($res eq "all") {
do_res($cmd, $res, @ARGV); do_res($cmd, $res, @ARGV);
} }
_trigger();