⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rr.c

📁 分布式文件系统
💻 C
字号:
/*   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 _CONFIG_H#define _CONFIG_H#include "config.h"#endif#include <sys/time.h>#include <stdlib.h>#include "rr.h"static int32_trr_init (xlator_t *xl){  int32_t index = 0;  struct rr_struct *rr_buf = calloc (1, sizeof (struct rr_struct));  xlator_list_t *trav_xl = xl->children;  data_t *data = dict_get (xl->options, "rr.limits.min-free-disk");  if (data) {    rr_buf->min_free_disk = gf_str_to_long_long (data->data);    if (rr_buf->min_free_disk >= 100) {      gf_log ("rr", GF_LOG_ERROR,	      "check the \"option rr.limits.min-free-disk\", it should be percentage value");      return -1;    }  } else {    gf_log (xl->name,	    GF_LOG_DEBUG,	    "'option rr.limits.min-free-disk' not specified, defaulting to 5%");    rr_buf->min_free_disk = gf_str_to_long_long ("5"); /* 5% free space */  }  data = dict_get (xl->options, "rr.refresh-interval");  if (data) {    rr_buf->refresh_interval = (int32_t)gf_str_to_long_long (data->data);  } else {    rr_buf->refresh_interval = 10; /* 10 Seconds */  }  while (trav_xl) {    index++;    trav_xl = trav_xl->next;  }  rr_buf->child_count = index;  rr_buf->sched_index = 0;  rr_buf->array = calloc (index + 1, sizeof (struct rr_sched_struct));  trav_xl = xl->children;  index = 0;  while (trav_xl) {    rr_buf->array[index].xl = trav_xl->xlator;    rr_buf->array[index].eligible = 1;    rr_buf->array[index].free_disk = rr_buf->min_free_disk;    rr_buf->array[index].refresh_interval = rr_buf->refresh_interval;    trav_xl = trav_xl->next;    index++;  }  data = dict_get (xl->options, "rr.read-only-subvolumes");  if (data) {    char *child = NULL;    char *tmp;    char *childs_data = strdup (data->data);        child = strtok_r (childs_data, ",", &tmp);    while (child) {      for (index = 1; index < rr_buf->child_count; index++) {	if (strcmp (rr_buf->array[index - 1].xl->name, child) == 0) {	  memcpy (&(rr_buf->array[index-1]), 		  &(rr_buf->array[rr_buf->child_count-1]), 		  sizeof (struct rr_sched_struct));	  rr_buf->child_count--;	  break;	}      }      child = strtok_r (NULL, ",", &tmp);    }  }  rr_buf->first_time = 1;  pthread_mutex_init (&rr_buf->rr_mutex, NULL);  *((long *)xl->private) = (long)rr_buf; // put it at the proper place  return 0;}static voidrr_fini (xlator_t *xl){  struct rr_struct *rr_buf = (struct rr_struct *)*((long *)xl->private);  pthread_mutex_destroy (&rr_buf->rr_mutex);  free (rr_buf->array);  free (rr_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){  struct rr_struct *rr_struct = (struct rr_struct *)*((long *)xl->private);  int32_t percent = 0;  int32_t idx = 0;    pthread_mutex_lock (&rr_struct->rr_mutex);  for (idx = 0; idx < rr_struct->child_count; idx++) {    if (rr_struct->array[idx].xl->name == (char *)cookie)      break;  }  pthread_mutex_unlock (&rr_struct->rr_mutex);  if (op_ret == 0) {    percent = (trav_stats->free_disk *100) / trav_stats->total_disk_size;    if ((rr_struct->array[idx].free_disk > percent)) {      if (rr_struct->array[idx].eligible)	gf_log ("rr", GF_LOG_CRITICAL, 		"node \"%s\" is _almost_ full", 		rr_struct->array[idx].xl->name);      rr_struct->array[idx].eligible = 0;    } else       rr_struct->array[idx].eligible = 1;        } else {    rr_struct->array[idx].eligible = 0;  }  STACK_DESTROY (frame->root);  return 0;}static void update_stat_array (xlator_t *xl){  /* This function schedules the file in one of the child nodes */  struct rr_struct *rr_buf = (struct rr_struct *)*((long *)xl->private);  call_ctx_t *cctx;  int32_t idx;  for (idx = 0; idx < rr_buf->child_count; idx++) {    call_pool_t *pool = xl->ctx->pool;    cctx = calloc (1, sizeof (*cctx));    cctx->frames.root  = cctx;    cctx->frames.this  = xl;        cctx->pool = pool;    LOCK (&pool->lock);    {      list_add (&cctx->all_frames, &pool->all_frames);    }    UNLOCK (&pool->lock);    STACK_WIND_COOKIE ((&cctx->frames), 		 update_stat_array_cbk,		 rr_buf->array[idx].xl->name, //cookie		 rr_buf->array[idx].xl, 		 (rr_buf->array[idx].xl)->mops->stats,		 0); //flag  }  return;}static void rr_update (xlator_t *xl){  struct timeval tv;  struct rr_struct *rr_buf = (struct rr_struct *)*((long *)xl->private);  gettimeofday (&tv, NULL);  if (tv.tv_sec > (rr_buf->refresh_interval 		   + rr_buf->last_stat_fetch.tv_sec)) {      /* Update the stats from all the server */    update_stat_array (xl);    rr_buf->last_stat_fetch.tv_sec = tv.tv_sec;  }  }static xlator_t *rr_schedule (xlator_t *xl, void *path){  int32_t rr;  struct rr_struct *rr_buf = (struct rr_struct *)*((long *)xl->private);  int32_t rr_orig = rr_buf->sched_index;    rr_update (xl);  while (1) {    pthread_mutex_lock (&rr_buf->rr_mutex);    rr = rr_buf->sched_index++;    rr_buf->sched_index = rr_buf->sched_index % rr_buf->child_count;    pthread_mutex_unlock (&rr_buf->rr_mutex);        /* if 'eligible' or there are _no_ eligible nodes */    if (rr_buf->array[rr].eligible) {      break;    }    if ((rr + 1) % rr_buf->child_count == rr_orig) {      gf_log ("rr", 	      GF_LOG_CRITICAL, 	      "free space not available on any server");      pthread_mutex_lock (&rr_buf->rr_mutex);      rr_buf->sched_index++;      rr_buf->sched_index = rr_buf->sched_index % rr_buf->child_count;      pthread_mutex_unlock (&rr_buf->rr_mutex);      break;    }    rr_update (xl);  }  return rr_buf->array[rr].xl;}static int32_t update_rr_seed_cbk (call_frame_t *frame,		    void *cookie,		    xlator_t *this,		    int32_t op_ret,		    int32_t op_errno){  struct rr_struct *rr_buf = cookie;  if (op_ret >= 0) {    pthread_mutex_lock (&rr_buf->rr_mutex);    rr_buf->sched_index = (op_ret % rr_buf->child_count);    pthread_mutex_unlock (&rr_buf->rr_mutex);  }  STACK_DESTROY (frame->root);  return 0;}/** * notify */voidrr_notify (xlator_t *xl, int32_t event, void *data){  struct rr_struct *rr_buf = (struct rr_struct *)*((long *)xl->private);  int32_t idx = 0;    if (!rr_buf)    return;  for (idx = 0; idx < rr_buf->child_count; idx++) {    if (rr_buf->array[idx].xl == (xlator_t *)data)      break;  }  switch (event)    {    case GF_EVENT_CHILD_UP:      {	/* Seeding, to be done only once */	if (rr_buf->first_time && (idx == rr_buf->child_count)) {	  call_ctx_t *cctx = NULL;	  xlator_t *ns = data;	  call_pool_t *pool = xl->ctx->pool;	  cctx = calloc (1, sizeof (*cctx));	  cctx->frames.root  = cctx;	  cctx->frames.this  = xl;    	  cctx->pool = pool;	  LOCK (&pool->lock);	  {	    list_add (&cctx->all_frames, &pool->all_frames);	  }	  UNLOCK (&pool->lock);	  	  STACK_WIND_COOKIE ((&cctx->frames), 		       update_rr_seed_cbk,		       rr_buf,		       ns,		       ns->fops->incver,		       "/");	  rr_buf->first_time = 0;	}      }      break;    case GF_EVENT_CHILD_DOWN:      {	rr_buf->array[idx].eligible = 0;      }      break;    default:      {	;      }      break;    }}struct sched_ops sched = {  .init     = rr_init,  .fini     = rr_fini,  .update   = rr_update,  .schedule = rr_schedule,  .notify   = rr_notify};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -