提交 011be044 编写于 作者: Y yhmo

Merge branch 'jinhai' into 'release-v1'

# Conflicts:
#   cpp/src/utils/Error.h

Former-commit-id: 18470ad3970bec55315d738a006355c1ce2c1f4c
......@@ -45,6 +45,10 @@ endif ()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -fPIC -DELPP_THREAD_SAFE")
if (GPU_VERSION STREQUAL "ON")
set(ENABLE_LICENSE "ON")
add_definitions("-DENABLE_LICENSE")
endif ()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -fPIC -DELPP_THREAD_SAFE")
endif()
......@@ -64,12 +68,12 @@ include_directories(${VECWISE_THIRD_PARTY_BUILD}/include)
link_directories(${CMAKE_CURRRENT_BINARY_DIR})
link_directories(${VECWISE_THIRD_PARTY_BUILD}/lib)
link_directories(${VECWISE_THIRD_PARTY_BUILD}/lib64)
#execute_process(COMMAND bash build.sh
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third_party)
add_subdirectory(src)
add_subdirectory(test_client)
#add_subdirectory(test_client)
if (BUILD_UNIT_TEST)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/unittest)
......
......@@ -10,6 +10,9 @@ db_config:
db_flush_interval: 5 #unit: second
idmapper_max_open_file: 128
license_config:
license_path: "/tmp/megasearch/abc.license"
log_config:
global:
format: "%datetime | %level | %logger | %msg"
......
......@@ -12,7 +12,13 @@ aux_source_directory(db db_files)
aux_source_directory(wrapper wrapper_files)
set(license_check_files
${CMAKE_CURRENT_SOURCE_DIR}/license/License.cpp
license/LicenseLibrary.cpp
license/LicenseCheck.cpp
)
set(license_generator_src
license/LicenseGenerator.cpp
license/LicenseLibrary.cpp
)
set(service_files
......@@ -28,6 +34,9 @@ set(vecwise_engine_src
${wrapper_files}
)
set(get_sys_info_src
license/GetSysInfo.cpp)
include_directories(/usr/include)
include_directories(/usr/local/cuda/include)
......@@ -53,19 +62,37 @@ else()
libgfortran.a
libquadmath.a
libsqlite3.a
)
)
endif ()
if (ENABLE_LICENSE STREQUAL "ON")
link_directories(/usr/local/cuda/lib64/stubs)
link_directories(/usr/local/cuda/lib64)
set(license_libs
nvidia-ml
libboost_system.a
libboost_filesystem.a
libboost_serialization.a
crypto
cudart
cublas
)
endif ()
cuda_add_library(vecwise_engine STATIC ${vecwise_engine_src})
cuda_add_library(vecwise_engine STATIC ${vecwise_engine_src})
target_link_libraries(vecwise_engine ${engine_libs})
if (ENABLE_LICENSE STREQUAL "ON")
add_library(vecwise_license STATIC ${license_check_files})
target_link_libraries(vecwise_license ${license_libs})
endif ()
add_executable(vecwise_server
${config_files}
${server_files}
${utils_files}
${service_files}
${license_check_files}
${VECWISE_THIRD_PARTY_BUILD}/include/easylogging++.cc
)
......@@ -77,7 +104,6 @@ set(server_libs
libyaml-cpp.a
libboost_system.a
libboost_filesystem.a
pthread
libsnappy.a
libbz2.a
libz.a
......@@ -86,11 +112,17 @@ set(server_libs
dl
)
target_link_libraries(vecwise_server ${server_libs})
if (ENABLE_LICENSE STREQUAL "ON")
target_link_libraries(vecwise_server ${server_libs} vecwise_license)
else ()
target_link_libraries(vecwise_server ${server_libs})
endif()
set(license_generator_src
${CMAKE_CURRENT_SOURCE_DIR}/license/LicenseGenerator.cpp)
add_executable(license_generator ${license_generator_src})
if (ENABLE_LICENSE STREQUAL "ON")
add_executable(license_generator ${license_generator_src})
add_executable(get_sys_info ${get_sys_info_src})
target_link_libraries(get_sys_info ${license_libs} vecwise_license)
target_link_libraries(license_generator ${license_libs})
endif ()
install(TARGETS vecwise_server DESTINATION bin)
install(TARGETS vecwise_server DESTINATION bin)
\ No newline at end of file
/*******************************************************************************
* Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited.
* Proprietary and confidential.
******************************************************************************/
#pragma once
#include <boost/serialization/access.hpp>
#include <string>
#include <map>
class GPUInfoFile {
public:
GPUInfoFile() = default;
GPUInfoFile(const int &device_count, const std::map<int, std::string> &uuid_encryption_map)
: device_count_(device_count), uuid_encryption_map_(uuid_encryption_map) {}
int get_device_count() {
return device_count_;
}
std::map<int, std::string> &get_uuid_encryption_map() {
return uuid_encryption_map_;
}
public:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & device_count_;
ar & uuid_encryption_map_;
}
public:
int device_count_ = 0;
std::map<int, std::string> uuid_encryption_map_;
};
class SerializedGPUInfoFile {
public:
~SerializedGPUInfoFile() {
if (gpu_info_file_ != nullptr) {
delete (gpu_info_file_);
gpu_info_file_ = nullptr;
}
}
void
set_gpu_info_file(GPUInfoFile *gpu_info_file) {
gpu_info_file_ = gpu_info_file;
}
GPUInfoFile *get_gpu_info_file() {
return gpu_info_file_;
}
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & gpu_info_file_;
}
private:
GPUInfoFile *gpu_info_file_ = nullptr;
};
#include "utils/Log.h"
#include "LicenseLibrary.h"
#include "utils/Error.h"
#include <iostream>
#include <getopt.h>
#include <memory.h>
// Not provide path: current work path will be used and system.info.
using namespace zilliz::vecwise;
void
print_usage(const std::string &app_name) {
printf("\n Usage: %s [OPTIONS]\n\n", app_name.c_str());
printf(" Options:\n");
printf(" -h --help Print this help\n");
printf(" -s --sysinfo filename Generate system info file as given name\n");
printf("\n");
}
int main(int argc, char *argv[]) {
std::string app_name = argv[0];
if (argc != 1 && argc != 3) {
print_usage(app_name);
return EXIT_FAILURE;
}
static struct option long_options[] = {{"system_info", required_argument, 0, 's'},
{"help", no_argument, 0, 'h'},
{NULL, 0, 0, 0}};
int value = 0;
int option_index = 0;
std::string system_info_filename = "./system.info";
while ((value = getopt_long(argc, argv, "s:h", long_options, &option_index)) != -1) {
switch (value) {
case 's': {
char *system_info_filename_ptr = strdup(optarg);
system_info_filename = system_info_filename_ptr;
free(system_info_filename_ptr);
// printf("Generate system info file: %s\n", system_info_filename.c_str());
break;
}
case 'h':print_usage(app_name);
return EXIT_SUCCESS;
case '?':print_usage(app_name);
return EXIT_FAILURE;
default:print_usage(app_name);
break;
}
}
int device_count = 0;
server::ServerError err = server::LicenseLibrary::GetDeviceCount(device_count);
if (err != server::SERVER_SUCCESS) return -1;
// 1. Get All GPU UUID
std::vector<std::string> uuid_array;
err = server::LicenseLibrary::GetUUID(device_count, uuid_array);
if (err != server::SERVER_SUCCESS) return -1;
// 2. Get UUID SHA256
std::vector<std::string> uuid_sha256_array;
err = server::LicenseLibrary::GetUUIDSHA256(device_count, uuid_array, uuid_sha256_array);
if (err != server::SERVER_SUCCESS) return -1;
// 3. Generate GPU ID map with GPU UUID
std::map<int, std::string> uuid_encrption_map;
for (int i = 0; i < device_count; ++i) {
uuid_encrption_map[i] = uuid_sha256_array[i];
}
// 4. Generate GPU_info File
err = server::LicenseLibrary::GPUinfoFileSerialization(system_info_filename,
device_count,
uuid_encrption_map);
if (err != server::SERVER_SUCCESS) return -1;
printf("Generate GPU_info File Success\n");
return 0;
}
\ No newline at end of file
#include "License.h"
namespace zilliz {
namespace vecwise {
namespace server {
ServerError
LicenseValidate(const std::string& path) {
return SERVER_SUCCESS;
}
}
}
}
\ No newline at end of file
#pragma once
#include "utils/Error.h"
namespace zilliz {
namespace vecwise {
namespace server {
ServerError
LicenseValidate(const std::string& path);
}
}
}
#include "LicenseCheck.h"
#include <iostream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
//#include <boost/foreach.hpp>
//#include <boost/serialization/vector.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/serialization/map.hpp>
#include <boost/filesystem/operations.hpp>
namespace zilliz {
namespace vecwise {
namespace server {
// Part 1: Legality check
ServerError
LicenseCheck::LegalityCheck(const std::string &license_file_path) {
int device_count;
LicenseLibrary::GetDeviceCount(device_count);
std::vector<std::string> uuid_array;
LicenseLibrary::GetUUID(device_count, uuid_array);
std::vector<std::string> sha_array;
LicenseLibrary::GetUUIDSHA256(device_count, uuid_array, sha_array);
int output_device_count;
std::map<int, std::string> uuid_encryption_map;
time_t starting_time;
time_t end_time;
ServerError err = LicenseLibrary::LicenseFileDeserialization(license_file_path,
output_device_count,
uuid_encryption_map,
starting_time,
end_time);
if(err !=SERVER_SUCCESS)
{
printf("License check error: 01\n");
return SERVER_UNEXPECTED_ERROR;
}
time_t system_time;
LicenseLibrary::GetSystemTime(system_time);
if (device_count != output_device_count) {
printf("License check error: 02\n");
return SERVER_UNEXPECTED_ERROR;
}
for (int i = 0; i < device_count; ++i) {
if (sha_array[i] != uuid_encryption_map[i]) {
printf("License check error: 03\n");
return SERVER_UNEXPECTED_ERROR;
}
}
if (system_time < starting_time || system_time > end_time) {
printf("License check error: 04\n");
return SERVER_UNEXPECTED_ERROR;
}
printf("Legality Check Success\n");
return SERVER_SUCCESS;
}
// Part 2: Timing check license
ServerError
LicenseCheck::AlterFile(const std::string &license_file_path,
const boost::system::error_code &ec,
boost::asio::deadline_timer *pt) {
ServerError err = LegalityCheck(license_file_path);
if(err!=SERVER_SUCCESS)
{
exit(1);
}
printf("---runing---\n");
pt->expires_at(pt->expires_at() + boost::posix_time::hours(1));
pt->async_wait(boost::bind(AlterFile, license_file_path, boost::asio::placeholders::error, pt));
return SERVER_SUCCESS;
}
ServerError
LicenseCheck::StartCountingDown(const std::string &license_file_path) {
if (!LicenseLibrary::IsFileExistent(license_file_path)) return SERVER_LICENSE_FILE_NOT_EXIST;
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::hours(1));
t.async_wait(boost::bind(AlterFile, license_file_path, boost::asio::placeholders::error, &t));
io.run();
return SERVER_SUCCESS;
}
}
}
}
\ No newline at end of file
#pragma once
#include "utils/Error.h"
#include "LicenseLibrary.h"
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace zilliz {
namespace vecwise {
namespace server {
class LicenseCheck {
public:
static LicenseCheck &
GetInstance() {
static LicenseCheck instance;
return instance;
};
// Part 1: Legality check
static ServerError
LegalityCheck(const std::string &license_file_path);
// Part 2: Timing check license
static ServerError
AlterFile(const std::string &license_file_path,
const boost::system::error_code &ec,
boost::asio::deadline_timer *pt);
static ServerError
StartCountingDown(const std::string &license_file_path);
private:
};
}
}
}
/*******************************************************************************
* Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited.
* Proprietary and confidential.
******************************************************************************/
#pragma once
#include <boost/serialization/access.hpp>
#include <string>
#include <map>
class LicenseFile {
public:
LicenseFile() = default;
LicenseFile(const int &device_count,
const std::map<int, std::string> &uuid_encryption_map,
const time_t &starting_time,
const time_t &end_time)
: device_count_(device_count),
uuid_encryption_map_(uuid_encryption_map),
starting_time_(starting_time),
end_time_(end_time) {}
int get_device_count() {
return device_count_;
}
std::map<int, std::string> &get_uuid_encryption_map() {
return uuid_encryption_map_;
}
time_t get_starting_time() {
return starting_time_;
}
time_t get_end_time() {
return end_time_;
}
public:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & device_count_;
ar & uuid_encryption_map_;
ar & starting_time_;
ar & end_time_;
}
public:
int device_count_ = 0;
std::map<int, std::string> uuid_encryption_map_;
time_t starting_time_ = 0;
time_t end_time_ = 0;
};
class SerializedLicenseFile {
public:
~SerializedLicenseFile() {
if (license_file_ != nullptr) {
delete (license_file_);
license_file_ = nullptr;
}
}
void
set_license_file(LicenseFile *license_file) {
license_file_ = license_file;
}
LicenseFile *get_license_file() {
return license_file_;
}
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & license_file_;
}
private:
LicenseFile *license_file_ = nullptr;
};
#include <iostream>
#include <getopt.h>
#include <memory.h>
#include "utils/Log.h"
#include "license/LicenseLibrary.h"
#include "utils/Error.h"
using namespace zilliz::vecwise;
// Not provide path: current work path will be used and system.info.
void
print_usage(const std::string &app_name) {
printf("\n Usage: %s [OPTIONS]\n\n", app_name.c_str());
printf(" Options:\n");
printf(" -h --help Print this help\n");
printf(" -s --sysinfo filename sysinfo file location\n");
printf(" -l --license filename Generate license file as given name\n");
printf(" -b --starting time Set start time (format: YYYY-MM-DD)\n");
printf(" -e --end time Set end time (format: YYYY-MM-DD)\n");
printf("\n");
}
int main(int argc, char *argv[]) {
std::string app_name = argv[0];
// if (argc != 1 && argc != 3) {
// print_usage(app_name);
// return EXIT_FAILURE;
// }
static struct option long_options[] = {{"system_info", required_argument, 0, 's'},
{"license", optional_argument, 0, 'l'},
{"help", no_argument, 0, 'h'},
{"starting_time", required_argument, 0, 'b'},
{"end_time", required_argument, 0, 'e'},
{NULL, 0, 0, 0}};
server::ServerError err;
int value = 0;
int option_index = 0;
std::string system_info_filename = "./system.info";
std::string license_filename = "./system.license";
char *string_starting_time = NULL;
char *string_end_time = NULL;
time_t starting_time = 0;
time_t end_time = 0;
int flag_s = 1;
int flag_b = 1;
int flag_e = 1;
while ((value = getopt_long(argc, argv, "hl:s:b:e:", long_options, NULL)) != -1) {
switch (value) {
case 's': {
flag_s = 0;
system_info_filename = (std::string) (optarg);
break;
}
case 'b': {
flag_b = 0;
string_starting_time = optarg;
break;
}
case 'e': {
flag_e = 0;
string_end_time = optarg;
break;
}
case 'l': {
license_filename = (std::string) (optarg);
break;
}
case 'h':print_usage(app_name);
return EXIT_SUCCESS;
case '?':print_usage(app_name);
return EXIT_FAILURE;
default:print_usage(app_name);
break;
}
}
if (flag_s) {
printf("Error: sysinfo file location must be entered\n");
return 1;
}
if (flag_b) {
printf("Error: start time must be entered\n");
return 1;
}
if (flag_e) {
printf("Error: end time must be entered\n");
return 1;
}
err = server::LicenseLibrary::GetDateTime(string_starting_time, starting_time);
if (err != server::SERVER_SUCCESS) return -1;
err = server::LicenseLibrary::GetDateTime(string_end_time, end_time);
if (err != server::SERVER_SUCCESS) return -1;
int output_info_device_count = 0;
std::map<int, std::string> output_info_uuid_encrption_map;
err = server::LicenseLibrary::GPUinfoFileDeserialization(system_info_filename,
output_info_device_count,
output_info_uuid_encrption_map);
if (err != server::SERVER_SUCCESS) return -1;
err = server::LicenseLibrary::LicenseFileSerialization(license_filename,
output_info_device_count,
output_info_uuid_encrption_map,
starting_time,
end_time);
if (err != server::SERVER_SUCCESS) return -1;
printf("Generate License File Success\n");
int main() {
std::cout << "This is license generator" << std::endl;
return 0;
}
\ No newline at end of file
}
////////////////////////////////////////////////////////////////////////////////
// Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited.
// Proprietary and confidential.
////////////////////////////////////////////////////////////////////////////////
#include "LicenseLibrary.h"
#include "utils/Log.h"
#include <cuda_runtime.h>
#include <nvml.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
//#include <boost/foreach.hpp>
//#include <boost/serialization/vector.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/serialization/map.hpp>
#include <boost/filesystem/operations.hpp>
namespace zilliz {
namespace vecwise {
namespace server {
constexpr int LicenseLibrary::sha256_length_;
// Part 0: File check
bool
LicenseLibrary::IsFileExistent(const std::string &path) {
boost::system::error_code error;
auto file_status = boost::filesystem::status(path, error);
if (error) {
return false;
}
if (!boost::filesystem::exists(file_status)) {
return false;
}
return !boost::filesystem::is_directory(file_status);
}
// Part 1: Get GPU Info
ServerError
LicenseLibrary::GetDeviceCount(int &device_count) {
nvmlReturn_t result = nvmlInit();
if (NVML_SUCCESS != result) {
printf("Failed to initialize NVML: %s\n", nvmlErrorString(result));
return SERVER_UNEXPECTED_ERROR;
}
cudaError_t error_id = cudaGetDeviceCount(&device_count);
if (error_id != cudaSuccess) {
printf("cudaGetDeviceCount returned %d\n-> %s\n", (int) error_id, cudaGetErrorString(error_id));
printf("Result = FAIL\n");
return SERVER_UNEXPECTED_ERROR;
}
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetUUID(int device_count, std::vector<std::string> &uuid_array) {
if (device_count == 0) {
printf("There are no available device(s) that support CUDA\n");
return SERVER_UNEXPECTED_ERROR;
}
for (int dev = 0; dev < device_count; ++dev) {
nvmlDevice_t device;
nvmlReturn_t result = nvmlDeviceGetHandleByIndex(dev, &device);
if (NVML_SUCCESS != result) {
printf("Failed to get handle for device %i: %s\n", dev, nvmlErrorString(result));
return SERVER_UNEXPECTED_ERROR;
}
char uuid[80];
unsigned int length = 80;
nvmlReturn_t err = nvmlDeviceGetUUID(device, uuid, length);
if (err != NVML_SUCCESS) {
printf("nvmlDeviceGetUUID error: %d\n", err);
return SERVER_UNEXPECTED_ERROR;
}
uuid_array.emplace_back(uuid);
}
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetUUIDMD5(int device_count,
std::vector<std::string> &uuid_array,
std::vector<std::string> &md5_array) {
MD5_CTX ctx;
unsigned char outmd[16];
char temp[2];
std::string md5;
for (int dev = 0; dev < device_count; ++dev) {
md5.clear();
memset(outmd, 0, sizeof(outmd));
MD5_Init(&ctx);
MD5_Update(&ctx, uuid_array[dev].c_str(), uuid_array[dev].size());
MD5_Final(outmd, &ctx);
for (int i = 0; i < 16; ++i) {
std::snprintf(temp, 2, "%02X", outmd[i]);
md5 += temp;
}
md5_array.push_back(md5);
}
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetUUIDSHA256(const int &device_count,
std::vector<std::string> &uuid_array,
std::vector<std::string> &sha_array) {
SHA256_CTX ctx;
unsigned char outmd[sha256_length_];
char temp[2];
std::string sha;
for (int dev = 0; dev < device_count; ++dev) {
sha.clear();
memset(outmd, 0, sizeof(outmd));
SHA256_Init(&ctx);
SHA256_Update(&ctx, uuid_array[dev].c_str(), uuid_array[dev].size());
SHA256_Final(outmd, &ctx);
for (int i = 0; i < sha256_length_; ++i) {
std::snprintf(temp, 2, "%02X", outmd[i]);
sha += temp;
}
sha_array.push_back(sha);
}
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetSystemTime(time_t &system_time) {
system_time = time(NULL);
return SERVER_SUCCESS;
}
// Part 2: Handle License File
ServerError
LicenseLibrary::LicenseFileSerialization(const std::string &path,
int device_count,
const std::map<int, std::string> &uuid_encrption_map,
time_t starting_time,
time_t end_time) {
std::ofstream file(path);
boost::archive::binary_oarchive oa(file);
oa.register_type<LicenseFile>();
SerializedLicenseFile serialized_license_file;
serialized_license_file.set_license_file(new LicenseFile(device_count,
uuid_encrption_map,
starting_time,
end_time));
oa << serialized_license_file;
file.close();
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::LicenseFileDeserialization(const std::string &path,
int &device_count,
std::map<int, std::string> &uuid_encrption_map,
time_t &starting_time,
time_t &end_time) {
if (!IsFileExistent(path)) return SERVER_LICENSE_FILE_NOT_EXIST;
std::ifstream file(path);
boost::archive::binary_iarchive ia(file);
ia.register_type<LicenseFile>();
SerializedLicenseFile serialized_license_file;
ia >> serialized_license_file;
device_count = serialized_license_file.get_license_file()->get_device_count();
uuid_encrption_map = serialized_license_file.get_license_file()->get_uuid_encryption_map();
starting_time = serialized_license_file.get_license_file()->get_starting_time();
end_time = serialized_license_file.get_license_file()->get_end_time();
file.close();
return SERVER_SUCCESS;
}
//ServerError
//LicenseLibrary::SecretFileSerialization(const std::string &path,
// const time_t &update_time,
// const off_t &file_size,
// const time_t &starting_time,
// const time_t &end_time,
// const std::string &file_md5) {
// std::ofstream file(path);
// boost::archive::binary_oarchive oa(file);
// oa.register_type<SecretFile>();
//
// SerializedSecretFile serialized_secret_file;
//
// serialized_secret_file.set_secret_file(new SecretFile(update_time, file_size, starting_time, end_time, file_md5));
// oa << serialized_secret_file;
//
// file.close();
// return SERVER_SUCCESS;
//}
//
//ServerError
//LicenseLibrary::SecretFileDeserialization(const std::string &path,
// time_t &update_time,
// off_t &file_size,
// time_t &starting_time,
// time_t &end_time,
// std::string &file_md5) {
// if (!IsFileExistent(path)) return SERVER_LICENSE_FILE_NOT_EXIST;
//
// std::ifstream file(path);
// boost::archive::binary_iarchive ia(file);
// ia.register_type<SecretFile>();
// SerializedSecretFile serialized_secret_file;
//
// ia >> serialized_secret_file;
// update_time = serialized_secret_file.get_secret_file()->get_update_time();
// file_size = serialized_secret_file.get_secret_file()->get_file_size();
// starting_time = serialized_secret_file.get_secret_file()->get_starting_time();
// end_time = serialized_secret_file.get_secret_file()->get_end_time();
// file_md5 = serialized_secret_file.get_secret_file()->get_file_md5();
// file.close();
// return SERVER_SUCCESS;
//}
// Part 3: File attribute: UpdateTime Time/ Size/ MD5
ServerError
LicenseLibrary::GetFileUpdateTimeAndSize(const std::string &path, time_t &update_time, off_t &file_size) {
if (!IsFileExistent(path)) return SERVER_LICENSE_FILE_NOT_EXIST;
struct stat buf;
int err_no = stat(path.c_str(), &buf);
if (err_no != 0) {
std::cout << strerror(err_no) << std::endl;
return SERVER_UNEXPECTED_ERROR;
}
update_time = buf.st_mtime;
file_size = buf.st_size;
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetFileMD5(const std::string &path, std::string &filemd5) {
if (!IsFileExistent(path)) return SERVER_LICENSE_FILE_NOT_EXIST;
filemd5.clear();
std::ifstream file(path.c_str(), std::ifstream::binary);
if (!file) {
return -1;
}
MD5_CTX md5Context;
MD5_Init(&md5Context);
char buf[1024 * 16];
while (file.good()) {
file.read(buf, sizeof(buf));
MD5_Update(&md5Context, buf, file.gcount());
}
unsigned char result[MD5_DIGEST_LENGTH];
MD5_Final(result, &md5Context);
char hex[35];
memset(hex, 0, sizeof(hex));
for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
sprintf(hex + i * 2, "%02X", result[i]);
}
hex[32] = '\0';
filemd5 = std::string(hex);
return SERVER_SUCCESS;
}
// Part 4: GPU Info File Serialization/Deserialization
ServerError
LicenseLibrary::GPUinfoFileSerialization(const std::string &path,
int device_count,
const std::map<int, std::string> &uuid_encrption_map) {
std::ofstream file(path);
boost::archive::binary_oarchive oa(file);
oa.register_type<GPUInfoFile>();
SerializedGPUInfoFile serialized_gpu_info_file;
serialized_gpu_info_file.set_gpu_info_file(new GPUInfoFile(device_count, uuid_encrption_map));
oa << serialized_gpu_info_file;
file.close();
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GPUinfoFileDeserialization(const std::string &path,
int &device_count,
std::map<int, std::string> &uuid_encrption_map) {
if (!IsFileExistent(path)) return SERVER_LICENSE_FILE_NOT_EXIST;
std::ifstream file(path);
boost::archive::binary_iarchive ia(file);
ia.register_type<GPUInfoFile>();
SerializedGPUInfoFile serialized_gpu_info_file;
ia >> serialized_gpu_info_file;
device_count = serialized_gpu_info_file.get_gpu_info_file()->get_device_count();
uuid_encrption_map = serialized_gpu_info_file.get_gpu_info_file()->get_uuid_encryption_map();
file.close();
return SERVER_SUCCESS;
}
ServerError
LicenseLibrary::GetDateTime(char *cha, time_t &data_time) {
tm tm_;
int year, month, day;
sscanf(cha, "%d-%d-%d", &year, &month, &day);
tm_.tm_year = year - 1900;
tm_.tm_mon = month - 1;
tm_.tm_mday = day;
tm_.tm_hour = 0;
tm_.tm_min = 0;
tm_.tm_sec = 0;
tm_.tm_isdst = 0;
data_time = mktime(&tm_);
return SERVER_SUCCESS;
}
}
}
}
\ No newline at end of file
#pragma once
#include "LicenseFile.h"
#include "GPUInfoFile.h"
#include "utils/Error.h"
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <vector>
#include <map>
#include <time.h>
namespace zilliz {
namespace vecwise {
namespace server {
class LicenseLibrary {
public:
// Part 0: File check
static bool
IsFileExistent(const std::string &path);
// Part 1: Get GPU Info
static ServerError
GetDeviceCount(int &device_count);
static ServerError
GetUUID(int device_count, std::vector<std::string> &uuid_array);
static ServerError
GetUUIDMD5(int device_count, std::vector<std::string> &uuid_array, std::vector<std::string> &md5_array);
static ServerError
GetUUIDSHA256(const int &device_count,
std::vector<std::string> &uuid_array,
std::vector<std::string> &sha_array);
static ServerError
GetSystemTime(time_t &system_time);
// Part 2: Handle License File
static ServerError
LicenseFileSerialization(const std::string &path,
int device_count,
const std::map<int, std::string> &uuid_encrption_map,
time_t starting_time,
time_t end_time);
static ServerError
LicenseFileDeserialization(const std::string &path,
int &device_count,
std::map<int, std::string> &uuid_encrption_map,
time_t &starting_time,
time_t &end_time);
// static ServerError
// SecretFileSerialization(const std::string &path,
// const time_t &update_time,
// const off_t &file_size,
// const time_t &starting_time,
// const time_t &end_time,
// const std::string &file_md5);
//
// static ServerError
// SecretFileDeserialization(const std::string &path,
// time_t &update_time,
// off_t &file_size,
// time_t &starting_time,
// time_t &end_time,
// std::string &file_md5);
// Part 3: File attribute: UpdateTime Time/ Size/ MD5
static ServerError
GetFileUpdateTimeAndSize(const std::string &path, time_t &update_time, off_t &file_size);
static ServerError
GetFileMD5(const std::string &path, std::string &filemd5);
// Part 4: GPU Info File Serialization/Deserialization
static ServerError
GPUinfoFileSerialization(const std::string &path,
int device_count,
const std::map<int, std::string> &uuid_encrption_map);
static ServerError
GPUinfoFileDeserialization(const std::string &path,
int &device_count,
std::map<int, std::string> &uuid_encrption_map);
static ServerError
GetDateTime(char *cha, time_t &data_time);
private:
static constexpr int sha256_length_ = 32;
};
}
}
}
......@@ -9,7 +9,7 @@
#include "utils/Log.h"
#include "utils/SignalUtil.h"
#include "utils/TimeRecorder.h"
#include "license/License.h"
#include "license/LicenseCheck.h"
#include <fcntl.h>
#include <sys/stat.h>
......@@ -133,12 +133,6 @@ Server::Daemonize() {
int
Server::Start() {
std::string license_file_path = "/tmp/vecwise.license";
if(LicenseValidate(license_file_path) != SERVER_SUCCESS) {
SERVER_LOG_ERROR << "License check failed";
return 1;
}
if (daemonized_) {
Daemonize();
}
......@@ -157,6 +151,21 @@ Server::Start() {
//print config into console and log
config.PrintAll();
#ifdef ENABLE_LICENSE
ConfigNode license_config = config.GetConfig(CONFIG_LICENSE);
std::string license_file_path = license_config.GetValue(CONFIG_LICENSE_PATH);
SERVER_LOG_INFO << "License path: " << license_file_path;
if(server::LicenseCheck::LegalityCheck(license_file_path) != SERVER_SUCCESS) {
SERVER_LOG_ERROR << "License check failed";
exit(1);
}
if(server::LicenseCheck::StartCountingDown(license_file_path) != SERVER_SUCCESS) {
SERVER_LOG_ERROR << "License counter start error";
exit(1);
}
#endif
// Handle Signal
signal(SIGINT, SignalUtil::HandleSignal);
signal(SIGHUP, SignalUtil::HandleSignal);
......
......@@ -32,6 +32,9 @@ static const std::string CONFIG_CACHE = "cache_config";
static const std::string CONFIG_CPU_CACHE_CAPACITY = "cpu_cache_capacity";
static const std::string CONFIG_GPU_CACHE_CAPACITY = "gpu_cache_capacity";
static const std::string CONFIG_LICENSE = "license_config";
static const std::string CONFIG_LICENSE_PATH = "license_path";
class ServerConfig {
public:
static ServerConfig &GetInstance();
......
......@@ -34,6 +34,8 @@ constexpr ServerError SERVER_BLOCKING_QUEUE_EMPTY = ToGlobalServerErrorCode(0x00
constexpr ServerError SERVER_GROUP_NOT_EXIST = ToGlobalServerErrorCode(0x008);
constexpr ServerError SERVER_INVALID_TIME_RANGE = ToGlobalServerErrorCode(0x009);
constexpr ServerError SERVER_INVALID_VECTOR_DIMENSION = ToGlobalServerErrorCode(0x00a);
constexpr ServerError SERVER_LICENSE_VALIDATION_FAIL = ToGlobalServerErrorCode(0x00b);
constexpr ServerError SERVER_LICENSE_FILE_NOT_EXIST = ToGlobalServerErrorCode(0x00c);
class ServerException : public std::exception {
public:
......
......@@ -11,34 +11,37 @@ aux_source_directory(../../src/cache cache_srcs)
aux_source_directory(../../src/wrapper wrapper_src)
include_directories(/usr/local/cuda/include)
link_directories("/usr/local/cuda/lib64")
link_directories(/usr/local/cuda)
link_directories(/usr/local/cuda/lib64)
link_directories(/usr/lib/x86_64-linux-gnu)
link_directories(/usr/lib/nvidia-415)
link_directories(/usr/local/cuda/targets/x86_64-linux/lib/stubs/)
set(require_files
../../src/server/ServerConfig.cpp
../../src/utils/CommonUtil.cpp
../../src/utils/TimeRecorder.cpp
../../src/license/License.cpp
)
../../src/license/LicenseLibrary.cpp
../../src/license/LicenseCheck.cpp
)
set(db_test_src
${unittest_srcs}
${config_files}
${cache_srcs}
${db_srcs}
${wrapper_src}
${require_files}
license_tests.cpp)
license_library_tests.cpp
license_check_test.cpp
${require_files})
cuda_add_executable(license_test ${db_test_src})
set(db_libs
faiss
nvidia-ml
cudart
cublas
sqlite3
boost_system
boost_filesystem
lz4
crypto
boost_serialization
)
target_link_libraries(license_test ${unittest_libs} ${db_libs})
//
// Created by zilliz on 19-5-13.
//
#include "utils/Log.h"
#include "license/LicenseCheck.h"
#include "utils/Error.h"
#include <gtest/gtest.h>
#include <iostream>
using namespace zilliz::vecwise;
TEST(LicenseLibraryTest, CHECK_TEST) {
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc.license");
// 2. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
TEST(LicenseLibraryTest, CHECK_ERROR1_TEST){
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc");
// 2. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
TEST(LicenseLibraryTest, CHECK_ERROR2_TEST){
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc.license");
// 2. Define output var
int device_count;
std::map<int, std::string> uuid_encryption_map;
time_t starting_time;
time_t end_time;
// 3. Read License File
err = server::LicenseLibrary::LicenseFileDeserialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 4. Change device count
++device_count;
err = server::LicenseLibrary::LicenseFileSerialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 5. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
TEST(LicenseLibraryTest, CHECK_ERROR3_TEST){
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc.license");
// 2. Define output var
int device_count;
std::map<int, std::string> uuid_encryption_map;
time_t starting_time;
time_t end_time;
// 3. Read License File
err = server::LicenseLibrary::LicenseFileDeserialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 4. Change device count
if(device_count) uuid_encryption_map[0]+="u";
err = server::LicenseLibrary::LicenseFileSerialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 5. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
TEST(LicenseLibraryTest, CHECK_ERROR4_1_TEST){
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc.license");
// 2. Define output var
int device_count;
std::map<int, std::string> uuid_encryption_map;
time_t starting_time;
time_t end_time;
// 3. Read License File
err = server::LicenseLibrary::LicenseFileDeserialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 4. Change starting time
time_t system_time;
err = server::LicenseLibrary::GetSystemTime(system_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
system_time+=60*60*24;
err = server::LicenseLibrary::LicenseFileSerialization(license_file_path,
device_count,
uuid_encryption_map,
system_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 5. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
TEST(LicenseLibraryTest, CHECK_ERROR4_2_TEST){
server::ServerError err;
// 1. Set license file name
std::string license_file_path("/tmp/megasearch/abc.license");
// 2. Define output var
int device_count;
std::map<int, std::string> uuid_encryption_map;
time_t starting_time;
time_t end_time;
// 3. Read License File
err = server::LicenseLibrary::LicenseFileDeserialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 4. Change end time
time_t system_time;
err = server::LicenseLibrary::GetSystemTime(system_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
system_time-=100;
err = server::LicenseLibrary::LicenseFileSerialization(license_file_path,
device_count,
uuid_encryption_map,
starting_time,
system_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 5. Legality check
err = server::LicenseCheck::LegalityCheck(license_file_path);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
/*******************************************************************************
* Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited.
* Proprietary and confidential.
******************************************************************************/
#include "utils/Log.h"
#include "license/LicenseLibrary.h"
#include "utils/Error.h"
#include <gtest/gtest.h>
#include <iostream>
using namespace zilliz::vecwise;
TEST(LicenseLibraryTest, FILE_EXISTENT_TEST) {
std::string hosts_file = "/etc/hosts";
ASSERT_EQ(server::LicenseLibrary::IsFileExistent(hosts_file), true);
std::string no_exist_file = "/temp/asdaasd";
ASSERT_EQ(server::LicenseLibrary::IsFileExistent(no_exist_file), false);
std::string directory = "/tmp";
ASSERT_EQ(server::LicenseLibrary::IsFileExistent(directory), false);
}
TEST(LicenseLibraryTest, GPU_INFO_TEST) {
int device_count = 0;
server::ServerError err = server::LicenseLibrary::GetDeviceCount(device_count);
ASSERT_EQ(err, server::SERVER_SUCCESS);
std::cout << "Device Count: " << device_count << std::endl;
std::vector<std::string> uuid_array;
err = server::LicenseLibrary::GetUUID(device_count, uuid_array);
ASSERT_EQ(err, server::SERVER_SUCCESS);
for (long i = 0; i < device_count; ++i) {
std::cout << "Device Id: " << i << ", UUID: " << uuid_array[i] << std::endl;
}
std::vector<std::string> uuid_md5_array;
err = server::LicenseLibrary::GetUUIDMD5(device_count, uuid_array, uuid_md5_array);
ASSERT_EQ(err, server::SERVER_SUCCESS);
for (long i = 0; i < device_count; ++i) {
std::cout << "Device Id: " << i << ", UUID: " << uuid_array[i] << ", UUID_MD5: " << uuid_md5_array[i]
<< std::endl;
}
std::vector<std::string> uuid_sha256_array;
err = server::LicenseLibrary::GetUUIDSHA256(device_count, uuid_array, uuid_sha256_array);
ASSERT_EQ(err, server::SERVER_SUCCESS);
for (long i = 0; i < device_count; ++i) {
std::cout << "Device Id: " << i << ", UUID: " << uuid_array[i] << ", UUID_SHA256: "
<< uuid_sha256_array[i] << std::endl;
}
time_t systemtime;
err = server::LicenseLibrary::GetSystemTime(systemtime);
ASSERT_EQ(err, server::SERVER_SUCCESS);
std::cout << "System Time: " << systemtime << std::endl;
}
TEST(LicenseLibraryTest, LICENSE_FILE_TEST) {
// 0. File check
std::string test("/tmp/a.test");
bool is = server::LicenseLibrary::IsFileExistent(test);
ASSERT_EQ(is, false);
// 1. Get Device Count
int device_count = 0;
server::ServerError err = server::LicenseLibrary::GetDeviceCount(device_count);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 2. Get All GPU UUID
std::vector<std::string> uuid_array;
err = server::LicenseLibrary::GetUUID(device_count, uuid_array);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 3. Get UUID SHA256
std::vector<std::string> uuid_sha256_array;
err = server::LicenseLibrary::GetUUIDSHA256(device_count, uuid_array, uuid_sha256_array);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 4. Generate GPU ID map with GPU UUID
std::map<int, std::string> uuid_encrption_map;
for (int i = 0; i < device_count; ++i) {
uuid_encrption_map[i] = uuid_sha256_array[i];
}
// 5.GPU_info File
std::string GPU_info_file_path("/tmp/megasearch.info");
// 6. Generate GPU_info File
err = server::LicenseLibrary::GPUinfoFileSerialization(GPU_info_file_path,
device_count,
uuid_encrption_map);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 7. Define output var
int output_info_device_count = 0;
std::map<int, std::string> output_info_uuid_encrption_map;
// 8. Read GPU_info File
err = server::LicenseLibrary::GPUinfoFileDeserialization(GPU_info_file_path,
output_info_device_count,
output_info_uuid_encrption_map);
ASSERT_EQ(err, server::SERVER_SUCCESS);
ASSERT_EQ(device_count, output_info_device_count);
for (int i = 0; i < device_count; ++i) {
ASSERT_EQ(uuid_encrption_map[i], output_info_uuid_encrption_map[i]);
}
// 9. Set license file name
std::string license_file_path("/tmp/megasearch.license");
// 10. Get System Time/starting_time ans End Time
time_t sysyem_time;
err = server::LicenseLibrary::GetSystemTime(sysyem_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 11.GetDateTime
time_t starting_time;
time_t end_time;
char *string_starting_time = "2019-05-10";
char *string_end_time = "2022-05-10";
err = server::LicenseLibrary::GetDateTime(string_starting_time, starting_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
err = server::LicenseLibrary::GetDateTime(string_end_time, end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 12. Generate License File
err = server::LicenseLibrary::LicenseFileSerialization(license_file_path,
device_count,
uuid_encrption_map,
starting_time,
end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
// 13. Define output var
int output_device_count = 0;
std::map<int, std::string> output_uuid_encrption_map;
time_t output_starting_time;
time_t output_end_time;
// 14. Read License File
err = server::LicenseLibrary::LicenseFileDeserialization(license_file_path,
output_device_count,
output_uuid_encrption_map,
output_starting_time,
output_end_time);
ASSERT_EQ(err, server::SERVER_SUCCESS);
ASSERT_EQ(device_count, output_device_count);
ASSERT_EQ(starting_time, output_starting_time);
ASSERT_EQ(end_time, output_end_time);
for (int i = 0; i < device_count; ++i) {
ASSERT_EQ(uuid_encrption_map[i], output_uuid_encrption_map[i]);
}
// // 15. Get License File Attribute
// time_t update_time;
// off_t file_size;
// err = server::LicenseLibrary::GetFileUpdateTimeAndSize(license_file_path, update_time, file_size);
// ASSERT_EQ(err, server::SERVER_SUCCESS);
//
// // 16. Get License File MD5
// std::string file_md5;
// err = server::LicenseLibrary::GetFileMD5(license_file_path, file_md5);
// ASSERT_EQ(err, server::SERVER_SUCCESS);
// // 17. Generate Secret File
// std::string secret_file_path("/tmp/megasearch.secret");
// err = server::LicenseLibrary::SecretFileSerialization(secret_file_path,
// update_time,
// file_size,
// starting_time,
// end_time,
// file_md5);
// ASSERT_EQ(err, server::SERVER_SUCCESS);
// // 18. Define output var
// time_t output_update_time;
// off_t output_file_size;
// time_t output_starting_time;
// time_t output_end_time;
// std::string output_file_md5;
// // 19. Read License File
// err = server::LicenseLibrary::SecretFileDeserialization(secret_file_path,
// output_update_time,
// output_file_size,
// output_starting_time,
// output_end_time,
// output_file_md5);
// ASSERT_EQ(err, server::SERVER_SUCCESS);
//
// ASSERT_EQ(update_time, output_update_time);
// ASSERT_EQ(file_size, output_file_size);
// ASSERT_EQ(starting_time, output_starting_time);
// ASSERT_EQ(end_time, output_end_time);
// ASSERT_EQ(file_md5, output_file_md5);
}
////////////////////////////////////////////////////////////////////////////////
// Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited.
// Proprietary and confidential.
////////////////////////////////////////////////////////////////////////////////
#include <gtest/gtest.h>
#include "license/License.h"
#include "utils/Error.h"
using namespace zilliz::vecwise;
TEST(LicenseTest, LICENSE_TEST) {
std::string path1 = "/tmp/vecwise_engine.license";
server::ServerError err = server::LicenseValidate(path1);
ASSERT_EQ(err, server::SERVER_SUCCESS);
}
# 软件许可协议
### 前言
下载或使用本协议随附的软件前,请仔细阅读条款和条件(下称“协议”)。使用软件或点击“我接受 (I ACCEPT)”按钮或类似的按钮,即表示您同意仅在遵循本协议条款和条件的前提下使用软件。您保证您至少年满十八周岁,并且您拥有签署合同的法定能力。如果您代表任何公司、组织或其他实体签署本协议,则 (A) 本协议中所称“您”同时亦指该公司、组织或实体;并且 (B) 您声明并保证您拥有约束该公司、组织或实体接受本协议所规定条款和条件的授权。“贵方”和“客户”亦指您。
您对软件的使用明确以您接受本协议的条款和条件为前提。如果您不同意本协议的条款和条件,则不得安装或使用软件。
### 定义
“许可软件” 指的是仅以目标代码形式呈现的 Zilliz 专有软件程序和 Zilliz 依据本协议提供的软件更新。
“知识产权” 指依据任何司法管辖区法律产生的专利、版权、商业秘密、商标或任何种类或性质的其他类似知识产权,包括任何所谓的“道德权利”。
“软件更新” 指 Zilliz 依据支持和维护服务协议向其客户广泛提供的有关许可软件和第三方软件的新版本、漏洞修复或补丁或配置数据变更。
“服务” 指 Zilliz 依据本协议的条款向客户提供的服务,包括支持和专业服务,明确限于直接与客户对软件的使用有关的服务,且明确排除任何其他服务。
“许可期限” 指自生效日起,到软件许可日结束时为止。
“支持” 指 Zilliz 依据本协议条款,向用户提供有关软件的支持和维护服务,包括任何更新、不定、增强和漏洞修复。
“授权用户” 指在遵循本协议中限制的前提下,被授权代表您使用许可软件的贵方员工和顾问。
### 交付和支持
对于在线试用版许可证, Zilliz 将在客户履行注册和资格认证程序后,立即交付软件使用令牌并安排用户在合适的时间试用软件。
对于离线试用版许可证, Zilliz 将在客户履行注册和资格认证程序且提供安装系统硬件信息后,立即交付软件以及任何适用的许可证密钥。
### 许可
对于在线试用版许可证,在您履行本协议的前提下,Zilliz 向您授予有限、非排他性、不可转让的许可证(无再许可权),期限为 Zilliz 与您商定的其他期限,从向您提供许可软件的试用版之日起计算,您可凭此许可证您可以试用 Zilliz 为您提供的 MegaSearch 软件。您在任何时候都不得将许可软件用于任何业务的经营。您不得(并且亦不得允许任何第三方)将任何许可软件用于任何基准测试目的,或应用服务提供商目的、分时或服务部目的,或者任何除本协议所设想的贵方内部评估目的以外的任何目的。Zilliz 可能会自行酌定延长期限。在原期限以后继续使用许可软件,即表示您同意在新期限内继续遵循本协议的条款。
对于离线试用版许可证,在您履行本协议的前提下,Zilliz 向您授予有限、非排他性、不可转让的许可证(无再许可权),期限为 Zilliz 与您书面商定的其他期限,从向您提供许可软件的试用版之日起计算,您可凭此许可证在您拥有或控制的且与 Zilliz 协商后,指定的设备上安装和使用仅以目标代码形式呈现的许可软件,但仅限您在内部评估软件之用。您在任何时候都不得将许可软件用于任何业务的经营。您不得(并且亦不得允许任何第三方)将任何许可软件用于任何基准测试目的,或应用服务提供商目的、分时或服务部目的,或者任何除本协议所设想的贵方内部评估目的以外的任何目的。Zilliz 可能会自行酌定延长期限。在原期限以后继续使用许可软件,即表示您同意在新期限内继续遵循本协议的条款。
### 限制
您不得(并且亦不得允许或鼓励任何第三方)全部或部分复制、分发、编制衍生作品、公开展示或公开演示许可软件,或为任何第三方使用或向任何第三方提供许可软件,或代表任何第三方使用许可软件。除非且仅限在适用的法律或第三方许可证不允许此类限制的情况下,您不得(并且亦不得允许任何第三方):(a) 对许可软件或与许可软件有关的任何其他应用程序、软件、文档或数据,或其中任何部分进行反向工程、反编译、反汇编或企图通过其他方式发现源代码、目标代码或底层结构、理念或算法;(b) 干扰或绕过许可软件的任何功能,包括但不限于任何旨在监控您遵守本协议情况的许可证密钥;(c) 出让、出售、出租、许可、再许可或以其他方式转让或企图转让许可软件的权利;(d) 以不符合本协议以及所有适用法律法规(包括但不限于任何适用的隐私、数据保护和知识产权法律)的方式使用任何许可软件;或者 (e) 篡改或删除许可软件上或其中出现的任何版权、商标、专利或其他专有权利通告或标签。您必须在本协议终止或到期后卸载并删除许可软件。您接受许可软件可包含导致许可软件在期限结束时不能正常使用的自动终止功能。
### 所有权
Zilliz 自行(及其许可人(如有))保留与许可软件有关的所有知识产权。许可软件的所有增强、衍生作品和修改,以及您或任何第三方提供的与许可软件有关的任何建议、理念、增强请求、反馈、推荐或其他信息,包括其中所有知识产权,均转让给 Zilliz。您保留您用于许可软件的所有您的保密信息和数据的所有权,并且除依据本协议提供服务这一唯一目的而使用数据外,您的保密信息或数据(下称“您的数据”)的权利并未转移或转让给 Zilliz。许可软件仅被许可,本协议的任何内容均不得解释或阐释为转让或出售 Zilliz 对许可软件的所有权。任何一方均不得质疑对方的知识产权。您不得质疑或造成第三方质疑 Zilliz 知识产权的有效性或强制性。
### 保密
##### 保密信息
指一方披露给另一方(“接收方”)且任何一方都将合理预期或认为属于保密或专有信息的,该方拥有权利的任何保密或专有知识、信息、材料或商业秘密,包括但不限于以各种介质形式呈现(包括但不限于口头、书面和电子数据形式)的与业务方法、产品、服务、财务、客户和潜在客户、供应商、定价和费率、成本、费用、营销、技术、财产、规范、人员或组织有关的信息。Zilliz 的保密信息包括所有许可软件、文档以及与之有关的任何其他技术信息。
##### 保密
各接收方:(i) 应对对方(“披露方”)披露的所有保密信息严格保密;(ii) 除因本协议而需要知晓该信息并且受严格程度不低于本协议条款的书面保密义务约束的接收方人员外,未经披露方书面同意不得向任何第三方披露、传播、分发或传输此类保密信息; (iii) 除为了履行其在本协议下的义务的唯一目的外,不得使用该保密信息;并且 (iv) 应当至少以接收方保护类似性质的自有保密信息所采取的相同注意程度保护保密信息,以防止对该保密信息的未经授权的访问、使用、传播或发布,但在任何情况下都不得低于合理的注意程度。接收方如获知该保密信息被未经授权访问、使用、传播或发布,应立即书面通知披露方。
##### 强制披露
在事先书面通知披露方(在法律允许的范围内)后,接收方可以在以下范围内披露披露方的保密信息:(i) 应法律法规要求予以披露;(ii) 应法院或其他政府机构裁定要求予以披露。接收方同意协助披露方(由披露方承担费用)采取一切正当的手段,以限制或阻止披露该保密信息,以及取得对所披露的任何信息的保密待遇。
##### 材料的归还
本协议终止或到期时,或者披露方提前提出书面请求时,接收方将立即(根据披露方的选择)归还或销毁其持有、保管或控制的从披露方收到的所有保密信息(包括所有副本)。应披露方请求,在归还或销毁后,接收方应以书面形式证明已经完成归还或销毁。
##### 例外
保密信息不包含接收方有书面证据证明属于下列任何情况的信息:(i) 接收方已经知晓或后来从第三方收到且不存在保密限制的;或者 (ii) 已经公开或非因接收方过错行为而被公开的。
##### 隐私政策
您自行负责发布并维护一份充分提供所有声明的隐私政策,并取得与使用许可软件以及其他方式相关的收集、使用和披露数据的所有同意,并且将赔偿并使 Zilliz 免受因违反前述条款而导致或引发的损害。您在本协议下不会向 Zilliz 提供任何个人身份识别信息。您对您的数据负责,并且您有义务备份您的所有数据,以防止在使用许可软件之前、期间和之后发生丢失。Zilliz 不对您的数据丢失负责。
### 期限与终止
##### 期限
本协议从向您提供许可软件之日起,至期限终止之间持续有效。
##### 终止
Zilliz 可以随时自行酌定向您发出通知后终止本协议。
### 您的责任
您自行负责您的数据的开发、内容、操作、维护和使用。例如,您自行负责下列方面:
- 您的数据的技术操作,包括确保您对任何服务的调用兼容该服务当时使用的 API。
- 您的数据对第三方可接受使用政策和法律的遵守。
- 与您的数据有关任何索赔。
- 正确受理和处理任何主张您的数据违反其权利的人向您(或您的任何关联人)发出的通知,包括依据《数字千年版权法》发出的通知。
您负责恰当配置和使用许可软件,自行采取措施维护您的数据的恰当安全性、保护和备份。此类措施可能包括使用加密技术来保护您的数据以防止未经授权的访问,以及定期存档您的数据。
默认情况下,许可软件在提供时将没有主机或网络,这意味着您必须选择要安装软件的主机和网络,并且您自行负责恰当管理、限制和监控相关访问权限和访问控制。
许可软件生成的登录凭据和私有密钥仅供您指定的主机使用,您不得向任何其他实体或个人出售、转让或再许可,您不得在任何除了您指定主机外的主机上使用该秘钥。
您承认您应当为您的数据实施恰当的保护机制。
\ No newline at end of file
# 隐私政策
我们重视保护您的私人信息。本隐私声明适用于 Zilliz (上海赜睿信息科技有限公司)拥有和经营的任何网站和产品对数据的收集和使用。使用 Zilliz 的网站和产品即表示您同意本声明所述的数据实践。
### 个人信息的收集
Zilliz 可能会收集您的个人身份识别信息,例如:
- 姓名
- 地址
- 电子邮件地址
- 电话号码
- IP 地址
- 您访问网站的日期和时间
请注意,如果您直接通过 Zilliz 的公开消息平台披露个人身份识别信息或个人敏感数据,此信息可能会被其他人收集和使用。
Zilliz 建议您查阅从 Zilliz 链接的网站的隐私声明,以了解这些网站如何收集、使用和共享您的信息。 Zilliz 不对除 Zilliz 以外其他公司或网站的隐私声明或其他内容负责。
### 个人信息的使用
为运营其网站和交付您请求的服务, Zilliz 收集和使用您的个人信息。
Zilliz 可能使用您的身份识别信息来为您介绍 Zilliz 及其关联公司提供的其他产品或服务。此外,Zilliz还可能邀请您参加调查,以了解您对当前服务或可能提供的新服务的意见。
Zilliz 不会将您的信息出售、出租或出赁给第三方。
Zilliz 可能会与受信任的合作伙伴共享您的信息,以帮助执行统计分析、向您发送电子邮件或寄送信件、提供客户支持或安排交付。除向 Zilliz 提供上述服务之外,所有此类第三方均不得出于其他目的使用您的个人信息,且必须维护您信息的机密性。
Zilliz 可能会跟踪用户在 Zilliz 访问的网站和网页,以确定最受欢迎的 Zilliz 服务。此数据用于在 Zilliz 根据客户行为所揭示的客户特定兴趣领域来为其提供定制内容和广告。
Zilliz 将在不通知您的情况下披露您的个人信息,但仅限于依据法律要求或有充分理由相信披露信息是以下情况所必要:(a) 遵循法令或遵循适用于 Zilliz 或网站的法律程序;(b) 维护和保护 Zilliz 的权利或财产;以及 (c) 在紧急情况下保护 Zilliz 用户或公众的人身安全。
### 自动收集的信息
Zilliz 可能会自动收集您计算机硬件和软件的相关信息。此信息可能包括:IP 地址、浏览器类型、域名、访问时间以及进站前链接网站的地址。此信息用于运营服务、维护服务质量以及提供关于 Zilliz 网站使用情况的一般统计信息。
### COOKIE 的使用
Zilliz 网站可能会使用“Cookie”来帮助您个性化自己的在线体验。Cookie 是网页服务器放置在您硬盘上的一个文本文件。Cookie 不能用于运行程序或向您的计算机发送病毒。分配给您的 Cookie 是唯一的,只能由向您发布 Cookie 的域中的 Web 服务器阅读。
使用 Cookie 的主要目的之一是提供方便的功能,为您节约时间。使用 Cookie 的目的是告诉 Web 服务器您回到了某个特定的页面。例如,如果您个性化了 Zilliz 页面,或者注册了 Zilliz 网站或服务,Cookie 可帮助 Zilliz 在您再次访问时重新调用您的具体信息。这可以简化您输入个人信息的过程,例如账单地址、收货地址等等。当您再次访问相同的 Zilliz 网站时,可检索您以前提供的信息,以便您轻松使用您自定义的 Zilliz 功能。您可以接受或拒绝 Cookie。大多数 Web 浏览器会自动接受 Cookie,但您通常可以通过修改浏览器设置来拒绝 Cookie。如果您选择拒绝 Cookie,您可能无法真正体验您所访问 Zilliz 服务或网站的交互功能。
### 儿童
Zilliz 不会在知情的情况下收集十三岁以下儿童的个人身份识别信息。如果您未满十三周岁,您必须取得您父母或监护人的允许方可使用本网站。
### 对本声明的修订
Zilliz 将不时根据公司和客户的反馈更新本隐私声明。Zilliz 建议您定期查阅本声明,或通过如下地址申请本政策的副本,从而了解 Zilliz 如何保护您的信息。
#### 联系信息
Zilliz 欢迎您就本隐私声明提出问题或意见。如果您认为 Zilliz 未遵守本声明,或者需要请求修改 Zilliz 持有的您的个人身份识别信息,或者需要行使有关我们如何收集和处理您的个人身份识别信息的选择权,请通过以下方式联系 Zilliz:
Zilliz
上海徐汇区桂箐路69号桂箐园28栋6C
电子邮件地址:info@zilliz.com
我们将依据相关数据隐私法律的规定,在系统能力范围内,尽商业上合理的努力响应请求。
2019 年 5 月 15 日生效
\ No newline at end of file
# MegaSearch SLA
### 1. 引言
本 MegaSearch 服务级别协议(以下简称“服务级别协议”)由 Zilliz 制定。如果我们未能达到和保持本服务级别协议中说明的每种服务的服务级别,则您有资格获得月度服务费用的部分服务费抵扣。在您的协议期间,这些条款都不会做任何变动。如果续展订购,则在续订期限开始时实行的本服务级别协议的版本将适用于整个续订期限。如果对本服务级别协议有任何重大不利变更,我们应至少提前九十(90)天进行通知。
### 2. 服务内容
MegaSearch 服务基于强大的GPU芯片和大规模并行算法,提供针对特征向量和多维度数据的联合查询。用户可以通过调用 MegaSearch 提供的API或者SDK将 MegaSearch 无缝对接到自己的AI预测业务上。
### 3. 定义
3.1 “服务” 指的是 Zilliz 根据本协议向开发者提供的付费服务(未付费情况,不适用于本协议)
3.2 “索赔” 指客户根据本服务级别协议向Zilliz提交的、有关尚未达到某个服务级别以及客户可获得的服务费抵扣的索赔。
3.3 “客户” 指签订本协议的机构。
3.4 “客户支持” 指 Zilliz 可由此为客户提供帮助以解决服务问题的服务。
3.5 “错误代码”用于指示某项操作出现了问题,例如,5xx 范围内的 HTTP 状态代码。
3.6 “事件” 表示导致无法达到服务级别的任何情况。
3.7 “管理界面” 指由 Zilliz 提供的 web 界面,客户可以通过该界面来管理 MegaSearch 服务。
3.8 “预览版” 指提供用来获得客户反馈的服务或软件的预览版、测试版或其他预发行版。
3.9 “服务费抵扣” 表示针对受影响的服务已经证实的服务索赔,返还给客户的月度服务费用的百分比。
3.10 “服务级别”指定世纪互联选择遵守并据此衡量其所提供的每种服务的服务级别的标准,具体如下所述。
3.11 “服务资源”指某个服务内可供使用的单独资源。
3.12 “成功代码”用于指示某项操作已经成功,例如,2xx 范围内的 HTTP 状态代码。
3.13 “支持时段”指支持某个服务功能或者支持与某个单独产品或服务兼容的时间范围。
### 4. 服务赔偿
#### 4.1 赔偿范围
因 MegaSearch 设计缺陷导致用户所购买的服务无法正常使用,Zilliz 将对不可用时间进行赔偿,但不包括以下原因所导致的服务不可用时间:
4.1.1 Zilliz 预先通知用户后进行系统维护所引起的,包括割接、维修、升级和模拟故障演练。
4.1.2 用户的应用程序或数据信息受到黑客攻击而引起的。
4.1.3 用户维护不当或保密不当致使数据、口令、密码等丢失或泄漏所引起的。
4.1.4 用户的疏忽或由用户授权的操作所引起的。
4.1.5 不可抗力以及意外事件引起的。
4.1.6 其他非 Zilliz 原因所造成的不可用。
#### 4.2 服务费抵扣
4.2.1 针对所描述的每一种服务,下文介绍了服务费抵扣的金额和计算方法。
4.2.2 服务费抵扣是客户针对未能达到任何服务级别的唯一且排他性的救济。
4.2.3 在任何情况下,任何帐单月份内提供的与特定服务或服务资源相关的服务费抵扣都不得超过客户在该帐单月份内用于该服务或服务资源(如果有)的月度服务费用。
#### 4.3 赔偿方案
4.3.1 “最大可用分钟数” 是指在一个帐单月份期间,用户可用 MegaSearch 的总分钟数。
4.3.2 “停机时间” 是指在一个账单月份期间,MegaSearch 的总累计分钟数。当在某一分钟内,客户所有试图与 MegaSearch 建立连接的连续尝试均失败,则将会视该分钟内该数据库不可用。
4.3.4 每月正常服务时间百分比计算公式: 每月正常服务时间百分比 % = (最大可用分钟数 − 停机时间) ÷ 最大可用分钟数
4.3.5 以下服务级别和服务费抵扣适用于客户对 MegaSearch 服务的使用:
| 每月正常服务时间百分比 | 服务费抵扣 |
| ---- | ---- |
| <99.9% | 10% |
| <99% | 25% |
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册