Code Monkey home page Code Monkey logo

leil-io / saunafs Goto Github PK

View Code? Open in Web Editor NEW
27.0 4.0 3.0 13.34 MB

SaunaFS is a free-and open source, distributed POSIX file system inspired by Google File System.

Home Page: https://saunafs.com

License: GNU General Public License v3.0

CMake 1.42% Shell 11.07% C++ 76.10% Python 4.63% HTML 0.01% CSS 0.11% C 6.40% Dockerfile 0.10% BitBake 0.16%
archiving distributed-file-system distributed-storage fault-tolerance high-availability high-performance high-performance-computing self-healing self-hosted

saunafs's Introduction

SaunaFS

A Distributed POSIX File System

Slack

About

SaunaFS is a free and open source, distributed POSIX file system inspired by Google File System. Designed to run on commodity hardware, SaunaFS is a high-performance, scalable, and reliable file system that provides high availability, data integrity, fault tolerance, and performance on par with local file systems. It it easy to deploy and manage, and it is designed to be used in a wide range of applications, from small clusters to large data centers.

Feature List

  • Resilient architecture to ensure seamless operation organized into distinct components (Metadata servers, data servers, clients).
  • Continuous assured data integrity and verification with CRC data stored within each chunk’s metadata.
  • Robust redundancy and enhanced data durability with Reed-Solomon erasure coding when up to two nodes can disappear without service interruption.
  • Instant Copy-on-Write Snapshots to implement immutability.
  • Data preservation and recovery with instant snapshotting mechanism.
  • Fast metadata logging for with support for access time attribute.
  • Seamless hardware refresh and expansion without downtime.

Quick Start

Installation

Please refer to the Installation Guide for detailed instructions on how to install SaunaFS.

Setup

Check the Quick Start guide for a simple setup of SaunaFS on a single machine.

After the Quick Start Guide, for an advanced setup, please refer to the Administration Guide as a starting place.

Building from source

This section assumes you have the necessary dependencies installed. If not, check the Installation Guide for a list of dependencies (at least for Ubuntu) and a more complete guide for compiling from source.

We use nice to set the building process to a lower priority, so it doesn't hog memory and CPU resources. We also set -j to the number of cores in your system to speed up the build process. Note that setting -j without nice can lead to the system running out of memory/hanging.

git clone https://github.com/leil-io/saunafs.github
cd saunafs
mkdir build
cd build
cmake ..
nice -n 16 make -j$(nproc)

Documentation

There are 2 types of documentation available:

Contributing

See the Contributing Guide for detailed information on how to contribute to SaunaFS.

The Developer Guide is a good starting point for how to setup a development environment and run tests.

Contact us

Join our Slack community to connect with fellow SaunaFS enthusiasts, developers, and users. In our Slack channels, you can:

  • Ask Questions: Seek guidance, share your experiences, and ask questions related to SaunaFS.
  • Discuss Ideas: Engage in discussions about new features, improvements, and best practices.
  • Receive Updates: Stay informed about SaunaFS developments, releases, and events.

Join us and be part of the discussion.

Other ways to contact us

Method Link
📧 Email [email protected]
🌐 Web https://saunafs.com

Thank you for your help.

The SaunaFS Team.

saunafs's People

Contributors

marcinsulikowski avatar darkhaze avatar psarna avatar ictus4u avatar lgsilva3087 avatar kazik208 avatar ralcolea avatar przemekpjski avatar fretek avatar amokhuginnsson avatar uristdwarf avatar antuan-ae avatar onlyjob avatar kskalski avatar pilusx avatar trzysiek avatar pjanicki avatar lamvak avatar blink69 avatar jedisct1 avatar aneutrino avatar qbm avatar malcom avatar rolysr avatar etam avatar three3 avatar yummybian avatar wojciesh avatar sfindeisen avatar sirnolaan avatar

Stargazers

 avatar Bartosz Pieniak avatar Dmitry Malinin avatar  avatar CIH avatar  avatar  avatar Noah Watkins avatar Kamilla 'ova avatar Simon Hauser avatar Oleg Senchenko avatar Alexfilus avatar Makariy avatar Егор Артемов avatar Maxim Zotov avatar  avatar  avatar  avatar Eugene Klimov avatar Andrei Kvapil avatar  avatar Max Hausch avatar Aliuska Marrero Nieblas avatar  avatar Aleksandr Ragel avatar  avatar  avatar

Watchers

 avatar  avatar Aliuska Marrero Nieblas avatar  avatar

saunafs's Issues

NFS Ganesha, FSAL, file corruption on master fail-over

Behavior of NFS Ganesha with SaunaFS FSAL on SaunaFS Master fail-over is flaky and sometimes files in-flight are corrupted.

Software versions

OS: Ubuntu 22.04LTS
SaunaFS Version: 4.0.1-20240301-164017-stable-main-82161d4f (from SaunaFS repositories)
Ganesha Version: 4.3-1 (from lunar repositories)

Setup

For easy reproduction, steps are performed on a single machine with SaunaFS Master, Chunkserver and NFS Ganesha. Master failover are simulated by restarting the service.

Configuration files:

  • /etc/saunafs/sfsmaster.cfg

    PERSONALITY = master
    MASTER_HOST = sfsmaster
    MASTER_PORT = 9419
    MASTER_TIMEOUT = 10
    AUTO_RECOVERY = 1
    REJECT_OLD_CLIENTS = 1
    AVOID_SAME_IP_CHUNKSERVERS = 1
    MATOCS_LISTEN_HOST = *
    MATOCS_LISTEN_PORT = 9420
    MATOCL_LISTEN_HOST = *
    MATOCL_LISTEN_PORT = 9421
    OPERATIONS_DELAY_DISCONNECT = 300
  • /etc/saunafs/sfsexports.cfg

    *                       /       rw,alldirs,maproot=0,ignoregid
    *                       .       rw
  • /etc/saunafs/sfsgoals.cfg

    1 1 : _
    2 2 : _ _
    3 3 : _ _ _
    4 4 : _ _ _ _
    5 5 : _ _ _ _ _
    10 ec21 : $ec(2,1)
    11 ec31 : $ec(3,1)
    12 ec32 : $ec(3,2)
  • /etc/saunafs/sfschunkserver.cfg

    MASTER_HOST = 10.20.32.159
    HDD_LEAVE_SPACE_DEFAULT = 2GB
  • /etc/saunafs/sfshdd.cfg

    /var/lib/saunafs-chunks
  • /etc/ganesha/ganesha.conf

    EXPORT
    {
        Export_Id = 77;
        Path = "/";
        Pseudo = "/";
        Access_Type = RW;
        Squash = None;
        Attr_Expiration_Time = 0;
    
        FSAL {
            Name = SaunaFS;
            hostname = "10.20.32.159";
            port = "9421";
            io_retries = 5;
            cache_expiration_time_ms = 2500;
        }
    
        Protocols = 3, 4;
    }
    

Reproduction steps

These steps are flaky, sometimes the file is sent correctly, sometimes it hangs indefinitely, sometimes it finishes with corrupted file.

# Mount using both SaunsFS Client and NFS
$ mkdir -p /mnt/{saunafs,nfs}
$ sfsmount /mnt/saunafs
$ mount -vvvv 10.20.32.159:/ /mnt/nfs

# Create a file for testing with checksum
$ head -c 3G /dev/random | pv > /mnt/test_file

# Upload the file using NFS while killing the master every ten seconds
$ while true; do sleep 10 && systemctl restart saunafs-master.service; done &
$ MASTER_KILL_PID=$!
$ pv /mnt/test_file > /mnt/nfs/test_file
$ kill $MASTER_KILL_PID

# Verify checksums
$ sha256sum /mnt/{,saunafs,nfs}/test_file

Refactor command-line option handling for executables

