blob: c7a58fb107dfceebea808f7b1d5de41b806ee182 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ARC_VM_VSOCK_PROXY_SERVER_PROXY_FILE_SYSTEM_H_
#define ARC_VM_VSOCK_PROXY_SERVER_PROXY_FILE_SYSTEM_H_
#include <fuse/fuse.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <map>
#include <memory>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/observer_list.h>
#include <base/optional.h>
#include <base/synchronization/lock.h>
#include "arc/vm/vsock_proxy/proxy_file_system.h"
#include "arc/vm/vsock_proxy/proxy_service.h"
namespace base {
class TaskRunner;
class WaitableEvent;
} // namespace base
namespace arc {
class VSockProxy;
// FUSE implementation to support regular file descriptor passing over VSOCK.
// This is designed to be used only in the host side.
class ServerProxyFileSystem : public ProxyFileSystem {
public:
class Observer {
public:
virtual ~Observer() = default;
// Called when initialization is completed.
virtual void OnInit() {}
};
// |mount_path| is the path to the mount point.
explicit ServerProxyFileSystem(const base::FilePath& mount_path);
~ServerProxyFileSystem() override;
// Adds the |observer| to be notified on events.
void AddObserver(Observer* observer);
// Removes the |observer|.
void RemoveObserver(Observer* observer);
// Starts the fuse file system in foreground. Returns on fuse termination
// such as unmount of the file system.
int Run(std::unique_ptr<ProxyService::ProxyFactory> factory);
// Implementation of the fuse operation callbacks.
int GetAttr(const char* path, struct stat* stat);
int Open(const char* path, struct fuse_file_info* fi);
int Read(const char* path,
char* buf,
size_t size,
off_t off,
struct fuse_file_info* fi);
int Release(const char* path, struct fuse_file_info* fi);
int ReadDir(const char* path,
void* buf,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info* fi);
void Init(struct fuse_conn_info* conn);
// ProxyFileSystem overrides.
// Operations for the returned file descriptor will be directed to the
// fuse operation implementation declared above.
base::ScopedFD RegisterHandle(int64_t handle) override;
// Runs an operation interacting with VSockProxy instance on the dedicated
// thread. This is a blocking operation, so wait for the |callback|
// completion.
void RunWithVSockProxyInSyncForTesting(
base::OnceCallback<void(VSockProxy* proxy)> callback);
private:
// Helper to operate GetAtt(). Called on the |task_runner_|.
void GetAttrInternal(base::WaitableEvent* event,
int64_t handle,
int* return_value,
off_t* size);
// Helper to operate Read(). Called on the |task_runner_|.
void ReadInternal(base::WaitableEvent* event,
int64_t handle,
char* buf,
size_t size,
off_t offset,
int* return_value);
// Returns the opened/not-opened-yet state of the given |handle|.
// If not registered, base::nullopt is returned.
enum class State {
NOT_OPENED,
OPENED,
};
base::Optional<State> GetState(int64_t handle);
const base::FilePath mount_path_;
// During the initialization, temporarily keep the |factory| instance,
// which will be passed to ProxyService on creation.
std::unique_ptr<ProxyService::ProxyFactory> factory_;
// ProxyService serving ServerProxy. Initialized in Init() callback.
// Should be touched on the initialization thread, or on |task_runner_|.
std::unique_ptr<ProxyService> proxy_service_;
// TaskRunner to run a task interract with ServerProxy.
// Initialized with |proxy_service_|.
scoped_refptr<base::TaskRunner> task_runner_;
// Registered |handle|s to its opened/not-yet-opened state.
// The access to |handle_map_| needs to be guarded by |handle_map_lock_|,
// because fuse starts as many threads as needed so this can be accessed
// from multiple threads.
std::map<int64_t, State> handle_map_;
base::Lock handle_map_lock_;
base::ObserverList<Observer> observer_list_;
DISALLOW_COPY_AND_ASSIGN(ServerProxyFileSystem);
};
} // namespace arc
#endif // ARC_VM_VSOCK_PROXY_SERVER_PROXY_FILE_SYSTEM_H_