|
Packit |
534379 |
// Copyright(c) 2017, Intel Corporation
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
534379 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer.
|
|
Packit |
534379 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
534379 |
// and/or other materials provided with the distribution.
|
|
Packit |
534379 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
534379 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
534379 |
// without specific prior written permission.
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
534379 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
534379 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
534379 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
534379 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
534379 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
534379 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
534379 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
534379 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
534379 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
534379 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
534379 |
/*
|
|
Packit |
534379 |
* test-system.cpp
|
|
Packit |
534379 |
*/
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "test_system.h"
|
|
Packit |
534379 |
#include <glob.h>
|
|
Packit |
534379 |
#include <stdarg.h>
|
|
Packit |
534379 |
#include <unistd.h>
|
|
Packit |
534379 |
#include <algorithm>
|
|
Packit |
534379 |
#include <cstring>
|
|
Packit |
534379 |
#include <fstream>
|
|
Packit |
534379 |
#include <iostream>
|
|
Packit |
534379 |
#include "c_test_system.h"
|
|
Packit |
534379 |
#include "test_utils.h"
|
|
Packit |
534379 |
#ifndef _GNU_SOURCE
|
|
Packit |
534379 |
#define _GNU_SOURCE 1
|
|
Packit |
534379 |
#endif
|
|
Packit |
534379 |
#include <dlfcn.h>
|
|
Packit |
534379 |
#include <fcntl.h>
|
|
Packit |
534379 |
#include <sys/stat.h>
|
|
Packit |
534379 |
#include <uuid/uuid.h>
|
|
Packit |
534379 |
#include <ftw.h>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void *__builtin_return_address(unsigned level);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// hijack malloc
|
|
Packit |
534379 |
static bool _invalidate_malloc = false;
|
|
Packit |
534379 |
static uint32_t _invalidate_malloc_after = 0;
|
|
Packit |
534379 |
static const char *_invalidate_malloc_when_called_from = nullptr;
|
|
Packit |
534379 |
void *malloc(size_t size) {
|
|
Packit |
534379 |
if (_invalidate_malloc) {
|
|
Packit |
534379 |
if (!_invalidate_malloc_when_called_from) {
|
|
Packit |
534379 |
if (!_invalidate_malloc_after) {
|
|
Packit |
534379 |
_invalidate_malloc = false;
|
|
Packit |
534379 |
return nullptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
--_invalidate_malloc_after;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
void *caller = __builtin_return_address(0);
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
Dl_info info;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dladdr(caller, &info;;
|
|
Packit |
534379 |
if (!info.dli_sname)
|
|
Packit |
534379 |
res = 1;
|
|
Packit |
534379 |
else
|
|
Packit |
534379 |
res = strcmp(info.dli_sname, _invalidate_malloc_when_called_from);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!_invalidate_malloc_after && !res) {
|
|
Packit |
534379 |
_invalidate_malloc = false;
|
|
Packit |
534379 |
_invalidate_malloc_when_called_from = nullptr;
|
|
Packit |
534379 |
return nullptr;
|
|
Packit |
534379 |
} else if (!res)
|
|
Packit |
534379 |
--_invalidate_malloc_after;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return __libc_malloc(size);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// hijack calloc
|
|
Packit |
534379 |
static bool _invalidate_calloc = false;
|
|
Packit |
534379 |
static uint32_t _invalidate_calloc_after = 0;
|
|
Packit |
534379 |
static const char *_invalidate_calloc_when_called_from = nullptr;
|
|
Packit |
534379 |
void *calloc(size_t nmemb, size_t size) {
|
|
Packit |
534379 |
if (_invalidate_calloc) {
|
|
Packit |
534379 |
if (!_invalidate_calloc_when_called_from) {
|
|
Packit |
534379 |
if (!_invalidate_calloc_after) {
|
|
Packit |
534379 |
_invalidate_calloc = false;
|
|
Packit |
534379 |
return nullptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
--_invalidate_calloc_after;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
void *caller = __builtin_return_address(0);
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
Dl_info info;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dladdr(caller, &info;;
|
|
Packit |
534379 |
if (!info.dli_sname)
|
|
Packit |
534379 |
res = 1;
|
|
Packit |
534379 |
else
|
|
Packit |
534379 |
res = strcmp(info.dli_sname, _invalidate_calloc_when_called_from);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!_invalidate_calloc_after && !res) {
|
|
Packit |
534379 |
_invalidate_calloc = false;
|
|
Packit |
534379 |
_invalidate_calloc_when_called_from = nullptr;
|
|
Packit |
534379 |
return nullptr;
|
|
Packit |
534379 |
} else if (!res)
|
|
Packit |
534379 |
--_invalidate_calloc_after;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return __libc_calloc(nmemb, size);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
namespace opae {
|
|
Packit |
534379 |
namespace testing {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static const char *dev_pattern =
|
|
Packit |
534379 |
R"regex(/dev/(intel-fpga|dfl)-(fme|port)\.([0-9]+))regex";
|
|
Packit |
534379 |
static const char *sysclass_pattern =
|
|
Packit |
534379 |
R"regex(/sys/class/fpga((?:_region)?/(region|intel-fpga-dev\.)([0-9]+))regex";
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static std::map<std::string, std::string> fpga_sysfs_path_map = {
|
|
Packit |
534379 |
{"/dev/intel", "/sys/class/fpga/intel-fpga-dev."},
|
|
Packit |
534379 |
{"/dev/dfl", "/sys/class/fpga_region/region"}};
|
|
Packit |
534379 |
|
|
Packit |
534379 |
mock_object::mock_object(const std::string &devpath,
|
|
Packit |
534379 |
const std::string &sysclass, uint32_t device_id,
|
|
Packit |
534379 |
type_t type)
|
|
Packit |
534379 |
: devpath_(devpath),
|
|
Packit |
534379 |
sysclass_(sysclass),
|
|
Packit |
534379 |
device_id_(device_id),
|
|
Packit |
534379 |
type_(type) {}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int mock_fme::ioctl(int request, va_list argp) {
|
|
Packit |
534379 |
(void)request;
|
|
Packit |
534379 |
(void)argp;
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int mock_port::ioctl(int request, va_list argp) {
|
|
Packit |
534379 |
(void)request;
|
|
Packit |
534379 |
(void)argp;
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define ASSERT_FN(fn) \
|
|
Packit |
534379 |
do { \
|
|
Packit |
534379 |
if (fn == nullptr) { \
|
|
Packit |
534379 |
throw std::runtime_error(#fn " not loaded"); \
|
|
Packit |
534379 |
} \
|
|
Packit |
534379 |
} while (false);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
test_device test_device::unknown() {
|
|
Packit |
534379 |
return test_device{.fme_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
|
|
Packit |
534379 |
.afu_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
|
|
Packit |
534379 |
.segment = 0x1919,
|
|
Packit |
534379 |
.bus = 0x0A,
|
|
Packit |
534379 |
.device = 9,
|
|
Packit |
534379 |
.function = 5,
|
|
Packit |
534379 |
.num_vfs = 8,
|
|
Packit |
534379 |
.socket_id = 9,
|
|
Packit |
534379 |
.num_slots = 9,
|
|
Packit |
534379 |
.bbs_id = 9,
|
|
Packit |
534379 |
.bbs_version = {0xFF, 0xFF, 0xFF},
|
|
Packit |
534379 |
.state = FPGA_ACCELERATOR_ASSIGNED,
|
|
Packit |
534379 |
.num_mmio = 0,
|
|
Packit |
534379 |
.num_interrupts = 0xf,
|
|
Packit |
534379 |
.fme_object_id = 9,
|
|
Packit |
534379 |
.port_object_id = 9,
|
|
Packit |
534379 |
.vendor_id = 0x1234,
|
|
Packit |
534379 |
.device_id = 0x1234,
|
|
Packit |
534379 |
.fme_num_errors = 0x1234,
|
|
Packit |
534379 |
.port_num_errors = 0x1234,
|
|
Packit |
534379 |
.gbs_guid = "C544CE5C-F630-44E1-8551-59BD87AF432E",
|
|
Packit |
534379 |
.mdata = ""};
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
test_system *test_system::instance_ = nullptr;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
test_system::test_system() : initialized_(false), root_("") {
|
|
Packit |
534379 |
open_ = (open_func)dlsym(RTLD_NEXT, "open");
|
|
Packit |
534379 |
open_create_ = open_;
|
|
Packit |
534379 |
read_ = (read_func)dlsym(RTLD_NEXT, "read");
|
|
Packit |
534379 |
fopen_ = (fopen_func)dlsym(RTLD_NEXT, "fopen");
|
|
Packit |
534379 |
popen_ = (popen_func)dlsym(RTLD_NEXT, "popen");
|
|
Packit |
534379 |
pclose_ = (pclose_func)dlsym(RTLD_NEXT, "pclose");
|
|
Packit |
534379 |
close_ = (close_func)dlsym(RTLD_NEXT, "close");
|
|
Packit |
534379 |
ioctl_ = (ioctl_func)dlsym(RTLD_NEXT, "ioctl");
|
|
Packit |
534379 |
opendir_ = (opendir_func)dlsym(RTLD_NEXT, "opendir");
|
|
Packit |
534379 |
readlink_ = (readlink_func)dlsym(RTLD_NEXT, "readlink");
|
|
Packit |
534379 |
xstat_ = (__xstat_func)dlsym(RTLD_NEXT, "__xstat");
|
|
Packit |
534379 |
lstat_ = (__xstat_func)dlsym(RTLD_NEXT, "__lxstat");
|
|
Packit |
534379 |
scandir_ = (scandir_func)dlsym(RTLD_NEXT, "scandir");
|
|
Packit |
534379 |
sched_setaffinity_ =
|
|
Packit |
534379 |
(sched_setaffinity_func)dlsym(RTLD_NEXT, "sched_setaffinity");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
glob_ = (glob_func)dlsym(RTLD_NEXT, "glob");
|
|
Packit |
534379 |
realpath_ = (realpath_func)dlsym(RTLD_NEXT, "realpath");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
hijack_sched_setaffinity_ = false;
|
|
Packit |
534379 |
hijack_sched_setaffinity_return_val_ = 0;
|
|
Packit |
534379 |
hijack_sched_setaffinity_after_ = 0;
|
|
Packit |
534379 |
hijack_sched_setaffinity_caller_ = nullptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
test_system *test_system::instance() {
|
|
Packit |
534379 |
if (test_system::instance_ == nullptr) {
|
|
Packit |
534379 |
test_system::instance_ = new test_system();
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return test_system::instance_;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::prepare_syfs(const test_platform &platform) {
|
|
Packit |
534379 |
int result = 0;
|
|
Packit |
534379 |
char tmpsysfs[]{"tmpsysfs-XXXXXX"};
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (platform.mock_sysfs != nullptr) {
|
|
Packit |
534379 |
char *tmp = mkdtemp(tmpsysfs);
|
|
Packit |
534379 |
if (tmp == nullptr) {
|
|
Packit |
534379 |
throw std::runtime_error("error making tmpsysfs");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
root_ = std::string(tmp);
|
|
Packit |
534379 |
std::string cmd = "tar xzf " + std::string(platform.mock_sysfs) + " -C " +
|
|
Packit |
534379 |
root_ + " --strip 1";
|
|
Packit |
534379 |
result = std::system(cmd.c_str());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return (void)result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
extern "C" {
|
|
Packit |
534379 |
int process_fpath(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftw) {
|
|
Packit |
534379 |
(void)sb;
|
|
Packit |
534379 |
(void)ftw;
|
|
Packit |
534379 |
if (typeflag & FTW_DP) {
|
|
Packit |
534379 |
if (rmdir(fpath)) {
|
|
Packit |
534379 |
if (errno == ENOTDIR) {
|
|
Packit |
534379 |
goto do_unlink;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
std::cerr << "error removing directory: " << fpath << " - " << strerror(errno) << "\n";
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
do_unlink:
|
|
Packit |
534379 |
if (unlink(fpath) && errno != ENOENT) {
|
|
Packit |
534379 |
std::cerr << "error removing node: " << fpath << " - " << strerror(errno) << "\n";
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::remove_sysfs_dir(const char *path) {
|
|
Packit |
534379 |
if (root_.find("tmpsysfs") != std::string::npos) {
|
|
Packit |
534379 |
auto real_path = path == nullptr ? root_ : get_sysfs_path(path);
|
|
Packit |
534379 |
return nftw(real_path.c_str(), process_fpath, 100, FTW_DEPTH | FTW_PHYS);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return 0;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::remove_sysfs() {
|
|
Packit |
534379 |
return remove_sysfs_dir();
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::set_root(const char *root) { root_ = root; }
|
|
Packit |
534379 |
std::string test_system::get_root() { return root_; }
|
|
Packit |
534379 |
|
|
Packit |
534379 |
std::string test_system::get_sysfs_path(const std::string &src) {
|
|
Packit |
534379 |
auto it = registered_files_.find(src);
|
|
Packit |
534379 |
if (it != registered_files_.end()) {
|
|
Packit |
534379 |
return it->second;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
if (src.find("/sys") == 0 || src.find("/dev/intel-fpga") == 0 ||
|
|
Packit |
534379 |
src.find("/dev/dfl-") == 0) {
|
|
Packit |
534379 |
if (!root_.empty() && root_.size() > 1) {
|
|
Packit |
534379 |
return root_ + src;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return src;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
std::vector<uint8_t> test_system::assemble_gbs_header(const test_device &td) {
|
|
Packit |
534379 |
std::vector<uint8_t> gbs_header(20, 0);
|
|
Packit |
534379 |
if (uuid_parse(td.gbs_guid, gbs_header.data())) {
|
|
Packit |
534379 |
std::string msg = "unable to parse UUID: ";
|
|
Packit |
534379 |
msg.append(td.gbs_guid);
|
|
Packit |
534379 |
throw std::runtime_error(msg);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
uint32_t len = strlen(td.mdata);
|
|
Packit |
534379 |
*reinterpret_cast<uint32_t *>(gbs_header.data() + 16) = len;
|
|
Packit |
534379 |
std::copy(&td.mdata[0], &td.mdata[len], std::back_inserter(gbs_header));
|
|
Packit |
534379 |
return gbs_header;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
std::vector<uint8_t> test_system::assemble_gbs_header(const test_device &td,
|
|
Packit |
534379 |
const char *mdata) {
|
|
Packit |
534379 |
if (mdata) {
|
|
Packit |
534379 |
test_device copy = td;
|
|
Packit |
534379 |
copy.mdata = mdata;
|
|
Packit |
534379 |
return assemble_gbs_header(copy);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return std::vector<uint8_t>(0);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::initialize() {
|
|
Packit |
534379 |
ASSERT_FN(open_);
|
|
Packit |
534379 |
ASSERT_FN(open_create_);
|
|
Packit |
534379 |
ASSERT_FN(read_);
|
|
Packit |
534379 |
ASSERT_FN(fopen_);
|
|
Packit |
534379 |
ASSERT_FN(popen_);
|
|
Packit |
534379 |
ASSERT_FN(pclose_);
|
|
Packit |
534379 |
ASSERT_FN(close_);
|
|
Packit |
534379 |
ASSERT_FN(ioctl_);
|
|
Packit |
534379 |
ASSERT_FN(readlink_);
|
|
Packit |
534379 |
ASSERT_FN(xstat_);
|
|
Packit |
534379 |
ASSERT_FN(lstat_);
|
|
Packit |
534379 |
ASSERT_FN(scandir_);
|
|
Packit |
534379 |
ASSERT_FN(sched_setaffinity_);
|
|
Packit |
534379 |
ASSERT_FN(glob_);
|
|
Packit |
534379 |
ASSERT_FN(realpath_);
|
|
Packit |
534379 |
for (const auto &kv : default_ioctl_handlers_) {
|
|
Packit |
534379 |
register_ioctl_handler(kv.first, kv.second);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
initialized_ = true;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::finalize() {
|
|
Packit |
534379 |
if (!initialized_) {
|
|
Packit |
534379 |
return;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
initialized_ = false;
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
for (auto kv : fds_) {
|
|
Packit |
534379 |
if (kv.second) {
|
|
Packit |
534379 |
delete kv.second;
|
|
Packit |
534379 |
kv.second = nullptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
remove_sysfs();
|
|
Packit |
534379 |
root_ = "";
|
|
Packit |
534379 |
fds_.clear();
|
|
Packit |
534379 |
for (auto kv : registered_files_) {
|
|
Packit |
534379 |
unlink(kv.second.c_str());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
registered_files_.clear();
|
|
Packit |
534379 |
ioctl_handlers_.clear();
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
bool test_system::default_ioctl_handler(int request, ioctl_handler_t h) {
|
|
Packit |
534379 |
bool already_registered =
|
|
Packit |
534379 |
default_ioctl_handlers_.find(request) != default_ioctl_handlers_.end();
|
|
Packit |
534379 |
default_ioctl_handlers_[request] = h;
|
|
Packit |
534379 |
return already_registered;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
bool test_system::register_ioctl_handler(int request, ioctl_handler_t h) {
|
|
Packit |
534379 |
bool already_registered =
|
|
Packit |
534379 |
ioctl_handlers_.find(request) != ioctl_handlers_.end();
|
|
Packit |
534379 |
ioctl_handlers_[request] = h;
|
|
Packit |
534379 |
return already_registered;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *test_system::register_file(const std::string &path) {
|
|
Packit |
534379 |
auto it = registered_files_.find(path);
|
|
Packit |
534379 |
if (it == registered_files_.end()) {
|
|
Packit |
534379 |
registered_files_[path] =
|
|
Packit |
534379 |
"/tmp/testfile" + std::to_string(registered_files_.size());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
auto fptr = fopen(path.c_str(), "w+");
|
|
Packit |
534379 |
return fptr;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::normalize_guid(std::string &guid_str, bool with_hyphens) {
|
|
Packit |
534379 |
// normalizing a guid string can make it easier to compare guid strings
|
|
Packit |
534379 |
// and can also put the string in a format that can be parsed into actual
|
|
Packit |
534379 |
// guid bytes (uuid_parse expects the string to include hyphens).
|
|
Packit |
534379 |
const size_t std_guid_str_size = 36;
|
|
Packit |
534379 |
const size_t char_guid_str_size = 32;
|
|
Packit |
534379 |
if (guid_str.back() == '\n') {
|
|
Packit |
534379 |
guid_str.erase(guid_str.end() - 1);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
std::locale lc;
|
|
Packit |
534379 |
auto c_idx = guid_str.find('-');
|
|
Packit |
534379 |
if (with_hyphens && c_idx == std::string::npos) {
|
|
Packit |
534379 |
// if we want the standard UUID format with hyphens (8-4-4-4-12)
|
|
Packit |
534379 |
if (guid_str.size() == char_guid_str_size) {
|
|
Packit |
534379 |
int idx = 20;
|
|
Packit |
534379 |
while (c_idx != 8) {
|
|
Packit |
534379 |
guid_str.insert(idx, 1, '-');
|
|
Packit |
534379 |
idx -= 4;
|
|
Packit |
534379 |
c_idx = guid_str.find('-');
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
throw std::invalid_argument("invalid guid string");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else if (!with_hyphens && c_idx == 8) {
|
|
Packit |
534379 |
// we want the hex characters only, no other extra chars
|
|
Packit |
534379 |
if (guid_str.size() == std_guid_str_size) {
|
|
Packit |
534379 |
while (c_idx != std::string::npos) {
|
|
Packit |
534379 |
guid_str.erase(c_idx, 1);
|
|
Packit |
534379 |
c_idx = guid_str.find('-');
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
throw std::invalid_argument("invalid guid string");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
for (auto &c : guid_str) {
|
|
Packit |
534379 |
c = std::tolower(c, lc);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
uint32_t get_device_id(const std::string &sysclass) {
|
|
Packit |
534379 |
uint32_t res(0);
|
|
Packit |
534379 |
std::ifstream fs;
|
|
Packit |
534379 |
fs.open(sysclass + "/device/device");
|
|
Packit |
534379 |
if (fs.is_open()) {
|
|
Packit |
534379 |
std::string line;
|
|
Packit |
534379 |
std::getline(fs, line);
|
|
Packit |
534379 |
fs.close();
|
|
Packit |
534379 |
return std::stoul(line, 0, 16);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
std::string test_system::get_sysfs_claass_path(const std::string &path) {
|
|
Packit |
534379 |
for (auto it : fpga_sysfs_path_map) {
|
|
Packit |
534379 |
if (path.find(it.first) == 0) {
|
|
Packit |
534379 |
return it.second;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return "";
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::open(const std::string &path, int flags) {
|
|
Packit |
534379 |
if (!initialized_) {
|
|
Packit |
534379 |
return open_(path.c_str(), flags);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
int fd;
|
|
Packit |
534379 |
auto r1 = regex<>::create(sysclass_pattern);
|
|
Packit |
534379 |
auto r2 = regex<>::create(dev_pattern);
|
|
Packit |
534379 |
match_t::ptr_t m;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// check if we are opening a driver attribute file
|
|
Packit |
534379 |
// or a device file to save the fd in an internal map
|
|
Packit |
534379 |
// this can be used later, (especially in ioctl)
|
|
Packit |
534379 |
if (r1 && (m = r1->match(path))) {
|
|
Packit |
534379 |
// path matches /sys/class/fpga/intel-fpga-dev\..*
|
|
Packit |
534379 |
// we are opening a driver attribute file
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (flags == O_WRONLY) {
|
|
Packit |
534379 |
// truncate the file to zero to emulate the sysfs behavior.
|
|
Packit |
534379 |
flags |= O_TRUNC;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fd = open_(syspath.c_str(), flags);
|
|
Packit |
534379 |
auto sysclass_path = m->group(0);
|
|
Packit |
534379 |
auto device_id = get_device_id(get_sysfs_path(sysclass_path));
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
fds_[fd] = new mock_object(path, sysclass_path, device_id);
|
|
Packit |
534379 |
} else if (r2 && (m = r2->match(path))) {
|
|
Packit |
534379 |
// path matches /dev/intel-fpga-(fme|port)\..*
|
|
Packit |
534379 |
// we are opening a device
|
|
Packit |
534379 |
fd = open_(syspath.c_str(), flags);
|
|
Packit |
534379 |
auto sysclass_path = get_sysfs_claass_path(path) + m->group(3);
|
|
Packit |
534379 |
auto device_id = get_device_id(get_sysfs_path(sysclass_path));
|
|
Packit |
534379 |
if (m->group(2) == "fme") {
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
fds_[fd] = new mock_fme(path, sysclass_path, device_id);
|
|
Packit |
534379 |
} else if (m->group(2) == "port") {
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
fds_[fd] = new mock_port(path, sysclass_path, device_id);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
fd = open_(syspath.c_str(), flags);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return fd;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::open(const std::string &path, int flags, mode_t mode) {
|
|
Packit |
534379 |
if (!initialized_) {
|
|
Packit |
534379 |
return open_create_(path.c_str(), flags, mode);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
int fd = open_create_(syspath.c_str(), flags, mode);
|
|
Packit |
534379 |
if (syspath.find(root_) == 0) {
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
std::map<int, mock_object *>::iterator it = fds_.find(fd);
|
|
Packit |
534379 |
if (it != fds_.end()) {
|
|
Packit |
534379 |
delete it->second;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
fds_[fd] = new mock_object(path, "", 0);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return fd;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
static bool _invalidate_read = false;
|
|
Packit |
534379 |
static uint32_t _invalidate_read_after = 0;
|
|
Packit |
534379 |
static const char *_invalidate_read_when_called_from = nullptr;
|
|
Packit |
534379 |
void test_system::invalidate_read(uint32_t after,
|
|
Packit |
534379 |
const char *when_called_from) {
|
|
Packit |
534379 |
_invalidate_read = true;
|
|
Packit |
534379 |
_invalidate_read_after = after;
|
|
Packit |
534379 |
_invalidate_read_when_called_from = when_called_from;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t test_system::read(int fd, void *buf, size_t count) {
|
|
Packit |
534379 |
if (_invalidate_read) {
|
|
Packit |
534379 |
if (!_invalidate_read_when_called_from) {
|
|
Packit |
534379 |
if (!_invalidate_read_after) {
|
|
Packit |
534379 |
_invalidate_read = false;
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
--_invalidate_read_after;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
// 2 here, because we were called through..
|
|
Packit |
534379 |
// 0 test_system.cpp:opae_test_read()
|
|
Packit |
534379 |
// 1 mock.c:read()
|
|
Packit |
534379 |
// 2 <caller>
|
|
Packit |
534379 |
void *caller = __builtin_return_address(2);
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
Dl_info info;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dladdr(caller, &info;;
|
|
Packit |
534379 |
if (!info.dli_sname)
|
|
Packit |
534379 |
res = 1;
|
|
Packit |
534379 |
else
|
|
Packit |
534379 |
res = strcmp(info.dli_sname, _invalidate_read_when_called_from);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!_invalidate_read_after && !res) {
|
|
Packit |
534379 |
_invalidate_read = false;
|
|
Packit |
534379 |
_invalidate_read_when_called_from = nullptr;
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
} else if (!res)
|
|
Packit |
534379 |
--_invalidate_read_after;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return read_(fd, buf, count);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *test_system::fopen(const std::string &path, const std::string &mode) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
return fopen_(syspath.c_str(), mode.c_str());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *test_system::popen(const std::string &cmd, const std::string &type) {
|
|
Packit |
534379 |
// Is this something we're interested in?
|
|
Packit |
534379 |
if (0 == cmd.compare(0, 5, "rdmsr")) {
|
|
Packit |
534379 |
char tmpfile[20];
|
|
Packit |
534379 |
strcpy(tmpfile, "popen-XXXXXX.tmp");
|
|
Packit |
534379 |
close(mkstemps(tmpfile, 4));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *fp = fopen(tmpfile, "w+");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
size_t last_spc = cmd.find_last_of(' ');
|
|
Packit |
534379 |
std::string msr(cmd.substr(last_spc + 1));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (0 == msr.compare("0x35")) {
|
|
Packit |
534379 |
fprintf(fp, "0x0000000000180030");
|
|
Packit |
534379 |
} else if (0 == msr.compare("0x610")) {
|
|
Packit |
534379 |
fprintf(fp, "0x000388d000148758");
|
|
Packit |
534379 |
} else if (0 == msr.compare("0x606")) {
|
|
Packit |
534379 |
fprintf(fp, "0x00000000000a0e03");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fseek(fp, 0, SEEK_SET);
|
|
Packit |
534379 |
popen_requests_.insert(std::make_pair(fp, tmpfile));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return fp;
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
return popen_(cmd.c_str(), type.c_str());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::pclose(FILE *stream) {
|
|
Packit |
534379 |
// Is this something we intercepted?
|
|
Packit |
534379 |
std::map<FILE *, std::string>::iterator it = popen_requests_.find(stream);
|
|
Packit |
534379 |
if (it != popen_requests_.end()) {
|
|
Packit |
534379 |
unlink(it->second.c_str());
|
|
Packit |
534379 |
popen_requests_.erase(it);
|
|
Packit |
534379 |
fclose(stream);
|
|
Packit |
534379 |
return 0; // process exit status
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return pclose_(stream);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::close(int fd) {
|
|
Packit |
534379 |
if (initialized_) {
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
std::map<int, mock_object *>::iterator it = fds_.find(fd);
|
|
Packit |
534379 |
if (it != fds_.end()) {
|
|
Packit |
534379 |
delete it->second;
|
|
Packit |
534379 |
fds_.erase(it);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return close_(fd);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::ioctl(int fd, unsigned long request, va_list argp) {
|
|
Packit |
534379 |
mock_object *mo = nullptr;
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
std::lock_guard<std::mutex> guard(fds_mutex_);
|
|
Packit |
534379 |
auto mi = fds_.find(fd);
|
|
Packit |
534379 |
if (mi != fds_.end()) {
|
|
Packit |
534379 |
mo = mi->second;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (mo == nullptr) {
|
|
Packit |
534379 |
char *arg = va_arg(argp, char *);
|
|
Packit |
534379 |
return ioctl_(fd, request, arg);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// replace mock_it->second with mo
|
|
Packit |
534379 |
auto handler_it = ioctl_handlers_.find(request);
|
|
Packit |
534379 |
if (handler_it != ioctl_handlers_.end()) {
|
|
Packit |
534379 |
return handler_it->second(mo, request, argp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return mo->ioctl(request, argp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
DIR *test_system::opendir(const char *path) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
return opendir_(syspath.c_str());
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t test_system::readlink(const char *path, char *buf, size_t bufsize) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
return readlink_(syspath.c_str(), buf, bufsize);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::xstat(int ver, const char *path, struct stat *buf) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
int res = xstat_(ver, syspath.c_str(), buf);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!res && strlen(path) > 5) {
|
|
Packit |
534379 |
// If path is rooted at /dev, assume it is a char device.
|
|
Packit |
534379 |
std::string p(path, 5);
|
|
Packit |
534379 |
if (p == std::string("/dev/")) {
|
|
Packit |
534379 |
buf->st_mode &= ~S_IFMT;
|
|
Packit |
534379 |
buf->st_mode |= S_IFCHR;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::lstat(int ver, const char *path, struct stat *buf) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(path);
|
|
Packit |
534379 |
int res = lstat_(ver, syspath.c_str(), buf);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!res && strlen(path) > 5) {
|
|
Packit |
534379 |
// If path is rooted at /dev, assume it is a char device.
|
|
Packit |
534379 |
std::string p(path, 5);
|
|
Packit |
534379 |
if (p == std::string("/dev/")) {
|
|
Packit |
534379 |
buf->st_mode &= ~S_IFMT;
|
|
Packit |
534379 |
buf->st_mode |= S_IFCHR;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::scandir(const char *dirp, struct dirent ***namelist,
|
|
Packit |
534379 |
filter_func filter, compare_func cmp) {
|
|
Packit |
534379 |
std::string syspath = get_sysfs_path(dirp);
|
|
Packit |
534379 |
return scandir_(syspath.c_str(), namelist, filter, cmp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::sched_setaffinity(pid_t pid, size_t cpusetsize,
|
|
Packit |
534379 |
const cpu_set_t *mask) {
|
|
Packit |
534379 |
UNUSED_PARAM(pid);
|
|
Packit |
534379 |
UNUSED_PARAM(cpusetsize);
|
|
Packit |
534379 |
UNUSED_PARAM(mask);
|
|
Packit |
534379 |
if (hijack_sched_setaffinity_) {
|
|
Packit |
534379 |
if (!hijack_sched_setaffinity_caller_) {
|
|
Packit |
534379 |
if (!hijack_sched_setaffinity_after_) {
|
|
Packit |
534379 |
hijack_sched_setaffinity_ = false;
|
|
Packit |
534379 |
int res = hijack_sched_setaffinity_return_val_;
|
|
Packit |
534379 |
hijack_sched_setaffinity_return_val_ = 0;
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
--hijack_sched_setaffinity_after_;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
// 2 here, because we were called through..
|
|
Packit |
534379 |
// 0 test_system.cpp:opae_test_sched_setaffinity()
|
|
Packit |
534379 |
// 1 mock.c:sched_setaffinity()
|
|
Packit |
534379 |
// 2 <caller>
|
|
Packit |
534379 |
void *caller = __builtin_return_address(2);
|
|
Packit |
534379 |
int res;
|
|
Packit |
534379 |
Dl_info info;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
dladdr(caller, &info;;
|
|
Packit |
534379 |
if (!info.dli_sname)
|
|
Packit |
534379 |
res = 1;
|
|
Packit |
534379 |
else
|
|
Packit |
534379 |
res = strcmp(info.dli_sname, hijack_sched_setaffinity_caller_);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!hijack_sched_setaffinity_after_ && !res) {
|
|
Packit |
534379 |
hijack_sched_setaffinity_ = false;
|
|
Packit |
534379 |
hijack_sched_setaffinity_caller_ = nullptr;
|
|
Packit |
534379 |
res = hijack_sched_setaffinity_return_val_;
|
|
Packit |
534379 |
hijack_sched_setaffinity_return_val_ = 0;
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
} else if (!res)
|
|
Packit |
534379 |
--hijack_sched_setaffinity_after_;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
return 0; // return success - we don't actually
|
|
Packit |
534379 |
// want to change the affinity.
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::hijack_sched_setaffinity(int return_val, uint32_t after,
|
|
Packit |
534379 |
const char *when_called_from) {
|
|
Packit |
534379 |
hijack_sched_setaffinity_ = true;
|
|
Packit |
534379 |
hijack_sched_setaffinity_return_val_ = return_val;
|
|
Packit |
534379 |
hijack_sched_setaffinity_after_ = after;
|
|
Packit |
534379 |
hijack_sched_setaffinity_caller_ = when_called_from;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int test_system::glob(const char *pattern, int flags,
|
|
Packit |
534379 |
int (*errfunc)(const char *epath, int eerrno),
|
|
Packit |
534379 |
glob_t *pglob) {
|
|
Packit |
534379 |
if (pattern == nullptr) {
|
|
Packit |
534379 |
return glob_(pattern, flags, errfunc, pglob);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
auto path = get_sysfs_path(pattern);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
auto res = glob_(path.c_str(), flags, errfunc, pglob);
|
|
Packit |
534379 |
if (!res) {
|
|
Packit |
534379 |
for (unsigned int i = 0; i < pglob->gl_pathc; ++i) {
|
|
Packit |
534379 |
std::string tmppath(pglob->gl_pathv[i]);
|
|
Packit |
534379 |
if (tmppath.find(get_root()) == 0) {
|
|
Packit |
534379 |
auto p = pglob->gl_pathv[i];
|
|
Packit |
534379 |
auto root_len = get_root().size();
|
|
Packit |
534379 |
auto new_len = tmppath.size() - root_len;
|
|
Packit |
534379 |
std::copy(tmppath.begin() + root_len, tmppath.end(), p);
|
|
Packit |
534379 |
p[new_len] = '\0';
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
char *test_system::realpath(const char *inp, char *dst)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
if (!initialized_ || root_.empty()) {
|
|
Packit |
534379 |
return realpath_(inp, dst);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
bool current_inv_state = _invalidate_malloc;
|
|
Packit |
534379 |
_invalidate_malloc = false;
|
|
Packit |
534379 |
char *retvalue = realpath_(get_sysfs_path(inp).c_str(), dst);
|
|
Packit |
534379 |
if (retvalue) {
|
|
Packit |
534379 |
std::string dst_str(dst);
|
|
Packit |
534379 |
char prefix[PATH_MAX] = {0};
|
|
Packit |
534379 |
char *prefix_ptr = realpath_(root_.c_str(), prefix);
|
|
Packit |
534379 |
std::string prefix_str(prefix_ptr ? prefix_ptr : "");
|
|
Packit |
534379 |
if (prefix_str.size() && dst_str.find(prefix_str) == 0) {
|
|
Packit |
534379 |
auto cleaned_str = dst_str.substr(prefix_str.size());
|
|
Packit |
534379 |
std::copy(cleaned_str.begin(), cleaned_str.end(), &dst[0]);
|
|
Packit |
534379 |
dst[cleaned_str.size()] = '\0';
|
|
Packit |
534379 |
retvalue = &dst[0];
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
_invalidate_malloc = current_inv_state;
|
|
Packit |
534379 |
return retvalue;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::invalidate_malloc(uint32_t after,
|
|
Packit |
534379 |
const char *when_called_from) {
|
|
Packit |
534379 |
_invalidate_malloc = true;
|
|
Packit |
534379 |
_invalidate_malloc_after = after;
|
|
Packit |
534379 |
_invalidate_malloc_when_called_from = when_called_from;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
void test_system::invalidate_calloc(uint32_t after,
|
|
Packit |
534379 |
const char *when_called_from) {
|
|
Packit |
534379 |
_invalidate_calloc = true;
|
|
Packit |
534379 |
_invalidate_calloc_after = after;
|
|
Packit |
534379 |
_invalidate_calloc_when_called_from = when_called_from;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} // end of namespace testing
|
|
Packit |
534379 |
} // end of namespace opae
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// C functions
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_open(const char *path, int flags) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->open(path, flags);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_open_create(const char *path, int flags, mode_t mode) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->open(path, flags, mode);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t opae_test_read(int fd, void *buf, size_t count) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->read(fd, buf, count);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *opae_test_fopen(const char *path, const char *mode) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->fopen(path, mode);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
FILE *opae_test_popen(const char *cmd, const char *type) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->popen(cmd, type);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_pclose(FILE *stream) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->pclose(stream);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_close(int fd) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->close(fd);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_ioctl(int fd, unsigned long request, va_list argp) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->ioctl(fd, request, argp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
DIR *opae_test_opendir(const char *name) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->opendir(name);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
ssize_t opae_test_readlink(const char *path, char *buf, size_t bufsize) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->readlink(path, buf, bufsize);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_xstat(int ver, const char *path, struct stat *buf) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->xstat(ver, path, buf);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_lstat(int ver, const char *path, struct stat *buf) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->lstat(ver, path, buf);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_scandir(const char *dirp, struct dirent ***namelist,
|
|
Packit |
534379 |
filter_func filter, compare_func cmp) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->scandir(dirp, namelist, filter,
|
|
Packit |
534379 |
cmp);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_sched_setaffinity(pid_t pid, size_t cpusetsize,
|
|
Packit |
534379 |
const cpu_set_t *mask) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->sched_setaffinity(
|
|
Packit |
534379 |
pid, cpusetsize, mask);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int opae_test_glob(const char *pattern, int flags,
|
|
Packit |
534379 |
int (*errfunc)(const char *epath, int eerrno),
|
|
Packit |
534379 |
glob_t *pglob) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->glob(pattern, flags, errfunc,
|
|
Packit |
534379 |
pglob);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
char *opae_test_realpath(const char *inp, char *dst) {
|
|
Packit |
534379 |
return opae::testing::test_system::instance()->realpath(inp, dst);
|
|
Packit |
534379 |
}
|