Prevent running multiple hpcore instances from the same directory (#207)

This commit is contained in:
Chalith Desaman
2021-01-05 11:18:23 +05:30
committed by GitHub
parent 99e4296746
commit e8a3882176
5 changed files with 106 additions and 3 deletions

View File

@@ -24,6 +24,8 @@ namespace conf
const static char *PATCH_FILE_NAME = "patch.cfg"; // Config patch filename.
bool init_success = false;
/**
* Loads and initializes the contract config for execution. Must be called once during application startup.
* @return 0 for success. -1 for failure.
@@ -35,23 +37,42 @@ namespace conf
// 2. Read and load the contract config into memory
// 3. Update contract config if patch file exists.
// 4. Validate the loaded config values
// 5. Locking the config file at the startup.
if (validate_contract_dir_paths() == -1 ||
read_config(cfg) == -1 ||
apply_patch_changes(cfg.contract) == -1 ||
validate_config(cfg) == -1)
validate_config(cfg) == -1 ||
set_config_lock() == -1)
{
return -1;
}
init_success = true;
return 0;
}
/**
* Cleanup any resources.
*/
void deinit()
{
if (init_success)
{
// Releases the config file lock at the termination.
release_config_lock();
}
}
/**
* Generates and saves new signing keys in the contract config.
*/
int rekey()
{
// Locking the config file at the startup. To check whether there's any already running hp instances.
if (set_config_lock() == -1)
return -1;
// Load the contract config and re-save with the newly generated keys.
contract_config cfg = {};
if (read_config(cfg) != 0)
@@ -66,6 +87,9 @@ namespace conf
std::cout << "New signing keys generated at " << ctx.config_file << std::endl;
// Releases the config file lock at the termination.
release_config_lock();
return 0;
}
@@ -874,4 +898,41 @@ namespace conf
}
return 0;
}
/**
* Locks the config file. If already locked means there's another hpcore instance running in the same directory.
* If so, log error and return, Otherwise lock the config.
* @return Returns 0 if lock is successfully aquired, -1 on error.
*/
int set_config_lock()
{
ctx.config_fd = open(ctx.config_file.data(), O_RDWR, 444);
if (ctx.config_fd == -1)
return -1;
if (util::set_lock(ctx.config_fd, ctx.config_lock, true, 0, 0) == -1)
{
if (errno == EACCES || errno == EAGAIN)
{
std::cerr << "Another hpcore instance is already running in directory " << ctx.contract_dir << "\n";
}
// Close fd if lock aquiring failed.
close(ctx.config_fd);
return -1;
}
return 0;
}
/**
* Releses the config file and closes the opened file descriptor.
* @return Returns 0 if lock is successfully aquired, -1 on error.
*/
int release_config_lock()
{
const int res = util::release_lock(ctx.config_fd, ctx.config_lock);
// Close fd in termination.
close(ctx.config_fd);
return res;
}
} // namespace conf