Summary: Most of the approach is copied from WebSQL's MySQL branch. It's nice that we can do this without touching core RocksDB code. Test Plan: Compiles and runs. Didn't test flashback code, as I don't have flashback device and most if it is c/p Reviewers: MarkCallaghan, sdong Reviewed By: sdong Subscribers: rven, lgalanis, kradhakrishnan, dhruba, leveldb Differential Revision: https://reviews.facebook.net/D35391main
parent
1c47c433ba
commit
d61cb0b9de
@ -0,0 +1,24 @@ |
|||||||
|
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include "rocksdb/env.h" |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
// This API is experimental. We will mark it stable once we run it in production
|
||||||
|
// for a while.
|
||||||
|
// NewFlashcacheAwareEnv() creates and Env that blacklists all background
|
||||||
|
// threads (used for flush and compaction) from using flashcache to cache their
|
||||||
|
// reads. Reads from compaction thread don't need to be cached because they are
|
||||||
|
// going to be soon made obsolete (due to nature of compaction)
|
||||||
|
// Usually you would pass Env::Default() as base.
|
||||||
|
// flashcache_dev is a path to the flashcache device
|
||||||
|
extern std::unique_ptr<Env> NewFlashcacheAwareEnv( |
||||||
|
Env* base, const std::string& flashcache_dev); |
||||||
|
|
||||||
|
} // namespace rocksdb
|
@ -0,0 +1,55 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* flashcache_ioctl.h |
||||||
|
* FlashCache: Device mapper target for block-level disk caching |
||||||
|
* |
||||||
|
* Copyright 2010 Facebook, Inc. |
||||||
|
* Author: Mohan Srinivasan (mohan@facebook.com) |
||||||
|
* |
||||||
|
* Based on DM-Cache: |
||||||
|
* Copyright (C) International Business Machines Corp., 2006 |
||||||
|
* Author: Ming Zhao (mingzhao@ufl.edu) |
||||||
|
* |
||||||
|
* 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; under version 2 of the License. |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/ |
||||||
|
|
||||||
|
#ifdef OS_LINUX |
||||||
|
#ifndef FLASHCACHE_IOCTL_H |
||||||
|
#define FLASHCACHE_IOCTL_H |
||||||
|
|
||||||
|
#include <linux/types.h> |
||||||
|
|
||||||
|
#define FLASHCACHE_IOCTL 0xfe |
||||||
|
|
||||||
|
enum { |
||||||
|
FLASHCACHEADDNCPID_CMD=200, |
||||||
|
FLASHCACHEDELNCPID_CMD, |
||||||
|
FLASHCACHEDELNCALL_CMD, |
||||||
|
FLASHCACHEADDWHITELIST_CMD, |
||||||
|
FLASHCACHEDELWHITELIST_CMD, |
||||||
|
FLASHCACHEDELWHITELISTALL_CMD, |
||||||
|
}; |
||||||
|
|
||||||
|
#define FLASHCACHEADDNCPID _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDNCPID_CMD, pid_t) |
||||||
|
#define FLASHCACHEDELNCPID _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCPID_CMD, pid_t) |
||||||
|
#define FLASHCACHEDELNCALL _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCALL_CMD, pid_t) |
||||||
|
|
||||||
|
#define FLASHCACHEADDBLACKLIST FLASHCACHEADDNCPID |
||||||
|
#define FLASHCACHEDELBLACKLIST FLASHCACHEDELNCPID |
||||||
|
#define FLASHCACHEDELALLBLACKLIST FLASHCACHEDELNCALL |
||||||
|
|
||||||
|
#define FLASHCACHEADDWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDWHITELIST_CMD, pid_t) |
||||||
|
#define FLASHCACHEDELWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELIST_CMD, pid_t) |
||||||
|
#define FLASHCACHEDELALLWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELISTALL_CMD, pid_t) |
||||||
|
|
||||||
|
#endif /* FLASHCACHE_IOCTL_H */ |
||||||
|
#endif /* OS_LINUX */ |
@ -0,0 +1,145 @@ |
|||||||
|
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#include "rocksdb/utilities/flashcache.h" |
||||||
|
|
||||||
|
#include "utilities/flashcache/flashcache.h" |
||||||
|
|
||||||
|
#ifdef OS_LINUX |
||||||
|
#include <fcntl.h> |
||||||
|
#include <sys/ioctl.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <sys/syscall.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include "third-party/flashcache/flashcache_ioctl.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
#if !defined(ROCKSDB_LITE) && defined(OS_LINUX) |
||||||
|
// Most of the code that handles flashcache is copied from websql's branch of
|
||||||
|
// mysql-5.6
|
||||||
|
class FlashcacheAwareEnv : public EnvWrapper { |
||||||
|
public: |
||||||
|
FlashcacheAwareEnv(Env* base, int cachedev_fd) |
||||||
|
: EnvWrapper(base), cachedev_fd_(cachedev_fd) { |
||||||
|
pid_t pid = getpid(); |
||||||
|
/* cleanup previous whitelistings */ |
||||||
|
if (ioctl(cachedev_fd_, FLASHCACHEDELALLWHITELIST, &pid) < 0) { |
||||||
|
close(cachedev_fd_); |
||||||
|
cachedev_fd_ = -1; |
||||||
|
fprintf(stderr, "ioctl del-all-whitelist for flashcache failed\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (ioctl(cachedev_fd_, FLASHCACHEADDWHITELIST, &pid) < 0) { |
||||||
|
fprintf(stderr, "ioctl add-whitelist for flashcache failed\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
~FlashcacheAwareEnv() { |
||||||
|
// cachedev_fd_ is -1 if it's unitialized
|
||||||
|
if (cachedev_fd_ != -1) { |
||||||
|
pid_t pid = getpid(); |
||||||
|
if (ioctl(cachedev_fd_, FLASHCACHEDELWHITELIST, &pid) < 0) { |
||||||
|
fprintf(stderr, "ioctl del-whitelist for flashcache failed\n"); |
||||||
|
} |
||||||
|
close(cachedev_fd_); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static int BlacklistCurrentThread(int cachedev_fd) { |
||||||
|
pid_t pid = syscall(SYS_gettid); |
||||||
|
return ioctl(cachedev_fd, FLASHCACHEADDNCPID, &pid); |
||||||
|
} |
||||||
|
|
||||||
|
static int WhitelistCurrentThread(int cachedev_fd) { |
||||||
|
pid_t pid = syscall(SYS_gettid); |
||||||
|
return ioctl(cachedev_fd, FLASHCACHEDELNCPID, &pid); |
||||||
|
} |
||||||
|
|
||||||
|
int GetFlashCacheFileDescriptor() { return cachedev_fd_; } |
||||||
|
|
||||||
|
struct Arg { |
||||||
|
Arg(void (*f)(void* arg), void* a, int _cachedev_fd) |
||||||
|
: original_function_(f), original_arg_(a), cachedev_fd(_cachedev_fd) {} |
||||||
|
|
||||||
|
void (*original_function_)(void* arg); |
||||||
|
void* original_arg_; |
||||||
|
int cachedev_fd; |
||||||
|
}; |
||||||
|
|
||||||
|
static void BgThreadWrapper(void* a) { |
||||||
|
Arg* arg = reinterpret_cast<Arg*>(a); |
||||||
|
if (arg->cachedev_fd != -1) { |
||||||
|
if (BlacklistCurrentThread(arg->cachedev_fd) < 0) { |
||||||
|
fprintf(stderr, "ioctl add-nc-pid for flashcache failed\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
arg->original_function_(arg->original_arg_); |
||||||
|
if (arg->cachedev_fd != -1) { |
||||||
|
if (WhitelistCurrentThread(arg->cachedev_fd) < 0) { |
||||||
|
fprintf(stderr, "ioctl del-nc-pid for flashcache failed\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
delete arg; |
||||||
|
} |
||||||
|
|
||||||
|
int UnSchedule(void* arg, Priority pri) override { |
||||||
|
// no unschedule for you
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void Schedule(void (*f)(void* arg), void* a, Priority pri, |
||||||
|
void* tag = nullptr) override { |
||||||
|
EnvWrapper::Schedule(&BgThreadWrapper, new Arg(f, a, cachedev_fd_), pri, |
||||||
|
tag); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
int cachedev_fd_; |
||||||
|
}; |
||||||
|
|
||||||
|
std::unique_ptr<Env> NewFlashcacheAwareEnv(Env* base, |
||||||
|
const std::string& flashcache_dev) { |
||||||
|
// Cachedev should remain open or ioctl will be lost
|
||||||
|
int cachedev_fd = open(flashcache_dev.c_str(), O_RDONLY); |
||||||
|
if (cachedev_fd < 0) { |
||||||
|
fprintf(stderr, "Open flash device failed\n"); |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
std::unique_ptr<Env> ret(new FlashcacheAwareEnv(base, cachedev_fd)); |
||||||
|
return std::move(ret); |
||||||
|
} |
||||||
|
|
||||||
|
int FlashcacheBlacklistCurrentThread(Env* flashcache_aware_env) { |
||||||
|
int fd = dynamic_cast<FlashcacheAwareEnv*>(flashcache_aware_env) |
||||||
|
->GetFlashCacheFileDescriptor(); |
||||||
|
if (fd == -1) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
return FlashcacheAwareEnv::BlacklistCurrentThread(fd); |
||||||
|
} |
||||||
|
int FlashcacheWhitelistCurrentThread(Env* flashcache_aware_env) { |
||||||
|
int fd = dynamic_cast<FlashcacheAwareEnv*>(flashcache_aware_env) |
||||||
|
->GetFlashCacheFileDescriptor(); |
||||||
|
if (fd == -1) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
return FlashcacheAwareEnv::WhitelistCurrentThread(fd); |
||||||
|
} |
||||||
|
|
||||||
|
#else // !defined(ROCKSDB_LITE) && defined(OS_LINUX)
|
||||||
|
std::unique_ptr<Env> NewFlashcacheAwareEnv(Env* base, |
||||||
|
const std::string& flashcache_dev) { |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
int FlashcacheBlacklistCurrentThread(Env* flashcache_aware_env) { return -1; } |
||||||
|
int FlashcacheWhitelistCurrentThread(Env* flashcache_aware_env) { return -1; } |
||||||
|
|
||||||
|
#endif // !defined(ROCKSDB_LITE) && defined(OS_LINUX)
|
||||||
|
|
||||||
|
} // namespace rocksdb
|
@ -0,0 +1,18 @@ |
|||||||
|
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include "rocksdb/env.h" |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
// This is internal API that will make hacking on flashcache easier. Not sure if
|
||||||
|
// we need to expose this to public users, probably not
|
||||||
|
extern int FlashcacheBlacklistCurrentThread(Env* flashcache_aware_env); |
||||||
|
extern int FlashcacheWhitelistCurrentThread(Env* flashcache_aware_env); |
||||||
|
|
||||||
|
} // namespace rocksdb
|
Loading…
Reference in new issue