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

📄 nufa.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 "nufa.h"#include <sys/time.h>static int32_tnufa_init (xlator_t *xl){  int32_t index = 0;  data_t *local_name = NULL;  data_t *data = NULL;  xlator_list_t *trav_xl = xl->children;  struct nufa_struct *nufa_buf = calloc (1, sizeof (struct nufa_struct));  data = dict_get (xl->options, "nufa.limits.min-free-disk");  if (data) {    nufa_buf->min_free_disk = gf_str_to_long_long (data->data);    if (nufa_buf->min_free_disk >= 100) {      gf_log ("nufa", GF_LOG_ERROR,	      "check the \"option nufa.limits.min-free-disk\", it should be percentage value");      return -1;    }  } else {    gf_log ("nufa", GF_LOG_WARNING, 	    "No option for limit min-free-disk given, defaulting it to 15%");    nufa_buf->min_free_disk = gf_str_to_long_long ("15"); /* 15% free-disk */  }  data = dict_get (xl->options, "nufa.refresh-interval");  if (data) {    nufa_buf->refresh_interval = (int32_t)gf_str_to_long_long (data->data);  } else {    gf_log ("nufa", GF_LOG_WARNING, 	    "No option for nufa.refresh-interval given, defaulting it to 30");    nufa_buf->refresh_interval = 30; /* 30 Seconds */  }  /* Get the array built */  while (trav_xl) {    index++;    trav_xl = trav_xl->next;  }  nufa_buf->child_count = index;  nufa_buf->sched_index = 0;  nufa_buf->array = calloc (index, sizeof (struct nufa_sched_struct));  nufa_buf->local_array = calloc (index, sizeof (int32_t));  trav_xl = xl->children;  local_name = dict_get (xl->options, "nufa.local-volume-name");  if (!local_name) {    /* Error */    gf_log ("nufa", GF_LOG_ERROR, 	    "No 'local-volume-name' option given in spec file\n");    freee (nufa_buf->array);    freee (nufa_buf->local_array);    freee (nufa_buf);    return -1;  }  /* Get the array properly */  index = 0;  trav_xl = xl->children;  while (trav_xl) {    nufa_buf->array[index].xl = trav_xl->xlator;    nufa_buf->array[index].eligible = 1;    nufa_buf->array[index].free_disk = nufa_buf->min_free_disk;    nufa_buf->array[index].refresh_interval = nufa_buf->refresh_interval;    trav_xl = trav_xl->next;    index++;  }    {     int32_t array_index = 0;    char *child = NULL;    char *tmp = NULL;    char *childs_data = strdup (local_name->data);        child = strtok_r (childs_data, ",", &tmp);    while (child) {      /* Check if the local_volume specified is proper subvolume of unify */      trav_xl = xl->children;      index=0;      while (trav_xl) {	if (strcmp (child, trav_xl->xlator->name) == 0)	  break;	trav_xl = trav_xl->next;	index++;      }      if (!trav_xl) {	/* entry for 'local-volume-name' is wrong, not present in subvolumes */	gf_log ("nufa", GF_LOG_ERROR, 		"option 'nufa.local-volume-name' is wrong\n");	freee (nufa_buf->array);	freee (nufa_buf->local_array);	freee (nufa_buf);	return -1;      } else {	nufa_buf->local_array[array_index++] = index;	nufa_buf->local_xl_count++;      }      child = strtok_r (NULL, ",", &tmp);    }    free (childs_data);  }  LOCK_INIT (&nufa_buf->nufa_lock);  *((long *)xl->private) = (long)nufa_buf; // put it at the proper place  return 0;}static voidnufa_fini (xlator_t *xl){  struct nufa_struct *nufa_buf = (struct nufa_struct *)*((long *)xl->private);  LOCK_DESTROY (&nufa_buf->nufa_lock);  freee (nufa_buf->local_array);  freee (nufa_buf->array);  freee (nufa_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 nufa_struct *nufa_struct = NULL;   int32_t idx = 0;  int32_t percent = 0;  nufa_struct = (struct nufa_struct *)*((long *)xl->private);  LOCK (&nufa_struct->nufa_lock);  for (idx = 0; idx < nufa_struct->child_count; idx++) {    if (nufa_struct->array[idx].xl->name == (char *)cookie)      break;  }  UNLOCK (&nufa_struct->nufa_lock);  if (op_ret == 0) {    percent = (trav_stats->free_disk * 100) / trav_stats->total_disk_size;    if (nufa_struct->array[idx].free_disk > percent) {      if (nufa_struct->array[idx].eligible)	gf_log ("nufa", GF_LOG_CRITICAL,		"node \"%s\" is _almost_ (%d %%) full", 		nufa_struct->array[idx].xl->name, 100 - percent);      nufa_struct->array[idx].eligible = 0;    } else {      nufa_struct->array[idx].eligible = 1;    }  } else {    nufa_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 */  int32_t idx;  call_ctx_t *cctx;  struct nufa_struct *nufa_buf = (struct nufa_struct *)*((long *)xl->private);  for (idx = 0; idx < nufa_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, 		 nufa_buf->array[idx].xl->name,		 nufa_buf->array[idx].xl, 		 (nufa_buf->array[idx].xl)->mops->stats,		 0); //flag  }  return;}static void nufa_update (xlator_t *xl){  struct nufa_struct *nufa_buf = (struct nufa_struct *)*((long *)xl->private);  struct timeval tv;  gettimeofday (&tv, NULL);  if (tv.tv_sec > (nufa_buf->refresh_interval 		   + nufa_buf->last_stat_fetch.tv_sec)) {    /* Update the stats from all the server */    update_stat_array (xl);    nufa_buf->last_stat_fetch.tv_sec = tv.tv_sec;  }}static xlator_t *nufa_schedule (xlator_t *xl, void *path){  struct nufa_struct *nufa_buf = (struct nufa_struct *)*((long *)xl->private);  int32_t nufa_orig = nufa_buf->local_xl_index;    int32_t rr;    nufa_update (xl);    while (1) {    LOCK (&nufa_buf->nufa_lock);    rr = nufa_buf->local_xl_index++;    nufa_buf->local_xl_index %= nufa_buf->local_xl_count;    UNLOCK (&nufa_buf->nufa_lock);        /* if 'eligible' or there are _no_ eligible nodes */    if (nufa_buf->array[nufa_buf->local_array[rr]].eligible) {      /* Return the local node */      return nufa_buf->array[nufa_buf->local_array[rr]].xl;    }    if ((rr + 1) % nufa_buf->local_xl_count == nufa_orig) {      gf_log ("nufa", 	      GF_LOG_CRITICAL, 	      "No free space available on any local volumes, using RR scheduler");      LOCK (&nufa_buf->nufa_lock);      nufa_buf->local_xl_index++;      nufa_buf->local_xl_index %= nufa_buf->local_xl_count;      UNLOCK (&nufa_buf->nufa_lock);      break;    }  }  nufa_orig = nufa_buf->sched_index;    while (1) {    LOCK (&nufa_buf->nufa_lock);    rr = nufa_buf->sched_index++;    nufa_buf->sched_index = nufa_buf->sched_index % nufa_buf->child_count;    UNLOCK (&nufa_buf->nufa_lock);        /* if 'eligible' or there are _no_ eligible nodes */    if (nufa_buf->array[rr].eligible) {      break;    }    if ((rr + 1) % nufa_buf->child_count == nufa_orig) {      gf_log ("nufa", 	      GF_LOG_CRITICAL, 	      "No free space available on any server, using RR scheduler.");      LOCK (&nufa_buf->nufa_lock);      nufa_buf->sched_index++;      nufa_buf->sched_index = nufa_buf->sched_index % nufa_buf->child_count;      UNLOCK (&nufa_buf->nufa_lock);      break;    }  }  return nufa_buf->array[rr].xl;}/** * notify */voidnufa_notify (xlator_t *xl, int32_t event, void *data){  struct nufa_struct *nufa_buf = (struct nufa_struct *)*((long *)xl->private);  int32_t idx = 0;    if (!nufa_buf)    return;  for (idx = 0; idx < nufa_buf->child_count; idx++) {    if (strcmp (nufa_buf->array[idx].xl->name, ((xlator_t *)data)->name) == 0)      break;  }  switch (event)    {    case GF_EVENT_CHILD_UP:      {	//nufa_buf->array[idx].eligible = 1;      }      break;    case GF_EVENT_CHILD_DOWN:      {	nufa_buf->array[idx].eligible = 0;      }      break;    default:      {	;      }      break;    }}struct sched_ops sched = {  .init     = nufa_init,  .fini     = nufa_fini,  .update   = nufa_update,  .schedule = nufa_schedule,  .notify   = nufa_notify};

⌨️ 快捷键说明

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