mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
Squash: Guess config files by FHS
This commit is contained in:
parent
3974b319d1
commit
6cde9a0230
5 changed files with 141 additions and 44 deletions
12
.github/ISSUE_TEMPLATE
vendored
12
.github/ISSUE_TEMPLATE
vendored
|
@ -3,26 +3,30 @@ name: File bug
|
|||
about: File bug to improve SRS
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
assignees: 'winlinvip'
|
||||
|
||||
---
|
||||
|
||||
> 注意:不提供以下信息的Issue会被直接删除(Please follow issue template, or we will delete it)
|
||||
|
||||
> 注意:咨询和讨论请提交到SRS星球(Please ask question at) http://bbs.ossrs.net
|
||||
> 注意:提问前,请先看FAQ(Please read FAQ before file an issue) https://github.com/ossrs/srs/issues/2716
|
||||
|
||||
**描述(Description)**
|
||||
|
||||
> 描述你遇到了什么问题(Please description your issue here)
|
||||
|
||||
1. SRS版本(Version): `xxxxxx`
|
||||
|
||||
1. SRS的日志如下(Log):
|
||||
```
|
||||
|
||||
xxxxxxxxxxxx
|
||||
|
||||
```
|
||||
|
||||
1. SRS的配置如下(Config):
|
||||
```
|
||||
|
||||
xxxxxxxxxxxx
|
||||
|
||||
```
|
||||
|
||||
**重现(Replay)**
|
||||
|
|
|
@ -30,6 +30,8 @@ The changelog for SRS.
|
|||
|
||||
## SRS 4.0 Changelog
|
||||
|
||||
* v4.0, 2021-11-07, Merge [#2711](https://github.com/ossrs/srs/pull/2711): Config: Guess config files by [FHS](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard). v4.0.194
|
||||
* v4.0, 2021-11-07, Merge [#2714](https://github.com/ossrs/srs/pull/2714): DVR: copy req from publish. v4.0.193
|
||||
* v4.0, 2021-11-04, Merge [#2707](https://github.com/ossrs/srs/pull/2707): Refuse edge request when state is stopping. v4.0.192
|
||||
* v4.0, 2021-11-02, Auto create package by github actions. v4.0.191
|
||||
* v4.0, 2021-10-30, Merge [#2552](https://github.com/ossrs/srs/pull/2552): Script: Refine CentOS7 service script to restart SRS. v4.0.190
|
||||
|
|
|
@ -1956,8 +1956,8 @@ srs_error_t SrsConfig::parse_options(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
// config
|
||||
show_help = true;
|
||||
// Show help if has any argv
|
||||
show_help = argc > 1;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if ((err = parse_argv(i, argv)) != srs_success) {
|
||||
return srs_error_wrap(err, "parse argv");
|
||||
|
@ -1981,20 +1981,44 @@ srs_error_t SrsConfig::parse_options(int argc, char** argv)
|
|||
// first hello message.
|
||||
srs_trace(_srs_version);
|
||||
|
||||
if (config_file.empty()) {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "no config, read help: %s -h", argv[0]);
|
||||
// Try config files as bellow:
|
||||
// config_file Specified by user, like conf/srs.conf
|
||||
// try_docker_config Guess by SRS, like conf/docker.conf
|
||||
// try_fhs_config For FHS, try /etc/srs/srs.conf first, @see https://github.com/ossrs/srs/pull/2711
|
||||
if (!srs_path_exists(config_file)) {
|
||||
vector<string> try_config_files;
|
||||
if (!config_file.empty()) {
|
||||
try_config_files.push_back(config_file);
|
||||
if (srs_string_ends_with(config_file, "docker.conf")) {
|
||||
try_config_files.push_back(srs_string_replace(config_file, "docker.conf", "srs.conf"));
|
||||
}
|
||||
}
|
||||
try_config_files.push_back(SRS_CONF_DEFAULT_COFNIG_FILE);
|
||||
if (srs_string_ends_with(SRS_CONF_DEFAULT_COFNIG_FILE, "docker.conf")) {
|
||||
try_config_files.push_back(srs_string_replace(SRS_CONF_DEFAULT_COFNIG_FILE, "docker.conf", "srs.conf"));
|
||||
}
|
||||
try_config_files.push_back("/etc/srs/srs.conf");
|
||||
|
||||
string exists_config_file;
|
||||
for (int i = 0; i < (int) try_config_files.size(); i++) {
|
||||
string try_config_file = try_config_files.at(i);
|
||||
if (srs_path_exists(try_config_file)) {
|
||||
exists_config_file = try_config_file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// For docker, if config is not specified, try srs.conf instead.
|
||||
string try_config = srs_string_replace(config_file, "docker.conf", "srs.conf");
|
||||
if (!srs_path_exists(config_file) && try_config != config_file) {
|
||||
if (!srs_path_exists(try_config)) {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "no config file %s or %s", config_file.c_str(), try_config.c_str());
|
||||
}
|
||||
srs_warn("user config %s does not exists, use %s instead", config_file.c_str(), try_config.c_str());
|
||||
config_file = try_config;
|
||||
if (exists_config_file.empty()) {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "no config file at %s", srs_join_vector_string(try_config_files, ", ").c_str());
|
||||
}
|
||||
|
||||
if (config_file != exists_config_file) {
|
||||
srs_warn("user config %s does not exists, use %s instead", config_file.c_str(), exists_config_file.c_str());
|
||||
config_file = exists_config_file;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the matched config file.
|
||||
err = parse_file(config_file.c_str());
|
||||
|
||||
if (test_conf) {
|
||||
|
@ -3567,8 +3591,8 @@ int SrsConfig::get_rtc_server_reuseport()
|
|||
|
||||
#if !defined(SO_REUSEPORT)
|
||||
if (v > 1) {
|
||||
srs_warn("REUSEPORT not supported, reset %d to %d", reuseport, DEFAULT);
|
||||
v = 1
|
||||
srs_warn("REUSEPORT not supported, reset to 1");
|
||||
v = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 192
|
||||
#define VERSION_REVISION 194
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,27 +69,18 @@ class MockTcpHandler : public ISrsTcpHandler
|
|||
private:
|
||||
srs_netfd_t fd;
|
||||
public:
|
||||
MockTcpHandler();
|
||||
virtual ~MockTcpHandler();
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
};
|
||||
|
||||
MockTcpHandler::MockTcpHandler()
|
||||
{
|
||||
MockTcpHandler() {
|
||||
fd = NULL;
|
||||
}
|
||||
|
||||
MockTcpHandler::~MockTcpHandler()
|
||||
{
|
||||
virtual ~MockTcpHandler() {
|
||||
srs_close_stfd(fd);
|
||||
}
|
||||
|
||||
srs_error_t MockTcpHandler::on_tcp_client(srs_netfd_t stfd)
|
||||
{
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd) {
|
||||
fd = stfd;
|
||||
return srs_success;
|
||||
}
|
||||
};
|
||||
|
||||
VOID TEST(TCPServerTest, PingPong)
|
||||
{
|
||||
|
@ -1459,7 +1450,7 @@ public:
|
|||
int r0;
|
||||
int r1;
|
||||
SrsFastCoroutine trd;
|
||||
MockStopSelfThread() : trd("mock", this), r0(0), r1(0) {
|
||||
MockStopSelfThread() : r0(0), r1(0), trd("mock", this) {
|
||||
}
|
||||
virtual ~MockStopSelfThread() {
|
||||
}
|
||||
|
@ -1476,12 +1467,88 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VOID TEST(StopSelfThreadTest, ShouldFailWhenStopSelf)
|
||||
VOID TEST(ThreadCriticalTest, ShouldFailWhenStopSelf)
|
||||
{
|
||||
srs_error_t err;
|
||||
MockStopSelfThread trd;
|
||||
trd.start();
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Switch to thread cycle, should fail.
|
||||
srs_usleep(0);
|
||||
EXPECT_EQ(-1, trd.r0);
|
||||
EXPECT_EQ(EDEADLK, trd.r1);
|
||||
}
|
||||
|
||||
class MockAsyncReaderThread : public ISrsCoroutineHandler
|
||||
{
|
||||
public:
|
||||
SrsFastCoroutine trd;
|
||||
srs_netfd_t fd;
|
||||
MockAsyncReaderThread(srs_netfd_t v) : trd("mock", this), fd(v) {
|
||||
}
|
||||
virtual ~MockAsyncReaderThread() {
|
||||
}
|
||||
srs_error_t start() {
|
||||
return trd.start();
|
||||
}
|
||||
void stop() {
|
||||
trd.stop();
|
||||
}
|
||||
virtual srs_error_t cycle() {
|
||||
srs_error_t err = srs_success;
|
||||
while (true) {
|
||||
if ((err = trd.pull()) != srs_success) {
|
||||
return err;
|
||||
}
|
||||
char buf[16] = {0};
|
||||
if (st_read((st_netfd_t)fd, buf, sizeof(buf), SRS_UTIME_NO_TIMEOUT) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
MockTcpHandler h;
|
||||
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
||||
HELPER_EXPECT_SUCCESS(l.listen());
|
||||
|
||||
SrsTcpClient c0(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||
HELPER_EXPECT_SUCCESS(c0.connect());
|
||||
|
||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_TRUE(h.fd != NULL);
|
||||
|
||||
MockAsyncReaderThread trd0(h.fd);
|
||||
HELPER_EXPECT_SUCCESS(trd0.start());
|
||||
|
||||
MockAsyncReaderThread trd1(h.fd);
|
||||
HELPER_EXPECT_SUCCESS(trd1.start());
|
||||
|
||||
// Wait for all threads to run.
|
||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
||||
|
||||
// Should fail when close, because there is 2 threads reading fd.
|
||||
int r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(-1, r0);
|
||||
EXPECT_EQ(EBUSY, errno);
|
||||
|
||||
// Stop thread1, still fail because thread0 is reading fd.
|
||||
trd1.stop();
|
||||
r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(-1, r0);
|
||||
EXPECT_EQ(EBUSY, errno);
|
||||
|
||||
// Stop thread0, should success, no threads is reading fd.
|
||||
trd0.stop();
|
||||
r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(0, r0);
|
||||
|
||||
// Set fd to NULL to avoid close fail for EBADF.
|
||||
h.fd = NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue