diff --git a/app/master/daemon/changes.txt b/app/master/daemon/changes.txt index 03efd3793..78b64e6d5 100644 --- a/app/master/daemon/changes.txt +++ b/app/master/daemon/changes.txt @@ -1,4 +1,7 @@ +10) 2017.11.7 +10.1) feature: master can start one service with the specified path + 9) 2017.10.26 9.1) feature: when starting one or more services remotely, sync or async can be used. diff --git a/app/master/daemon/master/master_ent.cpp b/app/master/daemon/master/master_ent.cpp index c33cf173d..b0118b771 100644 --- a/app/master/daemon/master/master_ent.cpp +++ b/app/master/daemon/master/master_ent.cpp @@ -578,7 +578,7 @@ static int service_args(ACL_XINETD_CFG_PARSER *xcp, ACL_MASTER_SERV *serv, { const char *myname = "service_args"; const char *command, *name, *transport, *args, *ptr_const; - char *args_buf, *ptr, *cp; + char *args_buf, *ptr, *cp; char unprivileged, chroot_var; ACL_VSTRING *junk = acl_vstring_alloc(100); @@ -611,12 +611,26 @@ static int service_args(ACL_XINETD_CFG_PARSER *xcp, ACL_MASTER_SERV *serv, return -1; } - serv->path = acl_concatenate(acl_var_master_daemon_dir, "/", - command, (char *) 0); - - /* - * Notify Address + /* if command is a absolute path starting with '/', just use it, + * else the relative path added with default path will be used. */ + if (*command == '/' && access(command, F_OK) == 0) + ptr = acl_mystrdup(command); + else + ptr = acl_concatenate(acl_var_master_daemon_dir, "/", + command, (char *) 0); + + if (access(ptr, F_OK | X_OK) == -1) { + acl_msg_error("%s(%d), %s: command %s can't be executed %s", + __FILE__, __LINE__, __FUNCTION__, ptr, + acl_last_serror()); + acl_myfree(ptr); + return -1; + } + + serv->path = ptr; + + /* Notify Address */ ptr_const = get_str_ent(xcp, ACL_VAR_MASTER_NOTIFY_ADDR, "no"); if (ptr_const == NULL || strcasecmp(ptr_const, "no") == 0) serv->notify_addr = NULL; diff --git a/app/master/tools/changes.txt b/app/master/tools/changes.txt index 6887943ac..22ff0b819 100644 --- a/app/master/tools/changes.txt +++ b/app/master/tools/changes.txt @@ -1,4 +1,7 @@ +2) 2017.11.7 +2.1) feature: master_ctl supports compiling according different conditions. + 1) 2017.7.20 1.1) master_ctld: ok 1.2) master_ctl: fixed some bugs diff --git a/app/master/tools/master_ctl/Makefile.in b/app/master/tools/master_ctl/Makefile.in index 13aa1fd4d..2182fdb11 100644 --- a/app/master/tools/master_ctl/Makefile.in +++ b/app/master/tools/master_ctl/Makefile.in @@ -1,4 +1,5 @@ -CC = g++ +CC = g++ +HAS_READLINE = CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \ -Wno-long-long \ @@ -17,6 +18,24 @@ ifeq ($(CC),) CC = gcc endif +ifeq ($(findstring on, $(HAS_READLINE)), on) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring ON, $(HAS_READLINE)), ON) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring yes, $(HAS_READLINE)), yes) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring YES, $(HAS_READLINE)), YES) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring on, $(has_readline)), on) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring ON, $(has_readline)), ON) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring yes, $(has_readline)), yes) + CFLAGS += -DHAS_READLINE +else ifeq ($(findstring YES, $(has_readline)), YES) + CFLAGS += -DHAS_READLINE +endif + # For FreeBSD ifeq ($(findstring FreeBSD, $(OSNAME)), FreeBSD) ifeq ($(findstring gcc, $(CC)), gcc) diff --git a/app/master/tools/master_ctl/main.cpp b/app/master/tools/master_ctl/main.cpp index 28d1d6d4b..e572314f2 100644 --- a/app/master/tools/master_ctl/main.cpp +++ b/app/master/tools/master_ctl/main.cpp @@ -15,7 +15,11 @@ static void print_space(int n) static void print_name(const char* name, int tabs = 1) { +#ifdef HAS_READLINE printf("\033[1;33;40m%-s\033[0m", name); +#else + printf("%-s", name); +#endif for (int i = 0; i < tabs; i++) printf("\t"); @@ -23,7 +27,11 @@ static void print_name(const char* name, int tabs = 1) static void print_value(const char* value, int tabs = 1) { +#ifdef HAS_READLINE printf("\033[1;36;40m%-s\033[0m", value); +#else + printf("%-s", value); +#endif for (int i = 0; i < tabs; i++) printf("\t"); @@ -60,14 +68,26 @@ static void print_server(const serv_info_t& server) static void println_underline(const char* name, const char* value) { +#ifdef HAS_READLINE printf("\033[4m\033[1;36;40m%c\033[0m\033[0m", *name); +#else + printf("%c", *name); +#endif name++; +#ifdef HAS_READLINE printf("\033[1;33;40m%-18s\033[0m: %s\r\n", name, value); +#else + printf("%-18s: %s\r\n", name, value); +#endif } static void println(const char* name, const char* value) { +#ifdef HAS_READLINE printf("\033[1;33;40m%-18s\033[0m: %s\r\n", name, value); +#else + printf("%-18s: %s\r\n", name, value); +#endif } static void println(const char* name, int value) @@ -366,8 +386,12 @@ static bool do_reload(const std::vector& tokens, { if (*fpath == 0) { +#ifdef HAS_READLINE printf("\033[1;34;40musage\033[0m: " "\033[1;33;40mreload\033[0m configure_path timeout\r\n"); +#else + printf("usage: reload configure_path timeout\r\n"); +#endif return false; } @@ -395,8 +419,12 @@ static bool do_set(const std::vector& tokens, { if (*fpath == 0) { +#ifdef HAS_READLINE printf("\033[1;34;40musage\033[0m: " "\033[1;33;40mset\033[0m configure_path timeout\r\n"); +#else + printf("usage: set configure_path timeout\r\n"); +#endif return true; } @@ -416,8 +444,12 @@ static bool do_server(const std::vector& tokens, printf("set server to %s ok\r\n", addr); } else if (*addr == 0) +#ifdef HAS_READLINE printf("\033[1;34;40musage\033[0m: " "\033[1;33;40mserver\033[0m addr\r\n"); +#else + printf("usage: server addr\r\n"); +#endif else printf("server addr is %s\r\n", addr); return true; @@ -429,8 +461,12 @@ static bool do_timeout(const std::vector& tokens, if (tokens.size() >= 2) __timeout = atoll(tokens[1]); else +#ifdef HAS_READLINE printf("\033[1;34;40musage\033[0m: " "\033[1;33;40mtimeout\033[0m timeout\r\n"); +#else + printf("usage: timeout timeout\r\n"); +#endif return true; } @@ -564,15 +600,19 @@ static void run(const char* server, const char* filepath) if (!__verbose) print_space(100); +#ifdef HAS_READLINE printf("\033[1;36;40m%s\033[0m ==> \033[1;32;40m%s\033[0m\r\n", __actions[i].cmd, ret ? "ok" : "err"); +#else + printf("%s ==> %s\r\n", __actions[i].cmd, ret ? "ok" : "err"); +#endif } } static void usage(const char* procname) { printf("usage: %s -h[help]\r\n" - " -s master_manage_addr[default: 127.0.0.1:8190]\r\n" + " -s master_manage_addr[default: 127.0.0.1:8290]\r\n" " -f servicde_path\r\n" " -a cmd[list|stat|start|stop|reload]\r\n", procname); diff --git a/lib_fiber/c/src/event.h b/lib_fiber/c/src/event.h index 987410cce..7d66c4f82 100644 --- a/lib_fiber/c/src/event.h +++ b/lib_fiber/c/src/event.h @@ -92,6 +92,7 @@ struct EVENT { DEFER_DELETE *r_defers; DEFER_DELETE *w_defers; +#define USE_RING #ifdef USE_RING // xxx: some bugs ? ACL_RING poll_list; ACL_RING epoll_list; diff --git a/lib_fiber/c/src/fiber.c b/lib_fiber/c/src/fiber.c index d8023bb6f..67f9c4dc3 100644 --- a/lib_fiber/c/src/fiber.c +++ b/lib_fiber/c/src/fiber.c @@ -6,6 +6,12 @@ #include #endif +#define FIBER_STACK_GUARDS +#ifdef FIBER_STACK_GUARDS +#include +#include +#endif + #include "fiber/lib_fiber.h" #include "event_epoll.h" /* just for hook_epoll */ #include "fiber.h" @@ -43,6 +49,78 @@ __thread int acl_var_hook_sys_api = 0; static acl_pthread_key_t __fiber_key; +#ifdef FIBER_STACK_GUARDS + +static size_t page_size(void) +{ + static __thread long pgsz = 0; + + if (pgsz == 0) { + pgsz = sysconf(_SC_PAGE_SIZE); + assert(pgsz > 0); + } + + return (size_t) pgsz; +} + +static size_t stack_size(size_t size) +{ + size_t pgsz = page_size(); + if (size < pgsz) + size = pgsz; + size_t sz = (size + pgsz - 1) & ~(pgsz - 1); + return sz; +} + +static void *stack_alloc(size_t size) +{ + size_t pgsz = page_size(); + size = stack_size(size); + + size += pgsz + pgsz; + + char *ptr; + int ret = posix_memalign((void *) &ptr, pgsz, size); + assert(ret == 0); + + ret = mprotect(ptr, pgsz, PROT_NONE); + assert(ret == 0); + +// ret = mprotect(ptr + size - pgsz, pgsz, PROT_NONE); +// assert(ret == 0); + + ptr += pgsz; + + return ptr; +} + +static void stack_free(void *ptr) +{ + size_t pgsz = page_size(); + ptr = (char *) ptr - pgsz; + int ret = mprotect(ptr, page_size(), PROT_READ|PROT_WRITE); + assert(ret == 0); +// ret = mprotect(ptr + size - pgsz, page_size(), PROT_READ|PROT_WRITE); +// assert(ret == 0); + free(ptr); +} + +#else + +static void *stack_alloc(size_t size) +{ + return acl_mymalloc(size); +} + +static void stack_free(void *ptr) +{ + acl_myfree(ptr); +} + +#endif + +/****************************************************************************/ + /* forward declare */ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), void *arg, size_t size); @@ -111,7 +189,7 @@ static void fiber_check(void) __thread_fiber->original.context = NULL; #else __thread_fiber->original.context = (ucontext_t *) - acl_mycalloc(1, sizeof(ucontext_t)); + stack_calloc(sizeof(ucontext_t)); #endif __thread_fiber->fibers = NULL; __thread_fiber->size = 0; @@ -130,6 +208,8 @@ static void fiber_check(void) acl_msg_fatal("acl_pthread_setspecific error!"); } +#ifdef HOOK_ERRNO + /* see /usr/include/bits/errno.h for __errno_location */ #ifdef ACL_ARM_LINUX volatile int* __errno(void) @@ -153,6 +233,8 @@ int *__errno_location(void) return &__thread_fiber->original.errnum; } +#endif + int acl_fiber_sys_errno(void) { if (__sys_errno == NULL) @@ -270,7 +352,8 @@ void fiber_save_errno(void) # define SETJMP(ctx) ({\ int ret;\ - asm("lea LJMPRET%=(%%rip), %%rcx\n\t"\ + asm(".cfi_undefined rip;\r\n"\ + "lea LJMPRET%=(%%rip), %%rcx\n\t"\ "xor %%rax, %%rax\n\t"\ "mov %%rbx, (%%rdx)\n\t"\ "mov %%rbp, 8(%%rdx)\n\t"\ @@ -549,7 +632,7 @@ static void fiber_start(unsigned int x, unsigned int y) #ifdef USE_JMP /* when using setjmp/longjmp, the context just be used only once */ if (fiber->context != NULL) { - acl_myfree(fiber->context); + stack_free(fiber->context); fiber->context = NULL; } #endif @@ -586,8 +669,8 @@ void fiber_free(ACL_FIBER *fiber) VALGRIND_STACK_DEREGISTER(fiber->vid); #endif if (fiber->context) - acl_myfree(fiber->context); - acl_myfree(fiber->buff); + stack_free(fiber->context); + stack_free(fiber->buff); acl_myfree(fiber); } @@ -608,15 +691,14 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), if (head == NULL) { fiber = (ACL_FIBER *) acl_mycalloc(1, sizeof(ACL_FIBER)); /* no using calloc just avoiding using real memory */ - fiber->buff = (char *) acl_mymalloc(size); + fiber->buff = (char *) stack_alloc(size); } else if ((fiber = APPL(head, ACL_FIBER, me))->size < size) { /* if using realloc, real memory will be used, when we first * free and malloc again, then we'll just use virtual memory, * because memcpy will be called in realloc. */ - /* fiber->buff = (char *) acl_myrealloc(fiber->buff, size); */ - acl_myfree(fiber->buff); - fiber->buff = (char *) acl_mymalloc(size); + stack_free(fiber->buff); + fiber->buff = (char *) stack_alloc(size); } else size = fiber->size; @@ -639,13 +721,17 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), carg.p = fiber; if (fiber->context == NULL) - fiber->context = (ucontext_t *) acl_mymalloc(sizeof(ucontext_t)); + fiber->context = (ucontext_t *) stack_alloc(sizeof(ucontext_t)); memset(fiber->context, 0, sizeof(ucontext_t)); sigemptyset(&zero); sigaddset(&zero, SIGPIPE); - sigaddset(&zero, SIGINT); - sigaddset(&zero, SIGHUP); + sigaddset(&zero, SIGSYS); + sigaddset(&zero, SIGALRM); + sigaddset(&zero, SIGURG); + sigaddset(&zero, SIGWINCH); +// sigaddset(&zero, SIGINT); +// sigaddset(&zero, SIGHUP); sigprocmask(SIG_BLOCK, &zero, &fiber->context->uc_sigmask); if (getcontext(fiber->context) < 0) diff --git a/lib_fiber/cpp/Makefile b/lib_fiber/cpp/Makefile index b6901ccb9..c1a815f1b 100644 --- a/lib_fiber/cpp/Makefile +++ b/lib_fiber/cpp/Makefile @@ -9,7 +9,7 @@ RANLIB = ${ENV_RANLIB} FLAGS = ${ENV_FLAGS} CFLAGS = -c -g -W \ --O3 \ +-O \ -fPIC \ -Wall \ -Werror \