From fbcdf864613bfeb84edfa945304c065f6a29b44e Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 13 Feb 2016 22:14:04 -0500 Subject: Save root file descriptor when starting up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow access to underlying file system by saving a file descriptor to the underlying directory when starting. Close the FD during FUSE’s destroy routine, though it won’t matter much. --- src/CMakeLists.txt | 23 +++++++++++++++-------- src/operations.cc | 10 +++++++++- src/operations.h | 2 +- src/scoville.cc | 49 ++++++++++++++++++++++++++++++++++++------------- src/utility.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/utility.h | 26 ++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 src/utility.cc create mode 100644 src/utility.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2f0c0f..b7cf018 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,34 +15,41 @@ include(FindPkgConfig) pkg_check_modules(FUSE REQUIRED fuse) +pkg_check_modules(GFLAGS REQUIRED libgflags) pkg_check_modules(GLOG REQUIRED libglog) link_directories( ${FUSE_LIBRARY_DIRS} + ${GFLAGS_LIBRARY_DIRS} ${GLOG_LIBRARY_DIRS} ) -set( - CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${FUSE_CFLAGS_OTHER} ${GLOG_CFLAGS_OTHER}" -) -set( - CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} ${FUSE_LDFLAGS_OTHER} ${GLOG_LDFLAGS_OTHER}" -) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FUSE_CFLAGS_OTHER}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GFLAGS_CFLAGS_OTHER}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GLOG_CFLAGS_OTHER}") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FUSE_LDFLAGS_OTHER}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GFLAGS_LDFLAGS_OTHER}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GLOG_LDFLAGS_OTHER}") add_executable( scoville encoding.cc operations.cc scoville.cc + utility.cc ) + target_include_directories( scoville SYSTEM PRIVATE ${FUSE_INCLUDE_DIRS} + SYSTEM PRIVATE ${GFLAGS_INCLUDE_DIRS} SYSTEM PRIVATE ${GLOG_INCLUDE_DIRS} ) + target_link_libraries( scoville ${FUSE_LIBRARIES} + ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES} ) diff --git a/src/operations.cc b/src/operations.cc index abd2f0c..d22a1e2 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -33,10 +33,14 @@ #include #include +#include "utility.h" + namespace scoville { namespace { +int root_fd_; + struct Directory { DIR* fd; dirent* entry; @@ -75,6 +79,8 @@ void* Initialize(fuse_conn_info*) { void Destroy(void*) { LOG(INFO) << "destroy"; + LOG_IF(ERROR, close(root_fd_) == -1) << "could not close root FD: " + << ErrnoText(); } int Getattr(const char* const path, struct stat* output) { @@ -153,7 +159,9 @@ int Releasedir(const char*, fuse_file_info* const file_info) { } // namespace -fuse_operations FuseOperations() { +fuse_operations FuseOperations(const int root_fd) { + root_fd_ = root_fd; + fuse_operations result; result.flag_nullpath_ok = true; diff --git a/src/operations.h b/src/operations.h index a623fef..2e55f24 100644 --- a/src/operations.h +++ b/src/operations.h @@ -20,7 +20,7 @@ namespace scoville { -fuse_operations FuseOperations(); +fuse_operations FuseOperations(int root_fd); } // namespace scoville diff --git a/src/scoville.cc b/src/scoville.cc index b5c4822..d8d1692 100644 --- a/src/scoville.cc +++ b/src/scoville.cc @@ -1,26 +1,49 @@ -// Copyright 2016 Benjamin Barenblat +// Copyright (C) 2007, 2008 Jan Engelhardt +// Copyright (C) 2016 Benjamin Barenblat // -// Licensed 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 +// This program 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. // -// http://www.apache.org/licenses/LICENSE-2.0 +// This program 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. // -// 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. +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . +#include + +#include +#include #include +#include +#include #include "operations.h" +#include "utility.h" + +constexpr char kUsage[] = R"(allow forbidden characters on VFAT file systems -int main(const int argc, char* argv[]) { - FLAGS_logtostderr = true; +usage: scoville [flags] target_dir [-- fuse_options])"; + +int main(int argc, char* argv[]) { google::InstallFailureSignalHandler(); + google::SetUsageMessage(kUsage); + google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); - const fuse_operations operations = scoville::FuseOperations(); + const char* const root_path = argv[argc - 1]; + int root_fd; + if ((root_fd = open(root_path, O_DIRECTORY)) == -1) { + std::cerr << "scoville: bad mount point `" << root_path + << "': " << scoville::ErrnoText(); + std::exit(EXIT_FAILURE); + } + LOG(INFO) << "overlaying " << root_path; + + const fuse_operations operations = scoville::FuseOperations(root_fd); return fuse_main(argc, argv, &operations, nullptr); } diff --git a/src/utility.cc b/src/utility.cc new file mode 100644 index 0000000..5ccb58a --- /dev/null +++ b/src/utility.cc @@ -0,0 +1,44 @@ +// Copyright 2016 Benjamin Barenblat +// +// Licensed 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. + +#define _POSIX_C_SOURCE 201502L +#undef _GNU_SOURCE + +#include "utility.h" + +#include + +#include +#include +#include + +#include + +namespace scoville { + +std::string ErrnoText() { + std::vector text(64); + int strerror_result; + while ((strerror_result = strerror_r(errno, text.data(), text.size())) == + ERANGE) { + VLOG(1) << "ErrnoText doubling message size from " << text.size(); + text.resize(text.size() * 2); + } + if (strerror_result != 0) { + return "(could not generate error message)"; + } + return std::string(text.begin(), text.end()); +} + +} // namespace scoville diff --git a/src/utility.h b/src/utility.h new file mode 100644 index 0000000..53e3840 --- /dev/null +++ b/src/utility.h @@ -0,0 +1,26 @@ +// Copyright 2016 Benjamin Barenblat +// +// Licensed 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. + +#ifndef UTILITY_H_ +#define UTILITY_H_ + +#include + +namespace scoville { + +std::string ErrnoText(); + +} // namespace scoville + +#endif // UTILITY_H_ -- cgit v1.2.3