diff --git a/README.md b/README.md index ce2cd0120..844625701 100755 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ For previous versions, please read: ## V3 changes -* v3.0, 2020-03-12, For [#1635][bug #1635], inotify watch ConfigMap for reload. 3.0.130 +* v3.0, 2020-03-12, For [#1635][bug #1635], inotify watch ConfigMap for reload. 3.0.131 * v3.0, 2020-03-12, For [#1635][bug #1635], support auto reaload config by inotify. 3.0.129 * v3.0, 2020-03-12, For [#1630][bug #1630], disable cache for stream changing, and drop dup header. 3.0.128 * v3.0, 2020-03-12, For [#1594][bug #1594], detect and disable daemon for docker. 3.0.127 diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 19cd88174..df1ed4436 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -505,7 +505,56 @@ srs_error_t SrsInotifyWorker::start() return srs_error_new(ERROR_INOTIFY_OPENFD, "closeexec fd=%d", fd); } - srs_trace("auto reload watching fd=%d", fd); + // /* the following are legal, implemented events that user-space can watch for */ + // #define IN_ACCESS 0x00000001 /* File was accessed */ + // #define IN_MODIFY 0x00000002 /* File was modified */ + // #define IN_ATTRIB 0x00000004 /* Metadata changed */ + // #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ + // #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ + // #define IN_OPEN 0x00000020 /* File was opened */ + // #define IN_MOVED_FROM 0x00000040 /* File was moved from X */ + // #define IN_MOVED_TO 0x00000080 /* File was moved to Y */ + // #define IN_CREATE 0x00000100 /* Subfile was created */ + // #define IN_DELETE 0x00000200 /* Subfile was deleted */ + // #define IN_DELETE_SELF 0x00000400 /* Self was deleted */ + // #define IN_MOVE_SELF 0x00000800 /* Self was moved */ + // + // /* the following are legal events. they are sent as needed to any watch */ + // #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ + // #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ + // #define IN_IGNORED 0x00008000 /* File was ignored */ + // + // /* helper events */ + // #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */ + // #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ + // + // /* special flags */ + // #define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ + // #define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ + // #define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */ + // #define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ + // #define IN_ISDIR 0x40000000 /* event occurred against dir */ + // #define IN_ONESHOT 0x80000000 /* only send event once */ + + // Watch the config directory events. + string config_dir = srs_path_dirname(_srs_config->config()); + if (true) { + uint32_t mask = IN_MODIFY | IN_CREATE; + if (::inotify_add_watch(fd, config_dir.c_str(), mask) < 0) { + return srs_error_new(ERROR_INOTIFY_WATCH, "watch file=%s, fd=%d, mask=%#x", config_dir.c_str(), fd, mask); + } + srs_trace("auto reload watching fd=%d, file=%s", fd, config_dir.c_str()); + } + + // Watch k8s sub directory. + string k8s_file = config_dir + "/..data"; + if (srs_path_exists(k8s_file)) { + uint32_t mask = IN_MODIFY; + if (::inotify_add_watch(fd, k8s_file.c_str(), mask) < 0) { + return srs_error_new(ERROR_INOTIFY_WATCH, "watch file=%s, fd=%d, mask=%#x", k8s_file.c_str(), fd, mask); + } + srs_trace("auto reload watching fd=%d, file=%s", fd, k8s_file.c_str()); + } if ((err = trd->start()) != srs_success) { return srs_error_wrap(err, "inotify"); @@ -518,80 +567,41 @@ srs_error_t SrsInotifyWorker::cycle() { srs_error_t err = srs_success; - int fd = srs_netfd_fileno(inotify_fd); - // Watch the config file events. - string config_file = _srs_config->config(); - // Only care about the modify or create or moved(for symbol link) event. - // @see https://github.com/ossrs/srs/issues/1635#issuecomment-598077374 - // #define IN_MODIFY 0x00000002 /* File was modified */ - // #define IN_CREATE 0x00000100 /* Subfile was created */ - // #define IN_DELETE_SELF 0x00000400 /* Self was deleted */ - // #define IN_MOVE_SELF 0x00000800 /* Self was moved */ - // #define IN_IGNORED 0x00008000 /* File was ignored */ - uint32_t mask = IN_MODIFY | IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF | IN_IGNORED; - // Whether config file is removed, then we should watch it again. - bool self_gone = false; - // The current watch fd, if file is gone, we set to -1. - int watch_fd = 0; + string config_path = _srs_config->config(); + string config_file = srs_path_basename(config_path); + string k8s_file = "..data"; while (true) { - if (watch_fd <= 0 && srs_path_exists(config_file)) { - if ((watch_fd = ::inotify_add_watch(fd, config_file.c_str(), mask)) < 0) { - srs_warn("inotify ignore error, fd=%d, watch=%d, file=%s, mask=%#x", - fd, watch_fd, config_file.c_str(), mask); - } else { - srs_trace("inotify watch %s fd=%d, watch=%d, mask=%#x, gone=%d", - config_file.c_str(), fd, watch_fd, mask, self_gone); - } - - // If the file come back again, we should reload it. - if (watch_fd > 0 && self_gone) { - // Notify server to do reload. - server->on_signal(SRS_SIGNAL_RELOAD); - } + char buf[4096]; + ssize_t nn = srs_read(inotify_fd, buf, (size_t)sizeof(buf), SRS_UTIME_NO_TIMEOUT); + if (nn < 0) { + srs_warn("inotify ignore read failed, nn=%d", (int)nn); + break; } - if (watch_fd > 0) { - char buf[4096]; - ssize_t nn = srs_read(inotify_fd, buf, (size_t)sizeof(buf), SRS_UTIME_NO_TIMEOUT); - if (nn < 0) { - srs_warn("inotify ignore read failed, nn=%d", (int)nn); - break; - } - - // Whether config file changed. - bool do_reload = false; - // Now, we should reset it, for it come back. - self_gone = false; - - // Parse all inotify events. - for (int i = 0; i < (int)nn; i += (int)sizeof(inotify_event)) { - inotify_event* ie = (inotify_event*)(buf + i); - if (ie->wd != watch_fd) { - continue; - } + // Whether config file changed. + bool do_reload = false; - if (ie->mask & (IN_MOVE_SELF|IN_DELETE_SELF|IN_IGNORED)) { - self_gone = true; - } else if (ie->mask & (IN_MODIFY|IN_CREATE)) { - do_reload = true; - } + // Parse all inotify events. + inotify_event* ie = NULL; + for (char* ptr = buf; ptr < buf + nn; ptr += sizeof(inotify_event) + ie->len) { + ie = (inotify_event*)ptr; - srs_trace("inotify event wd=%d, mask=%#x, len=%d, name=%s, reload=%d, moved=%d", - ie->wd, ie->mask, ie->len, ie->name, do_reload, self_gone); + if (!ie->len || !ie->name) { + continue; } - // Notify server to do reload. - if (do_reload && srs_path_exists(config_file)) { - server->on_signal(SRS_SIGNAL_RELOAD); + string name = ie->name; + if ((name == k8s_file || name == config_file) && ie->mask & (IN_MODIFY|IN_CREATE)) { + do_reload = true; } - // Remove watch when self moved. - if (self_gone && watch_fd > 0) { - int r0 = inotify_rm_watch(fd, watch_fd); - srs_trace("inotify remove fd=%d, watch=%d, r0=%d", fd, watch_fd, r0); - watch_fd = -1; - } + srs_trace("inotify event wd=%d, mask=%#x, len=%d, name=%s, reload=%d", ie->wd, ie->mask, ie->len, ie->name, do_reload); + } + + // Notify server to do reload. + if (do_reload && srs_path_exists(config_path)) { + server->on_signal(SRS_SIGNAL_RELOAD); } srs_usleep(3000 * SRS_UTIME_MILLISECONDS); diff --git a/trunk/src/core/srs_core_version3.hpp b/trunk/src/core/srs_core_version3.hpp index 525f289d8..c61be0d07 100644 --- a/trunk/src/core/srs_core_version3.hpp +++ b/trunk/src/core/srs_core_version3.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION3_HPP #define SRS_CORE_VERSION3_HPP -#define SRS_VERSION3_REVISION 130 +#define SRS_VERSION3_REVISION 131 #endif diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 5f8ee02c2..558bde405 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -286,6 +286,7 @@ #define ERROR_OCLUSTER_REDIRECT 3091 #define ERROR_INOTIFY_CREATE 3092 #define ERROR_INOTIFY_OPENFD 3093 +#define ERROR_INOTIFY_WATCH 3094 /////////////////////////////////////////////////////// // HTTP/StreamCaster protocol error.