blob: c55436eafae759e4915dd5ee18bd59cdf278eb54 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <set>
#include <string>
#include "kudu/util/path_util.h"
#include "kudu/util/status.h"
namespace kudu {
class DirInstanceMetadataPB;
class Env;
class FileLock;
namespace fs {
// Reads and writes block manager instance metadata files.
//
// Thread-unsafe; access to this object must be externally synchronized.
class DirInstanceMetadataFile {
public:
// 'env' must remain valid for the lifetime of this class.
//
// 'uuid' is the UUID used for this instance file, though the UUID may be
// changed if we read the instance file from disk and find a different UUID.
DirInstanceMetadataFile(Env* env, std::string uuid, std::string dir_type,
std::string filename);
~DirInstanceMetadataFile();
// Creates, writes, synchronizes, and closes a new instance metadata file.
// Fails the PIMF in the case of a failed directory.
//
// 'all_uuids' is all of the unique UUIDs in this instance's dir set.
// 'uuid_' must exist in this set. 'created_dir' is set to true if the parent
// directory of the file was also created during this process.
//
// This should be called if we've already tried to load the instance file but
// found it didn't exist.
Status Create(const std::set<std::string>& all_uuids, bool* created_dir = nullptr);
// Opens, reads, verifies, and closes an existing instance metadata file.
//
// On success, either 'metadata_' is overwritten with the contents of the
// file, or, in the case of disk failure, returns OK and sets
// 'health_status_' to a non-OK value.
Status LoadFromDisk();
// Locks the instance metadata file, which must exist on-disk. Returns an
// error if it's already locked. The lock is released when Unlock() is
// called, when this object is destroyed, or when the process exits.
//
// Note: the lock is also released if any fd of the instance metadata file
// in this process is closed. Thus, it is an error to call Create() or
// LoadFromDisk() on a locked file.
Status Lock();
// Unlocks the instance metadata file. Must have been locked to begin with.
Status Unlock();
// Sets that the instance failed (e.g. due to a disk failure).
//
// If failed, there is no guarantee that the instance will have a 'metadata_'.
void SetInstanceFailed(const Status& s = Status::IOError("directory instance failed")) {
health_status_ = s;
}
// Whether or not the instance is healthy. If the instance file lives on a
// disk that has failed, this should return false.
bool healthy() const {
return health_status_.ok();
}
const Status& health_status() const {
return health_status_;
}
std::string uuid() const { return uuid_; }
std::string dir() const { return DirName(filename_); }
const std::string& path() const { return filename_; }
DirInstanceMetadataPB* metadata() const { return metadata_.get(); }
private:
Env* env_;
// The UUID of this instance file. This is initialized in the constructor so
// it can be used when creating a new instance file. However, it may be
// overwritten when loading an existing instance from disk.
//
// This helps provide the invariant that, healthy or otherwise, every
// instance has a valid UUID, which is useful for failed-directory-tracking,
// which generally uses UUIDs.
std::string uuid_;
// The type of this instance file.
const std::string dir_type_;
// The name of the file associated with this instance.
const std::string filename_;
std::unique_ptr<DirInstanceMetadataPB> metadata_;
// In order to prevent multiple Kudu processes from starting up using the
// same directories, we lock the instance files when starting up.
std::unique_ptr<FileLock> lock_;
// The health of the instance file.
Status health_status_;
};
} // namespace fs
} // namespace kudu