mirror of
https://github.com/schoebel/mars
synced 2025-02-16 20:16:57 +00:00
import mars-63.tgz
This commit is contained in:
parent
db2dfebcb1
commit
a92db584bb
50
brick.c
50
brick.c
@ -629,11 +629,13 @@ void set_button_wait(struct generic_switch *sw, bool val, bool force, int timeou
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_button_wait);
|
||||
|
||||
int set_recursive_button(struct generic_brick *orig_brick, bool val, bool force, int timeout)
|
||||
int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode, int timeout)
|
||||
{
|
||||
struct generic_brick **table = NULL;
|
||||
int max = PAGE_SIZE / sizeof(void*) / 2;
|
||||
int stack;
|
||||
bool val = (mode == BR_ON_ONE || mode == BR_ON_ALL);
|
||||
bool force = (mode != BR_OFF_ONE && mode != BR_OFF_ALL);
|
||||
int status;
|
||||
|
||||
restart:
|
||||
@ -662,26 +664,26 @@ int set_recursive_button(struct generic_brick *orig_brick, bool val, bool force,
|
||||
status = -EDEADLK;
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; i < brick->nr_inputs; i++) {
|
||||
struct generic_input *input = brick->inputs[i];
|
||||
struct generic_output *output;
|
||||
struct generic_brick *next;
|
||||
if (!input)
|
||||
continue;
|
||||
output = input->connect;
|
||||
if (!output)
|
||||
continue;
|
||||
next = output->brick;
|
||||
if (!next)
|
||||
continue;
|
||||
if (next->power.led_on)
|
||||
continue;
|
||||
table[stack++] = next;
|
||||
if (unlikely(stack > max)) {
|
||||
goto restart;
|
||||
if (mode >= BR_ON_ALL) {
|
||||
for (i = 0; i < brick->nr_inputs; i++) {
|
||||
struct generic_input *input = brick->inputs[i];
|
||||
struct generic_output *output;
|
||||
struct generic_brick *next;
|
||||
if (!input)
|
||||
continue;
|
||||
output = input->connect;
|
||||
if (!output)
|
||||
continue;
|
||||
next = output->brick;
|
||||
if (!next)
|
||||
continue;
|
||||
table[stack++] = next;
|
||||
if (unlikely(stack > max)) {
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (mode >= BR_ON_ALL) {
|
||||
int i;
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
struct generic_output *output = brick->outputs[i];
|
||||
@ -693,8 +695,6 @@ int set_recursive_button(struct generic_brick *orig_brick, bool val, bool force,
|
||||
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;
|
||||
if (next->power.led_off)
|
||||
continue;
|
||||
table[stack++] = next;
|
||||
if (unlikely(stack > max)) {
|
||||
goto restart;
|
||||
@ -713,6 +713,14 @@ int set_recursive_button(struct generic_brick *orig_brick, bool val, bool force,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (force && !val && (mode == BR_FREE_ONE || mode == BR_FREE_ALL) && brick->free) {
|
||||
status = brick->free(brick);
|
||||
if (status < 0) {
|
||||
BRICK_DBG("freeing brick '%s' (%s) failed, status = %d\n", brick->brick_name, orig_brick->brick_name, status);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
status = 0;
|
||||
|
||||
|
20
brick.h
20
brick.h
@ -142,6 +142,7 @@ struct generic_switch {
|
||||
struct BRICK##_input **inputs; \
|
||||
struct BRICK##_output **outputs; \
|
||||
struct generic_switch power; \
|
||||
int (*free)(struct BRICK##_brick *del); \
|
||||
struct list_head tmp_head; \
|
||||
|
||||
struct generic_brick {
|
||||
@ -684,7 +685,9 @@ extern void set_lamport(struct timespec *old);
|
||||
|
||||
#endif
|
||||
|
||||
/* Generic interface to simple brick status changes
|
||||
/* Generic interface to simple brick status changes.
|
||||
*
|
||||
* "Forced switch off" means that it cannot be switched on again.
|
||||
*/
|
||||
extern void set_button(struct generic_switch *sw, bool val, bool force);
|
||||
extern void set_button_wait(struct generic_switch *sw, bool val, bool force, int timeout);
|
||||
@ -701,7 +704,20 @@ extern void set_led_off(struct generic_switch *sw, bool val);
|
||||
* There is one exception: when @force is set, only the direction to
|
||||
* "off" remains possible. This is useful for emergency shutdowns.
|
||||
*/
|
||||
extern int set_recursive_button(struct generic_brick *brick, bool val, bool force, int timeout);
|
||||
typedef enum {
|
||||
// only one brick instance
|
||||
BR_ON_ONE, // switch on one brick instance
|
||||
BR_OFF_ONE, // just switch off (may be switched on again)
|
||||
BR_KILL_ONE, // forced switch off => may be never switched on again
|
||||
BR_FREE_ONE, // forced switch off + deallocation (when possible)
|
||||
// dito, but operating on the whole graph
|
||||
BR_ON_ALL,
|
||||
BR_OFF_ALL,
|
||||
BR_KILL_ALL,
|
||||
BR_FREE_ALL,
|
||||
} brick_switch_t;
|
||||
|
||||
extern int set_recursive_button(struct generic_brick *brick, brick_switch_t mode, int timeout);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
35
mars.h
35
mars.h
@ -248,11 +248,11 @@ extern const struct meta mars_mref_meta[];
|
||||
extern struct mars_global *mars_global;
|
||||
|
||||
extern void mars_trigger(void);
|
||||
extern int mars_power_button(struct mars_brick *brick, bool val, bool force);
|
||||
extern int mars_power_button(struct mars_brick *brick, bool val);
|
||||
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, bool force, int timeout);
|
||||
extern int mars_power_button_recursive(struct mars_brick *brick, bool val, int timeout);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -295,11 +295,13 @@ extern const struct meta mars_timespec_meta[];
|
||||
extern const struct meta mars_kstat_meta[];
|
||||
extern const struct meta mars_dent_meta[];
|
||||
|
||||
extern struct generic_brick_type *_client_brick_type; // for avoidance of cyclic references
|
||||
|
||||
struct mars_global {
|
||||
struct semaphore mutex;
|
||||
struct generic_switch global_power;
|
||||
struct list_head dent_anchor;
|
||||
struct list_head brick_anchor;
|
||||
struct generic_switch global_power;
|
||||
struct semaphore mutex;
|
||||
volatile bool main_trigger;
|
||||
wait_queue_head_t main_event;
|
||||
//void *private;
|
||||
@ -314,8 +316,33 @@ extern struct mars_dent *mars_find_dent(struct mars_global *global, const char *
|
||||
extern void mars_dent_free(struct mars_dent *dent);
|
||||
extern void mars_dent_free_all(struct list_head *anchor);
|
||||
|
||||
// lowe-level brick instantiation
|
||||
|
||||
extern struct mars_brick *mars_find_brick(struct mars_global *global, const void *brick_type, const char *path);
|
||||
extern struct mars_brick *mars_make_brick(struct mars_global *global, const void *_brick_type, const char *path, const char *name);
|
||||
extern int mars_free_brick(struct mars_brick *brick);
|
||||
extern int mars_kill_brick(struct mars_brick *brick);
|
||||
|
||||
// mid-level brick instantiation (identity is based on path strings)
|
||||
|
||||
extern char *vpath_make(struct mars_dent *father, const char *fmt, va_list *args);
|
||||
extern char *path_make(struct mars_dent *father, const char *fmt, ...);
|
||||
|
||||
extern struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, struct mars_dent *father, const char *fmt, ...);
|
||||
|
||||
extern struct mars_brick *make_brick_all(
|
||||
struct mars_global *global,
|
||||
struct mars_dent *father,
|
||||
struct generic_brick_type *new_brick_type,
|
||||
const char *new_name,
|
||||
int timeout,
|
||||
const char *new_fmt,
|
||||
const char *prev_fmt[],
|
||||
int prev_count,
|
||||
...
|
||||
);
|
||||
|
||||
// general MARS infrastructure
|
||||
|
||||
#define MARS_ERR_ONCE(dent, args...) if (!dent->d_once_error++) MARS_ERR(args)
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#define _STRATEGY // only for _client_brick_type
|
||||
#include "mars.h"
|
||||
|
||||
///////////////////////// own type definitions ////////////////////////
|
||||
@ -493,6 +494,7 @@ EXPORT_SYMBOL_GPL(client_brick_type);
|
||||
static int __init init_client(void)
|
||||
{
|
||||
MARS_INF("init_client()\n");
|
||||
_client_brick_type = (void*)&client_brick_type;
|
||||
return client_register_brick_type();
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ static int device_aio_switch(struct device_aio_brick *brick)
|
||||
{
|
||||
static int index = 0;
|
||||
struct device_aio_output *output = brick->outputs[0];
|
||||
const char *path = output->output_name;
|
||||
const char *path = output->brick->brick_name;
|
||||
int flags = O_CREAT | O_RDWR | O_LARGEFILE;
|
||||
int prot = 0600;
|
||||
mm_segment_t oldfs;
|
||||
@ -533,7 +533,7 @@ static int device_aio_output_construct(struct device_aio_output *output)
|
||||
|
||||
static int device_aio_output_destruct(struct device_aio_output *output)
|
||||
{
|
||||
return mars_power_button((void*)output->brick, false, true);
|
||||
return mars_power_button((void*)output->brick, false);
|
||||
}
|
||||
|
||||
///////////////////////// static structs ////////////////////////
|
||||
|
376
mars_generic.c
376
mars_generic.c
@ -18,6 +18,73 @@
|
||||
#include <linux/namei.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// meta descriptions
|
||||
|
||||
const struct meta mars_info_meta[] = {
|
||||
META_INI(current_size, struct mars_info, FIELD_INT),
|
||||
META_INI(transfer_order, struct mars_info, FIELD_INT),
|
||||
META_INI(transfer_size, struct mars_info, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_info_meta);
|
||||
|
||||
const struct meta mars_mref_meta[] = {
|
||||
META_INI(ref_pos, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_len, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_may_write, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_flags, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_rw, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_id, struct mref_object, FIELD_INT),
|
||||
META_INI(_ref_cb.cb_error, struct mref_object, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_mref_meta);
|
||||
|
||||
const struct meta mars_timespec_meta[] = {
|
||||
META_INI(tv_sec, struct timespec, FIELD_INT),
|
||||
META_INI(tv_nsec, struct timespec, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_timespec_meta);
|
||||
|
||||
const struct meta mars_kstat_meta[] = {
|
||||
META_INI(ino, struct kstat, FIELD_INT),
|
||||
META_INI(mode, struct kstat, FIELD_INT),
|
||||
META_INI(size, struct kstat, FIELD_INT),
|
||||
META_INI_SUB(atime, struct kstat, mars_timespec_meta),
|
||||
META_INI_SUB(mtime, struct kstat, mars_timespec_meta),
|
||||
META_INI_SUB(ctime, struct kstat, mars_timespec_meta),
|
||||
META_INI(blksize, struct kstat, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_kstat_meta);
|
||||
|
||||
const struct meta mars_dent_meta[] = {
|
||||
META_INI(d_name, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_rest, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_path, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_namelen, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_pathlen, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_type, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_class, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_version, struct mars_dent, FIELD_INT),
|
||||
META_INI_SUB(new_stat,struct mars_dent, mars_kstat_meta),
|
||||
META_INI_SUB(old_stat,struct mars_dent, mars_kstat_meta),
|
||||
META_INI(new_link, struct mars_dent, FIELD_STRING),
|
||||
META_INI(old_link, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_args, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[0], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[1], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[2], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[3], struct mars_dent, FIELD_STRING),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_dent_meta);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// some helpers
|
||||
|
||||
int mars_lstat(const char *path, struct kstat *stat)
|
||||
@ -178,7 +245,7 @@ void mars_trigger(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_trigger);
|
||||
|
||||
int mars_power_button(struct mars_brick *brick, bool val, bool force)
|
||||
int mars_power_button(struct mars_brick *brick, bool val)
|
||||
{
|
||||
int status = 0;
|
||||
bool oldval = brick->power.button;
|
||||
@ -186,10 +253,10 @@ int mars_power_button(struct mars_brick *brick, bool val, bool force)
|
||||
if (brick->power.force_off)
|
||||
val = false;
|
||||
|
||||
if (val != oldval || force) {
|
||||
if (val != oldval) {
|
||||
MARS_DBG("brick '%s' type '%s' power button %d -> %d\n", brick->brick_path, brick->type->type_name, oldval, val);
|
||||
|
||||
set_button(&brick->power, val, force);
|
||||
set_button(&brick->power, val, false);
|
||||
|
||||
if (brick->ops)
|
||||
status = brick->ops->brick_switch(brick);
|
||||
@ -200,7 +267,7 @@ int mars_power_button(struct mars_brick *brick, bool val, bool force)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_power_button);
|
||||
|
||||
int mars_power_button_recursive(struct mars_brick *brick, bool val, bool force, int timeout)
|
||||
int mars_power_button_recursive(struct mars_brick *brick, bool val, int timeout)
|
||||
{
|
||||
int status = 0;
|
||||
bool oldval = brick->power.button;
|
||||
@ -208,15 +275,13 @@ int mars_power_button_recursive(struct mars_brick *brick, bool val, bool force,
|
||||
if (brick->power.force_off)
|
||||
val = false;
|
||||
|
||||
if (val != oldval || force) {
|
||||
MARS_DBG("brick '%s' type '%s' power button %d -> %d\n", brick->brick_path, brick->type->type_name, oldval, val);
|
||||
if (val != oldval) {
|
||||
brick_switch_t mode;
|
||||
mode = (val ? BR_ON_ALL : BR_OFF_ALL);
|
||||
|
||||
status = set_recursive_button((void*)brick, val, force, timeout);
|
||||
|
||||
if (status >= 0)
|
||||
status = brick->ops->brick_switch(brick);
|
||||
MARS_DBG("brick '%s' type '%s' power button %d -> %d (mode = %d)\n", brick->brick_path, brick->type->type_name, oldval, val, mode);
|
||||
|
||||
mars_trigger();
|
||||
status = set_recursive_button((void*)brick, mode, timeout);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -619,6 +684,10 @@ void mars_dent_free_all(struct list_head *anchor)
|
||||
EXPORT_SYMBOL_GPL(mars_dent_free_all);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// low-level brick instantiation
|
||||
|
||||
struct mars_brick *mars_find_brick(struct mars_global *global, const void *brick_type, const char *path)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
@ -646,6 +715,53 @@ struct mars_brick *mars_find_brick(struct mars_global *global, const void *brick
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_find_brick);
|
||||
|
||||
int mars_free_brick(struct mars_brick *brick)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
|
||||
if (!brick) {
|
||||
MARS_ERR("bad brick parameter\n");
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!brick->power.force_off || !brick->power.led_off) {
|
||||
MARS_DBG("brick '%s' is not freeable\n", brick->brick_name);
|
||||
status = -ETXTBSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// first check whether the brick is in use somewhere
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
if (brick->outputs[i]->nr_connected > 0) {
|
||||
MARS_DBG("brick '%s' not freeable, output %i is used\n", brick->brick_name, i);
|
||||
status = -EEXIST;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
MARS_DBG("===> freeing brick name = '%s'\n", brick->brick_name);
|
||||
|
||||
#if 1 // TODO: debug locking crash
|
||||
(void)generic_brick_exit_full((void*)brick);
|
||||
#endif
|
||||
|
||||
if (brick->brick_name)
|
||||
kfree(brick->brick_name);
|
||||
if (brick->brick_path)
|
||||
kfree(brick->brick_path);
|
||||
kfree(brick);
|
||||
|
||||
mars_trigger();
|
||||
|
||||
status = 0;
|
||||
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_free_brick);
|
||||
|
||||
struct mars_brick *mars_make_brick(struct mars_global *global, const void *_brick_type, const char *path, const char *_name)
|
||||
{
|
||||
const char *name = kstrdup(_name, GFP_MARS);
|
||||
@ -702,6 +818,7 @@ struct mars_brick *mars_make_brick(struct mars_global *global, const void *_bric
|
||||
MARS_ERR("cannot init brick %s\n", brick_type->type_name);
|
||||
goto err_path;
|
||||
}
|
||||
res->free = mars_free_brick;
|
||||
|
||||
/* Immediately make it visible, regardless of internal state.
|
||||
* Switching on / etc must be done separately.
|
||||
@ -710,6 +827,8 @@ struct mars_brick *mars_make_brick(struct mars_global *global, const void *_bric
|
||||
list_add(&res->brick_link, &global->brick_anchor);
|
||||
up(&global->mutex);
|
||||
|
||||
mars_trigger();
|
||||
|
||||
return res;
|
||||
|
||||
err_path:
|
||||
@ -722,71 +841,192 @@ err_name:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_make_brick);
|
||||
|
||||
int mars_kill_brick(struct mars_brick *brick)
|
||||
{
|
||||
struct mars_global *global;
|
||||
int status = -EINVAL;
|
||||
|
||||
CHECK_PTR(brick, done);
|
||||
global = brick->global;
|
||||
CHECK_PTR(global, done);
|
||||
|
||||
MARS_DBG("===> killing brick path = '%s' name = '%s'\n", brick->brick_path, brick->brick_name);
|
||||
|
||||
down(&global->mutex);
|
||||
list_del_init(&brick->brick_link);
|
||||
up(&global->mutex);
|
||||
|
||||
// start shutdown
|
||||
status = set_recursive_button((void*)brick, BR_FREE_ALL, 10 * HZ);
|
||||
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mars_kill_brick);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// meta descriptions
|
||||
// mid-level brick instantiation (identity is based on path strings)
|
||||
|
||||
const struct meta mars_info_meta[] = {
|
||||
META_INI(current_size, struct mars_info, FIELD_INT),
|
||||
META_INI(transfer_order, struct mars_info, FIELD_INT),
|
||||
META_INI(transfer_size, struct mars_info, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_info_meta);
|
||||
char *vpath_make(struct mars_dent *father, const char *fmt, va_list *args)
|
||||
{
|
||||
int len = father->d_pathlen;
|
||||
char *res = kmalloc(len + MARS_PATH_MAX, GFP_MARS);
|
||||
|
||||
const struct meta mars_mref_meta[] = {
|
||||
META_INI(ref_pos, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_len, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_may_write, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_flags, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_rw, struct mref_object, FIELD_INT),
|
||||
META_INI(ref_id, struct mref_object, FIELD_INT),
|
||||
META_INI(_ref_cb.cb_error, struct mref_object, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_mref_meta);
|
||||
if (likely(res)) {
|
||||
memcpy(res, father->d_path, len);
|
||||
vsnprintf(res + len, MARS_PATH_MAX, fmt, *args);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vpath_make);
|
||||
|
||||
const struct meta mars_timespec_meta[] = {
|
||||
META_INI(tv_sec, struct timespec, FIELD_INT),
|
||||
META_INI(tv_nsec, struct timespec, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_timespec_meta);
|
||||
char *path_make(struct mars_dent *father, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *res;
|
||||
va_start(args, fmt);
|
||||
res = vpath_make(father, fmt, &args);
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(path_make);
|
||||
|
||||
const struct meta mars_kstat_meta[] = {
|
||||
META_INI(ino, struct kstat, FIELD_INT),
|
||||
META_INI(mode, struct kstat, FIELD_INT),
|
||||
META_INI(size, struct kstat, FIELD_INT),
|
||||
META_INI_SUB(atime, struct kstat, mars_timespec_meta),
|
||||
META_INI_SUB(mtime, struct kstat, mars_timespec_meta),
|
||||
META_INI_SUB(ctime, struct kstat, mars_timespec_meta),
|
||||
META_INI(blksize, struct kstat, FIELD_INT),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_kstat_meta);
|
||||
struct mars_brick *path_find_brick(struct mars_global *global, const void *brick_type, struct mars_dent *father, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *fullpath;
|
||||
struct mars_brick *res;
|
||||
|
||||
const struct meta mars_dent_meta[] = {
|
||||
META_INI(d_name, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_rest, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_path, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_namelen, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_pathlen, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_type, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_class, struct mars_dent, FIELD_INT),
|
||||
META_INI(d_version, struct mars_dent, FIELD_INT),
|
||||
META_INI_SUB(new_stat,struct mars_dent, mars_kstat_meta),
|
||||
META_INI_SUB(old_stat,struct mars_dent, mars_kstat_meta),
|
||||
META_INI(new_link, struct mars_dent, FIELD_STRING),
|
||||
META_INI(old_link, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_args, struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[0], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[1], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[2], struct mars_dent, FIELD_STRING),
|
||||
META_INI(d_argv[3], struct mars_dent, FIELD_STRING),
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mars_dent_meta);
|
||||
va_start(args, fmt);
|
||||
fullpath = vpath_make(father, fmt, &args);
|
||||
va_end(args);
|
||||
|
||||
if (!fullpath) {
|
||||
return NULL;
|
||||
}
|
||||
res = mars_find_brick(global, brick_type, fullpath);
|
||||
kfree(fullpath);
|
||||
MARS_DBG("search for '%s' found = %p\n", fullpath, res);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(path_find_brick);
|
||||
|
||||
struct generic_brick_type *_client_brick_type = NULL;
|
||||
EXPORT_SYMBOL_GPL(_client_brick_type);
|
||||
|
||||
struct mars_brick *make_brick_all(
|
||||
struct mars_global *global,
|
||||
struct mars_dent *father,
|
||||
struct generic_brick_type *new_brick_type,
|
||||
const char *new_name,
|
||||
int timeout,
|
||||
const char *new_fmt,
|
||||
const char *prev_fmt[],
|
||||
int prev_count,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list args;
|
||||
char *new_path;
|
||||
struct mars_brick *brick = NULL;
|
||||
char *paths[prev_count];
|
||||
struct mars_brick *prev[prev_count];
|
||||
int i;
|
||||
|
||||
// treat variable arguments
|
||||
va_start(args, prev_count);
|
||||
new_path = vpath_make(father, new_fmt, &args);
|
||||
for (i = 0; i < prev_count; i++) {
|
||||
paths[i] = vpath_make(father, prev_fmt[i], &args);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
if (!new_path) {
|
||||
MARS_ERR("could not create new path\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// don't do anything if brick already exists
|
||||
brick = mars_find_brick(global, new_brick_type, new_path);
|
||||
if (brick) {
|
||||
MARS_DBG("found brick '%s'\n", new_path);
|
||||
goto done;
|
||||
}
|
||||
|
||||
MARS_DBG("----> new brick '%s'\n", new_path);
|
||||
// get all predecessor bricks
|
||||
for (i = 0; i < prev_count; i++) {
|
||||
char *path = paths[i];
|
||||
|
||||
if (!path) {
|
||||
MARS_ERR("could not create path %d\n", i);
|
||||
goto err;
|
||||
}
|
||||
|
||||
prev[i] = mars_find_brick(global, NULL, path);
|
||||
if (!prev[i] && _client_brick_type) {
|
||||
char *remote = strchr(path, '@');
|
||||
if (remote) {
|
||||
remote++;
|
||||
prev[i] = mars_make_brick(global, _client_brick_type, path, remote);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prev[i]) {
|
||||
MARS_ERR("prev brick '%s' does not exist\n", path);
|
||||
goto err;
|
||||
}
|
||||
MARS_DBG("------> predecessor %d '%s'\n", i, path);
|
||||
}
|
||||
|
||||
// create it...
|
||||
brick = mars_make_brick(global, new_brick_type, new_path, new_name);
|
||||
if (unlikely(!brick)) {
|
||||
MARS_DBG("creation failed '%s' '%s'\n", new_path, new_name);
|
||||
goto err;
|
||||
}
|
||||
if (unlikely(brick->nr_inputs < prev_count)) {
|
||||
MARS_ERR("wrong number of arguments: %d < %d\n", brick->nr_inputs, prev_count);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// connect the wires
|
||||
for (i = 0; i < prev_count; i++) {
|
||||
int status;
|
||||
status = generic_connect((void*)brick->inputs[i], (void*)prev[i]->outputs[0]);
|
||||
if (unlikely(status < 0)) {
|
||||
MARS_ERR("'%s' '%s' cannot connect input %d\n", new_path, new_name, i);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
// switch on (may fail silently, but responsibility is at the workers)
|
||||
if (timeout > 0) {
|
||||
int status;
|
||||
status = mars_power_button_recursive((void*)brick, true, timeout);
|
||||
MARS_DBG("switch on status = %d\n", status);
|
||||
}
|
||||
|
||||
return brick;
|
||||
|
||||
err:
|
||||
if (brick)
|
||||
mars_kill_brick(brick);
|
||||
brick = NULL;
|
||||
done:
|
||||
for (i = 0; i < prev_count; i++) {
|
||||
if (paths[i]) {
|
||||
kfree(paths[i]);
|
||||
}
|
||||
}
|
||||
if (new_path)
|
||||
kfree(new_path);
|
||||
|
||||
return brick;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(make_brick_all);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
243
mars_light.c
243
mars_light.c
@ -31,11 +31,7 @@
|
||||
|
||||
static struct task_struct *main_thread = NULL;
|
||||
|
||||
struct light_dent {
|
||||
MARS_DENT(light_dent);
|
||||
};
|
||||
|
||||
typedef int (*light_worker_fn)(void *buf, struct light_dent *dent);
|
||||
typedef int (*light_worker_fn)(void *buf, struct mars_dent *dent);
|
||||
|
||||
struct light_class {
|
||||
char *cl_name;
|
||||
@ -48,104 +44,12 @@ struct light_class {
|
||||
light_worker_fn cl_backward;
|
||||
};
|
||||
|
||||
static
|
||||
struct mars_brick *make_brick(struct mars_global *global, const void *_brick_type, const char *path, const char *name)
|
||||
{
|
||||
struct mars_brick *res;
|
||||
MARS_DBG("type = '%s' path = '%s' name = '%s'\n", ((struct generic_brick_type*)_brick_type)->type_name, path, name);
|
||||
res = mars_make_brick(global, _brick_type, path, name);
|
||||
MARS_DBG("brick = %p\n", res);
|
||||
if (res) {
|
||||
mars_trigger();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static
|
||||
int kill_brick(struct mars_brick *brick, int max_level)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
|
||||
if (!brick) {
|
||||
MARS_ERR("bad brick parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// first check whether the brick is in use somewhere
|
||||
for (i = 0; i < brick->nr_outputs; i++) {
|
||||
if (brick->outputs[i]->nr_connected > 0) {
|
||||
MARS_DBG("brick '%s' not killable, output %i is used\n", brick->brick_name, i);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
MARS_DBG("===> killing brick name = '%s'\n", brick->brick_name);
|
||||
|
||||
// start shutdown
|
||||
#if 1
|
||||
status = mars_power_button_recursive((void*)brick, false, true, 5 * HZ);
|
||||
#else
|
||||
status = mars_power_button((void*)brick, false, true);
|
||||
|
||||
MARS_DBG("kill '%s' status = %d led_off = %d\n", brick->brick_name, status, brick->power.led_off);
|
||||
|
||||
// wait until clean shutdown
|
||||
if (status >= 0 && brick->power.led_off) {
|
||||
int count = 0;
|
||||
struct mars_brick *prev[brick->nr_inputs];
|
||||
|
||||
// remove from the global list => no longer visible
|
||||
down(&brick->global->mutex);
|
||||
list_del_init(&brick->brick_link);
|
||||
up(&brick->global->mutex);
|
||||
|
||||
/* Disconnect all inputs.
|
||||
* This must not start earlier, because during shutdown
|
||||
* the inputs could be needed for cleanup operations etc.
|
||||
*/
|
||||
for (i = 0; i < brick->nr_inputs; i++) {
|
||||
if (brick->inputs[i]->connect) {
|
||||
prev[count++] = brick->inputs[i]->connect->brick;
|
||||
(void)generic_disconnect((void*)brick->inputs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* recursively kill predecessors
|
||||
*/
|
||||
if (max_level > 0) {
|
||||
struct mars_brick *old = NULL;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!prev[i] || prev[i] == old || list_empty(&prev[i]->brick_link))
|
||||
continue;
|
||||
old = prev[i];
|
||||
status |= kill_brick(prev[i], max_level - 1);
|
||||
#if 1
|
||||
msleep(500);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* This runs unchecked and may therefore leave memory remains,
|
||||
* but we currently have no separate list for "zombies".
|
||||
* TODO: do better.
|
||||
*/
|
||||
#if 0 // TODO: debug locking crash
|
||||
(void)generic_brick_exit_full((void*)brick);
|
||||
#endif
|
||||
mars_trigger();
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
// internal helpers
|
||||
|
||||
static
|
||||
void _normalized_path(char *res, int maxlen, struct light_dent *father, const char *prefix, const char *suffix)
|
||||
void _normalized_path(char *res, int maxlen, struct mars_dent *father, const char *prefix, const char *suffix)
|
||||
{
|
||||
char *test;
|
||||
int prelen;
|
||||
@ -189,8 +93,7 @@ done:
|
||||
*res = '\0';
|
||||
}
|
||||
|
||||
static
|
||||
struct mars_brick *find_other(struct mars_global *global, const void *brick_type, struct light_dent *father, const char *prefix, const char *suffix)
|
||||
struct mars_brick *find_other(struct mars_global *global, const void *brick_type, struct mars_dent *father, const char *prefix, const char *suffix)
|
||||
{
|
||||
int len = (father ? father->d_pathlen : 0)
|
||||
+ strlen(prefix)
|
||||
@ -206,12 +109,11 @@ struct mars_brick *find_other(struct mars_global *global, const void *brick_type
|
||||
/* Create a new brick and connect its inputs to a set of predecessors.
|
||||
* Before starting that, check whether all predecessors exist and are healthy.
|
||||
*/
|
||||
static
|
||||
struct mars_brick *make_all(struct mars_global *global,
|
||||
const void *new_brick_type,
|
||||
const char *new_path,
|
||||
const char *new_name,
|
||||
struct light_dent *father,
|
||||
struct mars_dent *father,
|
||||
const void *brick_type[],
|
||||
const char *prefix[],
|
||||
const char *suffix[],
|
||||
@ -242,30 +144,13 @@ struct mars_brick *make_all(struct mars_global *global,
|
||||
}
|
||||
}
|
||||
|
||||
// special case for client brick: treat network indirection
|
||||
if (new_brick_type == &client_brick_type) {
|
||||
struct mars_dent *test;
|
||||
char path[256];
|
||||
snprintf(path, sizeof(path), "/mars/ips/ip-%s", new_name);
|
||||
test = mars_find_dent(global, path);
|
||||
if (test && test->new_link) {
|
||||
MARS_DBG("translation '%s' => '%s'\n", new_name, test->new_link);
|
||||
new_name = test->new_link;
|
||||
}
|
||||
}
|
||||
|
||||
// create it...
|
||||
brick = make_brick(global, new_brick_type, fullpath, new_name);
|
||||
brick = mars_make_brick(global, new_brick_type, fullpath, new_name);
|
||||
if (unlikely(!brick)) {
|
||||
MARS_DBG("creation failed '%s' '%s'\n", fullpath, new_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// special case for aio: file name is treated different IMPROVEME!
|
||||
if (new_brick_type == &device_aio_brick_type) {
|
||||
brick->outputs[0]->output_name = brick->brick_name;
|
||||
}
|
||||
|
||||
// connect the wires
|
||||
for (i = 0; i < count; i++) {
|
||||
status = generic_connect((void*)brick->inputs[i], (void*)prev[i]->outputs[0]);
|
||||
@ -281,13 +166,13 @@ struct mars_brick *make_all(struct mars_global *global,
|
||||
|
||||
// switch on (may fail silently, but responsibility is at the workers)
|
||||
if (switch_on) {
|
||||
status = mars_power_button((void*)brick, true, false);
|
||||
status = mars_power_button((void*)brick, true);
|
||||
MARS_DBG("switch on status = %d\n", status);
|
||||
}
|
||||
return brick;
|
||||
|
||||
err:
|
||||
status = kill_brick(brick, 0);
|
||||
status = mars_kill_brick(brick);
|
||||
if (status >= 0) {
|
||||
brick = NULL;
|
||||
}
|
||||
@ -296,7 +181,7 @@ err:
|
||||
|
||||
#define MARS_DELIM ','
|
||||
|
||||
static int _parse_args(struct light_dent *dent, char *str, int count)
|
||||
static int _parse_args(struct mars_dent *dent, char *str, int count)
|
||||
{
|
||||
int i;
|
||||
int status = -EINVAL;
|
||||
@ -350,7 +235,7 @@ done:
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
int __make_copy(struct mars_global *global, struct light_dent *parent, const char *path, const char *argv[], loff_t start_pos, struct copy_brick **__copy)
|
||||
int __make_copy(struct mars_global *global, struct mars_dent *parent, const char *path, const char *argv[], loff_t start_pos, struct copy_brick **__copy)
|
||||
{
|
||||
const char *new_argv[4];
|
||||
struct mars_brick *copy;
|
||||
@ -464,7 +349,7 @@ int __make_copy(struct mars_global *global, struct light_dent *parent, const cha
|
||||
_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((void*)copy, true, false);
|
||||
status = mars_power_button((void*)copy, true);
|
||||
MARS_DBG("copy switch status = %d\n", status);
|
||||
}
|
||||
}
|
||||
@ -491,7 +376,7 @@ struct mars_peerinfo {
|
||||
};
|
||||
|
||||
static
|
||||
int _update_file(struct mars_global *global, struct light_dent *parent, const char *peer, const char *path)
|
||||
int _update_file(struct mars_global *global, struct mars_dent *parent, const char *peer, const char *path)
|
||||
{
|
||||
char tmp[MARS_PATH_MAX] = {};
|
||||
const char *argv[2] = { tmp, path};
|
||||
@ -526,7 +411,7 @@ int _is_peer_logfile(const char *name, const char *id)
|
||||
}
|
||||
|
||||
static
|
||||
int run_bones(void *buf, struct light_dent *dent)
|
||||
int run_bones(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
int status = 0;
|
||||
struct mars_peerinfo *peer = buf;
|
||||
@ -697,7 +582,7 @@ int remote_thread(void *data)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
for (tmp = tmp_list.next; tmp != &tmp_list; tmp = tmp->next) {
|
||||
struct light_dent *dent = container_of(tmp, struct light_dent, sub_link);
|
||||
struct mars_dent *dent = container_of(tmp, struct mars_dent, sub_link);
|
||||
if (!dent->d_path) {
|
||||
MARS_DBG("NULL\n");
|
||||
continue;
|
||||
@ -732,7 +617,7 @@ done:
|
||||
|
||||
// helpers for worker functions
|
||||
|
||||
static int _kill_peer(void *buf, struct light_dent *dent)
|
||||
static int _kill_peer(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct mars_peerinfo *peer = dent->d_private;
|
||||
@ -755,7 +640,7 @@ static int _kill_peer(void *buf, struct light_dent *dent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _make_peer(void *buf, struct light_dent *dent, char *mypeer, char *path, light_worker_fn worker)
|
||||
static int _make_peer(void *buf, struct mars_dent *dent, char *mypeer, char *path, light_worker_fn worker)
|
||||
{
|
||||
static int serial = 0;
|
||||
struct mars_global *global = buf;
|
||||
@ -804,22 +689,22 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int _kill_remote(void *buf, struct light_dent *dent)
|
||||
static int _kill_remote(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
return _kill_peer(buf, dent);
|
||||
}
|
||||
|
||||
static int _make_remote(void *buf, struct light_dent *dent)
|
||||
static int _make_remote(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
return _make_peer(buf, dent, NULL, "/mars", NULL);
|
||||
}
|
||||
|
||||
static int kill_scan(void *buf, struct light_dent *dent)
|
||||
static int kill_scan(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
return _kill_peer(buf, dent);
|
||||
}
|
||||
|
||||
static int make_scan(void *buf, struct light_dent *dent)
|
||||
static int make_scan(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
MARS_DBG("path = '%s' peer = '%s'\n", dent->d_path, dent->d_rest);
|
||||
if (!strcmp(dent->d_rest, my_id())) {
|
||||
@ -830,7 +715,7 @@ static int make_scan(void *buf, struct light_dent *dent)
|
||||
|
||||
|
||||
static
|
||||
int _kill_default(void *buf, struct light_dent *dent, int maxlevel)
|
||||
int kill_all(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct mars_brick *brick;
|
||||
@ -843,37 +728,23 @@ int _kill_default(void *buf, struct light_dent *dent, int maxlevel)
|
||||
if (!brick) {
|
||||
return 0;
|
||||
}
|
||||
return kill_brick(brick, maxlevel);
|
||||
return mars_kill_brick(brick);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int kill_default(void *buf, struct light_dent *dent)
|
||||
{
|
||||
return _kill_default(buf, dent, 0);
|
||||
}
|
||||
|
||||
static
|
||||
int kill_all(void *buf, struct light_dent *dent)
|
||||
{
|
||||
return _kill_default(buf, dent, 999);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
// handlers / helpers for logfile rotation
|
||||
|
||||
struct mars_rotate {
|
||||
struct light_dent *replay_link;
|
||||
struct light_dent *aio_dent;
|
||||
struct mars_dent *replay_link;
|
||||
struct mars_dent *aio_dent;
|
||||
struct device_aio_brick *aio_brick;
|
||||
struct mars_info aio_info;
|
||||
struct trans_logger_brick *trans_brick;
|
||||
struct light_dent *relevant_log;
|
||||
struct light_dent *current_log;
|
||||
struct light_dent *prev_log;
|
||||
struct light_dent *next_log;
|
||||
struct mars_dent *relevant_log;
|
||||
struct mars_dent *current_log;
|
||||
struct mars_dent *prev_log;
|
||||
struct mars_dent *next_log;
|
||||
long long last_jiffies;
|
||||
loff_t start_pos;
|
||||
loff_t end_pos;
|
||||
@ -904,7 +775,7 @@ void _create_new_logfile(char *path)
|
||||
}
|
||||
|
||||
static
|
||||
int _update_link(struct mars_rotate *rot, struct light_dent *parent, int sequence, loff_t pos)
|
||||
int _update_link(struct mars_rotate *rot, struct mars_dent *parent, int sequence, loff_t pos)
|
||||
{
|
||||
struct timespec now = {};
|
||||
char old[MARS_PATH_MAX] = {};
|
||||
@ -931,14 +802,14 @@ int _update_link(struct mars_rotate *rot, struct light_dent *parent, int sequenc
|
||||
/* This must be called once at every round of logfile checking.
|
||||
*/
|
||||
static
|
||||
int make_log_init(void *buf, struct light_dent *parent)
|
||||
int make_log_init(void *buf, struct mars_dent *parent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct mars_brick *aio_brick;
|
||||
struct mars_brick *trans_brick;
|
||||
struct mars_rotate *rot = parent->d_private;
|
||||
struct light_dent *replay_link;
|
||||
struct light_dent *aio_dent;
|
||||
struct mars_dent *replay_link;
|
||||
struct mars_dent *aio_dent;
|
||||
struct mars_output *output;
|
||||
char tmp[MARS_PATH_MAX] = {};
|
||||
int status;
|
||||
@ -1074,9 +945,9 @@ done:
|
||||
* ret == 3 : relevant for appending
|
||||
*/
|
||||
static
|
||||
int _check_logging_status(struct mars_global *global, struct light_dent *dent, long long *oldpos, long long *newpos)
|
||||
int _check_logging_status(struct mars_global *global, struct mars_dent *dent, long long *oldpos, long long *newpos)
|
||||
{
|
||||
struct light_dent *parent = dent->d_parent;
|
||||
struct mars_dent *parent = dent->d_parent;
|
||||
struct mars_rotate *rot = parent->d_private;
|
||||
int status = -EINVAL;
|
||||
|
||||
@ -1130,13 +1001,13 @@ done:
|
||||
* This is important!
|
||||
*/
|
||||
static
|
||||
int make_log(void *buf, struct light_dent *dent)
|
||||
int make_log(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct light_dent *parent = dent->d_parent;
|
||||
struct mars_dent *parent = dent->d_parent;
|
||||
struct mars_rotate *rot = parent->d_private;
|
||||
struct trans_logger_brick *trans_brick;
|
||||
struct light_dent *prev_log;
|
||||
struct mars_dent *prev_log;
|
||||
loff_t start_pos = 0;
|
||||
loff_t end_pos = 0;
|
||||
int status = -EINVAL;
|
||||
@ -1272,7 +1143,7 @@ int _start_trans(struct mars_rotate *rot)
|
||||
|
||||
/* Switch on....
|
||||
*/
|
||||
status = mars_power_button((void*)trans_brick, true, false);
|
||||
status = mars_power_button((void*)trans_brick, true);
|
||||
MARS_DBG("status = %d\n", status);
|
||||
|
||||
done:
|
||||
@ -1291,7 +1162,7 @@ int _stop_trans(struct mars_rotate *rot)
|
||||
|
||||
/* Switch off....
|
||||
*/
|
||||
status = mars_power_button((void*)trans_brick, false, false);
|
||||
status = mars_power_button((void*)trans_brick, false);
|
||||
MARS_DBG("status = %d\n", status);
|
||||
if (status < 0) {
|
||||
goto done;
|
||||
@ -1308,7 +1179,7 @@ done:
|
||||
}
|
||||
|
||||
static
|
||||
int make_log_finalize(struct mars_global *global, struct light_dent *parent)
|
||||
int make_log_finalize(struct mars_global *global, struct mars_dent *parent)
|
||||
{
|
||||
struct mars_rotate *rot = parent->d_private;
|
||||
struct trans_logger_brick *trans_brick;
|
||||
@ -1382,9 +1253,9 @@ done:
|
||||
// specific handlers
|
||||
|
||||
static
|
||||
int make_primary(void *buf, struct light_dent *dent)
|
||||
int make_primary(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct light_dent *parent;
|
||||
struct mars_dent *parent;
|
||||
struct mars_rotate *rot;
|
||||
int status = -EINVAL;
|
||||
|
||||
@ -1401,7 +1272,7 @@ done:
|
||||
}
|
||||
|
||||
static
|
||||
int make_aio(void *buf, struct light_dent *dent)
|
||||
int make_aio(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct mars_brick *brick;
|
||||
@ -1415,7 +1286,7 @@ int make_aio(void *buf, struct light_dent *dent)
|
||||
goto done;
|
||||
}
|
||||
dent->d_kill_inactive = true;
|
||||
brick = make_brick(global, &device_aio_brick_type, dent->d_path, dent->d_path);
|
||||
brick = mars_make_brick(global, &device_aio_brick_type, dent->d_path, dent->d_path);
|
||||
if (unlikely(!brick)) {
|
||||
status = -ENXIO;
|
||||
goto done;
|
||||
@ -1423,18 +1294,18 @@ int make_aio(void *buf, struct light_dent *dent)
|
||||
brick->outputs[0]->output_name = dent->d_path;
|
||||
_brick = (void*)brick;
|
||||
_brick->outputs[0]->o_fdsync = true;
|
||||
status = mars_power_button((void*)brick, true, false);
|
||||
status = mars_power_button((void*)brick, true);
|
||||
if (status < 0) {
|
||||
kill_default(buf, dent);
|
||||
kill_all(buf, dent);
|
||||
}
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int make_dev(void *buf, struct light_dent *dent)
|
||||
static int make_dev(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct light_dent *parent = dent->d_parent;
|
||||
struct mars_dent *parent = dent->d_parent;
|
||||
struct mars_rotate *rot = parent->d_private;
|
||||
struct mars_brick *dev_brick;
|
||||
int status = 0;
|
||||
@ -1493,7 +1364,7 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int _make_direct(void *buf, struct light_dent *dent)
|
||||
static int _make_direct(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
struct mars_brick *brick;
|
||||
@ -1546,7 +1417,7 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int _make_copy(void *buf, struct light_dent *dent)
|
||||
static int _make_copy(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
int status;
|
||||
@ -1566,11 +1437,11 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int make_sync(void *buf, struct light_dent *dent)
|
||||
static int make_sync(void *buf, struct mars_dent *dent)
|
||||
{
|
||||
struct mars_global *global = buf;
|
||||
loff_t start_pos = 0;
|
||||
struct light_dent *connect_dent;
|
||||
struct mars_dent *connect_dent;
|
||||
char *peer;
|
||||
struct copy_brick *copy = NULL;
|
||||
char src[MARS_PATH_MAX];
|
||||
@ -1624,7 +1495,7 @@ static int make_sync(void *buf, struct light_dent *dent)
|
||||
snprintf(dst, sizeof(dst), "%s/syncstatus-%s", dent->d_parent->d_path, my_id());
|
||||
status = mars_symlink(src, dst, NULL, 0);
|
||||
if (status >= 0 && copy->copy_last == copy->copy_end) {
|
||||
status = mars_power_button((void*)copy, false, false);
|
||||
status = mars_power_button((void*)copy, false);
|
||||
MARS_DBG("copy switch status = %d\n", status);
|
||||
}
|
||||
}
|
||||
@ -1725,7 +1596,7 @@ static const struct light_class light_classes[] = {
|
||||
.cl_hostcontext = true,
|
||||
.cl_father = CL_RESOURCE,
|
||||
.cl_forward = make_aio,
|
||||
.cl_backward = kill_default,
|
||||
.cl_backward = kill_all,
|
||||
},
|
||||
/* Symlink pointing to the name of the primary node
|
||||
*/
|
||||
@ -1748,7 +1619,7 @@ static const struct light_class light_classes[] = {
|
||||
.cl_hostcontext = true,
|
||||
.cl_father = CL_RESOURCE,
|
||||
.cl_forward = make_aio,
|
||||
.cl_backward = kill_default,
|
||||
.cl_backward = kill_all,
|
||||
},
|
||||
/* symlink indicating the current status / end
|
||||
* of initial data sync.
|
||||
@ -1761,7 +1632,7 @@ static const struct light_class light_classes[] = {
|
||||
.cl_father = CL_RESOURCE,
|
||||
#if 1
|
||||
.cl_forward = make_sync,
|
||||
.cl_backward = kill_default,
|
||||
.cl_backward = kill_all,
|
||||
#endif
|
||||
},
|
||||
/* Only for testing: make a copy instance
|
||||
@ -1839,7 +1710,7 @@ static const struct light_class light_classes[] = {
|
||||
.cl_hostcontext = true,
|
||||
.cl_father = CL_RESOURCE,
|
||||
.cl_forward = make_dev,
|
||||
.cl_backward = kill_default,
|
||||
.cl_backward = kill_all,
|
||||
},
|
||||
{}
|
||||
};
|
||||
@ -1989,7 +1860,7 @@ static int light_thread(void *data)
|
||||
int status;
|
||||
global.global_power.button = !kthread_should_stop();
|
||||
|
||||
status = mars_dent_work(&global, "/mars", sizeof(struct light_dent), light_checker, light_worker, &global, 3);
|
||||
status = mars_dent_work(&global, "/mars", sizeof(struct mars_dent), light_checker, light_worker, &global, 3);
|
||||
MARS_DBG("worker status = %d\n", status);
|
||||
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ char *mars_translate_hostname(struct mars_global *global, const char *name)
|
||||
{
|
||||
const char *res = name;
|
||||
|
||||
if (global) {
|
||||
if (likely(global)) {
|
||||
char tmp[MARS_PATH_MAX];
|
||||
struct mars_dent *test;
|
||||
|
||||
|
@ -75,7 +75,6 @@ static int handler_thread(void *data)
|
||||
struct server_brick *brick = data;
|
||||
struct socket **sock = &brick->handler_socket;
|
||||
int max_round = 300;
|
||||
int timeout;
|
||||
int status = 0;
|
||||
|
||||
brick->handler_thread = NULL;
|
||||
@ -221,31 +220,17 @@ static int handler_thread(void *data)
|
||||
|
||||
done:
|
||||
MARS_DBG("handler_thread terminating, status = %d\n", status);
|
||||
mars_power_button((void*)brick, false, true);
|
||||
do {
|
||||
int status;
|
||||
status = brick->ops->brick_switch(brick);
|
||||
if (status < 0) {
|
||||
MARS_ERR("server shutdown failed, status = %d\n", status);
|
||||
} else if (max_round-- < 0)
|
||||
int status = mars_kill_brick((void*)brick);
|
||||
if (status >= 0)
|
||||
break;
|
||||
if (status >= 0 || max_round-- < 0) {
|
||||
MARS_INF("not dead, giving up....\n");
|
||||
break;
|
||||
}
|
||||
msleep(1000);
|
||||
} while (!brick->power.led_off);
|
||||
|
||||
if (brick->inputs[0] && brick->inputs[0]->connect) {
|
||||
MARS_DBG("disconnecting input %p\n", brick->inputs[0]->connect);
|
||||
(void)generic_disconnect((void*)brick->inputs[0]);
|
||||
}
|
||||
|
||||
timeout = 60 * 1000;
|
||||
while (atomic_read(&brick->in_flight) || !brick->power.led_off) {
|
||||
MARS_ERR("server brick has resources allocated - cannot terminate thread\n");
|
||||
msleep(timeout);
|
||||
if (timeout < 3600 * 1000)
|
||||
timeout += 30 * 1000;
|
||||
}
|
||||
|
||||
(void)generic_brick_exit_full((void*)brick);
|
||||
MARS_DBG("done\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ void make_test_instance(void)
|
||||
#ifdef CONF_FDSYNC
|
||||
_device_brick->outputs[0]->o_fdsync = true;
|
||||
#endif
|
||||
mars_power_button((void*)device_brick, true, false);
|
||||
mars_power_button((void*)device_brick, true);
|
||||
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, false);
|
||||
mars_power_button((void*)if_brick, true);
|
||||
//_if_brick->is_active = true;
|
||||
|
||||
msleep(2000);
|
||||
|
Loading…
Reference in New Issue
Block a user