mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-16 09:58:21 +00:00
Merge branch 'erasure' of github.com:rustfs/s3-rustfs into erasure
This commit is contained in:
+27
-12
@@ -1,5 +1,5 @@
|
|||||||
use super::ellipses::*;
|
use super::ellipses::*;
|
||||||
use anyhow::{Error, Result};
|
use super::error::{Error, Result};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl<T: AsRef<str>> TryFrom<&[T]> for DisksLayout {
|
|||||||
|
|
||||||
fn try_from(args: &[T]) -> Result<Self, Self::Error> {
|
fn try_from(args: &[T]) -> Result<Self, Self::Error> {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return Err(Error::msg("Invalid argument"));
|
return Err(Error::from_string("Invalid argument"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_ellipses = args.iter().any(|v| has_ellipses(&[v]));
|
let is_ellipses = args.iter().any(|v| has_ellipses(&[v]));
|
||||||
@@ -54,7 +54,9 @@ impl<T: AsRef<str>> TryFrom<&[T]> for DisksLayout {
|
|||||||
let mut layout = Vec::with_capacity(args.len());
|
let mut layout = Vec::with_capacity(args.len());
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
if !has_ellipses(&[arg]) && args.len() > 1 {
|
if !has_ellipses(&[arg]) && args.len() > 1 {
|
||||||
return Err(Error::msg("all args must have ellipses for pool expansion (Invalid arguments specified)"));
|
return Err(Error::from_string(
|
||||||
|
"all args must have ellipses for pool expansion (Invalid arguments specified)",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let set_args = get_all_sets(is_ellipses, &[arg])?;
|
let set_args = get_all_sets(is_ellipses, &[arg])?;
|
||||||
@@ -69,6 +71,19 @@ impl<T: AsRef<str>> TryFrom<&[T]> for DisksLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DisksLayout {
|
||||||
|
pub fn is_empty_layout(&self) -> bool {
|
||||||
|
self.pools.is_empty()
|
||||||
|
|| self.pools[0].layout.is_empty()
|
||||||
|
|| self.pools[0].layout[0].is_empty()
|
||||||
|
|| self.pools[0].layout[0][0].is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_single_drive_layout(&self) -> bool {
|
||||||
|
self.pools.len() == 1 && self.pools[0].layout.len() == 1 && self.pools[0].layout[0].len() == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// parses all ellipses input arguments, expands them into
|
/// parses all ellipses input arguments, expands them into
|
||||||
/// corresponding list of endpoints chunked evenly in accordance with a
|
/// corresponding list of endpoints chunked evenly in accordance with a
|
||||||
/// specific set size.
|
/// specific set size.
|
||||||
@@ -95,7 +110,7 @@ fn get_all_sets<T: AsRef<str>>(is_ellipses: bool, args: &[T]) -> Result<Vec<Vec<
|
|||||||
for args in set_args.iter() {
|
for args in set_args.iter() {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if unique_args.contains(arg) {
|
if unique_args.contains(arg) {
|
||||||
return Err(Error::msg(format!("Input args {} has duplicate ellipses", arg)));
|
return Err(Error::from_string(format!("Input args {} has duplicate ellipses", arg)));
|
||||||
}
|
}
|
||||||
unique_args.insert(arg);
|
unique_args.insert(arg);
|
||||||
}
|
}
|
||||||
@@ -254,20 +269,20 @@ fn possible_set_counts_with_symmetry(set_counts: &[usize], arg_patterns: &[ArgPa
|
|||||||
/// indexes (total sets)
|
/// indexes (total sets)
|
||||||
fn get_set_indexes<T: AsRef<str>>(args: &[T], total_sizes: &[usize], arg_patterns: &[ArgPattern]) -> Result<Vec<Vec<usize>>> {
|
fn get_set_indexes<T: AsRef<str>>(args: &[T], total_sizes: &[usize], arg_patterns: &[ArgPattern]) -> Result<Vec<Vec<usize>>> {
|
||||||
if args.is_empty() || total_sizes.is_empty() {
|
if args.is_empty() || total_sizes.is_empty() {
|
||||||
return Err(Error::msg("Invalid argument"));
|
return Err(Error::from_string("Invalid argument"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for &size in total_sizes {
|
for &size in total_sizes {
|
||||||
// Check if total_sizes has minimum range upto set_size
|
// Check if total_sizes has minimum range upto set_size
|
||||||
if size < SET_SIZES[0] {
|
if size < SET_SIZES[0] {
|
||||||
return Err(Error::msg(format!("Incorrect number of endpoints provided, size {}", size)));
|
return Err(Error::from_string(format!("Incorrect number of endpoints provided, size {}", size)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let common_size = get_divisible_size(total_sizes);
|
let common_size = get_divisible_size(total_sizes);
|
||||||
let mut set_counts = possible_set_counts(common_size);
|
let mut set_counts = possible_set_counts(common_size);
|
||||||
if set_counts.is_empty() {
|
if set_counts.is_empty() {
|
||||||
return Err(Error::msg(format!(
|
return Err(Error::from_string(format!(
|
||||||
"Incorrect number of endpoints provided, number of drives {} is not divisible by any supported erasure set sizes {}",
|
"Incorrect number of endpoints provided, number of drives {} is not divisible by any supported erasure set sizes {}",
|
||||||
common_size, 0
|
common_size, 0
|
||||||
)));
|
)));
|
||||||
@@ -278,13 +293,13 @@ fn get_set_indexes<T: AsRef<str>>(args: &[T], total_sizes: &[usize], arg_pattern
|
|||||||
// Returns possible set counts with symmetry.
|
// Returns possible set counts with symmetry.
|
||||||
set_counts = possible_set_counts_with_symmetry(&set_counts, arg_patterns);
|
set_counts = possible_set_counts_with_symmetry(&set_counts, arg_patterns);
|
||||||
if set_counts.is_empty() {
|
if set_counts.is_empty() {
|
||||||
return Err(Error::msg("No symmetric distribution detected with input endpoints provided"));
|
return Err(Error::from_string("No symmetric distribution detected with input endpoints provided"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final set size with all the symmetry accounted for.
|
// Final set size with all the symmetry accounted for.
|
||||||
let set_size = common_set_drive_count(common_size, &set_counts);
|
let set_size = common_set_drive_count(common_size, &set_counts);
|
||||||
if !is_valid_set_size(set_size) {
|
if !is_valid_set_size(set_size) {
|
||||||
return Err(Error::msg("Incorrect number of endpoints provided3"));
|
return Err(Error::from_string("Incorrect number of endpoints provided3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(total_sizes
|
Ok(total_sizes
|
||||||
@@ -475,7 +490,7 @@ mod test {
|
|||||||
arg_patterns.push(patterns);
|
arg_patterns.push(patterns);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
panic!("Test{}: Unexpected failure {}", test_case.num, err);
|
panic!("Test{}: Unexpected failure {:?}", test_case.num, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,7 +509,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if test_case.success {
|
if test_case.success {
|
||||||
panic!("Test{}: Expected success but failed instead {}", test_case.num, err);
|
panic!("Test{}: Expected success but failed instead {:?}", test_case.num, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,7 +769,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if test_case.success {
|
if test_case.success {
|
||||||
panic!("Test{}: Expected success but failed instead {}", test_case.num, err);
|
panic!("Test{}: Expected success but failed instead {:?}", test_case.num, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
|
|
||||||
use anyhow::{Error, Result};
|
use super::error::{Error, Result};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@@ -88,7 +88,7 @@ pub fn find_ellipses_patterns(arg: &str) -> Result<ArgPattern> {
|
|||||||
let mut parts = match ELLIPSES_RE.captures(arg) {
|
let mut parts = match ELLIPSES_RE.captures(arg) {
|
||||||
Some(caps) => caps,
|
Some(caps) => caps,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::msg(format!("Invalid ellipsis format in ({}), Ellipsis range must be provided in format {{N...M}} where N and M are positive integers, M must be greater than N, with an allowed minimum range of 4", arg)));
|
return Err(Error::from_string(format!("Invalid ellipsis format in ({}), Ellipsis range must be provided in format {{N...M}} where N and M are positive integers, M must be greater than N, with an allowed minimum range of 4", arg)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ pub fn find_ellipses_patterns(arg: &str) -> Result<ArgPattern> {
|
|||||||
|| p.suffix.contains(OPEN_BRACES)
|
|| p.suffix.contains(OPEN_BRACES)
|
||||||
|| p.suffix.contains(CLOSE_BRACES)
|
|| p.suffix.contains(CLOSE_BRACES)
|
||||||
{
|
{
|
||||||
return Err(Error::msg(format!("Invalid ellipsis format in ({}), Ellipsis range must be provided in format {{N...M}} where N and M are positive integers, M must be greater than N, with an allowed minimum range of 4", arg)));
|
return Err(Error::from_string(format!("Invalid ellipsis format in ({}), Ellipsis range must be provided in format {{N...M}} where N and M are positive integers, M must be greater than N, with an allowed minimum range of 4", arg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,10 +146,10 @@ pub fn has_ellipses<T: AsRef<str>>(s: &[T]) -> bool {
|
|||||||
/// {33...64}
|
/// {33...64}
|
||||||
pub fn parse_ellipses_range(pattern: &str) -> Result<Vec<String>> {
|
pub fn parse_ellipses_range(pattern: &str) -> Result<Vec<String>> {
|
||||||
if !pattern.contains(OPEN_BRACES) {
|
if !pattern.contains(OPEN_BRACES) {
|
||||||
return Err(Error::msg("Invalid argument"));
|
return Err(Error::from_string("Invalid argument"));
|
||||||
}
|
}
|
||||||
if !pattern.contains(OPEN_BRACES) {
|
if !pattern.contains(OPEN_BRACES) {
|
||||||
return Err(Error::msg("Invalid argument"));
|
return Err(Error::from_string("Invalid argument"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ellipses_range: Vec<&str> = pattern
|
let ellipses_range: Vec<&str> = pattern
|
||||||
@@ -159,7 +159,7 @@ pub fn parse_ellipses_range(pattern: &str) -> Result<Vec<String>> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if ellipses_range.len() != 2 {
|
if ellipses_range.len() != 2 {
|
||||||
return Err(Error::msg("Invalid argument"));
|
return Err(Error::from_string("Invalid argument"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add support for hexadecimals.
|
// TODO: Add support for hexadecimals.
|
||||||
@@ -167,7 +167,7 @@ pub fn parse_ellipses_range(pattern: &str) -> Result<Vec<String>> {
|
|||||||
let end = ellipses_range[1].parse::<usize>()?;
|
let end = ellipses_range[1].parse::<usize>()?;
|
||||||
|
|
||||||
if start > end {
|
if start > end {
|
||||||
return Err(Error::msg("Invalid argument:range start cannot be bigger than end"));
|
return Err(Error::from_string("Invalid argument:range start cannot be bigger than end"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ret: Vec<String> = Vec::with_capacity(end - start + 1);
|
let mut ret: Vec<String> = Vec::with_capacity(end - start + 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user