📄 alu.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/>.*//* ALU code needs a complete re-write. This is one of the most important part of * GlusterFS and so needs more and more reviews and testing */#ifndef _CONFIG_H#define _CONFIG_H#include "config.h"#endif#include <sys/time.h>#include <stdint.h>#include "stack.h"#include "alu.h"static int64_t get_stats_disk_usage (struct xlator_stats *this){ return this->disk_usage;}static int64_t get_stats_write_usage (struct xlator_stats *this){ return this->write_usage;}static int64_t get_stats_read_usage (struct xlator_stats *this){ return this->read_usage;}static int64_t get_stats_disk_speed (struct xlator_stats *this){ return this->disk_speed;}static int64_t get_stats_file_usage (struct xlator_stats *this){ (void) &get_stats_file_usage; /* Avoid warning "defined but not used" */ return this->nr_files;}static int64_t get_stats_num_client (struct xlator_stats *this){ (void) &get_stats_num_client; /* Avoid warning "defined but not used" */ return this->nr_clients;}static int64_t get_stats_free_disk (struct xlator_stats *this){ (void) &get_stats_free_disk; /* Avoid warning "defined but not used" */ if (this->total_disk_size > 0) return (this->free_disk * 100) / this->total_disk_size; return 0;}static int64_t get_max_diff_write_usage (struct xlator_stats *max, struct xlator_stats *min){ return (max->write_usage - min->write_usage);}static int64_t get_max_diff_read_usage (struct xlator_stats *max, struct xlator_stats *min){ return (max->read_usage - min->read_usage);}static int64_t get_max_diff_disk_usage (struct xlator_stats *max, struct xlator_stats *min){ return (max->disk_usage - min->disk_usage);}static int64_t get_max_diff_disk_speed (struct xlator_stats *max, struct xlator_stats *min){ return (max->disk_speed - min->disk_speed);}static int64_t get_max_diff_file_usage (struct xlator_stats *max, struct xlator_stats *min){ return (max->nr_files - min->nr_files);}static int64_t get_max_diff_num_client (struct xlator_stats *max, struct xlator_stats *min){ (void) &get_max_diff_num_client; /* Avoid warning "defined but not used" */ return (max->nr_clients - min->nr_clients);}static int64_t get_max_diff_free_disk (struct xlator_stats *max, struct xlator_stats *min){ (void) &get_max_diff_free_disk; /* Avoid warning "defined but not used" */ return (max->free_disk - min->free_disk);}static int32_talu_init (xlator_t *xl){ struct alu_sched *alu_sched = calloc (1, sizeof (struct alu_sched)); { data_t *order = dict_get (xl->options, "alu.order"); if (!order) { gf_log ("alu", GF_LOG_ERROR, "alu_init: order not specified"); return -1; } struct alu_threshold *_threshold_fn; struct alu_threshold *tmp_threshold; data_t *entry_fn = NULL; data_t *exit_fn = NULL; char *tmp_str; char *order_str = strtok_r (order->data, ":", &tmp_str); /* Get the scheduling priority order, specified by the user. */ while (order_str) { gf_log ("alu", GF_LOG_DEBUG, "alu_init: order string: %s", order_str); if (strcmp (order_str, "disk-usage") == 0) { /* Disk usage */ _threshold_fn = calloc (1, sizeof (struct alu_threshold)); _threshold_fn->diff_value = get_max_diff_disk_usage; _threshold_fn->sched_value = get_stats_disk_usage; entry_fn = dict_get (xl->options, "alu.disk-usage.entry-threshold"); if (!entry_fn) { alu_sched->entry_limit.disk_usage = 1024 * 1024 * 1024; /* Byte Unit */ } else { alu_sched->entry_limit.disk_usage = gf_str_to_long_long (entry_fn->data); } _threshold_fn->entry_value = get_stats_disk_usage; exit_fn = dict_get (xl->options, "alu.disk-usage.exit-threshold"); if (!exit_fn) { alu_sched->exit_limit.disk_usage = 512 * 1024 * 1024; } else { alu_sched->exit_limit.disk_usage = gf_str_to_long_long (exit_fn->data); } _threshold_fn->exit_value = get_stats_disk_usage; tmp_threshold = alu_sched->threshold_fn; if (!tmp_threshold) { alu_sched->threshold_fn = _threshold_fn; } else { while (tmp_threshold->next) { tmp_threshold = tmp_threshold->next; } tmp_threshold->next = _threshold_fn; } gf_log ("alu", GF_LOG_DEBUG, "alu_init: = %"PRId64",%"PRId64"", alu_sched->entry_limit.disk_usage, alu_sched->exit_limit.disk_usage); } else if (strcmp (order_str, "write-usage") == 0) { /* Handle "write-usage" */ _threshold_fn = calloc (1, sizeof (struct alu_threshold)); _threshold_fn->diff_value = get_max_diff_write_usage; _threshold_fn->sched_value = get_stats_write_usage; entry_fn = dict_get (xl->options, "alu.write-usage.entry-threshold"); if (!entry_fn) { alu_sched->entry_limit.write_usage = 25; } else { alu_sched->entry_limit.write_usage = (long)gf_str_to_long_long (entry_fn->data); } _threshold_fn->entry_value = get_stats_write_usage; exit_fn = dict_get (xl->options, "alu.write-usage.exit-threshold"); if (!exit_fn) { alu_sched->exit_limit.write_usage = 5; } else { alu_sched->exit_limit.write_usage = (long)gf_str_to_long_long (exit_fn->data); } _threshold_fn->exit_value = get_stats_write_usage; tmp_threshold = alu_sched->threshold_fn; if (!tmp_threshold) { alu_sched->threshold_fn = _threshold_fn; } else { while (tmp_threshold->next) { tmp_threshold = tmp_threshold->next; } tmp_threshold->next = _threshold_fn; } gf_log ("alu", GF_LOG_DEBUG, "alu_init: = %"PRId64",%"PRId64"", alu_sched->entry_limit.write_usage, alu_sched->exit_limit.write_usage); } else if (strcmp (order_str, "read-usage") == 0) { /* Read usage */ _threshold_fn = calloc (1, sizeof (struct alu_threshold)); _threshold_fn->diff_value = get_max_diff_read_usage; _threshold_fn->sched_value = get_stats_read_usage; entry_fn = dict_get (xl->options, "alu.read-usage.entry-threshold"); if (!entry_fn) { alu_sched->entry_limit.read_usage = 25; } else { alu_sched->entry_limit.read_usage = (long)gf_str_to_long_long (entry_fn->data); } _threshold_fn->entry_value = get_stats_read_usage; exit_fn = dict_get (xl->options, "alu.read-usage.exit-threshold"); if (!exit_fn) { alu_sched->exit_limit.read_usage = 5; } else { alu_sched->exit_limit.read_usage = (long)gf_str_to_long_long (exit_fn->data); } _threshold_fn->exit_value = get_stats_read_usage; tmp_threshold = alu_sched->threshold_fn; if (!tmp_threshold) { alu_sched->threshold_fn = _threshold_fn; } else { while (tmp_threshold->next) { tmp_threshold = tmp_threshold->next; } tmp_threshold->next = _threshold_fn; } gf_log ("alu", GF_LOG_DEBUG, "alu_init: = %"PRId64",%"PRId64"", alu_sched->entry_limit.read_usage, alu_sched->exit_limit.read_usage); } else if (strcmp (order_str, "open-files-usage") == 0) { /* Open files counter */ _threshold_fn = calloc (1, sizeof (struct alu_threshold)); _threshold_fn->diff_value = get_max_diff_file_usage; _threshold_fn->sched_value = get_stats_file_usage; entry_fn = dict_get (xl->options, "alu.open-files-usage.entry-threshold"); if (!entry_fn) { alu_sched->entry_limit.nr_files = 1000; } else { alu_sched->entry_limit.nr_files = strtol (entry_fn->data, NULL, 0); } _threshold_fn->entry_value = get_stats_file_usage; exit_fn = dict_get (xl->options, "alu.open-files-usage.exit-threshold"); if (!exit_fn) { alu_sched->exit_limit.nr_files = 100; } else { alu_sched->exit_limit.nr_files = strtol (exit_fn->data, NULL, 0); } _threshold_fn->exit_value = get_stats_file_usage; tmp_threshold = alu_sched->threshold_fn; if (!tmp_threshold) { alu_sched->threshold_fn = _threshold_fn; } else { while (tmp_threshold->next) { tmp_threshold = tmp_threshold->next; } tmp_threshold->next = _threshold_fn; } gf_log ("alu", GF_LOG_DEBUG, "alu.c->alu_init: = %ld,%ld\n", alu_sched->entry_limit.nr_files, alu_sched->exit_limit.nr_files); } else if (strcmp (order_str, "disk-speed-usage") == 0) { /* Disk speed */ _threshold_fn = calloc (1, sizeof (struct alu_threshold)); _threshold_fn->diff_value = get_max_diff_disk_speed; _threshold_fn->sched_value = get_stats_disk_speed; entry_fn = dict_get (xl->options, "alu.disk-speed-usage.entry-threshold"); if (entry_fn) { gf_log ("alu", GF_LOG_DEBUG, "alu_init: entry-threshold is given for disk-speed, \which is constant"); } _threshold_fn->entry_value = NULL; exit_fn = dict_get (xl->options, "alu.disk-speed-usage.exit-threshold"); if (exit_fn) { gf_log ("alu", GF_LOG_DEBUG, "alu_init: exit-threshold is given for disk-speed, \which is constant"); } _threshold_fn->exit_value = NULL; tmp_threshold = alu_sched->threshold_fn; if (!tmp_threshold) { alu_sched->threshold_fn = _threshold_fn; } else { while (tmp_threshold->next) { tmp_threshold = tmp_threshold->next; } tmp_threshold->next = _threshold_fn; } } else { gf_log ("alu", GF_LOG_DEBUG, "alu_init: %s, unknown option provided to scheduler", order_str); } order_str = strtok_r (NULL, ":", &tmp_str); } } { /* Get the limits */ struct alu_limits *_limit_fn = NULL; struct alu_limits *tmp_limits = NULL; data_t *limits = NULL; limits = dict_get (xl->options, "alu.limits.min-free-disk"); if (limits) { _limit_fn = calloc (1, sizeof (struct alu_limits)); _limit_fn->min_value = get_stats_free_disk; _limit_fn->cur_value = get_stats_free_disk; tmp_limits = alu_sched->limits_fn ; _limit_fn->next = tmp_limits; alu_sched->limits_fn = _limit_fn; alu_sched->spec_limit.free_disk = gf_str_to_long_long (limits->data); if (alu_sched->spec_limit.free_disk >= 100) { gf_log ("alu", GF_LOG_ERROR, "check the \"option rr.limits.min-free-disk\", it should be percentage value"); return -1; } alu_sched->spec_limit.total_disk_size = 100; /* Its in % */ gf_log ("alu", GF_LOG_DEBUG, "alu.limit.min-disk-free = %"PRId64"", _limit_fn->cur_value (&(alu_sched->spec_limit))); } limits = dict_get (xl->options, "alu.limits.max-open-files"); if (limits) { // Update alu_sched->priority properly _limit_fn = calloc (1, sizeof (struct alu_limits)); _limit_fn->max_value = get_stats_file_usage; _limit_fn->cur_value = get_stats_file_usage; tmp_limits = alu_sched->limits_fn ; _limit_fn->next = tmp_limits; alu_sched->limits_fn = _limit_fn; alu_sched->spec_limit.nr_files = gf_str_to_long_long (limits->data); gf_log ("alu", GF_LOG_DEBUG, "alu_init: limit.max-open-files = %"PRId64"", _limit_fn->cur_value (&(alu_sched->spec_limit))); } } { /* Stats refresh options */ data_t *stats_refresh = dict_get (xl->options, "refresh-interval"); if (stats_refresh) { alu_sched->refresh_interval = (int)gf_str_to_long_long (stats_refresh->data); } else { alu_sched->refresh_interval = 5; // set to the default value } gettimeofday (&(alu_sched->last_stat_fetch), NULL); stats_refresh = dict_get (xl->options, "alu.stat-refresh.num-file-create"); if (stats_refresh) { alu_sched->refresh_create_count = (int)gf_str_to_long_long (stats_refresh->data); } else { alu_sched->refresh_create_count = 5; // set to the default value } } { /* Build an array of child_nodes */ struct alu_sched_struct *sched_array = NULL; xlator_list_t *trav_xl = xl->children; data_t *data = NULL; int32_t index = 0; while (trav_xl) { index++; trav_xl = trav_xl->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -