light: emergency stop logging on filesystem full

This commit is contained in:
Thomas Schoebel-Theuer 2012-07-23 09:17:18 +02:00 committed by Thomas Schoebel-Theuer
parent 69d47e8f96
commit 2897ddf812
4 changed files with 70 additions and 3 deletions

View File

@ -625,7 +625,7 @@ int trans_logger_ref_get(struct trans_logger_output *output, struct mref_object
mref->ref_len = REGION_SIZE - base_offset;
}
if (mref->ref_may_write == READ) {
if (mref->ref_may_write == READ || unlikely(brick->cease_logging)) {
return _read_ref_get(output, mref_a);
}
@ -824,7 +824,7 @@ void trans_logger_ref_io(struct trans_logger_output *output, struct mref_object
}
// only READ is allowed on non-shadow buffers
if (unlikely(mref->ref_rw != READ)) {
if (unlikely(mref->ref_rw != READ && !brick->cease_logging)) {
MARS_FAT("bad operation %d on non-shadow\n", mref->ref_rw);
}

View File

@ -120,6 +120,7 @@ struct trans_logger_brick {
bool replay_mode; // mode of operation
bool continuous_replay_mode; // mode of operation
bool log_reads; // additionally log pre-images
bool cease_logging; // direct IO without logging (only in case of EMERGENCY)
bool debug_shortcut; // only for testing! never use in production!
loff_t replay_start_pos; // where to start replay
loff_t replay_end_pos; // end of replay

View File

@ -87,6 +87,7 @@ struct mars_rotate {
struct mars_dent *next_next_relevant_log;
struct mars_dent *prev_log;
struct mars_dent *next_log;
struct mars_dent *syncstatus_dent;
struct if_brick *if_brick;
const char *copy_path;
struct copy_brick *copy_brick;
@ -165,6 +166,8 @@ EXPORT_SYMBOL_GPL(mars_mem_percent);
#define EXHAUSTED(x,max) (false)
#endif
#define JAMMED(x) ((x) <= 1024 * 1024)
static
int _set_trans_params(struct mars_brick *_brick, void *private)
{
@ -2348,6 +2351,40 @@ done:
return status;
}
static
void override_all_syncstatus(struct mars_global *global, struct mars_rotate *rot, char *parent_path)
{
char *prefix = NULL;
struct mars_dent **table = NULL;
int count;
int i;
prefix = path_make("%s/syncstatus-", parent_path);
if (!prefix)
goto done;
count = mars_find_dent_all(global, prefix, &table);
MARS_DBG("prefix='%s' count=%d\n", prefix, count);
for (i = 0; i < count; i++) {
struct mars_dent *dent = table[i];
int status;
if (!dent || !dent->d_path || dent == rot->syncstatus_dent)
continue;
status = mars_symlink("0", dent->d_path, NULL, 0);
MARS_DBG("clearing syncstatus link '%s' status=%d\n", dent->d_path, status);
}
done:
if (table)
brick_mem_free(table);
if (prefix)
brick_string_free(prefix);
}
static
int make_log_finalize(struct mars_global *global, struct mars_dent *dent)
{
@ -2367,6 +2404,17 @@ int make_log_finalize(struct mars_global *global, struct mars_dent *dent)
goto done;
}
/* Handle jamming (a very exceptional state)
*/
if (global->jammed) {
if (rot->todo_primary || rot->is_primary)
trans_brick->cease_logging = true;
} else if (!rot->todo_primary && !rot->is_primary) {
trans_brick->cease_logging = false;
}
if (trans_brick->cease_logging)
override_all_syncstatus(global, rot, parent->d_path);
// check whether some copy has finished
copy_brick = (struct copy_brick*)mars_find_brick(global, &copy_brick_type, rot->copy_path);
MARS_DBG("copy_path = '%s' copy_brick = %p\n", rot->copy_path, copy_brick);
@ -2824,6 +2872,7 @@ static int make_sync(void *buf, struct mars_dent *dent)
rot = dent->d_parent->d_private;
if (rot) {
rot->allow_update = true;
rot->syncstatus_dent = dent;
}
/* Sync necessary?
@ -3039,6 +3088,7 @@ enum {
CL_PEERS,
CL_ALIVE,
CL_EXHAUSTED,
CL_JAMMED,
CL_REST_SPACE,
// resource definitions
CL_RESOURCE,
@ -3166,6 +3216,12 @@ static const struct light_class light_classes[] = {
.cl_type = 'l',
.cl_father = CL_ROOT,
},
[CL_JAMMED] = {
.cl_name = "jammed-",
.cl_len = 7,
.cl_type = 'l',
.cl_father = CL_ROOT,
},
/* Directory containing all items of a resource
*/
@ -3703,6 +3759,7 @@ static int light_thread(void *data)
int status;
loff_t rest_space;
bool exhausted;
bool jammed;
MARS_DBG("-------- NEW ROUND ---------\n");
@ -3718,11 +3775,19 @@ static int light_thread(void *data)
_make_alivelink("alive", _global.global_power.button ? 1 : 0);
mars_remaining_space("/mars", &_global.total_space, &_global.remaining_space);
exhausted = EXHAUSTED(_global.remaining_space, _global.total_space);
_global.exhausted = exhausted;
_make_alivelink("exhausted", exhausted ? 1 : 0);
if (exhausted)
MARS_WRN("EXHAUSTED filesystem space = %lld, STOPPING IO\n", _global.remaining_space);
MARS_WRN("EXHAUSTED filesystem space = %lld\n", _global.remaining_space);
jammed = JAMMED(_global.remaining_space);
_global.jammed = jammed;
_make_alivelink("jammed", jammed ? 1 : 0);
if (jammed)
MARS_WRN("JAMMED filesystem space = %lld, STOPPING TRANSACTION LOGGING\n", _global.remaining_space);
rest_space = _global.remaining_space - EXHAUSTED_LIMIT(_global.total_space);
_make_alivelink("rest-space", rest_space);

View File

@ -59,6 +59,7 @@ struct mars_global {
int deleted_min;
bool main_trigger;
bool exhausted;
bool jammed;
};
typedef int (*mars_dent_checker_fn)(struct mars_dent *parent, const char *name, int namlen, unsigned int d_type, int *prefix, int *serial);