blob: d3f7f74d6ef076d215e128be07750ab787875c63 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/fvm/host/container.h"
#include <inttypes.h>
#include <memory>
#include <utility>
#include <fbl/unique_fd.h>
#include "src/storage/fvm/host/fvm_container.h"
#include "src/storage/fvm/host/sparse_container.h"
zx_status_t Container::Create(const char* path, off_t offset, uint32_t flags,
std::unique_ptr<Container>* container) {
if ((flags & ~fvm::kSparseFlagAllValid) != 0) {
fprintf(stderr, "Invalid flags: %08" PRIx32 "\n", flags);
return -1;
}
fbl::unique_fd fd(open(path, O_RDONLY));
if (!fd) {
fprintf(stderr, "Unable to open path %s\n", path);
return -1;
}
uint8_t data[HEADER_SIZE];
if (lseek(fd.get(), offset, SEEK_SET) < 0) {
fprintf(stderr, "Error seeking block device\n");
return -1;
}
if (read(fd.get(), data, sizeof(data)) != sizeof(data)) {
fprintf(stderr, "Error reading block device\n");
return -1;
}
if (!memcmp(data, fvm_magic, sizeof(fvm_magic))) {
// Found fvm container
std::unique_ptr<FvmContainer> fvmContainer;
zx_status_t status = FvmContainer::CreateExisting(path, offset, &fvmContainer);
if (status != ZX_OK) {
return status;
}
*container = std::move(fvmContainer);
return ZX_OK;
}
fvm::SparseImage* image = reinterpret_cast<fvm::SparseImage*>(data);
if (image->magic == fvm::kSparseFormatMagic) {
if (offset > 0) {
fprintf(stderr, "Invalid offset for sparse file\n");
return ZX_ERR_INVALID_ARGS;
}
// Found sparse container
std::unique_ptr<SparseContainer> sparseContainer;
zx_status_t status = SparseContainer::CreateExisting(path, &sparseContainer);
if (status != ZX_OK) {
return status;
}
*container = std::move(sparseContainer);
return ZX_OK;
}
fprintf(stderr, "File format not supported\n");
return ZX_ERR_NOT_SUPPORTED;
}
Container::Container(const char* path, size_t slice_size, uint32_t flags)
: slice_size_(slice_size), flags_(flags) {
path_.AppendPrintf("%s", path);
}
Container::~Container() {}
uint64_t Container::CalculateDiskSizeForSlices(size_t slice_count) const {
return fvm::Header::FromSliceCount(fvm::kMaxUsablePartitions, slice_count, slice_size_)
.fvm_partition_size;
}