statuslinks will be updated more often

This commit is contained in:
Thomas Schoebel-Theuer 2011-09-27 13:57:04 +02:00 committed by Thomas Schoebel-Theuer
parent ef55a73ad9
commit 3715fdf93d
3 changed files with 154 additions and 113 deletions

1
mars.h
View File

@ -165,6 +165,7 @@ struct mars_info {
struct list_head dent_brick_link; \
const char *brick_path; \
struct mars_global *global; \
void (*show_status)(struct mars_brick *brick, bool shutdown); \
int status_level; \
struct mars_brick {

View File

@ -365,6 +365,125 @@ done:
return status;
}
///////////////////////////////////////////////////////////////////////
// needed for logfile rotation
struct mars_rotate {
struct mars_global *global;
struct mars_dent *replay_link;
struct mars_dent *aio_dent;
struct aio_brick *aio_brick;
struct mars_info aio_info;
struct trans_logger_brick *trans_brick;
struct mars_dent *relevant_log;
struct mars_brick *relevant_brick;
struct mars_dent *next_relevant_log;
struct mars_dent *current_log;
struct mars_dent *prev_log;
struct mars_dent *next_log;
struct if_brick *if_brick;
long long last_jiffies;
loff_t start_pos;
loff_t end_pos;
int max_sequence;
bool has_error;
bool try_sync;
bool do_replay;
bool todo_primary;
bool is_primary;
};
///////////////////////////////////////////////////////////////////////
// status display
static
int _show_actual(const char *path, const char *name, bool val)
{
char *src;
char *dst = NULL;
int status = -EINVAL;
src = val ? "1" : "0";
dst = path_make("%s/actual-%s/%s", path, my_id(), name);
status = -ENOMEM;
if (!dst)
goto done;
MARS_DBG("symlink '%s' -> '%s'\n", dst, src);
status = mars_symlink(src, dst, NULL, 0);
done:
brick_string_free(dst);
return status;
}
static
void _show_primary(struct mars_rotate *rot, struct mars_dent *parent)
{
int status;
if (!rot || !parent) {
return;
}
status = _show_actual(parent->d_path, "is-primary", rot->is_primary);
}
static
void _show_brick_status(struct mars_brick *test, bool shutdown)
{
const char *path;
char *src;
char *dst;
int status;
path = test->brick_path;
if (!path) {
MARS_WRN("bad path\n");
return;
}
if (*path != '/') {
MARS_WRN("bogus path '%s'\n", path);
return;
}
src = (test->power.led_on && !shutdown) ? "1" : "0";
dst = backskip_replace(path, '/', true, "/actual-%s/", my_id());
if (!dst) {
return;
}
status = mars_symlink(src, dst, NULL, 0);
MARS_DBG("status symlink '%s' -> '%s' status = %d\n", dst, src, status);
if (test->status_level > 1) {
char perc[8];
char *dst2 = path_make("%s.percent", dst);
if (likely(dst2)) {
snprintf(perc, sizeof(perc), "%d", test->power.percent_done);
status = mars_symlink(perc, dst2, NULL, 0);
MARS_DBG("percent symlink '%s' -> '%s' status = %d\n", dst2, src, status);
brick_string_free(dst2);
}
}
brick_string_free(dst);
}
static
void _show_status_all(struct mars_global *global)
{
struct list_head *tmp;
down_read(&global->brick_mutex);
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);
if (test->status_level <= 0)
continue;
_show_brick_status(test, false);
}
up_read(&global->brick_mutex);
}
///////////////////////////////////////////////////////////////////////
static
@ -450,6 +569,7 @@ int __make_copy(
MARS_DBG("creation of copy brick '%s' failed\n", copy_path);
goto done;
}
copy->show_status = _show_brick_status;
copy->status_level = 2;
_copy = (void*)copy;
if (__copy)
@ -468,35 +588,6 @@ done:
///////////////////////////////////////////////////////////////////////
// needed for logfile rotation
struct mars_rotate {
struct mars_global *global;
struct mars_dent *replay_link;
struct mars_dent *aio_dent;
struct aio_brick *aio_brick;
struct mars_info aio_info;
struct trans_logger_brick *trans_brick;
struct mars_dent *relevant_log;
struct mars_brick *relevant_brick;
struct mars_dent *next_relevant_log;
struct mars_dent *current_log;
struct mars_dent *prev_log;
struct mars_dent *next_log;
struct if_brick *if_brick;
long long last_jiffies;
loff_t start_pos;
loff_t end_pos;
int max_sequence;
bool has_error;
bool try_sync;
bool do_replay;
bool todo_primary;
bool is_primary;
};
///////////////////////////////////////////////////////////////////////
// remote workers
struct mars_peerinfo {
@ -1035,7 +1126,7 @@ int kill_any(void *buf, struct mars_dent *dent)
MARS_DBG("killing dent = '%s'\n", dent->d_path);
mars_kill_dent(dent);
return 0;
return 1;
}
///////////////////////////////////////////////////////////////////////
@ -1999,31 +2090,6 @@ done:
return status;
}
static
void _show_primary(struct mars_rotate *rot, struct mars_dent *parent)
{
char *src;
char *dst;
bool ok;
int status;
if (!rot || !parent) {
return;
}
ok = rot->is_primary;
src = ok ? "1" : "0";
dst = path_make("%s/actual-%s/is-primary", parent->d_path, my_id());
if (!dst)
return;
MARS_DBG("symlink '%s' -> '%s'\n", dst, src);
status = mars_symlink(src, dst, NULL, 0);
if (dst)
brick_string_free(dst);
}
static
int make_dev(void *buf, struct mars_dent *dent)
{
@ -2039,10 +2105,6 @@ int make_dev(void *buf, struct mars_dent *dent)
MARS_ERR("nothing to do\n");
return -EINVAL;
}
if (!global->global_power.button) {
MARS_DBG("nothing to do\n");
goto done;
}
rot = parent->d_private;
if (!rot) {
MARS_DBG("nothing to do\n");
@ -2052,6 +2114,11 @@ int make_dev(void *buf, struct mars_dent *dent)
MARS_DBG("transaction logger does not exist\n");
goto done;
}
if (!global->global_power.button &&
(!rot->if_brick || rot->if_brick->power.led_off)) {
MARS_DBG("nothing to do\n");
goto done;
}
status = _parse_args(dent, dent->new_link, 1);
if (status < 0) {
@ -2064,6 +2131,9 @@ int make_dev(void *buf, struct mars_dent *dent)
(rot->todo_primary &&
!rot->trans_brick->do_replay &&
rot->trans_brick->power.led_on);
if (!global->global_power.button) {
switch_on = false;
}
dev_brick =
make_brick_all(global,
@ -2076,7 +2146,7 @@ int make_dev(void *buf, struct mars_dent *dent)
(const struct generic_brick_type*)&if_brick_type,
(const struct generic_brick_type*[]){(const struct generic_brick_type*)&trans_logger_brick_type},
switch_on ? NULL : "", // KLUDGE
"%s/linuxdev-%s",
"%s/device-%s",
(const char *[]){"%s/logger"},
1,
parent->d_path,
@ -2087,6 +2157,7 @@ int make_dev(void *buf, struct mars_dent *dent)
MARS_DBG("device not shown\n");
goto done;
}
dev_brick->show_status = _show_brick_status;
dev_brick->status_level = 1;
_dev_brick = (void*)dev_brick;
#if 0
@ -2103,6 +2174,20 @@ done:
return status;
}
static
int kill_dev(void *buf, struct mars_dent *dent)
{
struct mars_dent *parent = dent->d_parent;
int status = kill_any(buf, dent);
if (status > 0 && parent) {
struct mars_rotate *rot = parent->d_private;
if (rot) {
rot->if_brick = NULL;
}
}
return status;
}
static int _make_direct(void *buf, struct mars_dent *dent)
{
struct mars_global *global = buf;
@ -2161,7 +2246,7 @@ static int _make_direct(void *buf, struct mars_dent *dent)
(const struct generic_brick_type*)&if_brick_type,
(const struct generic_brick_type*[]){NULL},
NULL,
"%s/linuxdev-%s",
"%s/directdevice-%s",
(const char *[]){ "%s" },
1,
dent->d_parent->d_path,
@ -2630,7 +2715,7 @@ static const struct light_class light_classes[] = {
#ifdef RUN_DEVICE
.cl_forward = make_dev,
#endif
.cl_backward = kill_any,
.cl_backward = kill_dev,
},
{}
};
@ -2782,55 +2867,6 @@ static int light_worker(struct mars_global *global, struct mars_dent *dent, bool
return 0;
}
static
void _show_status(struct mars_global *global)
{
struct list_head *tmp;
down_read(&global->brick_mutex);
for (tmp = global->brick_anchor.next; tmp != &global->brick_anchor; tmp = tmp->next) {
struct mars_brick *test;
const char *path;
char *src;
char *dst;
int status;
test = container_of(tmp, struct mars_brick, global_brick_link);
if (test->status_level <= 0)
continue;
path = test->brick_path;
if (!path) {
MARS_DBG("bad path\n");
continue;
}
if (*path != '/') {
MARS_DBG("bogus path '%s'\n", path);
continue;
}
src = test->power.led_on ? "1" : "0";
dst = backskip_replace(path, '/', true, "/actual-%s/", my_id());
if (!dst)
continue;
status = mars_symlink(src, dst, NULL, 0);
MARS_DBG("status symlink '%s' -> '%s' status = %d\n", dst, src, status);
if (test->status_level > 1) {
char perc[8];
char *dst2 = path_make("%s.percent", dst);
if (likely(dst2)) {
snprintf(perc, sizeof(perc), "%d", test->power.percent_done);
status = mars_symlink(perc, dst2, NULL, 0);
MARS_DBG("percent symlink '%s' -> '%s' status = %d\n", dst2, src, status);
brick_string_free(dst2);
}
}
brick_string_free(dst);
}
up_read(&global->brick_mutex);
}
#ifdef STAT_DEBUGGING
static
void _show_one(struct mars_brick *test, int *brick_count)
@ -2948,7 +2984,7 @@ static int light_thread(void *data)
status = mars_dent_work(&_global, "/mars", sizeof(struct mars_dent), light_checker, light_worker, &_global, 3);
MARS_DBG("worker status = %d\n", status);
_show_status(&_global);
_show_status_all(&_global);
#ifdef STAT_DEBUGGING
_show_statist(&_global);
#endif
@ -2966,7 +3002,7 @@ done:
mars_free_dent_all(&_global, &_global.dent_anchor);
mars_kill_brick_all(&_global, &_global.brick_anchor, false);
_show_status(&_global);
_show_status_all(&_global);
#ifdef STAT_DEBUGGING
_show_statist(&_global);
#endif

View File

@ -933,6 +933,10 @@ int mars_kill_brick(struct mars_brick *brick)
up_write(&global->brick_mutex);
}
if (brick->show_status) {
brick->show_status(brick, true);
}
if (unlikely(brick->nr_outputs > 0 && brick->outputs[0] && brick->outputs[0]->nr_connected)) {
MARS_ERR("sorry, output is in use '%s'\n", SAFE_STR(brick->brick_path));
goto done;