diff --git a/kernel/mars_server.c b/kernel/mars_server.c index e47fe431..9e7aac83 100644 --- a/kernel/mars_server.c +++ b/kernel/mars_server.c @@ -710,14 +710,8 @@ static int _server_thread(void *data) if (server_show_statist) show_statistics(&server_global, "server"); - status = mars_kill_brick_when_possible(&server_global, &server_global.brick_anchor, false, (void*)&server_brick_type, false); - MARS_DBG("kill server bricks (when possible) = %d\n", status); - status = mars_kill_brick_when_possible(&server_global, &server_global.brick_anchor, false, (void*)&bio_brick_type, false); - MARS_DBG("kill server bio bricks (when possible) = %d\n", status); - status = mars_kill_brick_when_possible(&server_global, &server_global.brick_anchor, false, (void*)&aio_brick_type, false); - MARS_DBG("kill server aio bricks (when possible) = %d\n", status); - status = mars_kill_brick_when_possible(&server_global, &server_global.brick_anchor, false, (void*)&sio_brick_type, false); - MARS_DBG("kill server sio bricks (when possible) = %d\n", status); + status = mars_kill_brick_when_possible(&server_global, &server_global.brick_anchor, false, NULL, true); + MARS_DBG("kill server bricks (when possible) = %d\n", status); if (!mars_global || !mars_global->global_power.button) { brick_msleep(1000); diff --git a/kernel/sy_old/mars_light.c b/kernel/sy_old/mars_light.c index adb7ab90..e7374869 100644 --- a/kernel/sy_old/mars_light.c +++ b/kernel/sy_old/mars_light.c @@ -1127,7 +1127,6 @@ int __make_copy( struct copy_brick **__copy) { struct mars_brick *copy; - struct copy_brick *_copy; struct copy_cookie cc = {}; struct client_cookie clc[2] = { { @@ -1139,6 +1138,7 @@ int __make_copy( }, }; int i; + bool switch_copy; int status = -EINVAL; if (!switch_path || !global) { @@ -1146,8 +1146,9 @@ int __make_copy( } // don't generate empty aio files if copy does not yet exist + switch_copy = _check_switch(global, switch_path); copy = mars_find_brick(global, ©_brick_type, copy_path); - if (!copy && !_check_switch(global, switch_path)) + if (!copy && !switch_copy) goto done; // create/find predecessor aio bricks @@ -1174,7 +1175,7 @@ int __make_copy( (const struct generic_brick_type*)&bio_brick_type, (const struct generic_brick_type*[]){}, NULL, - 1, // start always + switch_copy ? 1 : -1, cc.fullpath[i], (const char *[]){}, 0); @@ -1197,25 +1198,21 @@ int __make_copy( cc.fullpath[1], (const struct generic_brick_type*)©_brick_type, (const struct generic_brick_type*[]){NULL,NULL,NULL,NULL}, - "%s", - (!switch_path[0] || IS_EXHAUSTED()) ? -1 : 0, + NULL, + (!switch_copy || IS_EXHAUSTED()) ? -1 : 0, "%s", (const char *[]){"%s", "%s", "%s", "%s"}, 4, - switch_path, copy_path, cc.fullpath[0], cc.fullpath[0], cc.fullpath[1], cc.fullpath[1]); - if (!copy) { - MARS_DBG("creation of copy brick '%s' failed\n", copy_path); - goto done; + if (copy) { + copy->show_status = _show_brick_status; } - copy->show_status = _show_brick_status; - _copy = (void*)copy; if (__copy) - *__copy = _copy; + *__copy = (void*)copy; status = 0; @@ -2095,7 +2092,7 @@ int make_log_init(void *buf, struct mars_dent *dent) const char *parent_path; const char *replay_path = NULL; const char *aio_path = NULL; - const char *switch_path = NULL; + bool switch_on; int status = 0; if (!global->global_power.button) { @@ -2213,6 +2210,9 @@ int make_log_init(void *buf, struct mars_dent *dent) } rot->aio_dent = aio_dent; + // check whether attach is allowed + switch_on = _check_allow(global, parent, "attach"); + /* Fetch / make the AIO brick instance */ aio_brick = @@ -2224,17 +2224,16 @@ int make_log_init(void *buf, struct mars_dent *dent) (const struct generic_brick_type*)&aio_brick_type, (const struct generic_brick_type*[]){}, NULL, - 1, // start always + rot->trans_brick || switch_on ? 1 : -1, // disallow detach when trans_logger is present "%s", (const char *[]){}, 0, aio_path); - if (!aio_brick) { - MARS_ERR("cannot access '%s'\n", aio_path); - status = -EIO; - goto done; - } rot->aio_brick = (void*)aio_brick; + status = 0; + if (unlikely(!aio_brick || !aio_brick->power.led_on)) { + goto done; // this may happen in case of detach + } /* Fetch the actual logfile size */ @@ -2257,9 +2256,6 @@ int make_log_init(void *buf, struct mars_dent *dent) brick_string_free(new_path); } - // check whether attach is allowed - switch_path = path_make("%s/todo-%s/attach", parent_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_step(). @@ -2273,19 +2269,19 @@ int make_log_init(void *buf, struct mars_dent *dent) aio_path, (const struct generic_brick_type*)&trans_logger_brick_type, (const struct generic_brick_type*[]){NULL}, - switch_path, - 0, // let switch decide + NULL, + rot->trans_brick && rot->trans_brick->power.led_on ? 1 : switch_on ? -100 : -1, // keep old state, create always if attach "%s/logger", (const char *[]){"%s/data-%s"}, 1, parent_path, parent_path, my_id()); + rot->trans_brick = (void*)trans_brick; status = -ENOENT; if (!trans_brick) { goto done; } - rot->trans_brick = (void*)trans_brick; rot->trans_brick->replay_limiter = &rot->replay_limiter; /* For safety, default is to try an (unnecessary) replay in case * something goes wrong later. @@ -2297,7 +2293,6 @@ int make_log_init(void *buf, struct mars_dent *dent) done: brick_string_free(aio_path); brick_string_free(replay_path); - brick_string_free(switch_path); return status; } @@ -2948,9 +2943,14 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *dent) if (trans_brick->replay_mode) { do_stop = trans_brick->replay_code != 0 || !global->global_power.button || - !_check_allow(global, parent, "allow-replay"); + !_check_allow(global, parent, "allow-replay") || + !_check_allow(global, parent, "attach") ; } else { - do_stop = !rot->is_primary; + do_stop = + !rot->if_brick && + !rot->is_primary && + (!rot->todo_primary || + !_check_allow(global, parent, "attach")); } MARS_DBG("replay_mode = %d replay_code = %d is_primary = %d do_stop = %d\n", trans_brick->replay_mode, trans_brick->replay_code, rot->is_primary, (int)do_stop); @@ -3002,9 +3002,19 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *dent) } done: + // remove trans_logger (when possible) upon detach is_attached = !!rot->trans_brick; _show_actual(rot->parent_path, "is-attached", is_attached); + if (rot->trans_brick && rot->trans_brick->power.led_off && !rot->trans_brick->outputs[0]->nr_connected) { + bool do_attach = _check_allow(global, parent, "attach"); + MARS_DBG("do_attach = %d\n", do_attach); + if (!do_attach) { + rot->trans_brick->killme = true; + rot->trans_brick = NULL; + } + } + if (rot->trans_brick) _show_rate(rot, &rot->replay_limiter, rot->trans_brick->power.led_on, "replay_rate"); if (rot->copy_brick) @@ -3050,15 +3060,15 @@ int make_bio(void *buf, struct mars_dent *dent) { struct mars_global *global = buf; struct mars_brick *brick; + bool switch_on; int status = 0; - if (!global->global_power.button) { + if (!global || !global->global_power.button || !dent->d_parent) { goto done; } - brick = mars_find_brick(global, NULL, dent->d_path); - if (brick) { - goto check; - } + + switch_on = _check_allow(global, dent->d_parent, "attach"); + brick = make_brick_all(global, dent, @@ -3068,7 +3078,7 @@ int make_bio(void *buf, struct mars_dent *dent) (const struct generic_brick_type*)&bio_brick_type, (const struct generic_brick_type*[]){}, NULL, - 1, // start always + switch_on ? 1 : -1, dent->d_path, (const char *[]){}, 0); @@ -3077,17 +3087,11 @@ 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, false); - if (status < 0) { - kill_any(buf, dent); - goto done; - } -check: /* Report the actual size of the device. * It may be larger than the global size. */ - if (brick && brick->power.led_on && dent->d_parent) { + if (brick && brick->power.led_on) { struct mars_info info = {}; struct mars_output *output; char *src = NULL; @@ -3177,7 +3181,8 @@ int make_dev(void *buf, struct mars_dent *dent) (rot->if_brick && atomic_read(&rot->if_brick->open_count) > 0) || (rot->todo_primary && !rot->trans_brick->replay_mode && - rot->trans_brick->power.led_on); + rot->trans_brick->power.led_on && + _check_allow(global, dent->d_parent, "attach")); if (!global->global_power.button) { switch_on = false; } @@ -3203,6 +3208,10 @@ int make_dev(void *buf, struct mars_dent *dent) MARS_DBG("device not shown\n"); goto done; } + if (!switch_on) { + MARS_DBG("setting killme on if_brick\n"); + dev_brick->killme = true; + } dev_brick->show_status = _show_brick_status; _dev_brick = (void*)dev_brick; __show_actual(rot->parent_path, "open-count", atomic_read(&_dev_brick->open_count)); @@ -3240,6 +3249,7 @@ static int _make_direct(void *buf, struct mars_dent *dent) struct mars_brick *brick; char *src_path = NULL; int status; + bool switch_on; bool do_dealloc = false; if (!global->global_power.button || !dent->d_parent || !dent->new_link) { @@ -3260,6 +3270,9 @@ static int _make_direct(void *buf, struct mars_dent *dent) } do_dealloc = true; } + + switch_on = _check_allow(global, dent->d_parent, "attach"); + brick = make_brick_all(global, dent, @@ -3269,7 +3282,7 @@ static int _make_direct(void *buf, struct mars_dent *dent) (const struct generic_brick_type*)&bio_brick_type, (const struct generic_brick_type*[]){}, NULL, - 0, + switch_on ? 1 : -1, "%s", (const char *[]){}, 0, @@ -3289,7 +3302,7 @@ static int _make_direct(void *buf, struct mars_dent *dent) (const struct generic_brick_type*)&if_brick_type, (const struct generic_brick_type*[]){NULL}, NULL, - 0, + switch_on ? 1 : -1, "%s/directdevice-%s", (const char *[]){ "%s" }, 1, @@ -3358,13 +3371,15 @@ static int make_sync(void *buf, struct mars_dent *dent) const char *copy_path = NULL; const char *src = NULL; const char *dst = NULL; - bool do_start = true; + bool do_start; int status; if (!global->global_power.button || !dent->d_parent || !dent->new_link) { return 0; } + do_start = _check_allow(global, dent->d_parent, "attach"); + /* Analyze replay position */ status = sscanf(dent->new_link, "%lld", &start_pos); @@ -4222,15 +4237,21 @@ static int light_thread(void *data) MARS_DBG("-------- worker deleted_min = %d status = %d\n", _global.deleted_min, status); if (!_global.global_power.button) { - status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)©_brick_type, false); + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)©_brick_type, true); MARS_DBG("kill copy bricks (when possible) = %d\n", status); } - status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&client_brick_type, false); + + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, NULL, false); + MARS_DBG("kill main bricks (when possible) = %d\n", status); + + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&client_brick_type, true); MARS_DBG("kill client bricks (when possible) = %d\n", status); - status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&aio_brick_type, false); + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&aio_brick_type, true); MARS_DBG("kill aio bricks (when possible) = %d\n", status); - status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&sio_brick_type, false); + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&sio_brick_type, true); MARS_DBG("kill sio bricks (when possible) = %d\n", status); + status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&bio_brick_type, true); + MARS_DBG("kill bio bricks (when possible) = %d\n", status); if ((long long)jiffies + mars_rollover_interval * HZ >= last_rollover) { last_rollover = jiffies; diff --git a/kernel/sy_old/strategy.h b/kernel/sy_old/strategy.h index d1b072f3..92125bd4 100644 --- a/kernel/sy_old/strategy.h +++ b/kernel/sy_old/strategy.h @@ -98,7 +98,7 @@ extern struct mars_brick *mars_make_brick(struct mars_global *global, struct mar extern int mars_free_brick(struct mars_brick *brick); extern int mars_kill_brick(struct mars_brick *brick); extern int mars_kill_brick_all(struct mars_global *global, struct list_head *anchor, bool use_dent_link); -extern int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool only_off); +extern int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool even_on); // mid-level brick instantiation (identity is based on path strings) diff --git a/kernel/sy_old/sy_generic.c b/kernel/sy_old/sy_generic.c index aaa526e5..7fac90eb 100644 --- a/kernel/sy_old/sy_generic.c +++ b/kernel/sy_old/sy_generic.c @@ -1283,7 +1283,7 @@ done: } EXPORT_SYMBOL_GPL(mars_kill_brick_all); -int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool only_off) +int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool even_on) { int return_status = 0; struct list_head *tmp; @@ -1312,16 +1312,8 @@ restart: if (brick->nr_outputs > 0 && brick->outputs[0] && brick->outputs[0]->nr_connected > 0) { continue; } - if (only_off) { - if (brick->power.led_off) { // already off - continue; - } - if (global) { - up_write(&global->brick_mutex); - } - MARS_DBG("POWER OFF '%s'\n", brick->brick_name); - status = mars_power_button(brick, false, false); - goto success; + if (!even_on && (brick->power.button || !brick->power.led_off)) { + continue; } /* Workaround FIXME: * only kill bricks which have not been touched during the current mars_dent_work() round. @@ -1342,7 +1334,6 @@ restart: MARS_DBG("KILLING '%s'\n", brick->brick_name); status = mars_kill_brick(brick); - success: if (status >= 0) { return_status++; } else { @@ -1526,7 +1517,7 @@ struct mars_brick *make_brick_all( } goto do_switch; } - if (!switch_state) { // don't start => also don't create + if (!switch_state && switch_override > -99) { // don't start => also don't create MARS_DBG("no need for brick '%s'\n", new_path); goto done; }