diff options
| author | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
|---|---|---|
| committer | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
| commit | 77adf4cd648dce41f89469dd185deec6b6b53a0b (patch) | |
| tree | 02e155a5753b398ee572b45793f889b538efab6b /scheduler/random | |
| parent | f3b2e6580e5663292ee113c741343c8a43ee133f (diff) | |
Added all files
Diffstat (limited to 'scheduler/random')
| -rw-r--r-- | scheduler/random/Makefile.am | 3 | ||||
| -rw-r--r-- | scheduler/random/src/Makefile.am | 14 | ||||
| -rw-r--r-- | scheduler/random/src/random.c | 283 | ||||
| -rw-r--r-- | scheduler/random/src/random.h | 46 | 
4 files changed, 346 insertions, 0 deletions
diff --git a/scheduler/random/Makefile.am b/scheduler/random/Makefile.am new file mode 100644 index 000000000..d471a3f92 --- /dev/null +++ b/scheduler/random/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +CLEANFILES =  diff --git a/scheduler/random/src/Makefile.am b/scheduler/random/src/Makefile.am new file mode 100644 index 000000000..572181336 --- /dev/null +++ b/scheduler/random/src/Makefile.am @@ -0,0 +1,14 @@ +sched_LTLIBRARIES = random.la +scheddir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler + +random_la_LDFLAGS = -module -avoidversion + +random_la_SOURCES = random.c +random_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la + +noinst_HEADERS = random.h + +AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ +	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) + +CLEANFILES =  diff --git a/scheduler/random/src/random.c b/scheduler/random/src/random.c new file mode 100644 index 000000000..9e761d08a --- /dev/null +++ b/scheduler/random/src/random.c @@ -0,0 +1,283 @@ +/* +  Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +  This file is part of GlusterFS. + +  GlusterFS is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3 of the License, +  or (at your option) any later version. + +  GlusterFS is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU General Public License +  along with this program.  If not, see +  <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <sys/time.h> + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "random.h" + +#define RANDOM_LIMITS_MIN_FREE_DISK_DEFAULT    15 +#define RANDOM_REFRESH_INTERVAL_DEFAULT        10 + + +static int32_t +random_init (xlator_t *xl) +{ +	struct random_struct *random_buf = NULL; +	xlator_list_t *trav_xl = xl->children; +	data_t *limit = NULL; +	int32_t index = 0; + +	random_buf = CALLOC (1, sizeof (struct random_struct)); +	ERR_ABORT (random_buf); +   +	/* Set the seed for the 'random' function */ +	srandom ((uint32_t) time (NULL)); +   +	limit = dict_get (xl->options, "scheduler.limits.min-free-disk"); +	if (limit) { +		if (gf_string2percent (data_to_str (limit), +				       &random_buf->min_free_disk) != 0) { +			gf_log ("random", GF_LOG_ERROR,  +				"invalid number format \"%s\" of \"option " +				"scheduler.limits.min-free-disk\"",  +				limit->data); +			return -1; +		} +		if (random_buf->min_free_disk >= 100) { +			gf_log ("random", GF_LOG_ERROR, +				"check the \"option random.limits.min-free" +				"-disk\", it should be percentage value"); +			return -1; +		} +       +	} else { +		gf_log ("random", GF_LOG_WARNING,  +			"No option for limit min-free-disk given, " +			"defaulting it to 5%%"); +		random_buf->min_free_disk =  +			RANDOM_LIMITS_MIN_FREE_DISK_DEFAULT; +	} +   +	limit = dict_get (xl->options, "scheduler.refresh-interval"); +	if (limit) { +		if (gf_string2time (data_to_str (limit), +				    &random_buf->refresh_interval) != 0) { +			gf_log ("random", GF_LOG_ERROR,  +				"invalid number format \"%s\" of " +				"\"option random.refresh-interval\"",  +				limit->data); +			return -1; +		} +	} else { +		random_buf->refresh_interval = RANDOM_REFRESH_INTERVAL_DEFAULT; +	} +   +	while (trav_xl) { +		index++; +		trav_xl = trav_xl->next; +	} +	random_buf->child_count = index; +	random_buf->array = CALLOC (index,  +				    sizeof (struct random_sched_struct)); +	ERR_ABORT (random_buf->array); +	trav_xl = xl->children; +	index = 0; + +	while (trav_xl) { +		random_buf->array[index].xl = trav_xl->xlator; +		random_buf->array[index].eligible = 1; +		trav_xl = trav_xl->next; +		index++; +	} +	pthread_mutex_init (&random_buf->random_mutex, NULL); + +	// put it at the proper place   +	*((long *)xl->private) = (long)random_buf;  +	return 0; +} + +static void +random_fini (xlator_t *xl) +{ +	struct random_struct *random_buf = NULL; + +	random_buf = (struct random_struct *)*((long *)xl->private); +	pthread_mutex_destroy (&random_buf->random_mutex); +	free (random_buf->array); +	free (random_buf); +} + + +static int32_t  +update_stat_array_cbk (call_frame_t *frame, +		       void *cookie, +		       xlator_t *xl, +		       int32_t op_ret, +		       int32_t op_errno, +		       struct xlator_stats *trav_stats) +{ +	int32_t idx = 0; +	int32_t percent = 0; +	struct random_struct *random_buf = NULL; +	 +	random_buf = (struct random_struct *)*((long *)xl->private); + +	pthread_mutex_lock (&random_buf->random_mutex); +	for (idx = 0; idx < random_buf->child_count; idx++) { +		if (strcmp (random_buf->array[idx].xl->name,  +			    (char *)cookie) == 0) +			break; +	} +	pthread_mutex_unlock (&random_buf->random_mutex); + +	if (op_ret == 0) { +		percent = ((trav_stats->free_disk *100) /  +			   trav_stats->total_disk_size); +		if (random_buf->min_free_disk > percent) { +			random_buf->array[idx].eligible = 0; +		} else { +			random_buf->array[idx].eligible = 1; +		} +	} else { +		random_buf->array[idx].eligible = 0; +	}     + +	STACK_DESTROY (frame->root); +	return 0; +} + +static void  +update_stat_array (xlator_t *xl) +{ +	int32_t idx; +	struct random_struct *random_buf = NULL; +	call_frame_t *frame = NULL; +	call_pool_t *pool = xl->ctx->pool; + +	random_buf = (struct random_struct *)*((long *)xl->private); +	for (idx = 0; idx < random_buf->child_count; idx++) { +		frame = create_frame (xl, pool); + +		STACK_WIND_COOKIE (frame, +				   update_stat_array_cbk, +				   random_buf->array[idx].xl->name, +				   random_buf->array[idx].xl, +				   (random_buf->array[idx].xl)->mops->stats, +				   0); +	} +	return ; +} + +static void  +random_update (xlator_t *xl) +{ +	struct timeval tv; +	struct random_struct *random_buf = NULL; + +	random_buf = (struct random_struct *)*((long *)xl->private); + +	gettimeofday(&tv, NULL); +	if (tv.tv_sec > (random_buf->refresh_interval +  +			 random_buf->last_stat_entry.tv_sec)) { +		update_stat_array (xl); +		random_buf->last_stat_entry.tv_sec = tv.tv_sec; +	} +} + +static xlator_t * +random_schedule (xlator_t *xl, const void *path) +{ +	struct random_struct *random_buf = NULL;        +	int32_t rand = 0; +	int32_t try = 0; +	 +	random_buf = (struct random_struct *)*((long *)xl->private); + +	rand = (int32_t) (1.0*random_buf->child_count *  +			  (random() / (RAND_MAX + 1.0))); + +	random_update (xl); + +	while (!random_buf->array[rand].eligible) { +		if (try++ > 100) { +			/* there is a chance of this becoming a  +			   infinite loop otherwise. */ +			break;  +		} +		rand = (int32_t) (1.0*random_buf->child_count *  +				  (random() / (RAND_MAX + 1.0))); +	} +	return random_buf->array[rand].xl; +} + + +/** + * notify + */ +void +random_notify (xlator_t *xl, int32_t event, void *data) +{ +	struct random_struct *random_buf = NULL; +	int32_t idx = 0; +   +	random_buf = (struct random_struct *)*((long *)xl->private); +	if (!random_buf) +		return; + +	for (idx = 0; idx < random_buf->child_count; idx++) { +		if (random_buf->array[idx].xl == (xlator_t *)data) +			break; +	} + +	switch (event) +	{ +	case GF_EVENT_CHILD_UP: +	{ +		//random_buf->array[idx].eligible = 1; +	} +	break; +	case GF_EVENT_CHILD_DOWN: +	{ +		random_buf->array[idx].eligible = 0; +	} +	break; +	default: +	{ +		; +	} +	break; +	} + +} + +struct sched_ops sched = { +	.init     = random_init, +	.fini     = random_fini, +	.update   = random_update, +	.schedule = random_schedule, +	.notify   = random_notify +}; + +struct volume_options options[] = { +	{ .key   = { "scheduler.refresh-interval",  +		     "random.refresh-interval" },   +	  .type  = GF_OPTION_TYPE_TIME +	}, +	{ .key   = { "scheduler.limits.min-free-disk",  +		     "random.limits.min-free-disk" },   +	  .type  = GF_OPTION_TYPE_PERCENT +	}, +	{ .key = {NULL} } +}; diff --git a/scheduler/random/src/random.h b/scheduler/random/src/random.h new file mode 100644 index 000000000..35c9e02ee --- /dev/null +++ b/scheduler/random/src/random.h @@ -0,0 +1,46 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#ifndef _RANDOM_H +#define _RANDOM_H + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + + +#include <sys/time.h> +#include "scheduler.h" + +struct random_sched_struct { +  xlator_t *xl; +  unsigned char eligible; +}; + +struct random_struct { +  int32_t child_count; +  uint32_t refresh_interval; +  uint32_t min_free_disk; +  struct timeval last_stat_entry; +  struct random_sched_struct *array; +  pthread_mutex_t random_mutex; +}; + +#endif /* _RANDOM_H */  | 
