mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +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
|
about: File bug to improve SRS
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: 'winlinvip'
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
> 注意:不提供以下信息的Issue会被直接删除(Please follow issue template, or we will delete it)
|
> 注意:提问前,请先看FAQ(Please read FAQ before file an issue) https://github.com/ossrs/srs/issues/2716
|
||||||
|
|
||||||
> 注意:咨询和讨论请提交到SRS星球(Please ask question at) http://bbs.ossrs.net
|
|
||||||
|
|
||||||
**描述(Description)**
|
**描述(Description)**
|
||||||
|
|
||||||
> 描述你遇到了什么问题(Please description your issue here)
|
> 描述你遇到了什么问题(Please description your issue here)
|
||||||
|
|
||||||
1. SRS版本(Version): `xxxxxx`
|
1. SRS版本(Version): `xxxxxx`
|
||||||
|
|
||||||
1. SRS的日志如下(Log):
|
1. SRS的日志如下(Log):
|
||||||
```
|
```
|
||||||
|
|
||||||
xxxxxxxxxxxx
|
xxxxxxxxxxxx
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
1. SRS的配置如下(Config):
|
1. SRS的配置如下(Config):
|
||||||
```
|
```
|
||||||
|
|
||||||
xxxxxxxxxxxx
|
xxxxxxxxxxxx
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**重现(Replay)**
|
**重现(Replay)**
|
||||||
|
|
|
@ -30,6 +30,8 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 4.0 Changelog
|
## 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-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-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
|
* 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 if has any argv
|
||||||
show_help = true;
|
show_help = argc > 1;
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if ((err = parse_argv(i, argv)) != srs_success) {
|
if ((err = parse_argv(i, argv)) != srs_success) {
|
||||||
return srs_error_wrap(err, "parse argv");
|
return srs_error_wrap(err, "parse argv");
|
||||||
|
@ -1980,21 +1980,45 @@ srs_error_t SrsConfig::parse_options(int argc, char** argv)
|
||||||
|
|
||||||
// first hello message.
|
// first hello message.
|
||||||
srs_trace(_srs_version);
|
srs_trace(_srs_version);
|
||||||
|
|
||||||
if (config_file.empty()) {
|
// Try config files as bellow:
|
||||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "no config, read help: %s -h", argv[0]);
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For docker, if config is not specified, try srs.conf instead.
|
// Parse the matched config file.
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parse_file(config_file.c_str());
|
err = parse_file(config_file.c_str());
|
||||||
|
|
||||||
if (test_conf) {
|
if (test_conf) {
|
||||||
|
@ -3567,8 +3591,8 @@ int SrsConfig::get_rtc_server_reuseport()
|
||||||
|
|
||||||
#if !defined(SO_REUSEPORT)
|
#if !defined(SO_REUSEPORT)
|
||||||
if (v > 1) {
|
if (v > 1) {
|
||||||
srs_warn("REUSEPORT not supported, reset %d to %d", reuseport, DEFAULT);
|
srs_warn("REUSEPORT not supported, reset to 1");
|
||||||
v = 1
|
v = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 4
|
#define VERSION_MAJOR 4
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 192
|
#define VERSION_REVISION 194
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,28 +69,19 @@ class MockTcpHandler : public ISrsTcpHandler
|
||||||
private:
|
private:
|
||||||
srs_netfd_t fd;
|
srs_netfd_t fd;
|
||||||
public:
|
public:
|
||||||
MockTcpHandler();
|
MockTcpHandler() {
|
||||||
virtual ~MockTcpHandler();
|
fd = NULL;
|
||||||
|
}
|
||||||
|
virtual ~MockTcpHandler() {
|
||||||
|
srs_close_stfd(fd);
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
virtual srs_error_t on_tcp_client(srs_netfd_t stfd) {
|
||||||
|
fd = stfd;
|
||||||
|
return srs_success;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MockTcpHandler::MockTcpHandler()
|
|
||||||
{
|
|
||||||
fd = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
MockTcpHandler::~MockTcpHandler()
|
|
||||||
{
|
|
||||||
srs_close_stfd(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockTcpHandler::on_tcp_client(srs_netfd_t stfd)
|
|
||||||
{
|
|
||||||
fd = stfd;
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(TCPServerTest, PingPong)
|
VOID TEST(TCPServerTest, PingPong)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
@ -1459,7 +1450,7 @@ public:
|
||||||
int r0;
|
int r0;
|
||||||
int r1;
|
int r1;
|
||||||
SrsFastCoroutine trd;
|
SrsFastCoroutine trd;
|
||||||
MockStopSelfThread() : trd("mock", this), r0(0), r1(0) {
|
MockStopSelfThread() : r0(0), r1(0), trd("mock", this) {
|
||||||
}
|
}
|
||||||
virtual ~MockStopSelfThread() {
|
virtual ~MockStopSelfThread() {
|
||||||
}
|
}
|
||||||
|
@ -1476,12 +1467,88 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VOID TEST(StopSelfThreadTest, ShouldFailWhenStopSelf)
|
VOID TEST(ThreadCriticalTest, ShouldFailWhenStopSelf)
|
||||||
{
|
{
|
||||||
|
srs_error_t err;
|
||||||
MockStopSelfThread trd;
|
MockStopSelfThread trd;
|
||||||
trd.start();
|
HELPER_EXPECT_SUCCESS(trd.start());
|
||||||
|
|
||||||
|
// Switch to thread cycle, should fail.
|
||||||
srs_usleep(0);
|
srs_usleep(0);
|
||||||
EXPECT_EQ(-1, trd.r0);
|
EXPECT_EQ(-1, trd.r0);
|
||||||
EXPECT_EQ(EDEADLK, trd.r1);
|
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…
Add table
Add a link
Reference in a new issue