mirror of https://github.com/schoebel/mars
import mars-82.tgz
This commit is contained in:
parent
ee9a1d47ff
commit
9b1410c0ef
155
brick.c
155
brick.c
|
@ -94,52 +94,62 @@ int generic_brick_init_full(
|
|||
BRICK_DBG("generic_brick_init_full: switch to default input_types\n");
|
||||
input_types = brick_type->default_input_types;
|
||||
names = brick_type->default_input_names;
|
||||
if (unlikely(!input_types)) {
|
||||
BRICK_ERR("no input types specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (input_types) {
|
||||
BRICK_DBG("generic_brick_init_full: input_types\n");
|
||||
brick->inputs = data;
|
||||
data += sizeof(void*) * brick_type->max_inputs;
|
||||
size -= sizeof(void*) * brick_type->max_inputs;
|
||||
if (size < 0) {
|
||||
BRICK_DBG("generic_brick_init_full: input_types\n");
|
||||
brick->inputs = data;
|
||||
data += sizeof(void*) * brick_type->max_inputs;
|
||||
size -= sizeof(void*) * brick_type->max_inputs;
|
||||
if (size < 0) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (i = 0; i < brick_type->max_inputs; i++) {
|
||||
struct generic_input *input = data;
|
||||
const struct generic_input_type *type = *input_types++;
|
||||
if (!type || type->input_size <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
BRICK_DBG("generic_brick_init_full: calling generic_input_init()\n");
|
||||
status = generic_input_init(brick, i, type, input, (names && *names) ? *names++ : type->type_name);
|
||||
if (status < 0)
|
||||
return status;
|
||||
data += type->input_size;
|
||||
size -= type->input_size;
|
||||
if (size < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (i = 0; i < brick_type->max_inputs; i++) {
|
||||
struct generic_input *input = data;
|
||||
const struct generic_input_type *type = *input_types++;
|
||||
BRICK_DBG("generic_brick_init_full: calling generic_input_init()\n");
|
||||
status = generic_input_init(brick, i, type, input, (names && *names) ? *names++ : type->type_name);
|
||||
if (status)
|
||||
return status;
|
||||
data += type->input_size;
|
||||
size -= type->input_size;
|
||||
if (size < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (!output_types) {
|
||||
BRICK_DBG("generic_brick_init_full: switch to default output_types\n");
|
||||
output_types = brick_type->default_output_types;
|
||||
names = brick_type->default_output_names;
|
||||
if (unlikely(!output_types)) {
|
||||
BRICK_ERR("no output types specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (output_types) {
|
||||
BRICK_DBG("generic_brick_init_full: output_types\n");
|
||||
brick->outputs = data;
|
||||
data += sizeof(void*) * brick_type->max_outputs;
|
||||
size -= sizeof(void*) * brick_type->max_outputs;
|
||||
BRICK_DBG("generic_brick_init_full: output_types\n");
|
||||
brick->outputs = data;
|
||||
data += sizeof(void*) * brick_type->max_outputs;
|
||||
size -= sizeof(void*) * brick_type->max_outputs;
|
||||
if (size < 0)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < brick_type->max_outputs; i++) {
|
||||
struct generic_output *output = data;
|
||||
const struct generic_output_type *type = *output_types++;
|
||||
if (!type || type->output_size <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
BRICK_DBG("generic_brick_init_full: calling generic_output_init()\n");
|
||||
generic_output_init(brick, i, type, output, (names && *names) ? *names++ : type->type_name);
|
||||
if (status < 0)
|
||||
return status;
|
||||
data += type->output_size;
|
||||
size -= type->output_size;
|
||||
if (size < 0)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < brick_type->max_outputs; i++) {
|
||||
struct generic_output *output = data;
|
||||
const struct generic_output_type *type = *output_types++;
|
||||
BRICK_DBG("generic_brick_init_full: calling generic_output_init()\n");
|
||||
generic_output_init(brick, i, type, output, (names && *names) ? *names++ : type->type_name);
|
||||
if (status)
|
||||
return status;
|
||||
data += type->output_size;
|
||||
size -= type->output_size;
|
||||
if (size < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
// call the specific constructors
|
||||
|
@ -147,7 +157,7 @@ int generic_brick_init_full(
|
|||
if (brick_type->brick_construct) {
|
||||
BRICK_DBG("generic_brick_init_full: calling brick_construct()\n");
|
||||
status = brick_type->brick_construct(brick);
|
||||
if (status)
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
for (i = 0; i < brick_type->max_inputs; i++) {
|
||||
|
@ -161,7 +171,7 @@ int generic_brick_init_full(
|
|||
if (input->type->input_construct) {
|
||||
BRICK_DBG("generic_brick_init_full: calling input_construct()\n");
|
||||
status = input->type->input_construct(input);
|
||||
if (status)
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +186,7 @@ int generic_brick_init_full(
|
|||
if (output->type->output_construct) {
|
||||
BRICK_DBG("generic_brick_init_full: calling output_construct()\n");
|
||||
status = output->type->output_construct(output);
|
||||
if (status)
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +199,7 @@ int generic_brick_exit_full(struct generic_brick *brick)
|
|||
int i;
|
||||
int status;
|
||||
// first, check all outputs
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
for (i = 0; i < brick->type->max_outputs; i++) {
|
||||
struct generic_output *output = brick->outputs[i];
|
||||
if (!output)
|
||||
continue;
|
||||
|
@ -260,13 +270,13 @@ int generic_brick_exit_recursively(struct generic_brick *brick, bool destroy_inp
|
|||
int postpone = 0;
|
||||
brick = container_of(tmp.next, struct generic_brick, tmp_head);
|
||||
list_del_init(&brick->tmp_head);
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
for (i = 0; i < brick->type->max_outputs; i++) {
|
||||
struct generic_output *output = brick->outputs[i];
|
||||
if (output && output->nr_connected) {
|
||||
postpone += output->nr_connected;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < brick->nr_inputs; i++) {
|
||||
for (i = 0; i < brick->type->max_inputs; i++) {
|
||||
struct generic_input *input = brick->inputs[i];
|
||||
if (input && input->connect) {
|
||||
struct generic_brick *other = input->connect->brick;
|
||||
|
@ -301,7 +311,14 @@ int generic_add_aspect(struct generic_output *output, struct generic_object_layo
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
nr = object_layout->object_type->brick_obj_nr;
|
||||
if (nr < 0 || nr >= BRICK_OBJ_NR) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
nr = 0;
|
||||
#endif
|
||||
aspect_layout = (void*)&output->output_aspect_layouts[nr];
|
||||
if (aspect_layout->aspect_type && aspect_layout->aspect_layout_generation == object_layout->object_layout_generation) {
|
||||
/* aspect_layout is already initialized.
|
||||
|
@ -682,24 +699,26 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
int stack;
|
||||
bool val = (mode == BR_ON_ONE || mode == BR_ON_ALL);
|
||||
bool force = (mode != BR_OFF_ONE && mode != BR_OFF_ALL);
|
||||
int oldstack = 0;
|
||||
int pos;
|
||||
int status;
|
||||
|
||||
#define PUSH_STACK(next) \
|
||||
{ \
|
||||
int j; \
|
||||
bool found = false; \
|
||||
/* eliminate duplicates */ \
|
||||
for (j = 0; j < stack; j++) { \
|
||||
if (table[j] == next) { \
|
||||
BRICK_DBG(" double entry %d '%s' stack = %d\n", i, next->brick_name, stack); \
|
||||
if (table[j] == (next)) { \
|
||||
BRICK_DBG(" double entry %d '%s' stack = %d\n", i, (next)->brick_name, stack); \
|
||||
found = true; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (!found) { \
|
||||
BRICK_DBG(" push %d '%s' stack = %d\n", i, next->brick_name, stack); \
|
||||
table[stack++] = next; \
|
||||
BRICK_DBG(" push '%s' stack = %d\n", (next)->brick_name, stack); \
|
||||
table[stack++] = (next); \
|
||||
if (unlikely(stack > max)) { \
|
||||
BRICK_ERR("---- max = %d overflow, restarting...\n", max); \
|
||||
goto restart; \
|
||||
} \
|
||||
} \
|
||||
|
@ -719,15 +738,10 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
table[stack++] = orig_brick;
|
||||
|
||||
status = -EAGAIN;
|
||||
while (stack > oldstack) {
|
||||
int i;
|
||||
struct generic_brick *brick;
|
||||
for (pos = 0; pos < stack; pos++) {
|
||||
struct generic_brick *brick = table[pos];
|
||||
|
||||
oldstack = stack;
|
||||
|
||||
brick = table[stack - 1];
|
||||
BRICK_DBG("--> brick = '%s' inputs = %d stack = %d\n", brick->brick_name, brick->nr_inputs, stack);
|
||||
msleep(1000);
|
||||
BRICK_DBG("--> pos = %d stack = %d brick = '%s' inputs = %d/%d outputs = %d/%d\n", pos, stack, brick->brick_name, brick->nr_inputs, brick->type->max_inputs, brick->nr_outputs, brick->type->max_outputs);
|
||||
|
||||
if (val) {
|
||||
force = false;
|
||||
|
@ -736,10 +750,13 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
goto done;
|
||||
}
|
||||
if (mode >= BR_ON_ALL) {
|
||||
for (i = 0; i < brick->nr_inputs; i++) {
|
||||
int i;
|
||||
for (i = 0; i < brick->type->max_inputs; i++) {
|
||||
struct generic_input *input = brick->inputs[i];
|
||||
struct generic_output *output;
|
||||
struct generic_brick *next;
|
||||
BRICK_DBG("---> i = %d\n", i);
|
||||
msleep(1000);
|
||||
if (!input)
|
||||
continue;
|
||||
output = input->connect;
|
||||
|
@ -753,22 +770,32 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
}
|
||||
}
|
||||
} else if (mode >= BR_ON_ALL) {
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
int i;
|
||||
for (i = 0; i < brick->type->max_outputs; i++) {
|
||||
struct generic_output *output = brick->outputs[i];
|
||||
struct list_head *tmp;
|
||||
struct generic_input *input;
|
||||
struct generic_brick *next;
|
||||
BRICK_DBG("---> i = %d output = %p\n", i, output);
|
||||
msleep(1000);
|
||||
if (!output)
|
||||
continue;
|
||||
for (tmp = output->output_head.next; tmp && tmp != &output->output_head; tmp = tmp->next) {
|
||||
input = container_of(tmp, struct generic_input, input_head);
|
||||
next = input->brick;
|
||||
struct generic_input *input = container_of(tmp, struct generic_input, input_head);
|
||||
struct generic_brick *next = input->brick;
|
||||
BRICK_DBG("----> tmp = %p input = %p next = %p\n", tmp, input, next);
|
||||
msleep(1000);
|
||||
if (unlikely(!next)) {
|
||||
BRICK_ERR("oops, bad brick pointer\n");
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
PUSH_STACK(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BRICK_DBG("-> stack = %d\n", stack);
|
||||
|
||||
while (stack > 0) {
|
||||
struct generic_brick *brick = table[--stack];
|
||||
BRICK_DBG("--> switch '%s' stack = %d\n", brick->brick_name, stack);
|
||||
|
@ -779,7 +806,9 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
}
|
||||
|
||||
if (force && !val && (mode == BR_FREE_ONE || mode == BR_FREE_ALL) && brick->free) {
|
||||
BRICK_DBG("---> freeing '%s'\n", brick->brick_name);
|
||||
status = brick->free(brick);
|
||||
BRICK_DBG("---> freeing '%s' status = %d\n", brick->brick_name, status);
|
||||
if (status < 0) {
|
||||
BRICK_DBG("freeing brick '%s' (%s) failed, status = %d\n", brick->brick_name, orig_brick->brick_name, status);
|
||||
goto done;
|
||||
|
@ -789,10 +818,10 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||
}
|
||||
status = 0;
|
||||
|
||||
done:
|
||||
done:
|
||||
BRICK_DBG("-> done '%s' status = %d\n", orig_brick->brick_name, status);
|
||||
if (table)
|
||||
kfree(table);
|
||||
BRICK_DBG("-> done '%s' status = %d\n", orig_brick->brick_name, status);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_recursive_button);
|
||||
|
|
11
brick.h
11
brick.h
|
@ -183,7 +183,7 @@ struct generic_input {
|
|||
struct BRICK##_output_ops *ops; \
|
||||
struct list_head output_head; \
|
||||
int nr_connected; \
|
||||
/* _must_ be the last member */ \
|
||||
/* _must_ be the last member (may expand to open array) */ \
|
||||
struct generic_aspect_layout output_aspect_layouts[BRICK_OBJ_MAX]; \
|
||||
|
||||
struct generic_output {
|
||||
|
@ -365,16 +365,19 @@ inline int generic_connect(struct generic_input *input, struct generic_output *o
|
|||
return -EINVAL;
|
||||
if (unlikely(input->connect))
|
||||
return -EEXIST;
|
||||
if (unlikely(!list_empty(&input->input_head)))
|
||||
return -EINVAL;
|
||||
// helps only against the most common errors
|
||||
if (unlikely(input->brick == output->brick))
|
||||
return -EDEADLK;
|
||||
|
||||
input->connect = output;
|
||||
output->nr_connected++;
|
||||
list_add(&input->input_head, &output->output_head);
|
||||
BRICK_DBG("now nr_connected=%d\n", output->nr_connected);
|
||||
/* no atomic_t necessary (_any_ change is sufficient)
|
||||
*/
|
||||
brick_layout_generation++;
|
||||
list_add(&input->input_head, &output->output_head);
|
||||
BRICK_DBG("now nr_connected=%d\n", output->nr_connected);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -384,8 +387,8 @@ inline int generic_disconnect(struct generic_input *input)
|
|||
if (!input)
|
||||
return -EINVAL;
|
||||
if (input->connect) {
|
||||
BRICK_DBG("now nr_connected=%d\n", input->connect->nr_connected);
|
||||
input->connect->nr_connected--;
|
||||
BRICK_DBG("now nr_connected=%d\n", input->connect->nr_connected);
|
||||
input->connect = NULL;
|
||||
list_del_init(&input->input_head);
|
||||
//brick_layout_generation++;
|
||||
|
|
|
@ -243,12 +243,6 @@ bool log_finalize(struct log_status *logst, int len, void (*endio)(void *private
|
|||
|
||||
ok = true;
|
||||
|
||||
#if 0
|
||||
if (logst->restlen < PAGE_SIZE + OVERHEAD) {
|
||||
log_flush(logst);
|
||||
}
|
||||
#endif
|
||||
|
||||
err:
|
||||
return ok;
|
||||
}
|
||||
|
|
14
mars.h
14
mars.h
|
@ -10,7 +10,11 @@
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// include the brick infrastucture
|
||||
// include the generic brick infrastucture
|
||||
|
||||
#ifdef BRICK_H
|
||||
#error "brick.h must not be already included - please reorganize your includes"
|
||||
#endif
|
||||
|
||||
#define BRICK_OBJ_MREF 0
|
||||
#define BRICK_OBJ_MAX 1
|
||||
|
@ -22,7 +26,7 @@
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// MARS-specific debugging helper
|
||||
// MARS-specific debugging helpers
|
||||
|
||||
#define MARS_DELAY /**/
|
||||
//#define MARS_DELAY msleep(20000)
|
||||
|
@ -277,11 +281,11 @@ extern struct mars_global *mars_global;
|
|||
|
||||
extern void _mars_trigger(void);
|
||||
#define mars_trigger() do { MARS_INF("trigger...\n"); _mars_trigger(); } while (0)
|
||||
extern int mars_power_button(struct mars_brick *brick, bool val);
|
||||
extern int mars_power_button(struct mars_brick *brick, bool val, bool force_off);
|
||||
extern void mars_power_led_on(struct mars_brick *brick, bool val);
|
||||
extern void mars_power_led_off(struct mars_brick *brick, bool val);
|
||||
|
||||
extern int mars_power_button_recursive(struct mars_brick *brick, bool val, int timeout);
|
||||
extern int mars_power_button_recursive(struct mars_brick *brick, bool val, bool force_off, int timeout);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -335,7 +339,7 @@ struct mars_global {
|
|||
//void *private;
|
||||
};
|
||||
|
||||
typedef int (*mars_dent_checker)(const char *path, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial);
|
||||
typedef int (*mars_dent_checker)(struct mars_dent *parent, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial);
|
||||
typedef int (*mars_dent_worker)(struct mars_global *global, struct mars_dent *dent, bool direction);
|
||||
|
||||
extern int mars_dent_work(struct mars_global *global, char *dirname, int allocsize, mars_dent_checker checker, mars_dent_worker worker, void *buf, int maxdepth);
|
||||
|
|
12
mars_aio.c
12
mars_aio.c
|
@ -628,7 +628,7 @@ static int aio_output_construct(struct aio_output *output)
|
|||
|
||||
static int aio_output_destruct(struct aio_output *output)
|
||||
{
|
||||
return mars_power_button((void*)output->brick, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////// static structs ////////////////////////
|
||||
|
@ -645,6 +645,15 @@ static struct aio_output_ops aio_output_ops = {
|
|||
.mars_get_info = aio_get_info,
|
||||
};
|
||||
|
||||
const struct aio_input_type aio_input_type = {
|
||||
.type_name = "aio_input",
|
||||
.input_size = sizeof(struct aio_input),
|
||||
};
|
||||
|
||||
static const struct aio_input_type *aio_input_types[] = {
|
||||
&aio_input_type,
|
||||
};
|
||||
|
||||
const struct aio_output_type aio_output_type = {
|
||||
.type_name = "aio_output",
|
||||
.output_size = sizeof(struct aio_output),
|
||||
|
@ -667,6 +676,7 @@ const struct aio_brick_type aio_brick_type = {
|
|||
.max_inputs = 0,
|
||||
.max_outputs = 1,
|
||||
.master_ops = &aio_brick_ops,
|
||||
.default_input_types = aio_input_types,
|
||||
.default_output_types = aio_output_types,
|
||||
.brick_construct = &aio_brick_construct,
|
||||
};
|
||||
|
|
|
@ -256,11 +256,14 @@ void _mars_trigger(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(_mars_trigger);
|
||||
|
||||
int mars_power_button(struct mars_brick *brick, bool val)
|
||||
int mars_power_button(struct mars_brick *brick, bool val, bool force_off)
|
||||
{
|
||||
int status = 0;
|
||||
bool oldval = brick->power.button;
|
||||
|
||||
if (force_off && !val)
|
||||
brick->power.force_off = true;
|
||||
|
||||
if (brick->power.force_off)
|
||||
val = false;
|
||||
|
||||
|
@ -278,17 +281,20 @@ int mars_power_button(struct mars_brick *brick, bool val)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mars_power_button);
|
||||
|
||||
int mars_power_button_recursive(struct mars_brick *brick, bool val, int timeout)
|
||||
int mars_power_button_recursive(struct mars_brick *brick, bool val, bool force_off, int timeout)
|
||||
{
|
||||
int status = 0;
|
||||
bool oldval = brick->power.button;
|
||||
|
||||
if (force_off && !val)
|
||||
brick->power.force_off = true;
|
||||
|
||||
if (brick->power.force_off)
|
||||
val = false;
|
||||
|
||||
if (val != oldval) {
|
||||
brick_switch_t mode;
|
||||
mode = (val ? BR_ON_ALL : BR_OFF_ALL);
|
||||
mode = (val ? BR_ON_ALL : (force_off ? BR_FREE_ALL : BR_OFF_ALL));
|
||||
|
||||
MARS_DBG("brick '%s' type '%s' power button %d -> %d (mode = %d)\n", brick->brick_path, brick->type->type_name, oldval, val, mode);
|
||||
|
||||
|
@ -329,7 +335,7 @@ struct mars_cookie {
|
|||
struct mars_global *global;
|
||||
mars_dent_checker checker;
|
||||
char *path;
|
||||
void *parent;
|
||||
struct mars_dent *parent;
|
||||
int pathlen;
|
||||
int allocsize;
|
||||
int depth;
|
||||
|
@ -425,7 +431,7 @@ int mars_filler(void *__buf, const char *name, int namlen, loff_t offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
class = cookie->checker(cookie->path, name, namlen, d_type, &prefix, &serial);
|
||||
class = cookie->checker(cookie->parent, name, namlen, d_type, &prefix, &serial);
|
||||
if (class < 0)
|
||||
return 0;
|
||||
|
||||
|
@ -761,6 +767,7 @@ EXPORT_SYMBOL_GPL(mars_find_brick);
|
|||
|
||||
int mars_free_brick(struct mars_brick *brick)
|
||||
{
|
||||
struct mars_global *global;
|
||||
int i;
|
||||
int status;
|
||||
|
||||
|
@ -787,19 +794,28 @@ int mars_free_brick(struct mars_brick *brick)
|
|||
|
||||
MARS_DBG("===> freeing brick name = '%s'\n", brick->brick_name);
|
||||
|
||||
#if 1 // TODO: debug locking crash
|
||||
(void)generic_brick_exit_full((void*)brick);
|
||||
global = brick->global;
|
||||
if (global) {
|
||||
down(&global->mutex);
|
||||
list_del_init(&brick->global_brick_link);
|
||||
list_del_init(&brick->dent_brick_link);
|
||||
up(&global->mutex);
|
||||
}
|
||||
|
||||
status = generic_brick_exit_full((void*)brick);
|
||||
|
||||
if (status >= 0) {
|
||||
#if 0 // TODO: check whether crash remains possible
|
||||
if (brick->brick_name)
|
||||
kfree(brick->brick_name);
|
||||
if (brick->brick_path)
|
||||
kfree(brick->brick_path);
|
||||
kfree(brick);
|
||||
#endif
|
||||
|
||||
if (brick->brick_name)
|
||||
kfree(brick->brick_name);
|
||||
if (brick->brick_path)
|
||||
kfree(brick->brick_path);
|
||||
kfree(brick);
|
||||
|
||||
mars_trigger();
|
||||
|
||||
status = 0;
|
||||
mars_trigger();
|
||||
} else {
|
||||
MARS_ERR("error freeing brick, status = %d\n", status);
|
||||
}
|
||||
|
||||
done:
|
||||
return status;
|
||||
|
@ -832,6 +848,10 @@ struct mars_brick *mars_make_brick(struct mars_global *global, struct mars_dent
|
|||
MARS_ERR("input_type %d is missing\n", i);
|
||||
goto err_name;
|
||||
}
|
||||
if (unlikely(type->input_size <= 0)) {
|
||||
MARS_ERR("bad input_size at %d\n", i);
|
||||
goto err_name;
|
||||
}
|
||||
size += type->input_size;
|
||||
}
|
||||
output_types = brick_type->default_output_types;
|
||||
|
@ -841,6 +861,10 @@ struct mars_brick *mars_make_brick(struct mars_global *global, struct mars_dent
|
|||
MARS_ERR("output_type %d is missing\n", i);
|
||||
goto err_name;
|
||||
}
|
||||
if (unlikely(type->output_size <= 0)) {
|
||||
MARS_ERR("bad output_size at %d\n", i);
|
||||
goto err_name;
|
||||
}
|
||||
size += type->output_size;
|
||||
}
|
||||
|
||||
|
@ -898,11 +922,6 @@ int mars_kill_brick(struct mars_brick *brick)
|
|||
|
||||
MARS_DBG("===> killing brick path = '%s' name = '%s'\n", brick->brick_path, brick->brick_name);
|
||||
|
||||
down(&global->mutex);
|
||||
list_del_init(&brick->global_brick_link);
|
||||
list_del_init(&brick->dent_brick_link);
|
||||
up(&global->mutex);
|
||||
|
||||
// start shutdown
|
||||
status = set_recursive_button((void*)brick, BR_FREE_ALL, 10 * HZ);
|
||||
|
||||
|
@ -1021,12 +1040,14 @@ struct mars_brick *make_brick_all(
|
|||
struct mars_brick *brick = NULL;
|
||||
char *paths[prev_count];
|
||||
struct mars_brick *prev[prev_count];
|
||||
int switch_state = true;
|
||||
int i;
|
||||
|
||||
// treat variable arguments
|
||||
va_start(args, prev_count);
|
||||
if (switch_fmt) {
|
||||
switch_path = vpath_make(switch_fmt, &args);
|
||||
switch_state = false;
|
||||
}
|
||||
if (new_fmt) {
|
||||
new_path = _new_path = vpath_make(new_fmt, &args);
|
||||
|
@ -1042,11 +1063,21 @@ struct mars_brick *make_brick_all(
|
|||
MARS_ERR("could not create new path\n");
|
||||
goto err;
|
||||
}
|
||||
if (switch_path) {
|
||||
struct mars_dent *test = mars_find_dent(global, switch_path);
|
||||
if (test && test->new_link) {
|
||||
sscanf(test->new_link, "%d", &switch_state);
|
||||
}
|
||||
}
|
||||
|
||||
// don't do anything if brick already exists
|
||||
// brick already existing?
|
||||
brick = mars_find_brick(global, new_brick_type != _aio_brick_type && new_brick_type != _bio_brick_type ? new_brick_type : NULL, new_path);
|
||||
if (brick) {
|
||||
// just switch the power state
|
||||
MARS_IO("found brick '%s'\n", new_path);
|
||||
goto do_switch;
|
||||
}
|
||||
if (!switch_state) { // don't start => also don't create
|
||||
goto done;
|
||||
}
|
||||
if (!new_name)
|
||||
|
@ -1120,11 +1151,17 @@ struct mars_brick *make_brick_all(
|
|||
setup_fn(brick, private);
|
||||
}
|
||||
|
||||
// switch on (may fail silently, but responsibility is at the workers)
|
||||
if (timeout > 0) {
|
||||
do_switch:
|
||||
// switch on/off (may fail silently, but responsibility is at the workers)
|
||||
if (timeout > 0 || !switch_state) {
|
||||
int status;
|
||||
status = mars_power_button_recursive((void*)brick, true, timeout);
|
||||
status = mars_power_button_recursive((void*)brick, switch_state, !switch_state, timeout);
|
||||
MARS_DBG("switch on status = %d\n", status);
|
||||
#if 1 // TODO: need cleanup_fn() here
|
||||
if (!switch_state && status >= 0 && !brick->power.button && brick->power.led_off) {
|
||||
mars_kill_brick(brick);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return brick;
|
||||
|
|
40
mars_if.c
40
mars_if.c
|
@ -487,7 +487,15 @@ static int if_switch(struct if_brick *brick)
|
|||
mars_power_led_on((void*)brick, false);
|
||||
disk = input->disk;
|
||||
if (!disk)
|
||||
goto down;
|
||||
goto is_down;
|
||||
|
||||
#if 0
|
||||
q = disk->queue;
|
||||
if (q) {
|
||||
blk_cleanup_queue(q);
|
||||
input->q = NULL;
|
||||
}
|
||||
#endif
|
||||
if (atomic_read(&input->open_count) > 0) {
|
||||
MARS_INF("device '%s' is open %d times, cannot shutdown\n", disk->disk_name, atomic_read(&input->open_count));
|
||||
return -EBUSY;
|
||||
|
@ -496,17 +504,10 @@ static int if_switch(struct if_brick *brick)
|
|||
bdput(input->bdev);
|
||||
input->bdev = NULL;
|
||||
}
|
||||
if (disk) {
|
||||
q = disk->queue;
|
||||
del_gendisk(input->disk);
|
||||
put_disk(input->disk);
|
||||
input->disk = NULL;
|
||||
if (q) {
|
||||
blk_cleanup_queue(q);
|
||||
}
|
||||
}
|
||||
//........
|
||||
down:
|
||||
del_gendisk(input->disk);
|
||||
put_disk(input->disk);
|
||||
input->disk = NULL;
|
||||
is_down:
|
||||
mars_power_led_off((void*)brick, true);
|
||||
}
|
||||
return 0;
|
||||
|
@ -560,14 +561,6 @@ static int if_input_construct(struct if_input *input)
|
|||
|
||||
static int if_input_destruct(struct if_input *input)
|
||||
{
|
||||
if (input->bdev)
|
||||
bdput(input->bdev);
|
||||
if (input->disk) {
|
||||
del_gendisk(input->disk);
|
||||
//put_disk(input->disk);
|
||||
}
|
||||
if (input->q)
|
||||
blk_cleanup_queue(input->q);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -607,6 +600,12 @@ const struct if_output_type if_output_type = {
|
|||
[BRICK_OBJ_MREF] = LAYOUT_ALL,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct if_output_type *if_output_types[] = {
|
||||
&if_output_type,
|
||||
};
|
||||
|
||||
|
||||
const struct if_brick_type if_brick_type = {
|
||||
.type_name = "if_brick",
|
||||
.brick_size = sizeof(struct if_brick),
|
||||
|
@ -614,6 +613,7 @@ const struct if_brick_type if_brick_type = {
|
|||
.max_outputs = 0,
|
||||
.master_ops = &if_brick_ops,
|
||||
.default_input_types = if_input_types,
|
||||
.default_output_types = if_output_types,
|
||||
.brick_construct = &if_brick_construct,
|
||||
.brick_destruct = &if_brick_destruct,
|
||||
};
|
||||
|
|
204
mars_light.c
204
mars_light.c
|
@ -228,35 +228,6 @@ done:
|
|||
return status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static
|
||||
char *_backskip_replace(const char *path, char delim, bool insert, const char *fmt, ...)
|
||||
{
|
||||
int path_len = strlen(path);
|
||||
int total_len = strlen(fmt) + path_len + MARS_PATH_MAX;
|
||||
char *res = kmalloc(total_len, GFP_MARS);
|
||||
if (likely(res)) {
|
||||
va_list args;
|
||||
int pos = path_len;
|
||||
int plus;
|
||||
|
||||
while (pos > 0 && path[pos] != delim) {
|
||||
pos--;
|
||||
}
|
||||
memcpy(res, path, pos);
|
||||
|
||||
va_start(args, fmt);
|
||||
plus = vsnprintf(res + pos, total_len - pos, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (insert) {
|
||||
strncpy(res + pos + plus, path + pos + 1, total_len - pos - plus);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
|
@ -276,7 +247,11 @@ int __make_copy(
|
|||
struct mars_output *output[2] = {};
|
||||
struct mars_info info[2] = {};
|
||||
int i;
|
||||
int status = -1;
|
||||
int status = -EINVAL;
|
||||
|
||||
if (!switch_path) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct mars_brick *aio;
|
||||
|
@ -368,7 +343,7 @@ int __make_copy(
|
|||
_copy->copy_end = info[0].current_size;
|
||||
MARS_DBG("copy_end = %lld\n", _copy->copy_end);
|
||||
if (_copy->copy_start < _copy->copy_end) {
|
||||
status = mars_power_button_recursive((void*)copy, true, 10 * HZ);
|
||||
status = mars_power_button_recursive((void*)copy, true, false, 10 * HZ);
|
||||
MARS_DBG("copy switch status = %d\n", status);
|
||||
}
|
||||
}
|
||||
|
@ -465,9 +440,7 @@ int check_logfile(struct mars_peerinfo *peer, struct mars_dent *dent, struct mar
|
|||
loff_t src_size = dent->new_stat.size;
|
||||
const char *switch_path = NULL;
|
||||
const char *copy_path = NULL;
|
||||
const char *connect_path = NULL;
|
||||
const char *alias_path = NULL;
|
||||
struct kstat connect_stat = {};
|
||||
struct mars_dent *local_alias;
|
||||
struct copy_brick *copy_brick;
|
||||
int status = 0;
|
||||
|
@ -508,23 +481,9 @@ int check_logfile(struct mars_peerinfo *peer, struct mars_dent *dent, struct mar
|
|||
}
|
||||
|
||||
// check whether connection is allowed
|
||||
connect_path = backskip_replace(dent->d_path, '/', false, "/connect-%s", my_id());
|
||||
if (unlikely(!connect_path)) {
|
||||
status = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
status = mars_stat(connect_path, &connect_stat, true);
|
||||
MARS_DBG("connect_path = '%s' stat status = %d uid = %d\n", connect_path, status, connect_stat.uid);
|
||||
if (status < 0 || connect_stat.uid > 0) {
|
||||
// stop running copy, if any
|
||||
if (copy_brick) {
|
||||
MARS_DBG("stopping copy '%s'\n", copy_brick->brick_name);
|
||||
mars_kill_brick((void*)copy_brick);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
switch_path = path_make("%s/switch-%s/connect", parent->d_path, my_id());
|
||||
|
||||
// start copy
|
||||
// start / treat copy brick instance
|
||||
status = _update_file(peer->global, switch_path, copy_path, dent->d_path, peer->peer, src_size);
|
||||
MARS_DBG("update '%s' from peer '%s' status = %d\n", dent->d_path, peer->peer, status);
|
||||
if (status < 0) {
|
||||
|
@ -550,10 +509,10 @@ int check_logfile(struct mars_peerinfo *peer, struct mars_dent *dent, struct mar
|
|||
done:
|
||||
if (copy_path)
|
||||
kfree(copy_path);
|
||||
if (connect_path)
|
||||
kfree(connect_path);
|
||||
if (alias_path)
|
||||
kfree(alias_path);
|
||||
if (switch_path)
|
||||
kfree(switch_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -917,7 +876,7 @@ struct mars_rotate {
|
|||
};
|
||||
|
||||
static
|
||||
void _create_new_logfile(char *path)
|
||||
void _create_new_logfile(const char *path)
|
||||
{
|
||||
struct file *f;
|
||||
const int flags = O_RDWR | O_CREAT | O_EXCL;
|
||||
|
@ -999,8 +958,9 @@ int make_log_init(void *buf, struct mars_dent *parent)
|
|||
struct mars_dent *replay_link;
|
||||
struct mars_dent *aio_dent;
|
||||
struct mars_output *output;
|
||||
char *replay_path = NULL;
|
||||
char *aio_path = NULL;
|
||||
const char *replay_path = NULL;
|
||||
const char *aio_path = NULL;
|
||||
const char *switch_path = NULL;
|
||||
int status;
|
||||
|
||||
if (!rot) {
|
||||
|
@ -1101,6 +1061,9 @@ int make_log_init(void *buf, struct mars_dent *parent)
|
|||
}
|
||||
MARS_DBG("logfile '%s' size = %lld\n", aio_path, rot->aio_info.current_size);
|
||||
|
||||
// check whether attach is allowed
|
||||
switch_path = path_make("%s/switch-%s/attach", parent->d_path, my_id());
|
||||
|
||||
/* Fetch / make the transaction logger.
|
||||
* We deliberately "forget" to connect the log input here.
|
||||
* Will be carried out later in make_log().
|
||||
|
@ -1115,7 +1078,7 @@ int make_log_init(void *buf, struct mars_dent *parent)
|
|||
aio_path,
|
||||
(const struct generic_brick_type*)&trans_logger_brick_type,
|
||||
(const struct generic_brick_type*[]){NULL},
|
||||
NULL,
|
||||
switch_path,
|
||||
"%s/logger",
|
||||
(const char *[]){"%s/data-%s"},
|
||||
1,
|
||||
|
@ -1139,6 +1102,8 @@ done:
|
|||
kfree(aio_path);
|
||||
if (replay_path)
|
||||
kfree(replay_path);
|
||||
if (switch_path)
|
||||
kfree(switch_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1377,7 +1342,7 @@ int _start_trans(struct mars_rotate *rot)
|
|||
|
||||
/* Switch on....
|
||||
*/
|
||||
status = mars_power_button((void*)trans_brick, true);
|
||||
status = mars_power_button((void*)trans_brick, true, false);
|
||||
MARS_DBG("status = %d\n", status);
|
||||
|
||||
done:
|
||||
|
@ -1394,9 +1359,9 @@ int _stop_trans(struct mars_rotate *rot)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Switch off....
|
||||
/* Switch off temporarily....
|
||||
*/
|
||||
status = mars_power_button((void*)trans_brick, false);
|
||||
status = mars_power_button((void*)trans_brick, false, false);
|
||||
MARS_DBG("status = %d\n", status);
|
||||
if (status < 0 || !trans_brick->power.led_off) {
|
||||
goto done;
|
||||
|
@ -1536,7 +1501,7 @@ int make_bio(void *buf, struct mars_dent *dent)
|
|||
goto done;
|
||||
}
|
||||
brick->outputs[0]->output_name = dent->d_path;
|
||||
status = mars_power_button((void*)brick, true);
|
||||
status = mars_power_button((void*)brick, true, false);
|
||||
if (status < 0) {
|
||||
kill_all(buf, dent);
|
||||
}
|
||||
|
@ -1697,6 +1662,8 @@ static int _make_copy(void *buf, struct mars_dent *dent)
|
|||
status = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
// check whether connection is allowed
|
||||
switch_path = path_make("%s/switch-%s/connect", dent->d_parent->d_path, my_id());
|
||||
|
||||
status = __make_copy(global, dent, switch_path, copy_path, dent->d_parent->d_path, (const char**)dent->d_argv, -1, NULL);
|
||||
|
||||
|
@ -1704,6 +1671,8 @@ done:
|
|||
MARS_DBG("status = %d\n", status);
|
||||
if (copy_path)
|
||||
kfree(copy_path);
|
||||
if (switch_path)
|
||||
kfree(switch_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1757,6 +1726,9 @@ static int make_sync(void *buf, struct mars_dent *dent)
|
|||
if (unlikely(!src || !dst || !copy_path))
|
||||
goto done;
|
||||
|
||||
// check whether connection is allowed
|
||||
switch_path = path_make("%s/switch-%s/sync", dent->d_parent->d_path, my_id());
|
||||
|
||||
MARS_DBG("starting initial sync '%s' => '%s'\n", src, dst);
|
||||
|
||||
{
|
||||
|
@ -1787,6 +1759,8 @@ done:
|
|||
kfree(dst);
|
||||
if (copy_path)
|
||||
kfree(copy_path);
|
||||
if (switch_path)
|
||||
kfree(switch_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1801,6 +1775,8 @@ enum {
|
|||
CL_PEERS,
|
||||
// resource definitions
|
||||
CL_RESOURCE,
|
||||
CL_SWITCH,
|
||||
CL_SWITCH_ITEMS,
|
||||
CL_CONNECT,
|
||||
CL_DATA,
|
||||
CL_PRIMARY,
|
||||
|
@ -1854,6 +1830,27 @@ static const struct light_class light_classes[] = {
|
|||
.cl_forward = make_log_init,
|
||||
.cl_backward = NULL,
|
||||
},
|
||||
/* Subdirectory for controlling items...
|
||||
*/
|
||||
[CL_SWITCH] = {
|
||||
.cl_name = "switch-",
|
||||
.cl_len = 7,
|
||||
.cl_type = 'd',
|
||||
.cl_hostcontext = true,
|
||||
.cl_father = CL_RESOURCE,
|
||||
.cl_forward = NULL,
|
||||
.cl_backward = NULL,
|
||||
},
|
||||
/* ... and its contents
|
||||
*/
|
||||
[CL_SWITCH_ITEMS] = {
|
||||
.cl_name = "",
|
||||
.cl_len = 0, // catch any
|
||||
.cl_type = 'l',
|
||||
.cl_father = CL_SWITCH,
|
||||
.cl_forward = NULL,
|
||||
.cl_backward = NULL,
|
||||
},
|
||||
/* Symlink indicating the current peer
|
||||
*/
|
||||
[CL_CONNECT] = {
|
||||
|
@ -1983,7 +1980,7 @@ static const struct light_class light_classes[] = {
|
|||
|
||||
/* Helper routine to pre-determine the relevance of a name from the filesystem.
|
||||
*/
|
||||
static int light_checker(const char *path, const char *_name, int namlen, unsigned int d_type, int *prefix, int *serial)
|
||||
static int light_checker(struct mars_dent *parent, const char *_name, int namlen, unsigned int d_type, int *prefix, int *serial)
|
||||
{
|
||||
int class;
|
||||
int status = -2;
|
||||
|
@ -1999,44 +1996,62 @@ static int light_checker(const char *path, const char *_name, int namlen, unsign
|
|||
for (class = CL_ROOT + 1; ; class++) {
|
||||
const struct light_class *test = &light_classes[class];
|
||||
int len = test->cl_len;
|
||||
if (!len || !test->cl_name)
|
||||
if (!test->cl_name) { // end of table
|
||||
break;
|
||||
}
|
||||
|
||||
//MARS_DBG(" testing class '%s'\n", test->cl_name);
|
||||
#if 0
|
||||
|
||||
#ifdef MARS_DEBUGGING
|
||||
if (len != strlen(test->cl_name)) {
|
||||
MARS_ERR("internal table '%s': %d != %d\n", test->cl_name, len, (int)strlen(test->cl_name));
|
||||
MARS_ERR("internal table '%s' mismatch: %d != %d\n", test->cl_name, len, (int)strlen(test->cl_name));
|
||||
len = strlen(test->cl_name);
|
||||
}
|
||||
#endif
|
||||
if (namlen >= len && !memcmp(name, test->cl_name, len)) {
|
||||
//MARS_DBG("path '%s/%s' matches class %d '%s'\n", path, name, class, test->cl_name);
|
||||
// special contexts
|
||||
if (test->cl_serial) {
|
||||
int plus = 0;
|
||||
int count;
|
||||
count = sscanf(name+len, "%d%n", serial, &plus);
|
||||
if (count < 1) {
|
||||
//MARS_DBG("'%s' serial number mismatch at '%s'\n", name, name+len);
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
len += plus;
|
||||
if (name[len] == '-')
|
||||
len++;
|
||||
}
|
||||
*prefix = len;
|
||||
if (test->cl_hostcontext) {
|
||||
if (memcmp(name+len, my_id(), namlen-len)) {
|
||||
//MARS_DBG("context mismatch '%s' at '%s'\n", name, name+len);
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
status = class;
|
||||
goto done;
|
||||
|
||||
if (test->cl_father &&
|
||||
(!parent || parent->d_class != test->cl_father)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > 0 &&
|
||||
(namlen < len || memcmp(name, test->cl_name, len))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//MARS_DBG("path '%s/%s' matches class %d '%s'\n", path, name, class, test->cl_name);
|
||||
|
||||
// check special contexts
|
||||
if (test->cl_serial) {
|
||||
int plus = 0;
|
||||
int count;
|
||||
count = sscanf(name+len, "%d%n", serial, &plus);
|
||||
if (count < 1) {
|
||||
//MARS_DBG("'%s' serial number mismatch at '%s'\n", name, name+len);
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
len += plus;
|
||||
if (name[len] == '-')
|
||||
len++;
|
||||
}
|
||||
if (prefix)
|
||||
*prefix = len;
|
||||
if (test->cl_hostcontext) {
|
||||
if (memcmp(name+len, my_id(), namlen-len)) {
|
||||
//MARS_DBG("context mismatch '%s' at '%s'\n", name, name+len);
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// all ok
|
||||
status = class;
|
||||
goto done;
|
||||
}
|
||||
|
||||
//MARS_DBG("no match for '%s' '%s'\n", path, name);
|
||||
|
||||
done:
|
||||
#ifdef MARS_DEBUGGING
|
||||
if (name)
|
||||
|
@ -2167,32 +2182,35 @@ void _show_statist(struct mars_global *global)
|
|||
int brick_count = 0;
|
||||
|
||||
down(&global->mutex);
|
||||
MARS_STAT("----------- lists:\n");
|
||||
MARS_STAT("================================== dents:\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++;
|
||||
}
|
||||
MARS_STAT("================================== bricks:\n");
|
||||
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);
|
||||
if (brick_count)
|
||||
MARS_STAT("---------\n");
|
||||
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);
|
||||
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);
|
||||
MARS_STAT(" input %d not connected\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
up(&global->mutex);
|
||||
|
||||
MARS_INF("----------- STATISTICS: %d dents, %d bricks\n", dent_count, brick_count);
|
||||
MARS_INF("==================== STATISTICS: %d dents, %d bricks\n", dent_count, brick_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ static struct task_struct *server_thread = NULL;
|
|||
///////////////////////// 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(struct mars_dent *parent, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
10
mars_sio.c
10
mars_sio.c
|
@ -511,6 +511,15 @@ static struct sio_output_ops sio_output_ops = {
|
|||
.mars_get_info = sio_get_info,
|
||||
};
|
||||
|
||||
const struct sio_input_type sio_input_type = {
|
||||
.type_name = "sio_input",
|
||||
.input_size = sizeof(struct sio_input),
|
||||
};
|
||||
|
||||
static const struct sio_input_type *sio_input_types[] = {
|
||||
&sio_input_type,
|
||||
};
|
||||
|
||||
const struct sio_output_type sio_output_type = {
|
||||
.type_name = "sio_output",
|
||||
.output_size = sizeof(struct sio_output),
|
||||
|
@ -533,6 +542,7 @@ const struct sio_brick_type sio_brick_type = {
|
|||
.max_inputs = 0,
|
||||
.max_outputs = 1,
|
||||
.master_ops = &sio_brick_ops,
|
||||
.default_input_types = sio_input_types,
|
||||
.default_output_types = sio_output_types,
|
||||
.brick_construct = &sio_brick_construct,
|
||||
};
|
||||
|
|
|
@ -154,7 +154,7 @@ void make_test_instance(void)
|
|||
#ifdef CONF_FDSYNC
|
||||
_device_brick->o_fdsync = true;
|
||||
#endif
|
||||
mars_power_button((void*)device_brick, true);
|
||||
mars_power_button((void*)device_brick, true, false);
|
||||
first = device_brick->outputs[0];
|
||||
|
||||
// last
|
||||
|
@ -269,7 +269,7 @@ void make_test_instance(void)
|
|||
|
||||
MARS_INF("------------- START GATE --------------\n");
|
||||
|
||||
mars_power_button((void*)if_brick, true);
|
||||
mars_power_button((void*)if_brick, true, false);
|
||||
//_if_brick->is_active = true;
|
||||
|
||||
msleep(2000);
|
||||
|
|
|
@ -13,7 +13,7 @@ $ip =~ s/\A.*inet +(?!127\.0\.)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*?\Z/$1/ms or di
|
|||
chomp $ip;
|
||||
print "my IP is $ip\n";
|
||||
|
||||
umask 0177;
|
||||
umask 0077;
|
||||
die "only root may use this tool\n" unless `whoami` eq "root\n"; # getpid() seems to be missing in perlfunc
|
||||
|
||||
##################################################################
|
||||
|
@ -67,23 +67,11 @@ sub _trigger {
|
|||
|
||||
sub _switch {
|
||||
my ($path, $on) = @_;
|
||||
|
||||
# Sadly, there is no system call lchmod().
|
||||
# It would be better to use the x flag even of symlinks if it were possible.
|
||||
# As a workaround, we use the owner uid - fortunately this is
|
||||
# changeable, even by perl (although direct calls to lchown()
|
||||
# seems to be missing)
|
||||
|
||||
if($on) {
|
||||
system("chown --no-dereference 0 $path");
|
||||
} else {
|
||||
system("chown --no-dereference nobody $path");
|
||||
}
|
||||
|
||||
my $oldmode = (lstat $path)[2] & 0700;
|
||||
my $newmode = $on ? $oldmode | 0100 : $oldmode & ~0100;
|
||||
print "chmod '$path' $oldmode $newmode";
|
||||
chmod($newmode, $path) == 1 or die "cannot chmod '$path'\n";
|
||||
my $tmp = $path;
|
||||
$tmp =~ s/\/([^\/]+)$/.tmp.$1/;
|
||||
my $src = $on ? "1" : "0";
|
||||
symlink($src, $tmp) or die "cannot create switch symlink\n";
|
||||
rename($tmp, $path) or die "cannot rename switch symlink\n";
|
||||
}
|
||||
|
||||
sub _writable {
|
||||
|
@ -222,6 +210,7 @@ sub create_res {
|
|||
mkdir("$tmp/defaults-$host");
|
||||
mkdir("$tmp/actual-$host");
|
||||
mkdir("$tmp/switch-$host");
|
||||
symlink("1", "$tmp/switch-$host/attach");
|
||||
symlink("0", "$tmp/switch-$host/connect");
|
||||
symlink("0", "$tmp/switch-$host/sync");
|
||||
|
||||
|
@ -245,8 +234,9 @@ sub create_res {
|
|||
sub attach_res {
|
||||
my ($cmd, $res) = @_;
|
||||
my $detach = ($cmd eq "detach");
|
||||
my $path = "$mars/resource-$res/data-$host";
|
||||
my $path = "$mars/resource-$res/switch-$host/attach";
|
||||
_switch($path, !$detach);
|
||||
print "successfully started ${cmd} of resource $res\n"
|
||||
}
|
||||
|
||||
sub connect_res {
|
||||
|
@ -254,6 +244,7 @@ sub connect_res {
|
|||
my $disconnect = ($cmd eq "disconnect");
|
||||
my $path = "$mars/resource-$res/switch-$host/connect";
|
||||
_switch($path, !$disconnect);
|
||||
print "successfully started ${cmd} on resource $res\n"
|
||||
}
|
||||
|
||||
sub pause_res {
|
||||
|
@ -261,6 +252,7 @@ sub pause_res {
|
|||
my $pause = ($cmd eq "pause-sync");
|
||||
my $path = "$mars/resource-$res/switch-$host/sync";
|
||||
_switch($path, !$pause);
|
||||
print "successfully started ${cmd} on resource $res\n"
|
||||
}
|
||||
|
||||
sub up_res {
|
||||
|
|
Loading…
Reference in New Issue