Instead of handling the command-line option for each executable, we should have a shared static library that handles this instead. This will require refactoring the command-line handling from both saunafs-admin and other executables.

No outside pull requests will be merged (at the moment...)

Currently we can't accept pull requests outside. We are working on fixing this issue. In the meantime, if you want to contribute code, please comment here and open pull requests, so we know people are interested and will work faster on it.

Sorry for the inconvenience.

Typo/Grammar/Nitpick Mega Issue

Instead of creating a pull request for every typographic/grammatical error or nitpick you find, you should instead post it here along with the location of said error/nitpick. Before every major/minor version release, we will look through these and include most of them here in a single commit, and properly credit you (if you want).

Please include:

  1. The location of the error/nitpick
  2. The correction
  3. (OPTIONALLY) Your name and email (can be a GitHub no-reply email) so we can add you to the "Co-authored by" section in the commit. Otherwise, we will use your GitHub username instead (You can also add that you don't want to be attributed, in which case we will include neither)

Note that we don't guarantee we will include these fixes (especially if we disagree with them), but it keeps the PR's clean of trivial changes and having to run the CI for each of those.

Known high-priority issues from LizardFS

These are know high-priority issues the SaunaFS team has analyzed from LizardFS that still potentially exist.

If you find an issue that was missed and still exists on SaunaFS, please open a new issue instead, thank you!

refactor: Configuration management

Currently, each caller to cfg_get sets it's own defaults. This makes it difficult to gather information about running configurations, since there is no single source that sets the default configuration and it could get messy if two callers are setting their own defaults.

The idea is that each executable that uses the common library configuration portion sets all configuration options on startup and including the defaults as well. This way, the caller won't have to worry about defaults at all (unless it specifically wants to).

Related to #13.

An example draft from @lgsilva3087:

#pragma once

#include "common/platform.h"

#include <cstdint>
#include <memory>
#include <sstream>
#include <string>

#include "common/cfg.h"

/// Abstract base class for configuration options.
/// Used to trick the compiler into allowing a map of different types of
/// templated options.
class OptionBase {
public:
	/// Default constructor.
	explicit OptionBase(std::string name) : name_(std::move(name)) {}

	/// Copy and move constructors and assignment operators.
	OptionBase(const OptionBase &) = delete;
	OptionBase(OptionBase &&) = delete;
	OptionBase &operator=(const OptionBase &) = delete;
	OptionBase &operator=(OptionBase &&) = delete;

	/// Default virtual destructor, needed for polymorphism.
	virtual ~OptionBase() = default;

	/// Get the name of the option.
	std::string getName() const { return name_; }

	/// Should return an string representation of the option.
	virtual std::string toString() const = 0;

private:
	/// The name of the option.
	std::string name_;
};

template<typename T>
class GenericOption : public OptionBase {
public:
	/// Constructor with parameters.
	GenericOption(std::string name, T defaultValue)
	    : OptionBase(std::move(name)),
	      defaultValue_(defaultValue),
	      value_(defaultValue_) {}

	/// Default constructor.
	GenericOption() = delete;

	/// Not needed constructors/assignment operators.
	GenericOption(const GenericOption &) = delete;
	GenericOption(GenericOption &&) = delete;
	GenericOption &operator=(const GenericOption &) = delete;
	GenericOption &operator=(GenericOption &&) = delete;

	/// Default virtual destructor, needed for polymorphism.
	virtual ~GenericOption() = default;

	/// Should update the value of the option from the configuration file using
	/// the concrete type.
	virtual void updateValueFromFile() = 0;

	/// Get the value of the option.
	T getValue() const { return value_; }

	/// Set the value of the option.
	void setValue(T newValue) {
		value_ = newValue;
	}

	/// Get the default value of the option.
	T getDefaultValue() const { return defaultValue_; }

	/// Returns an string representation of the option.
	std::string toString() const override {
		std::stringstream result;

		result << getName() << " = " << value_
		       << "; // Default: " << defaultValue_;

		return result.str();
	}

private:
	/// The default value of the option.
	T defaultValue_;

	/// The value of the option.
	T value_;
};

/// Specialization of GenericOption to handle uint32_t
class OptionUint32 : public GenericOption<uint32_t> {
public:
	OptionUint32(std::string name, uint32_t defaultValue)
	    : GenericOption<uint32_t>(std::move(name), defaultValue) {}

	void updateValueFromFile() override {
		auto val = cfg_getuint32(getName().c_str(), getDefaultValue());
		setValue(val);
	}
};

/// Specialization of GenericOption to handle std::string
class OptionString : public GenericOption<std::string> {
public:
	OptionString(std::string name, std::string defaultValue)
	    : GenericOption<std::string>(std::move(name), std::move(defaultValue)) {
	}

	void updateValueFromFile() override {
		auto *val = cfg_getstr(getName().c_str(), getDefaultValue().c_str());
		setValue(val);
	}
};

// The rest of the concrete options should be added here until we move them to
// their own file. Some of them will be: OptionDouble, OptionRanged, etc..

/// Singleton class to store configuration parameters.
/// All the calls to the cfg_get* functions should be replaced by calls to the
/// getOption method of this class. This way, the map will contain the actual
/// effective value of the options in a single place per module.
class Configuration {
public:
	/// Get the instance of the Configuration class.
	static Configuration& instance() {
		static Configuration instance;
		return instance;
	}

	// Not needed methods
	Configuration(const Configuration &) = delete;
	Configuration &operator=(const Configuration &) = delete;
	Configuration(Configuration &&) = delete;
	Configuration &operator=(Configuration &&) = delete;

	/// Default destructor
	~Configuration() = default;

	/// Retrieves an option from the configuration file as uint32_t.
	/// \param optionName The name of the option to retrieve.
	/// In the future, the option will be cached and only read from the file
	/// once, unless reaload is requested.
	template<typename T>
	auto getOption(const std::string &name) {
		// Make sure the option exists
		assert(options_.find(name) != options_.end());

		// Cast to the concrete type
		auto option = static_cast<GenericOption<T> *>(options_.at(name).get());

		// Update the value (always until we have add support for reload option)
		option->updateValueFromFile();

		return option->getValue();
	}

	/// Adds an option to the map. All options should be added at start time.
	/// \param option The option to add.
	void addOption(std::shared_ptr<OptionBase> &option) {
		if (options_.find(option->getName()) != options_.end()) {
			safs_pretty_syslog(LOG_WARNING,
			                   "Option %s already exists in the configuration",
			                   option->getName().c_str());
			return;
		}

		options_.insert({option->getName(), option});
	}

	/// Prints all the configurations options using safs_pretty_syslog.
	/// Used only for debugging purposes (GUILLEX remove later).
	void printAllOptions() const {
		safs_pretty_syslog(LOG_NOTICE, "Configuration options:");
		for (const auto &option : options_) {
			safs_pretty_syslog(LOG_NOTICE, "%s", option.second->toString().c_str());
		}
	}

private:
	/// Private constructor for the singleton pattern
	Configuration() = default;

	/// Map with all the configuration options.
	std::map<std::string, std::shared_ptr<OptionBase>> options_;
};

recursive_remove.cc: fail to build

I'm trying to build for arm64 (in docker, ubuntu jammy), but getting the following error:

/tmp/saunafs_deb_working_directory.2024-05-07_143835.1Z3oVs/saunafs/src/tools/recursive_remove.cc: In function 'int recursive_remove_run(int, char**)':
/tmp/saunafs_deb_working_directory.2024-05-07_143835.1Z3oVs/saunafs/src/tools/recursive_remove.cc:129:47: error: comparison is always true due to limited range of data type [-Werror=type-limits]
129 | while ((ch = getopt(argc, argv, "l")) != -1) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
cc1plus: all warnings being treated as errors

It seems that the issue is not related to the architecture, but rather that ch is unsigned.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.