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

📄 random.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/>.*/#include <stdlib.h>#include <sys/time.h>#ifndef _CONFIG_H#define _CONFIG_H#include "config.h"#endif#include "random.h"static int32_trandom_init (xlator_t *xl){  struct random_struct *random_buf = calloc (1, sizeof (struct random_struct));  xlator_list_t *trav_xl = xl->children;  int32_t index = 0;  /* Set the seed for the 'random' function */  srandom ((uint32_t) time (NULL));  data_t *limit = dict_get (xl->options, "random.limits.min-free-disk");  if (limit) {    random_buf->min_free_disk = gf_str_to_long_long (limit->data);    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 = gf_str_to_long_long ("5"); /* 5% free space */  }  limit = dict_get (xl->options, "random.refresh-interval");  if (limit) {    random_buf->refresh_interval = (int32_t)gf_str_to_long_long (limit->data);  } else {    random_buf->refresh_interval = 10; /* 10 Seconds */  }  while (trav_xl) {    index++;    trav_xl = trav_xl->next;  }  random_buf->child_count = index;  random_buf->array = calloc (index, sizeof (struct random_sched_struct));  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);    *((long *)xl->private) = (long)random_buf; // put it at the proper place  return 0;}static voidrandom_fini (xlator_t *xl){  struct random_struct *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 = (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;  call_ctx_t *cctx;  struct random_struct *random_buf = (struct random_struct *)*((long *)xl->private);  for (idx = 0; idx < random_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,		 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 = (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, void *path){  struct random_struct *random_buf = (struct random_struct *)*((long *)xl->private);  int32_t rand = (int32_t) (1.0*random_buf->child_count * (random() / (RAND_MAX + 1.0)));  int32_t try = 0;  random_update (xl);  while (!random_buf->array[rand].eligible) {    if (try++ > 100)      break; //there is a chance of this becoming a infinite loop otherwise.    rand = (int32_t) (1.0*random_buf->child_count * (random() / (RAND_MAX + 1.0)));  }  return random_buf->array[rand].xl;}/** * notify */voidrandom_notify (xlator_t *xl, int32_t event, void *data){  struct random_struct *random_buf = (struct random_struct *)*((long *)xl->private);  int32_t idx = 0;    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};

⌨️ 快捷键说明

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