From 91d9a0bcb0f679d1a205217d7809e9ecd2471be3 Mon Sep 17 00:00:00 2001 From: Enrico Giordani Date: Tue, 7 Jul 2015 13:04:19 +0200 Subject: [PATCH] Squashed 2.8 fixes since the 3.0 initial merge. Squashed commit of the following: commit ba143668b964885ca1b2cf3af927a49bec0f14a4 Author: Enrico Giordani Date: Tue Jul 7 11:53:46 2015 +0200 [Fix] aeWinQueueAccept wrong return value. [Change] Variable name acceptsocket changed to acceptfd. commit 75f6769fd52fe8215bd1a2149f1bd115078ea278 Author: Enrico Giordani Date: Mon Jul 6 17:26:55 2015 +0200 [Fix] Closing handled before returning. [Cleanup] Tabs->spaces. commit 4f22c9be7dee2f34f2cbf5b8a4fd50b87b443937 Author: Enrico Giordani Date: Mon Jul 6 17:15:20 2015 +0200 [Change] Removed extra space allocated at the end of the mmap file. [Log] Improved error messages. commit f306348c243493b192eaeee9aed404ec065bb60c Author: Enrico Giordani Date: Sat Jul 4 12:08:41 2015 +0200 [Fix] RFDMap was not thread safe. [Cleanup] Removed unused/commented out code, tabs->spaces. commit 8da060bf484898932f2ecd02c099266eb31d4d80 Author: Enrico Giordani Date: Sat Jul 4 12:02:58 2015 +0200 [Fix] UnhandledExceptiontHandler internal exception handling. commit 99e5e26fba4b48531cd2a544d5a22d6caba0f681 Author: Enrico Giordani Date: Thu Jul 2 08:15:11 2015 +0200 [Cleanup] Removed unused include. commit d812c4ed57cdc30cd817ad2e9181f5bf239dc07b Author: Enrico Giordani Date: Wed Jul 1 20:36:13 2015 +0200 [Cleanup] Removed useless platform definition from RedisServer.sln commit 0401c167120876ca5533beb0bc6054d6401e8b65 Author: Enrico Giordani Date: Wed Jul 1 20:32:51 2015 +0200 [Cleanup] Changed variable type to match function return value. checkForSentinelMode() returns an int, not a bool. commit 6a9ccd3906d5c007d4683d9caea64da78e5ed668 Author: Enrico Giordani Date: Wed Jul 1 20:27:21 2015 +0200 [Cleanup] Minor change to method signature. The method input parameter has been changed to a const. commit e60f617b543edff46ceebb9362f01619e2188594 Author: Enrico Giordani Date: Wed Jul 1 20:16:00 2015 +0200 [Cleanup] Removed non-existent file from hiredis project. commit 8d17c3dd052083ec4e47176921337822299167b1 Author: Enrico Giordani Date: Wed Jul 1 19:58:59 2015 +0200 [WinPort] Explicit cast. commit 426841dc8c454a2afbc44c8f005cb3bf31b20cd5 Author: Enrico Giordani Date: Wed Jul 1 17:07:22 2015 +0200 [Change] Move ReleasePackagingTool to its own solution. [Cleanup] Removed unused code in ReleasePackagingTool. [Changed] Chocolatey package now imports documents from the same folder where binaries are. commit 6ed0696c7902d6dc268fd34f55bce95783bc4286 Author: Enrico Giordani Date: Wed Jul 1 13:58:58 2015 +0200 [Fix] Ignore SymInitialize() return value to make sure Stack Trace is logged when redis-server is running as a Windows service. commit f5e18675c9046492e7dd5a2593c2f890627a093d Author: Enrico Giordani Date: Tue Jun 30 19:06:59 2015 +0200 [Change] EventLog.dll excluded from NuGet package. commit 1ae80857b6fe1b5f352d247376c8fbbd94e81dfc Author: Enrico Giordani Date: Mon Jun 29 16:02:25 2015 +0200 Updated scripts to create and push the NuGet and Chocolatey packages. - [Change] the binaries are now downloaded from the github release. - [Change] Redis.nuspec: don't copy the files from the "documentation" folder since the documentation is already included with the binaries. - [Fix] PullBinaries.ps1: replaced hardcoded Redis version number with input parameter. - [Fix] improved error handling. commit c8e70630693a4f505177623824dff998602e62b4 Author: Enrico Giordani Date: Mon Jun 29 12:21:58 2015 +0200 Fork code for background processing needed fixes and code refactoring. - [Fix] BeginForkOperation_Aof()/_Rdb()/_Socket() and BeginForkOperation() code refactoring. - [Fix] rewriteAppendOnlyFileBackground() code refactoring to minimize the code changes for WIN32. - [Fix] rewriteAppendOnlyFileBackground() must update the latency monitor, the fork stats and replicationScriptCacheFlush(). - [Fix] rdbSaveBackground() code refactoring to minimize the code changes for WIN32. - [Fix] rdbSaveBackground() must update the latency monitor and the fork stats. - [Fix] memory leak in rdbSaveToSlavesSockets(). - [Fix] properly releasing resources in rdbSaveToSlavesSockets(). - [Fix] QForkChildInit() not setting the operationFailed event in case of exception. - [Fix] QForkChildInit() AV in catch() statement. commit f1007fcaad5ceb17d27fcca081b8dbcf8906ee92 Author: Enrico Giordani Date: Fri Jun 26 11:54:09 2015 +0200 [Fix] deleting char** correctly (@zeliard) commit b8009c220aa7cb9768bb4f3dad13fe611b60e42d Author: Alexis Campailla Date: Wed Jun 24 23:10:27 2015 +0200 Fix 32-bit build commit 4f384b9e58a042d8949ff3472962038d2754a721 Author: Alexis Campailla Date: Wed Jun 24 21:36:57 2015 +0200 Update appveyor version commit b84d39011189d1d3321b223ba282ce45b50ff126 Author: Alexis Campailla Date: Wed Jun 24 20:53:17 2015 +0200 Fix child process handle closing commit fdbf5328c298d7221794bc4bf4609da069c32406 Author: Enrico Giordani Date: Wed Jun 24 17:43:54 2015 +0200 MapViewOfFileEx() error handling, UnhandledExceptiontHandler fixes. [log] Improved error message if MapViewOfFileEx() fails. [fix] Child process call exist(1) if MapViewOfFileEx() fails. [new] GetForkOperationStatus() now detects if the child process is not anymore running. [fix] Error reporting in UnhandledExceptiontHandler() for "UNKNOWN EXCEPTION". [new] UnhandledExceptiontHandler() now calls the default C++ unhandled exceptiont handler. [log] Changed the closing statement of the BUG REPORT. [comment] Removed commented out code in Win32_dlmalloc.c. commit 05b20f0e4b4b40f4b430d8fc5cf3b819a2638e11 Author: Enrico Giordani Date: Wed Jun 24 13:05:53 2015 +0200 Change BUG REPORT closing message to point to a different git hub page. commit 1cb3e8481435677510e042f59388299b9ff29d7e Author: Enrico Giordani Date: Wed Jun 24 11:59:45 2015 +0200 ReleasePackagingTool changes: [change] the release notes file is not anymore generated from a template [change] the .md files are not anymore generated from the .docx files [new] added redis-server.pdb symbols to the zip package file [fix] create the release package directory if it doesn't exist commit 8ea708f9e113f62221d12a8ac9017fc5792046f1 Author: Enrico Giordani Date: Wed Jun 24 01:21:27 2015 +0200 New release notes format (similar to Redis on UNIX) commit e2df601222d435ada24c5ca1a4b4d172bcbb4325 Author: Enrico Giordani Date: Wed Jun 24 01:16:02 2015 +0200 Fixed broken link in README. commit 93d00065e4c62bb82420df03553686be731219b4 Author: Enrico Giordani Date: Wed Jun 24 01:12:49 2015 +0200 Minor update to the README. commit bd2ee4d2dabe3e9ae0bdda6e4c8593bba12818f9 Author: Enrico Giordani Date: Tue Jun 23 23:40:50 2015 +0200 Warning message in config files for the maxmemory flag. commit 2943ec7db6bb27b7a471eedb406b688df0992162 Author: Enrico Giordani Date: Tue Jun 23 21:56:31 2015 +0200 Cleaned up the UnhandledExceptiontHandler() code. Minor changes. commit b805f2be89ccda276695842403681d23e5451b1f Author: Enrico Giordani Date: Tue Jun 23 19:02:03 2015 +0200 Calling abort() in redisOutOfMemoryHandler(). Changed out-of-memory error report. commit 18a653318d05627d502be15a289b20e9b403f01b Author: Enrico Giordani Date: Tue Jun 23 18:55:53 2015 +0200 Commented out printf calls in dlmalloc. commit f01052fb5d52eec7aca03a5f8297bf98a124357f Author: Enrico Giordani Date: Tue Jun 23 18:44:32 2015 +0200 Changed #if defined(_WIN64) to #ifdef _WIN64 It was causing an appveyor build failure. commit a4865f06a9f2c5a706694acc371525027c98b9c1 Author: Enrico Giordani Date: Tue Jun 23 18:15:20 2015 +0200 'save' config flag added to the 'incompatibleNoPersistenceCommands' list. The fix prevents redis-server from crashing if the 'save' flag is set and 'persistence-available' is set to 'no'. commit 3de4f6cb4700c91b63d82e5e9c28add2cd5d3d2d Author: Enrico Giordani Date: Tue Jun 23 16:54:23 2015 +0200 Change misleading variables/functions names: master->parent, slave->child. Master and Slave labels were using for the Parent and Child processes. commit 453b582eed0aaef02b5dc58d2911f19cc375d138 Author: Enrico Giordani Date: Tue Jun 23 13:46:45 2015 +0200 Updated authors and description for nuget and chocolatey. commit e91c9eeef7f7f9eafbed53146805abe719d8b782 Merge: 5c05765 dc3285a Author: Enrico Giordani Date: Tue Jun 23 13:40:41 2015 +0200 Merge branch '2.8-enrico' of https://github.com/janeasystems/redis-private into 2.8-enrico commit dc3285af0b4b71d77aff27754a37f75c4d95c017 Author: Enrico Giordani Date: Tue Jun 23 11:42:51 2015 +0200 Update Redis on Windows Release Notes.md commit 5c05765d9a882588d761388875e3417078578566 Author: Enrico Giordani Date: Mon Jun 22 21:23:08 2015 +0200 Typos in warning message. commit 510cc9bd3ec582ea39dbac1af5086656009647ff Author: Enrico Giordani Date: Mon Jun 22 19:57:52 2015 +0200 Replaced AddVectoredExceptionHandler with SetUnhandledExceptionFilter for unhandled exception handling. Added log warning if the maxmemory flag is not set. commit 4993487b2570d1ebb313195c44a4131f7b4279a9 Author: Enrico Giordani Date: Mon Jun 22 17:33:41 2015 +0200 Fixed links in README. commit 710d179f918baa51f07845aad79043a5b7ea1ab7 Author: Enrico Giordani Date: Mon Jun 22 17:25:21 2015 +0200 Added text to links. commit 04c1ba4c565566423387c186ff036dde84fa4fe3 Author: Enrico Giordani Date: Mon Jun 22 17:15:48 2015 +0200 Updated documentation. commit 019d317a104b12b35b5a247ecb23d3fa4d51f9e9 Author: Enrico Giordani Date: Mon Jun 22 13:58:40 2015 +0200 Use MEM_TOP_DOWN flag to allocate memory for memtest. commit 3b4bd2f84e99d8290e0f260c651bd664b7f3170c Author: NickMRamirez Date: Wed Jun 10 15:12:07 2015 -0400 Added logic to prevent firewall exception from being added if the Windows Firewall Windows service is stopped. (cherry picked from commit 12383540c65236b2657f74178d6c2e4ec0c4d15a) Conflicts: msvs/msi/RedisMsi/RedisMsi.wixproj commit 3935ffb302d0327537f91a0cd93f2af9949f2e9f Author: Enrico Giordani Date: Mon Jun 22 12:35:10 2015 +0200 RejoinCOWPages and background threads should be synchronized (part 2) commit 87e43c5ce653e4832226ac99ee9ff75582bbb4b3 Author: Enrico Giordani Date: Mon Jun 22 11:23:04 2015 +0200 Changed error message. commit af7ca8ca286cbe562c179a8130e65b6961bb5bad Author: Alexis Campailla Date: Fri Jun 19 21:22:48 2015 +0200 RejoinCOWPages and background threads should be synchronized RejoinCOWPages is copying dirty pages to a new view of the memory map. If another thread modifies the heap between when RejoincCOWPages copies the data and when the view is remapped, the modification will be lost, leading to a memory corruption. In short, when RejoincCOWPages is running, all other threads must be stopped. Fixes: https://github.com/MSOpenTech/redis/issues/244 commit 3cd7d92bf37701ffdf522a41d1f1f819b2360b3a Author: Alexis Campailla Date: Fri Jun 19 19:31:22 2015 +0200 Build ReleasePackagingTool in Debug for Debug solution configuration commit 4742811f48aee812139d43299e881f899ebd650a Author: Enrico Giordani Date: Fri Jun 19 12:05:32 2015 +0200 Comment wording. commit 2c8c9373255fc13ae03f6d4ec731822e0b6894c3 Author: Enrico Giordani Date: Fri Jun 19 00:24:32 2015 +0200 Cleaned up a few #ifdef _WIN32. commit 2772b6388e0fd1f4e2166bb2112294c83f65e8a8 Author: Enrico Giordani Date: Fri Jun 19 00:22:32 2015 +0200 Indentation. commit f8cc98586ea80f6abed3b991cba94857db3e63ed Author: Enrico Giordani Date: Fri Jun 19 00:20:19 2015 +0200 StackTrace and info report. commit d6ede8b354bf224790885aaf2c978d320e85a087 Author: Enrico Giordani Date: Thu Jun 11 17:03:08 2015 +0200 Moved RedisLog.* to Win32_Interop and renamed to Win32_RedisLog.* Deleted unused file msvs/RedisLog.h commit 13f36c88e08762354d4a490c6e5edcfb80e84164 Author: Enrico Giordani Date: Thu Jun 11 16:05:41 2015 +0200 Added symbols to MSI. Also updated the release number to 2.8.21. commit c68970e268e476a7789c5006440b422cff9d4a78 Author: Enrico Giordani Date: Thu Jun 11 15:30:04 2015 +0200 Enabled dlmalloc DEBUG mode in the debug build. commit 1cf1db97ae169043528e52722808327c70bae584 Author: Enrico Giordani Date: Wed Jun 10 23:08:53 2015 +0200 Final portability fixes for 'long' type. commit 365c4c7559620f2c11ae7bd5d237452d75a9568c Merge: fb63c21 fbb9d61 Author: Enrico Giordani Date: Wed Jun 10 12:32:11 2015 +0200 Merge version 2.8.21 from antirez into 2.8 Changes to be committed: modified: 00-RELEASENOTES modified: deps/lua/src/ldo.c modified: deps/lua/src/lua_cmsgpack.c modified: src/scripting.c modified: src/version.h commit fb63c21f81c812f69a6bf8aaf26ea63f560741a5 Author: Enrico Giordani Date: Wed Jun 10 12:15:57 2015 +0200 Comment. added a note in case 32bit support will be brought back. commit bf260ec746bc63d0b642c2435b2860a07b6e263a Author: Enrico Giordani Date: Wed Jun 10 00:43:46 2015 +0200 Test portability fix. the 'redis-sentinel' binary is not currently built on Windows, the quick workaround is to call 'redis-server --sentinel' commit 2975545e6a69128c30616bfecbd55ceb07b2d78a Author: Enrico Giordani Date: Tue Jun 9 17:21:56 2015 +0200 Restored support for the command argument --test-memory along with -h, --help, -v, --version commit 64c14409d99e61d8c2e137a8de8831fef5d464b3 Author: Enrico Giordani Date: Mon Jun 8 20:40:08 2015 +0200 Added back the RealeasePackaingTool project in the RedisServer.sln build It was removed by mistake in a previous commit. commit eaf29cc8aa7df099d2b62710dec73d8f8a13d171 Author: Enrico Giordani Date: Mon Jun 8 20:35:31 2015 +0200 Truncate AOF in case of unexpected EOF. The Win32 port was not truncating the AOF file. commit 91d01bf8fbce57efddb46d18e27cb2f4831ef779 Author: Enrico Giordani Date: Mon Jun 8 16:23:53 2015 +0200 Win32 portability for tests: fix the syntax to invoke 'tail'. tail -nX file -> tail -X file commit fbb9d619f7aa0e376a63286b57cec4518c4473f9 Author: antirez Date: Thu Jun 4 12:00:21 2015 +0200 Fix 2.8.21 release notes to give full credits. commit 7f8b865a65f25f0131d3062db31d82b669d9aba7 Author: antirez Date: Thu Jun 4 11:32:24 2015 +0200 Redis 2.8.21 commit 700b863f134ed02c6bfecc19f5d709d145335547 Author: Ben Murphy Date: Mon May 11 23:24:37 2015 +0100 hide access to debug table commit 5a1b22ad7f8ca3502fc0bae40d42fba3c6da4e9e Author: Ben Murphy Date: Mon May 11 23:24:24 2015 +0100 disable loading lua bytecode commit 1eeb9bd71477628d29d3366a68de6f7e89b84867 Author: antirez Date: Wed Jun 3 08:44:43 2015 +0200 Scripting: Lua cmsgpack lib updated to include str8 support Conflicts: 00-RELEASENOTES src/version.h tests/instances.tcl --- README | 173 -------------- README.md | 31 +-- Redis on Windows Release Notes.md | 67 ++++-- Redis on Windows.md | 7 + appveyor.yml | 2 +- deps/hiredis/dict.c | 1 - deps/hiredis/net.c | 5 +- deps/lua/src/ldo.c | 2 +- deps/lua/src/lua_cmsgpack.c | 71 +++--- msvs/RedisServer.sln | 86 ------- msvs/ReleasePackagingTool/Program.cs | 90 ++----- .../ReleasePackagingTool.csproj | 8 +- .../ReleasePackagingTool.sln | 22 ++ msvs/hiredis/hiredis.vcxproj | 3 - .../RedisMsi.CustomActions/CustomAction.cs | 123 ++++++---- .../RedisMsi.CustomActions.csproj | 141 +++++------ .../RedisMsi/Components/SymbolsComponents.wxs | 31 +++ .../Components/WindowsServiceComponents.wxs | 13 +- msvs/msi/RedisMsi/CustomActions.wxs | 30 +++ msvs/msi/RedisMsi/Dialogs/FirewallDialog.wxs | 9 +- msvs/msi/RedisMsi/License.rtf | Bin 43035 -> 1866 bytes msvs/msi/RedisMsi/Product.wxs | 13 +- msvs/msi/RedisMsi/RedisMsi.wixproj | 4 +- msvs/setups/CreatePackages.ps1 | 41 ++-- msvs/setups/PullBinaries.ps1 | 33 ++- msvs/setups/PushPackages.ps1 | 17 +- msvs/setups/chocolatey/Redis.nuspec | 11 +- .../chocolatey/template/Redis.nuspec.template | 9 +- .../Redis on Windows Release Notes.docx | Bin 13549 -> 12578 bytes .../Windows Service Documentation.docx | Bin 14136 -> 14707 bytes .../documentation/redis.windows-service.conf | 3 + msvs/setups/documentation/redis.windows.conf | 3 + .../Redis Release Notes Template.docx | Bin 13613 -> 0 bytes msvs/setups/nuget/Redis.nuspec | 16 +- .../nuget/template/Redis.nuspec.template | 14 +- src/Win32_Interop/Win32_CommandLine.cpp | 83 ++++--- src/Win32_Interop/Win32_CommandLine.h | 3 + src/Win32_Interop/Win32_FDAPI.cpp | 4 +- src/Win32_Interop/Win32_FDAPI.h | 2 +- src/Win32_Interop/Win32_Interop.vcxproj | 21 +- src/Win32_Interop/Win32_QFork.cpp | 183 ++++++++------- src/Win32_Interop/Win32_QFork.h | 15 +- .../Win32_RedisLog.c} | 10 +- .../Win32_RedisLog.h} | 0 src/Win32_Interop/Win32_StackTrace.cpp | 219 ++++++++++++++++++ src/Win32_Interop/Win32_StackTrace.h | 32 +++ src/Win32_Interop/Win32_ThreadControl.c | 111 +++++++++ .../Win32_Interop/Win32_ThreadControl.h | 28 ++- src/Win32_Interop/Win32_dlmalloc.c | 8 - src/Win32_Interop/Win32_service.cpp | 6 +- src/Win32_Interop/win32_rfdmap.cpp | 185 +++++++-------- src/Win32_Interop/win32_rfdmap.h | 86 +++---- src/Win32_Interop/win32_types.h | 14 +- src/Win32_Interop/win32_wsiocp.c | 18 +- src/Win32_Interop/win32fixes.c | 17 +- src/Win32_Interop/win32fixes.h | 1 - src/aof.c | 48 ++-- src/bio.c | 6 + src/debug.c | 4 + src/latency.c | 2 +- src/memtest.c | 13 +- src/object.c | 2 +- src/rdb.c | 37 +-- src/redis-check-dump.c | 31 +-- src/redis.c | 87 ++++--- src/redis.h | 6 +- src/replication.c | 4 +- src/scripting.c | 15 +- src/sentinel.c | 18 +- src/zmalloc.c | 4 +- tests/integration/aof.tcl | 9 +- tests/unit/aofrw.tcl | 3 +- 72 files changed, 1324 insertions(+), 1090 deletions(-) delete mode 100644 README create mode 100644 msvs/ReleasePackagingTool/ReleasePackagingTool.sln create mode 100644 msvs/msi/RedisMsi/Components/SymbolsComponents.wxs create mode 100644 msvs/msi/RedisMsi/CustomActions.wxs delete mode 100644 msvs/setups/documentation/templates/Redis Release Notes Template.docx rename src/{RedisLog.c => Win32_Interop/Win32_RedisLog.c} (97%) rename src/{redisLog.h => Win32_Interop/Win32_RedisLog.h} (100%) create mode 100644 src/Win32_Interop/Win32_StackTrace.cpp create mode 100644 src/Win32_Interop/Win32_StackTrace.h create mode 100644 src/Win32_Interop/Win32_ThreadControl.c rename msvs/RedisLog.h => src/Win32_Interop/Win32_ThreadControl.h (75%) diff --git a/README b/README deleted file mode 100644 index 36911863..00000000 --- a/README +++ /dev/null @@ -1,173 +0,0 @@ -Where to find complete Redis documentation? -------------------------------------------- - -This README is just a fast "quick start" document. You can find more detailed -documentation at http://redis.io - -Building Redis --------------- - -Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD. -We support big endian and little endian architectures. - -It may compile on Solaris derived systems (for instance SmartOS) but our -support for this platform is "best effort" and Redis is not guaranteed to -work as well as in Linux, OSX, and *BSD there. - -It is as simple as: - - % make - -You can run a 32 bit Redis binary using: - - % make 32bit - -After building Redis is a good idea to test it, using: - - % make test - -Fixing build problems with dependencies or cached build options -—-------- -Redis has some dependencies which are included into the "deps" directory. -"make" does not rebuild dependencies automatically, even if something in the -source code of dependencies is changes. - -When you update the source code with `git pull` or when code inside the -dependencies tree is modified in any other way, make sure to use the following -command in order to really clean everything and rebuild from scratch: - - make distclean - -This will clean: jemalloc, lua, hiredis, linenoise. - -Also if you force certain build options like 32bit target, no C compiler -optimizations (for debugging purposes), and other similar build time options, -those options are cached indefinitely until you issue a "make distclean" -command. - -Fixing problems building 32 bit binaries ---------- - -If after building Redis with a 32 bit target you need to rebuild it -with a 64 bit target, or the other way around, you need to perform a -"make distclean" in the root directory of the Redis distribution. - -In case of build errors when trying to build a 32 bit binary of Redis, try -the following steps: - -* Install the packages libc6-dev-i386 (also try g++-multilib). -* Try using the following command line instead of "make 32bit": - - make CFLAGS="-m32 -march=native" LDFLAGS="-m32" - -Allocator ---------- - -Selecting a non-default memory allocator when building Redis is done by setting -the `MALLOC` environment variable. Redis is compiled and linked against libc -malloc by default, with the exception of jemalloc being the default on Linux -systems. This default was picked because jemalloc has proven to have fewer -fragmentation problems than libc malloc. - -To force compiling against libc malloc, use: - - % make MALLOC=libc - -To compile against jemalloc on Mac OS X systems, use: - - % make MALLOC=jemalloc - -Verbose build -------------- - -Redis will build with a user friendly colorized output by default. -If you want to see a more verbose output use the following: - - % make V=1 - -Running Redis -------------- - -To run Redis with the default configuration just type: - - % cd src - % ./redis-server - -If you want to provide your redis.conf, you have to run it using an additional -parameter (the path of the configuration file): - - % cd src - % ./redis-server /path/to/redis.conf - -It is possible to alter the Redis configuration passing parameters directly -as options using the command line. Examples: - - % ./redis-server --port 9999 --slaveof 127.0.0.1 6379 - % ./redis-server /etc/redis/6379.conf --loglevel debug - -All the options in redis.conf are also supported as options using the command -line, with exactly the same name. - -Playing with Redis ------------------- - -You can use redis-cli to play with Redis. Start a redis-server instance, -then in another terminal try the following: - - % cd src - % ./redis-cli - redis> ping - PONG - redis> set foo bar - OK - redis> get foo - "bar" - redis> incr mycounter - (integer) 1 - redis> incr mycounter - (integer) 2 - redis> - -You can find the list of all the available commands here: - - http://redis.io/commands - -Installing Redis ------------------ - -In order to install Redis binaries into /usr/local/bin just use: - - % make install - -You can use "make PREFIX=/some/other/directory install" if you wish to use a -different destination. - -Make install will just install binaries in your system, but will not configure -init scripts and configuration files in the appropriate place. This is not -needed if you want just to play a bit with Redis, but if you are installing -it the proper way for a production system, we have a script doing this -for Ubuntu and Debian systems: - - % cd utils - % ./install_server.sh - -The script will ask you a few questions and will setup everything you need -to run Redis properly as a background daemon that will start again on -system reboots. - -You'll be able to stop and start Redis using the script named -/etc/init.d/redis_, for instance /etc/init.d/redis_6379. - -Code contributions ---- - -Note: by contributing code to the Redis project in any form, including sending -a pull request via Github, a code fragment or patch via private email or -public discussion groups, you agree to release your code under the terms -of the BSD license that you can find in the COPYING file included in the Redis -source distribution. - -Please see the CONTRIBUTING file in this source distribution for more -information. - -Enjoy! diff --git a/README.md b/README.md index d015d33b..e68aeef9 100644 --- a/README.md +++ b/README.md @@ -17,22 +17,24 @@ Redis on Windows - Signed binaries can be downloaded using Nuget and Chocolatey. - There is a replacement for the UNIX fork() API that simulates the copy-on-write behavior using a memory mapped file. - Because Redis makes some assumptions about the values of File Descriptors, we have built a virtual file descriptor mapping layer. -- We are moving towards moving all Windows-specific changes into the Win32_Interop library. - Redis can be installed as a Windows Service. -## What's new since 2.8.12 +## Redis 2.8 release notes -- See the Redis release notes: http://download.redis.io/redis-stable/00-RELEASENOTES +- Redis on UNIX [release notes](https://raw.githubusercontent.com/antirez/redis/2.8/00-RELEASENOTES) +- Redis on Windows [release notes](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md) -## Important: More documentation is available +## How to configure and deploy Redis on Windows -Please read the documentation in msvs\setups\documentation. This is the documentation that is bundled with the binaries, and contains vital information about configuring and deploying Redis on Windows. +- [Memory Configuration](https://github.com/MSOpenTech/redis/wiki/Memory-Configuration "Memory Configuration") +- [Redis on Windows](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows.md "Redis on Windows") +- [Windows Service Documentation](https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Windows%20Service%20Documentation.md "Windows Service Documentation") ## How to build Redis using Visual Studio You can use the free Visual Studio Community edition available at http://www.visualstudio.com/products/visual-studio-community-vs. -- Open the solution file msvs\redisserver.sln in Visual Studio, select a build configuration (Debug or Release) and target (Win32 or x64) then build. +- Open the solution file msvs\redisserver.sln in Visual Studio, select a build configuration (Debug or Release) and target (x64) then build. This should create the following executables in the msvs\$(Target)\$(Configuration) folder: @@ -52,21 +54,6 @@ To run the Redis test suite requires some manual work: - To run the tests you need to have a Unix shell on your machine, or MinGW tools in your path. To execute the tests, run the following command: "tclsh8.5.exe tests/test_helper.tcl --clients N", where N is the number of parallel clients . If a Unix shell is not installed you may see the following error message: "couldn't execute "cat": no such file or directory". -- By default the test suite launches 16 parallel tests. I will get time out errors on an iCore 7-2620m@2.7Ghz with some of the tests when the number of clients - is greater than 6. +- By default the test suite launches 16 parallel tests, but some of the tests may fail when the number of clients is greater than 2. -## Known issues - -Problem: -On versions of Windows prior to Windows 8/Server 2012, when an AOF or RDB operation is complete and the child process is being rejoined with the parent, it is -possible for Redis to unexpectedly terminate. - -Cause: -The PAGE_REVERT_TO_FILE_MAP flag is not usable in VirtualProtect() in earlier versions of the OS. This flag allows for removing copy on write(COW) pages from -a memory mapped view without unmapping the view. In prior versions of the OS, the only way to purge COW pages is to unmap and then remap the memory mapped view. -Between the unmapping and remapping operations a third party process(e.g., an anti-virus program) could allocate virtual memory occupied by the memory mapped view. -As this view is used for the Redis heap, failure to remap is a fatal error. (See RejoinCOWPages() in src\Win32_Interop\Win32_QFork.cpp) - -Solution: -If you encounter this problem, host Redis on Windows 8/Server 2012 or newer. diff --git a/Redis on Windows Release Notes.md b/Redis on Windows Release Notes.md index 465fc284..48b82b50 100644 --- a/Redis on Windows Release Notes.md +++ b/Redis on Windows Release Notes.md @@ -1,34 +1,61 @@ -MSOpenTech Redis 2.8.20 Release Notes -===================================== +MSOpenTech Redis on Windows 2.8 Release Notes +============================================= -Welcome to the binary release of Redis from Microsoft Open Technologies, Inc. +--[ Redis on Windows 2.8.21 ] Release date: Jun 24 2015 -What is Redis? --------------- + - Merged Redis 2.8.21 [https://raw.githubusercontent.com/antirez/redis/2.8/00-RELEASENOTES] + - Fixes for 64-bit portability. + - Fixed rejoin pages on COW race condition. + - Fixed AOF truncation. + - Fixed crash when the 'save' flag is set and the 'persistence-available' flag is set to 'no'. + - Logging a BUG REPORT (stack trace and server info) when Redis crashes. + - Restored native Redis command arguments: -h, --help, -version, --version, --test-memory. + - Install symbols for redis binaries. + - Prevent firewall exception from being added if the Windows Firewall Windows service is stopped. (NickMRamirez) + - Fix wrong pointer castings for x64 support. (zeliard) + - Fix pointer casting for supporting a 64bit case. (zeliard) + - Fix wrong memset argument. (zeliard) -Redis is an open source, high performance, key-value store. Values may contain strings, hashes, lists, sets and sorted sets. Redis has been developed primarily for UNIX-like operating systems. +--[ Redis on Windows 2.8.19.1 ] Release date: May 04 2015 -Porting Goals -------------- + - Added an MSI installer, in addition to the .zip distribution + - Various bug fixes, including: + #167 + #228 -Our goal is to provide a version of Redis that runs on Windows with a performance essentially equal to the performance of Redis on an equivalent UNIX machine. +--[ Redis on Windows 2.8.19 ] Release date: Feb 25 2015 -What is new with the 2.8.20 release ------------------------------------ + - Workaround for getpeername() issue, which affected sentinel failover over ipv6. + - Miscellaneous bug fixes. -Our last official release was 2.8.12. We have merged in the changes up to 2.8.20. Please see the [release notes for the UNIX 2.8 branch](http://download.redis.io/redis-stable/00-RELEASENOTES) to understand how this impacts Redis functionality. +--[ Redis on Windows 2.8.17.4 ] Release date: Feb 02 2015 -### Network layer changes + - Fix AV in AllocHeapBlock. -There have been significant changes to the networking layer for this version. Likely there will be a few weeks before there is another official (Chocolatey and Nuget) release. Most of these changes target IPv6. +--[ Redis on Windows 2.8.17.3 ] Release date: Dec 26 2014 -### persistence-available flag + - Fix redis-cli pipe mode. -If Redis is to be used as an in-memory-only cache without any kind of persistence, then the fork() mechanism used by the background AOF/RDB persistence is unnecessary. As an optimization, all persistence can be turned off in the Windows version of Redis in this scenario. This will disable the creation of the memory mapped heap file, redirect heap allocations to the system heap allocator, and disable commands that would otherwise cause fork() operations: BGSAVE and BGREWRITEAOF. This flag may not be combined with any of the other flags that configure AOF and RDB operations. +--[ Redis on Windows 2.8.17.2 ] Release date: Dec 23 2014 -persistence-available [(yes)|no] + - Moved binaries out of the repository, to the Releases page. + - Miscellaneous bug fixes. -How to develop for Redis ------------------------- +--[ Redis on Windows 2.8.17.1 ] Release date: Dec 16 2014 -You will need a client library for accessing Redis. There are a wide variety of client libraries available as listed at . + - Move release binaries to release page. + - Adopting the suggestions at #172. + - We no longer commit the binaries into the repo. + - Instead, we create periodic releases on the release page. + +--[ Redis on Windows 2.8.12 ] Release date: Sep 4 2014 + +--[ Redis on Windows 2.8.9 ] Release date: Jun 26 2014 + +--[ Redis on Windows 2.6.14 ] Release date: May 20 2014 + +--[ Redis on Windows 2.8.4 ] Release date: May 20 2014 + +--[ Redis on Windows 2.6.8 ] Release date: May 6 2013 + +--[ Redis on Windows 2.4.6 ] Release date: Feb 10 2012 diff --git a/Redis on Windows.md b/Redis on Windows.md index fc528378..25802f69 100644 --- a/Redis on Windows.md +++ b/Redis on Windows.md @@ -1,6 +1,8 @@ MSOpenTech’s Redis on Windows ============================= +Redis is an open source, high performance, key-value store. Values may contain strings, hashes, lists, sets and sorted sets. Redis has been developed primarily for UNIX-like operating systems. +Our goal is to provide a version of Redis that runs on Windows with a performance essentially equal to the performance of Redis on an equivalent UNIX machine. We strive to have a stable, functionally equivalent and comparably performing version of Redis on Windows. We have achieved performance nearly identical to the POSIX version running head-to-head on identical hardware across the network. Aside from feature differences that help Redis take advantage of the Windows infrastructure, our version of Redis should work in most situations with the identical setup and configuration that one would use on a POSIX operating system. How is Redis on Windows implemented? @@ -105,3 +107,8 @@ Service Account --------------- When using Redis as a Windows service, the default installation configures Redis to run under the system’s NETWORK SERVICE account. There are some environments where another account must be used (perhaps a domain service account). Configuration of this account needs to be done manually at this point with the service control manager. If this is done, it is also important to give read/write/create permission to the folder that the Redis executable is in to this user identity. + +How to develop for Redis +======================== + +You will need a client library for accessing Redis. There are a wide variety of client libraries available as listed at . diff --git a/appveyor.yml b/appveyor.yml index d0988ada..f5f621d9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.8.13.{build} +version: 2.8.21.{build} branches: # whitelist diff --git a/deps/hiredis/dict.c b/deps/hiredis/dict.c index 79d2c1c8..ccb844b0 100644 --- a/deps/hiredis/dict.c +++ b/deps/hiredis/dict.c @@ -34,7 +34,6 @@ */ #ifdef _WIN32 #include "../../src/win32_Interop/win32_types.h" -#include "../../src/win32_Interop/win32_util.h" #endif #include "fmacros.h" diff --git a/deps/hiredis/net.c b/deps/hiredis/net.c index c37521a2..1b0ef0b6 100644 --- a/deps/hiredis/net.c +++ b/deps/hiredis/net.c @@ -58,8 +58,9 @@ #include "net.h" #include "sds.h" #ifdef _WIN32 + #include "../../src/win32_Interop/win32_util.h" #include "../../src/win32_Interop/win32fixes.h" -#include "mstcpip.h" + #include "mstcpip.h" #endif /* Defined in hiredis.c */ @@ -234,7 +235,7 @@ static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) if (errno == EINPROGRESS) { int res; - if ((res = poll(wfd, 1, msec)) == -1) { + if ((res = poll(wfd, 1, (int) msec)) == -1) { WIN_PORT_FIX /* cast (int) */ __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; diff --git a/deps/lua/src/ldo.c b/deps/lua/src/ldo.c index d1bf786c..514f7a2a 100644 --- a/deps/lua/src/ldo.c +++ b/deps/lua/src/ldo.c @@ -495,7 +495,7 @@ static void f_parser (lua_State *L, void *ud) { struct SParser *p = cast(struct SParser *, ud); int c = luaZ_lookahead(p->z); luaC_checkGC(L); - tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + tf = (luaY_parser)(L, p->z, &p->buff, p->name); cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); cl->l.p = tf; diff --git a/deps/lua/src/lua_cmsgpack.c b/deps/lua/src/lua_cmsgpack.c index fe2e1cfa..e47f4af6 100644 --- a/deps/lua/src/lua_cmsgpack.c +++ b/deps/lua/src/lua_cmsgpack.c @@ -66,7 +66,7 @@ /* Reverse memory bytes if arch is little endian. Given the conceptual * simplicity of the Lua build system we prefer check for endianess at runtime. * The performance difference should be acceptable. */ -static void memrevifle(void *ptr, size_t len) { +void memrevifle(void *ptr, size_t len) { unsigned char *p = (unsigned char *)ptr, *e = (unsigned char *)p+len-1, aux; @@ -96,7 +96,7 @@ typedef struct mp_buf { size_t len, free; } mp_buf; -static void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) { +void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) { void *(*local_realloc) (void *, void *, size_t osize, size_t nsize) = NULL; void *ud; @@ -105,7 +105,7 @@ static void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) { return local_realloc(ud, target, osize, nsize); } -static mp_buf *mp_buf_new(lua_State *L) { +mp_buf *mp_buf_new(lua_State *L) { mp_buf *buf = NULL; /* Old size = 0; new size = sizeof(*buf) */ @@ -117,7 +117,7 @@ static mp_buf *mp_buf_new(lua_State *L) { return buf; } -static void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) { +void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) { if (buf->free < len) { size_t newlen = buf->len+len; @@ -153,7 +153,7 @@ typedef struct mp_cur { int err; } mp_cur; -static void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) { +void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) { cursor->p = s; cursor->left = len; cursor->err = MP_CUR_ERROR_NONE; @@ -173,13 +173,17 @@ static void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) { /* ------------------------- Low level MP encoding -------------------------- */ -static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) { +void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) { unsigned char hdr[5]; int hdrlen; if (len < 32) { hdr[0] = 0xa0 | (len&0xff); /* fix raw */ hdrlen = 1; + } else if (len <= 0xff) { + hdr[0] = 0xd9; + hdr[1] = len; + hdrlen = 2; } else if (len <= 0xffff) { hdr[0] = 0xda; hdr[1] = (len&0xff00)>>8; @@ -198,7 +202,7 @@ static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) { } /* we assume IEEE 754 internal format for single and double precision floats. */ -static void mp_encode_double(mp_buf *buf, double d) { +void mp_encode_double(mp_buf *buf, double d) { unsigned char b[9]; float f = d; @@ -216,7 +220,7 @@ static void mp_encode_double(mp_buf *buf, double d) { } } -static void mp_encode_int(mp_buf *buf, int64_t n) { +void mp_encode_int(mp_buf *buf, int64_t n) { unsigned char b[9]; int enclen; @@ -288,7 +292,7 @@ static void mp_encode_int(mp_buf *buf, int64_t n) { mp_buf_append(buf,b,enclen); } -static void mp_encode_array(mp_buf *buf, int64_t n) { +void mp_encode_array(mp_buf *buf, int64_t n) { unsigned char b[5]; int enclen; @@ -311,7 +315,7 @@ static void mp_encode_array(mp_buf *buf, int64_t n) { mp_buf_append(buf,b,enclen); } -static void mp_encode_map(mp_buf *buf, int64_t n) { +void mp_encode_map(mp_buf *buf, int64_t n) { unsigned char b[5]; int enclen; @@ -336,7 +340,7 @@ static void mp_encode_map(mp_buf *buf, int64_t n) { /* --------------------------- Lua types encoding --------------------------- */ -static void mp_encode_lua_string(lua_State *L, mp_buf *buf) { +void mp_encode_lua_string(lua_State *L, mp_buf *buf) { size_t len; const char *s; @@ -344,13 +348,13 @@ static void mp_encode_lua_string(lua_State *L, mp_buf *buf) { mp_encode_bytes(buf,(const unsigned char*)s,len); } -static void mp_encode_lua_bool(lua_State *L, mp_buf *buf) { +void mp_encode_lua_bool(lua_State *L, mp_buf *buf) { unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2; mp_buf_append(buf,&b,1); } /* Lua 5.3 has a built in 64-bit integer type */ -static void mp_encode_lua_integer(lua_State *L, mp_buf *buf) { +void mp_encode_lua_integer(lua_State *L, mp_buf *buf) { #if (LUA_VERSION_NUM < 503) && BITS_32 lua_Number i = lua_tonumber(L,-1); #else @@ -362,7 +366,7 @@ static void mp_encode_lua_integer(lua_State *L, mp_buf *buf) { /* Lua 5.2 and lower only has 64-bit doubles, so we need to * detect if the double may be representable as an int * for Lua < 5.3 */ -static void mp_encode_lua_number(lua_State *L, mp_buf *buf) { +void mp_encode_lua_number(lua_State *L, mp_buf *buf) { lua_Number n = lua_tonumber(L,-1); if (IS_INT64_EQUIVALENT(n)) { @@ -372,10 +376,10 @@ static void mp_encode_lua_number(lua_State *L, mp_buf *buf) { } } -static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level); +void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level); /* Convert a lua table into a message pack list. */ -static void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) { +void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) { #if LUA_VERSION_NUM < 502 size_t len = lua_objlen(L,-1), j; #else @@ -391,7 +395,7 @@ static void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) { } /* Convert a lua table into a message pack key-value map. */ -static void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) { +void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) { size_t len = 0; /* First step: count keys into table. No other way to do it with the @@ -418,7 +422,7 @@ static void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) { /* Returns true if the Lua table on top of the stack is exclusively composed * of keys from numerical keys from 1 up to N, with N being the total number * of elements, without any hole in the middle. */ -static int table_is_an_array(lua_State *L) { +int table_is_an_array(lua_State *L) { int count = 0, max = 0; #if LUA_VERSION_NUM < 503 lua_Number n; @@ -461,14 +465,14 @@ static int table_is_an_array(lua_State *L) { /* If the length operator returns non-zero, that is, there is at least * an object at key '1', we serialize to message pack list. Otherwise * we use a map. */ -static void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) { +void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) { if (table_is_an_array(L)) mp_encode_lua_table_as_array(L,buf,level); else mp_encode_lua_table_as_map(L,buf,level); } -static void mp_encode_lua_null(lua_State *L, mp_buf *buf) { +void mp_encode_lua_null(lua_State *L, mp_buf *buf) { unsigned char b[1]; (void)L; @@ -476,7 +480,7 @@ static void mp_encode_lua_null(lua_State *L, mp_buf *buf) { mp_buf_append(buf,b,1); } -static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) { +void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) { int t = lua_type(L,-1); /* Limit the encoding of nested tables to a specified maximum depth, so that @@ -506,7 +510,7 @@ static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) { * Packs all arguments as a stream for multiple upacking later. * Returns error if no arguments provided. */ -static int mp_pack(lua_State *L) { +int mp_pack(lua_State *L) { int nargs = lua_gettop(L); int i; mp_buf *buf; @@ -687,6 +691,15 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { mp_cur_consume(c,9); } break; + case 0xd9: /* raw 8 */ + mp_cur_need(c,2); + { + size_t l = c->p[1]; + mp_cur_need(c,2+l); + lua_pushlstring(L,(char*)c->p+2,l); + mp_cur_consume(c,2+l); + } + break; case 0xda: /* raw 16 */ mp_cur_need(c,3); { @@ -773,7 +786,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { } } -static int mp_unpack_full(lua_State *L, int limit, int offset) { +int mp_unpack_full(lua_State *L, int limit, int offset) { size_t len; const char *s; mp_cur c; @@ -826,18 +839,18 @@ static int mp_unpack_full(lua_State *L, int limit, int offset) { return cnt; } -static int mp_unpack(lua_State *L) { +int mp_unpack(lua_State *L) { return mp_unpack_full(L, 0, 0); } -static int mp_unpack_one(lua_State *L) { +int mp_unpack_one(lua_State *L) { int offset = luaL_optinteger(L, 2, 0); /* Variable pop because offset may not exist */ lua_pop(L, lua_gettop(L)-1); return mp_unpack_full(L, 1, offset); } -static int mp_unpack_limit(lua_State *L) { +int mp_unpack_limit(lua_State *L) { int limit = luaL_checkinteger(L, 2); int offset = luaL_optinteger(L, 3, 0); /* Variable pop because offset may not exist */ @@ -846,7 +859,7 @@ static int mp_unpack_limit(lua_State *L) { return mp_unpack_full(L, limit, offset); } -static int mp_safe(lua_State *L) { +int mp_safe(lua_State *L) { int argc, err, total_results; argc = lua_gettop(L); @@ -869,7 +882,7 @@ static int mp_safe(lua_State *L) { } /* -------------------------------------------------------------------------- */ -static const struct luaL_Reg cmds[] = { +const struct luaL_Reg cmds[] = { {"pack", mp_pack}, {"unpack", mp_unpack}, {"unpack_one", mp_unpack_one}, @@ -877,7 +890,7 @@ static const struct luaL_Reg cmds[] = { {0} }; -static int luaopen_create(lua_State *L) { +int luaopen_create(lua_State *L) { int i; /* Manually construct our module table instead of * relying on _register or _newlib */ diff --git a/msvs/RedisServer.sln b/msvs/RedisServer.sln index 9e07518b..fda4656f 100644 --- a/msvs/RedisServer.sln +++ b/msvs/RedisServer.sln @@ -33,164 +33,78 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua", "lua\lua\lua.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win32_Interop", "..\src\Win32_Interop\Win32_Interop.vcxproj", "{8C07F811-C81C-432C-B334-1AE6FAECF951}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReleasePackagingTool", "ReleasePackagingTool\ReleasePackagingTool.csproj", "{74A69E5D-6540-43CC-9975-20989BF19EB0}" - ProjectSection(ProjectDependencies) = postProject - {46842776-68A5-EC98-6A09-1859BBFC73AA} = {46842776-68A5-EC98-6A09-1859BBFC73AA} - {392BBB91-3934-4A56-AF42-65C5728311E8} = {392BBB91-3934-4A56-AF42-65C5728311E8} - {52193A97-D010-41D6-BF2B-33E8E764E308} = {52193A97-D010-41D6-BF2B-33E8E764E308} - {B00D4BB5-44DE-405E-839C-D16F547006CF} = {B00D4BB5-44DE-405E-839C-D16F547006CF} - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A} = {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A} - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Win32.ActiveCfg = Debug|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|Win32.Build.0 = Debug|Win32 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x64.ActiveCfg = Debug|x64 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x64.Build.0 = Debug|x64 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x86.ActiveCfg = Debug|Win32 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Debug|x86.Build.0 = Debug|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Mixed Platforms.Build.0 = Release|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Win32.ActiveCfg = Release|Win32 - {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|Win32.Build.0 = Release|Win32 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x64.ActiveCfg = Release|x64 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x64.Build.0 = Release|x64 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x86.ActiveCfg = Release|Win32 {46842776-68A5-EC98-6A09-1859BBFC73AA}.Release|x86.Build.0 = Release|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Win32.ActiveCfg = Debug|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|Win32.Build.0 = Debug|Win32 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x64.ActiveCfg = Debug|x64 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x64.Build.0 = Debug|x64 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x86.ActiveCfg = Debug|Win32 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Debug|x86.Build.0 = Debug|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Mixed Platforms.Build.0 = Release|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Win32.ActiveCfg = Release|Win32 - {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|Win32.Build.0 = Release|Win32 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x64.ActiveCfg = Release|x64 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x64.Build.0 = Release|x64 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x86.ActiveCfg = Release|Win32 {13E85053-54B3-487B-8DDB-3430B1C1B3BF}.Release|x86.Build.0 = Release|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Win32.ActiveCfg = Debug|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|Win32.Build.0 = Debug|Win32 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x64.ActiveCfg = Debug|x64 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x64.Build.0 = Debug|x64 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x86.ActiveCfg = Debug|Win32 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Debug|x86.Build.0 = Debug|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Mixed Platforms.Build.0 = Release|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Win32.ActiveCfg = Release|Win32 - {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|Win32.Build.0 = Release|Win32 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x64.ActiveCfg = Release|x64 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x64.Build.0 = Release|x64 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x86.ActiveCfg = Release|Win32 {B00D4BB5-44DE-405E-839C-D16F547006CF}.Release|x86.Build.0 = Release|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Win32.ActiveCfg = Debug|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|Win32.Build.0 = Debug|Win32 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x64.ActiveCfg = Debug|x64 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x64.Build.0 = Debug|x64 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x86.ActiveCfg = Debug|Win32 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Debug|x86.Build.0 = Debug|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Mixed Platforms.Build.0 = Release|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Win32.ActiveCfg = Release|Win32 - {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|Win32.Build.0 = Release|Win32 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x64.ActiveCfg = Release|x64 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x64.Build.0 = Release|x64 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x86.ActiveCfg = Release|Win32 {A65C2CD6-72A3-441A-AEA3-D754BEA9A86A}.Release|x86.Build.0 = Release|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Win32.ActiveCfg = Debug|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|Win32.Build.0 = Debug|Win32 {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x64.ActiveCfg = Debug|x64 {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x64.Build.0 = Debug|x64 {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x86.ActiveCfg = Debug|Win32 {52193A97-D010-41D6-BF2B-33E8E764E308}.Debug|x86.Build.0 = Debug|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Mixed Platforms.Build.0 = Release|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Win32.ActiveCfg = Release|Win32 - {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|Win32.Build.0 = Release|Win32 {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x64.ActiveCfg = Release|x64 {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x64.Build.0 = Release|x64 {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x86.ActiveCfg = Release|Win32 {52193A97-D010-41D6-BF2B-33E8E764E308}.Release|x86.Build.0 = Release|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Win32.ActiveCfg = Debug|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|Win32.Build.0 = Debug|Win32 {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x64.ActiveCfg = Debug|x64 {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x64.Build.0 = Debug|x64 {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x86.ActiveCfg = Debug|Win32 {392BBB91-3934-4A56-AF42-65C5728311E8}.Debug|x86.Build.0 = Debug|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Mixed Platforms.Build.0 = Release|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Win32.ActiveCfg = Release|Win32 - {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|Win32.Build.0 = Release|Win32 {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x64.ActiveCfg = Release|x64 {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x64.Build.0 = Release|x64 {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x86.ActiveCfg = Release|Win32 {392BBB91-3934-4A56-AF42-65C5728311E8}.Release|x86.Build.0 = Release|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Win32.ActiveCfg = Debug|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|Win32.Build.0 = Debug|Win32 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x64.ActiveCfg = Debug|x64 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x64.Build.0 = Debug|x64 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x86.ActiveCfg = Debug|Win32 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Debug|x86.Build.0 = Debug|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Mixed Platforms.Build.0 = Release|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Win32.ActiveCfg = Release|Win32 - {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|Win32.Build.0 = Release|Win32 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x64.ActiveCfg = Release|x64 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x64.Build.0 = Release|x64 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x86.ActiveCfg = Release|Win32 {170B0909-5F75-467F-9501-C99DEC16C6DC}.Release|x86.Build.0 = Release|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Win32.ActiveCfg = Debug|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|Win32.Build.0 = Debug|Win32 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x64.ActiveCfg = Debug|x64 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x64.Build.0 = Debug|x64 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x86.ActiveCfg = Debug|Win32 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Debug|x86.Build.0 = Debug|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Mixed Platforms.Build.0 = Release|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Win32.ActiveCfg = Release|Win32 - {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|Win32.Build.0 = Release|Win32 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x64.ActiveCfg = Release|x64 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x64.Build.0 = Release|x64 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x86.ActiveCfg = Release|Win32 {8C07F811-C81C-432C-B334-1AE6FAECF951}.Release|x86.Build.0 = Release|Win32 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|Win32.ActiveCfg = Debug|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x64.ActiveCfg = Release|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Debug|x86.ActiveCfg = Debug|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Mixed Platforms.Build.0 = Release|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|Win32.ActiveCfg = Release|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x64.ActiveCfg = Release|x64 - {74A69E5D-6540-43CC-9975-20989BF19EB0}.Release|x86.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/msvs/ReleasePackagingTool/Program.cs b/msvs/ReleasePackagingTool/Program.cs index dd7d1789..c00021b3 100644 --- a/msvs/ReleasePackagingTool/Program.cs +++ b/msvs/ReleasePackagingTool/Program.cs @@ -28,16 +28,15 @@ namespace ReleasePackagingTool string version; version = p.GetRedisVersion(); - p.UpdateReleaseNotes(version); p.UpdateNuSpecFiles(version); p.BuildReleasePackage(version); - p.DocxToMd(); + Console.Write("Release packaging complete."); Environment.ExitCode = 0; } catch(Exception ex) { - Console.WriteLine("Error. Failed to finish release packaging. \n" + ex.ToString()); + Console.WriteLine("Error. Failed to finish release packaging.\n" + ex.ToString()); Environment.ExitCode = -1; } } @@ -51,70 +50,6 @@ namespace ReleasePackagingTool return line.Substring(start + 1, last - start - 1); } - void DocxToMd() - { - // locate converter (pandoc v1.13.0+) - string pandocToolPath = Path.Combine(rootPath, @"msvs\tools\pandoc\pandoc.exe"); - if (File.Exists(pandocToolPath)) - { - var files = Directory.EnumerateFiles(Path.Combine(rootPath, @"msvs\setups\documentation"), "*.docx"); - foreach (string sourceFile in files) - { - string fileName = Path.GetFileName(sourceFile); - string destFile = Path.ChangeExtension(Path.Combine(rootPath, fileName), "md"); - System.Diagnostics.Process p = new Process(); - p.StartInfo.FileName = pandocToolPath; - p.StartInfo.UseShellExecute = false; - p.StartInfo.Arguments = string.Format( - "-f {0} -t {1} -o \"{2}\" \"{3}\"", - "docx", - "markdown_github", - destFile, - sourceFile); - p.Start(); - p.WaitForExit(); - if (p.ExitCode != 0) - { - Console.WriteLine("conversion of'{0}' to '{1}' failed.", sourceFile, destFile); - } - } - } - else - { - Console.WriteLine("pandoc tool not found. docx-->md conversion will not take place."); - } - } - - void UpdateReleaseNotes(string redisVersion) - { - string releaseNotesPath = Path.Combine(rootPath, @"msvs\setups\documentation\Redis on Windows Release Notes.docx"); - string templatePath = Path.Combine(rootPath, @"msvs\setups\documentation\templates\Redis Release Notes Template.docx"); - - ForceFileErase(releaseNotesPath); - File.Copy(templatePath, releaseNotesPath); - - var archive = ZipFile.Open(releaseNotesPath, ZipArchiveMode.Update); - - string docuemntContent = @"word/document.xml"; - ZipArchiveEntry entry = archive.GetEntry(docuemntContent); - string updatedContent; - using (TextReader tr = new StreamReader(entry.Open())) - { - string documentContent = tr.ReadToEnd(); - updatedContent = documentContent.Replace(versionReplacementText, redisVersion); - } - entry.Delete(); - archive.Dispose(); // forces the file to be written to disk with the documentContent entry deleted - - archive = System.IO.Compression.ZipFile.Open(releaseNotesPath, ZipArchiveMode.Update); - ZipArchiveEntry updatedEntry = archive.CreateEntry(docuemntContent, CompressionLevel.Optimal); - using (TextWriter tw = new StreamWriter(updatedEntry.Open())) - { - tw.Write(updatedContent); - } - archive.Dispose(); // rewrites the file with the updated content - } - void ForceFileErase(string file) { if (File.Exists(file)) @@ -143,17 +78,23 @@ namespace ReleasePackagingTool void UpdateNuSpecFiles(string redisVersion) { - string chocTemplate = Path.Combine(rootPath, @"msvs\setups\chocolatey\template\Redis.nuspec.template"); - string chocDocument = Path.Combine(rootPath, @"msvs\setups\chocolatey\Redis.nuspec"); + string chocTemplate = Path.Combine(rootPath, @"msvs\setups\chocolatey\template\redis.nuspec.template"); + string chocDocument = Path.Combine(rootPath, @"msvs\setups\chocolatey\redis.nuspec"); CreateTextFileFromTemplate(chocTemplate, chocDocument, versionReplacementText, redisVersion); - string nugetTemplate = Path.Combine(rootPath, @"msvs\setups\nuget\template\Redis.nuspec.template"); - string nugetDocument = Path.Combine(rootPath, @"msvs\setups\nuget\Redis.nuspec"); + string nugetTemplate = Path.Combine(rootPath, @"msvs\setups\nuget\template\redis.nuspec.template"); + string nugetDocument = Path.Combine(rootPath, @"msvs\setups\nuget\redis.nuspec"); CreateTextFileFromTemplate(nugetTemplate, nugetDocument, versionReplacementText, redisVersion); } void BuildReleasePackage(string version) { + string releasePackageDir = Path.Combine(rootPath, @"bin\Release\"); + if (Directory.Exists(releasePackageDir) == false) + { + Directory.CreateDirectory(releasePackageDir); + } + string releasePackagePath = Path.Combine(rootPath, @"bin\Release\redis-" + version + ".zip"); ForceFileErase(releasePackagePath); @@ -164,7 +105,9 @@ namespace ReleasePackagingTool "redis-check-aof.exe", "redis-check-dump.exe", "redis-cli.exe", - "redis-server.exe" + "redis-server.exe", + "redis-server.pdb", + "EventLog.dll" }; string documentsRoot = Path.Combine(rootPath, @"msvs\setups\documentation"); List docuementNames = new List() @@ -172,7 +115,8 @@ namespace ReleasePackagingTool "Redis on Windows.docx", "Redis on Windows Release Notes.docx", "Windows Service Documentation.docx", - "redis.windows.conf" + "redis.windows.conf", + "redis.windows-service.conf" }; using (ZipArchive archive = ZipFile.Open(releasePackagePath, ZipArchiveMode.Create)) diff --git a/msvs/ReleasePackagingTool/ReleasePackagingTool.csproj b/msvs/ReleasePackagingTool/ReleasePackagingTool.csproj index 0302b6db..8d42cbe3 100644 --- a/msvs/ReleasePackagingTool/ReleasePackagingTool.csproj +++ b/msvs/ReleasePackagingTool/ReleasePackagingTool.csproj @@ -11,6 +11,7 @@ ReleasePackagingTool v4.5 512 + false publish\ true Disk @@ -23,7 +24,6 @@ true 0 1.0.0.%2a - false false true @@ -51,6 +51,9 @@ Always + + ReleasePackagingTool.Program + @@ -88,7 +91,8 @@ - $(TargetPath) + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvs/msi/RedisMsi/Components/WindowsServiceComponents.wxs b/msvs/msi/RedisMsi/Components/WindowsServiceComponents.wxs index df936424..98b9727c 100644 --- a/msvs/msi/RedisMsi/Components/WindowsServiceComponents.wxs +++ b/msvs/msi/RedisMsi/Components/WindowsServiceComponents.wxs @@ -40,7 +40,7 @@ The following component creates the firewall exception. --> - + 1]]> - - - - - - - - - \ No newline at end of file diff --git a/msvs/msi/RedisMsi/CustomActions.wxs b/msvs/msi/RedisMsi/CustomActions.wxs new file mode 100644 index 00000000..6706a439 --- /dev/null +++ b/msvs/msi/RedisMsi/CustomActions.wxs @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvs/msi/RedisMsi/Dialogs/FirewallDialog.wxs b/msvs/msi/RedisMsi/Dialogs/FirewallDialog.wxs index 811fba3a..de71a8ca 100644 --- a/msvs/msi/RedisMsi/Dialogs/FirewallDialog.wxs +++ b/msvs/msi/RedisMsi/Dialogs/FirewallDialog.wxs @@ -2,6 +2,8 @@ + + @@ -18,7 +20,12 @@ - + + + + diff --git a/msvs/msi/RedisMsi/License.rtf b/msvs/msi/RedisMsi/License.rtf index 9e56c04795e5003e613b5c7f8d41ff4bdd1112dd..ae5237cc247916df34a631c6238a5ba5d6b0a2cd 100644 GIT binary patch delta 473 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 diff --git a/msvs/msi/RedisMsi/Product.wxs b/msvs/msi/RedisMsi/Product.wxs index 20709288..b9fa14e6 100644 --- a/msvs/msi/RedisMsi/Product.wxs +++ b/msvs/msi/RedisMsi/Product.wxs @@ -10,10 +10,10 @@ msiexec /i Redis-[version].msi set port and turn off firewall exception: - msiexec /i Redis-[version].msi PORT=1234 FIREWALL_ON="" + msiexec /i Redis-[version].msi PORT=1234 ADD_FIREWALL_RULE="" set port and turn on firewall exception: - msiexec /i Redis-[version].msi PORT=1234 FIREWALL_ON=1 + msiexec /i Redis-[version].msi PORT=1234 ADD_FIREWALL_RULE=1 --> @@ -21,7 +21,7 @@ - + + + + + + diff --git a/msvs/msi/RedisMsi/RedisMsi.wixproj b/msvs/msi/RedisMsi/RedisMsi.wixproj index b5cacacf..05a6acc7 100644 --- a/msvs/msi/RedisMsi/RedisMsi.wixproj +++ b/msvs/msi/RedisMsi/RedisMsi.wixproj @@ -39,7 +39,9 @@ + + @@ -56,7 +58,7 @@ - ..\..\..\..\Program Files (x86)\WiX Toolset v3.9\bin\WixUIExtension.dll + $(WixExtDir)\WixUIExtension.dll WixUIExtension diff --git a/msvs/setups/CreatePackages.ps1 b/msvs/setups/CreatePackages.ps1 index 9baab1ad..479eda9f 100644 --- a/msvs/setups/CreatePackages.ps1 +++ b/msvs/setups/CreatePackages.ps1 @@ -1,25 +1,36 @@ -$CurDir = split-path -parent $MyInvocation.MyCommand.Definition +$ErrorActionPreference = "Stop" -$ChocolateyDir = $CurDir + "\chocolatey" -$NugetDir = $CurDir + "\nuget" -$PackagesDir = $CurDir + "\packages" +$CurDir = split-path -parent $MyInvocation.MyCommand.Definition +$PackagesDir = $CurDir + "\packages" +$ChocolateySrcDir = $CurDir + "\chocolatey" +$ChocolateyDestDir = $PackagesDir + "\chocolatey" +$NugetSrcDir = $CurDir + "\nuget" +$NugetDestDir = $PackagesDir + "\nuget" If (Test-Path $PackagesDir){ Remove-Item $PackagesDir -recurse | Out-Null } -New-Item $PackagesDir -type directory | Out-Null -New-Item ($PackagesDir+"\Chocolatey") -type directory | Out-Null -New-Item ($PackagesDir+"\NuGet") -type directory | Out-Null +New-Item $PackagesDir -type directory | Out-Null +New-Item $ChocolateyDestDir -type directory | Out-Null +New-Item $NugetDestDir -type directory | Out-Null -Set-Location $ChocolateyDir +Set-Location $ChocolateySrcDir invoke-expression "chocolatey pack Redis.nuspec" -Copy-Item *.nupkg ..\packages\Chocolatey +if ($LASTEXITCODE -eq 0) { + Copy-Item *.nupkg $ChocolateyDestDir + Write-Host "Chocolatey package copied to the destination folder." -foregroundcolor black -backgroundcolor green +} else { + Write-Host "FAILED to create the Chocolatey package." -foregroundcolor white -backgroundcolor red +} -Set-Location $NugetDir -invoke-expression "NuGet Pack Redis.nuspec" -Copy-Item *.nupkg ..\packages\NuGet +Set-Location $NugetSrcDir +invoke-expression "nuget pack Redis.nuspec" +if ($LASTEXITCODE -eq 0) { + Copy-Item *.nupkg $NugetDestDir + Write-Host "NuGet package copied to the destination folder." -foregroundcolor black -backgroundcolor green +} else { + Write-Host "FAILED to create the NuGet package." -foregroundcolor white -backgroundcolor red +} +Write-Host "Run PushPackages to push the packages." -foregroundcolor red -backgroundcolor yellow Set-Location $CurDir - -Write-Host "The .nupkg files are in the 'packages' directory." -foregroundcolor black -backgroundcolor green -Write-Host "Run PushPackages to push them." -foregroundcolor red -backgroundcolor yellow diff --git a/msvs/setups/PullBinaries.ps1 b/msvs/setups/PullBinaries.ps1 index c65b8c51..eb0464d9 100644 --- a/msvs/setups/PullBinaries.ps1 +++ b/msvs/setups/PullBinaries.ps1 @@ -1,17 +1,32 @@ +param ( + [string] $Version = $(throw 'Redis version to download is required') +) + +$ErrorActionPreference = "Stop" [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null -$CurDir = split-path -parent $MyInvocation.MyCommand.Definition +$ZipFilename = "redis-x64-" + $Version + ".zip" +$CurDir = split-path -parent $MyInvocation.MyCommand.Definition +$SourceZip = [System.IO.Path]::Combine($CurDir, $ZipFilename ) +$DestinationDir = [System.IO.Path]::Combine($CurDir, "signed_binaries" ) +$GithubUrl = "https://github.com/MSOpenTech/redis/releases/download/win-" + $Version + "/" + $ZipFilename -$SourceZip = [System.IO.Path]::Combine($CurDir, "..\..\bin\Release\redis-2.8.16.zip" ) -$Destination = [System.IO.Path]::Combine($CurDir, "signed_binaries" ) +[System.IO.File]::Delete($SourceZip) +[System.IO.Directory]::CreateDirectory($DestinationDir) | Out-Null -[System.IO.Directory]::CreateDirectory($Destination) | Out-Null - -ForEach( $file in [System.IO.Directory]::EnumerateFiles($Destination) ) { +ForEach( $file in [System.IO.Directory]::EnumerateFiles($DestinationDir) ) { [System.IO.File]::Delete($file) } -[System.IO.Compression.ZipFile]::ExtractToDirectory($SourceZip,$Destination) +Write-Host "Downloading zip file from $GithubUrl" +(New-Object Net.WebClient).DownloadFile($GithubUrl, $SourceZip); +Write-Host "Download complete." -foregroundcolor black -backgroundcolor green -Write-Host "Binaries copied from $SourceZip to $Destination" -foregroundcolor black -backgroundcolor green -Write-Host "Sign these and then run CreatePackages.ps1" -foregroundcolor red -backgroundcolor yellow +Write-Host "Extracting files to $DestinationDir" +[System.IO.Compression.ZipFile]::ExtractToDirectory($SourceZip,$DestinationDir) +Write-Host "Extraction complete." -foregroundcolor black -backgroundcolor green + +# Clean up +[System.IO.File]::Delete($SourceZip) + +Write-Host "Sign the binaries and then run CreatePackages.ps1" -foregroundcolor red -backgroundcolor yellow diff --git a/msvs/setups/PushPackages.ps1 b/msvs/setups/PushPackages.ps1 index e61f8f54..d6a29010 100644 --- a/msvs/setups/PushPackages.ps1 +++ b/msvs/setups/PushPackages.ps1 @@ -2,6 +2,8 @@ param ( [string] $Version = $(throw 'Redis version to push is required') ) +$ErrorActionPreference = "Stop" + Write-Host "Ensure that the api keys have been set for chocolatey and nuget" -foregroundcolor red -backgroundcolor yellow Write-Host " NuGet SetApiKey -source http://chocolatey.org/" -foregroundcolor red -backgroundcolor yellow Write-Host " NuGet SetApiKey " -foregroundcolor red -backgroundcolor yellow @@ -9,17 +11,26 @@ Write-Host " NuGet SetApiKey " -foregroundcolor red -backgroundc $CurDir = split-path -parent $MyInvocation.MyCommand.Definition $PackagesDir = $CurDir + "\packages" -$ChocolateyDir = $PackagesDir + "\Chocolatey" -$NugetDir = $PackagesDir + "\Nuget" +$ChocolateyDir = $PackagesDir + "\chocolatey" +$NugetDir = $PackagesDir + "\nuget" Set-Location $ChocolateyDir $ChocolateyCommand = "chocolatey push Redis-64." + $Version + ".nupkg" invoke-expression $ChocolateyCommand +if ($LASTEXITCODE -eq 0) { + Write-Host "Chocolatey package pushed successfully." -foregroundcolor black -backgroundcolor green +} else { + Write-Host "FAILED to push the Chocolatey package." -foregroundcolor white -backgroundcolor red +} Set-Location $NugetDir $NugetCommand = "NuGet push Redis-64." + $Version + ".nupkg" invoke-expression $NugetCommand +if ($LASTEXITCODE -eq 0) { + Write-Host "NuGet package pushed successfully" -foregroundcolor black -backgroundcolor green +} else { + Write-Host "FAILED to push the NuGet package." -foregroundcolor white -backgroundcolor red +} Set-Location $CurDir -Write-Host "The .nupkg files have been pushed!" -foregroundcolor black -backgroundcolor green diff --git a/msvs/setups/chocolatey/Redis.nuspec b/msvs/setups/chocolatey/Redis.nuspec index 40860f5e..f4659f5f 100644 --- a/msvs/setups/chocolatey/Redis.nuspec +++ b/msvs/setups/chocolatey/Redis.nuspec @@ -2,22 +2,21 @@ redis-64 - redis-64 - 2.8.20 - Jonathan Pickett + Redis 64 + 2.8.21 + Alexis Campailla, Enrico Giordani, Jonathan Pickett Microsoft Open Technologies, Inc. Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API. - A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more. + Redis on Windows 64-bit. https://msopentech.com/opentech-projects/redis/ Redis nosql cache Copyright Microsoft Open Technologies, Inc. https://github.com/MSOpenTech/redis/blob/2.8/license.txt false http://redis.io/images/redis.png - Includes the changes from Redis 2.8.12 -> 2.8.20. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality. + https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md - diff --git a/msvs/setups/chocolatey/template/Redis.nuspec.template b/msvs/setups/chocolatey/template/Redis.nuspec.template index c44066ed..3c3f964c 100644 --- a/msvs/setups/chocolatey/template/Redis.nuspec.template +++ b/msvs/setups/chocolatey/template/Redis.nuspec.template @@ -2,22 +2,21 @@ redis-64 - redis-64 + Redis 64 CurrentRedisVersion - Jonathan Pickett + Alexis Campailla, Enrico Giordani, Jonathan Pickett Microsoft Open Technologies, Inc. Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API. - A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more. + Redis on Windows 64-bit. https://msopentech.com/opentech-projects/redis/ Redis nosql cache Copyright Microsoft Open Technologies, Inc. https://github.com/MSOpenTech/redis/blob/2.8/license.txt false http://redis.io/images/redis.png - Includes the changes from Redis 2.8.12 -> CurrentRedisVersion. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality. + https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md - diff --git a/msvs/setups/documentation/Redis on Windows Release Notes.docx b/msvs/setups/documentation/Redis on Windows Release Notes.docx index 76df8288ad460ac1cc97d4b21cc2b0779412e847..54c67e044424cfa194243c45231e01d7cfebfebb 100644 GIT binary patch delta 7327 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 diff --git a/msvs/setups/documentation/Windows Service Documentation.docx b/msvs/setups/documentation/Windows Service Documentation.docx index 78ec939a4d9daf4a82788480dca765cf4cefddf1..9e333d68d08d6448b1bf372087bc533c301d49a5 100644 GIT binary patch delta 6178 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 SNQsEg0V5D%K+O{T2mL?9sG)!W delta 5540 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 diff --git a/msvs/setups/documentation/redis.windows-service.conf b/msvs/setups/documentation/redis.windows-service.conf index 065480db..4510bfb5 100644 --- a/msvs/setups/documentation/redis.windows-service.conf +++ b/msvs/setups/documentation/redis.windows-service.conf @@ -497,6 +497,9 @@ slave-priority 100 # limit for maxmemory so that there is some free RAM on the system for slave # output buffers (but this is not needed if the policy is 'noeviction'). # +# WARNING: not setting maxmemory will cause Redis to terminate with an +# out-of-memory exception if the maxheap limit is reached. +# # maxmemory # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory diff --git a/msvs/setups/documentation/redis.windows.conf b/msvs/setups/documentation/redis.windows.conf index bc3fd35c..4e85f895 100644 --- a/msvs/setups/documentation/redis.windows.conf +++ b/msvs/setups/documentation/redis.windows.conf @@ -497,6 +497,9 @@ slave-priority 100 # limit for maxmemory so that there is some free RAM on the system for slave # output buffers (but this is not needed if the policy is 'noeviction'). # +# WARNING: not setting maxmemory will cause Redis to terminate with an +# out-of-memory exception if the maxheap limit is reached. +# # maxmemory # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory diff --git a/msvs/setups/documentation/templates/Redis Release Notes Template.docx b/msvs/setups/documentation/templates/Redis Release Notes Template.docx deleted file mode 100644 index 7136d26c3919fa46b80a8c0b1eece88a5d01b57f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13613 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 b|C5T#NkY7t$FC redis-64 - redis-64 - 2.8.20 - Jonathan Pickett + Redis-64 + 2.8.21 + Alexis Campailla, Enrico Giordani, Jonathan Pickett Microsoft Open Technologies, Inc. Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API. - A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more. + Redis on Windows 64-bit. https://msopentech.com/opentech-projects/redis/ Redis nosql cache Copyright Microsoft Open Technologies, Inc. https://github.com/MSOpenTech/redis/blob/2.8/license.txt false http://redis.io/images/redis.png - Includes the changes from Redis 2.8.12 -> 2.8.20. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality. + https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md - - + + + + diff --git a/msvs/setups/nuget/template/Redis.nuspec.template b/msvs/setups/nuget/template/Redis.nuspec.template index c44066ed..cc224dc1 100644 --- a/msvs/setups/nuget/template/Redis.nuspec.template +++ b/msvs/setups/nuget/template/Redis.nuspec.template @@ -2,22 +2,24 @@ redis-64 - redis-64 + Redis-64 CurrentRedisVersion - Jonathan Pickett + Alexis Campailla, Enrico Giordani, Jonathan Pickett Microsoft Open Technologies, Inc. Redis is a very popular open-source, networked, in-memory, key-value data store known for high performance, flexibility, a rich set of data structures, and a simple straightforward API. - A production-ready Windows port of Redis, including 64-bit support, Chocolatey support, and much more. + Redis on Windows 64-bit. https://msopentech.com/opentech-projects/redis/ Redis nosql cache Copyright Microsoft Open Technologies, Inc. https://github.com/MSOpenTech/redis/blob/2.8/license.txt false http://redis.io/images/redis.png - Includes the changes from Redis 2.8.12 -> CurrentRedisVersion. Please see the release notes for the UNIX 2.8 branch to understand how this impacts Redis functionality. + https://raw.githubusercontent.com/MSOpenTech/redis/2.8/Redis%20on%20Windows%20Release%20Notes.md - - + + + + diff --git a/src/Win32_Interop/Win32_CommandLine.cpp b/src/Win32_Interop/Win32_CommandLine.cpp index a8aeb1b2..7b37fedd 100644 --- a/src/Win32_Interop/Win32_CommandLine.cpp +++ b/src/Win32_Interop/Win32_CommandLine.cpp @@ -563,7 +563,8 @@ vector incompatibleNoPersistenceCommands{ "no_append_fsync_on_rewrite", "auto_aof_rewrite_percentage", "auto_aof_rewrite_on_size", - "aof_rewrite_incremental_fsync" + "aof_rewrite_incremental_fsync", + "save" }; void ValidateCommandlineCombinations() { @@ -595,41 +596,53 @@ void ParseCommandLineArguments(int argc, char** argv) { string argument = string(argv[n]).substr(2, argument.length() - 2); transform(argument.begin(), argument.end(), argument.begin(), ::tolower); - if (g_redisArgMap.find(argument) == g_redisArgMap.end()) { - stringstream err; - err << "unknown argument: " << argument; - throw invalid_argument(err.str()); - } - - vector params; - if (argument == cSentinel) { - try { - vector sentinelSubCommands = g_redisArgMap[argument]->Extract(n, argc, argv); - for (auto p : sentinelSubCommands) { - params.push_back(p); - } - } catch (invalid_argument iaerr) { - // if no subcommands could be mapped, then assume this is the parameterless --sentinel command line only argument - } - } else if (argument == cServiceRun ) { - // When the service starts the current directory is %systemdir%. This needs to be changed to the - // directory the executable is in so that the .conf file can be loaded. - char szFilePath[MAX_PATH]; - if (GetModuleFileNameA(NULL, szFilePath, MAX_PATH) == 0) { - throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetModuleFileName failed"); - } - string currentDir = szFilePath; - auto pos = currentDir.rfind("\\"); - currentDir.erase(pos); - - if (FALSE == SetCurrentDirectoryA(currentDir.c_str())) { - throw std::system_error(GetLastError(), system_category(), "SetCurrentDirectory failed"); + // Some -- arguments are passed directly to redis.c::main() + if (find(cRedisArgsForMainC.begin(), cRedisArgsForMainC.end(), argument) != cRedisArgsForMainC.end()) { + if (strcasecmp(argument.c_str(), "test-memory") == 0) { + // The test-memory argument is followed by a integer value + n++; } } else { - params = g_redisArgMap[argument]->Extract(n, argc, argv); + // -- arguments processed before calling redis.c::main() + if (g_redisArgMap.find(argument) == g_redisArgMap.end()) { + stringstream err; + err << "unknown argument: " << argument; + throw invalid_argument(err.str()); + } + + vector params; + if (argument == cSentinel) { + try { + vector sentinelSubCommands = g_redisArgMap[argument]->Extract(n, argc, argv); + for (auto p : sentinelSubCommands) { + params.push_back(p); + } + } + catch (invalid_argument iaerr) { + // if no subcommands could be mapped, then assume this is the parameterless --sentinel command line only argument + } + } else if (argument == cServiceRun) { + // When the service starts the current directory is %systemdir%. This needs to be changed to the + // directory the executable is in so that the .conf file can be loaded. + char szFilePath[MAX_PATH]; + if (GetModuleFileNameA(NULL, szFilePath, MAX_PATH) == 0) { + throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetModuleFileName failed"); + } + string currentDir = szFilePath; + auto pos = currentDir.rfind("\\"); + currentDir.erase(pos); + + if (FALSE == SetCurrentDirectoryA(currentDir.c_str())) { + throw std::system_error(GetLastError(), system_category(), "SetCurrentDirectory failed"); + } + } else { + params = g_redisArgMap[argument]->Extract(n, argc, argv); + } + g_argMap[argument].push_back(params); + n += (int) params.size(); } - g_argMap[argument].push_back(params); - n += (int)params.size(); + } else if (string(argv[n]).substr(0, 1) == "-") { + // Do nothing, the - arguments are passed to redis.c::main() as they are } else { confFile = true; confFilePath = argv[n]; @@ -641,7 +654,9 @@ void ParseCommandLineArguments(int argc, char** argv) { throw std::system_error(GetLastError(), system_category(), "ParseCommandLineArguments: GetCurrentDirectoryA failed"); } - if (confFile) ParseConfFile(confFilePath, cwd, g_argMap); + if (confFile) { + ParseConfFile(confFilePath, cwd, g_argMap); + } // grab directory where RDB/AOF/DAT files will be created so that service install can add access allowed ACE to path string fileCreationDirectory = ".\\"; diff --git a/src/Win32_Interop/Win32_CommandLine.h b/src/Win32_Interop/Win32_CommandLine.h index d2de8bae..e0985133 100644 --- a/src/Win32_Interop/Win32_CommandLine.h +++ b/src/Win32_Interop/Win32_CommandLine.h @@ -64,3 +64,6 @@ const string cNo = "no"; const string cDefaultSyslogIdent = "redis"; const string cDefaultLogfile = "stdout"; +/* List of -- command arguments to be passed to redis::main() unaltered */ +const vector cRedisArgsForMainC = {"help", "version", "test-memory"}; + diff --git a/src/Win32_Interop/Win32_FDAPI.cpp b/src/Win32_Interop/Win32_FDAPI.cpp index cac1f2d4..5d164d4c 100644 --- a/src/Win32_Interop/Win32_FDAPI.cpp +++ b/src/Win32_Interop/Win32_FDAPI.cpp @@ -32,7 +32,7 @@ #include "Win32_ANSI.h" #include "win32_util.h" #include -#include "..\redisLog.h" +#include "Win32_RedisLog.h" using namespace std; #define CATCH_AND_REPORT() catch(const std::exception &){::redisLog(REDIS_WARNING, "FDAPI: std exception");}catch(...){::redisLog(REDIS_WARNING, "FDAPI: other exception");} @@ -1138,7 +1138,7 @@ BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAdd return TRUE; } -int StorageSize(SOCKADDR_STORAGE *ss) { +int StorageSize(const SOCKADDR_STORAGE *ss) { switch (ss->ss_family) { case AF_INET: return sizeof(SOCKADDR_IN); diff --git a/src/Win32_Interop/Win32_FDAPI.h b/src/Win32_Interop/Win32_FDAPI.h index b33f7069..6b67e57a 100644 --- a/src/Win32_Interop/Win32_FDAPI.h +++ b/src/Win32_Interop/Win32_FDAPI.h @@ -260,7 +260,7 @@ int FDAPI_UpdateAcceptContext( int fd ); // other networking functions BOOL ParseStorageAddress(const char *ip, int port, SOCKADDR_STORAGE* pSotrageAddr); -int StorageSize(SOCKADDR_STORAGE *ss); +int StorageSize(const SOCKADDR_STORAGE *ss); // macroize CRT definitions to point to our own #ifndef FDAPI_NOCRTREDEFS diff --git a/src/Win32_Interop/Win32_Interop.vcxproj b/src/Win32_Interop/Win32_Interop.vcxproj index 913e543c..282f797f 100644 --- a/src/Win32_Interop/Win32_Interop.vcxproj +++ b/src/Win32_Interop/Win32_Interop.vcxproj @@ -19,7 +19,6 @@ - @@ -29,14 +28,16 @@ + + + - @@ -46,9 +47,13 @@ + + + + @@ -150,8 +155,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll MSVCRT - - + DbgHelp.lib;%(AdditionalDependencies) @@ -170,8 +174,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll MSVCRT - - + DbgHelp.lib;%(AdditionalDependencies) @@ -198,8 +201,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll true - - + DbgHelp.lib;%(AdditionalDependencies) @@ -221,8 +223,7 @@ link.exe -dll -noentry resources/EventLog.res -out:$(TargetDir)EventLog.dll true - - + DbgHelp.lib;%(AdditionalDependencies) diff --git a/src/Win32_Interop/Win32_QFork.cpp b/src/Win32_Interop/Win32_QFork.cpp index b35c1b60..e6704e36 100644 --- a/src/Win32_Interop/Win32_QFork.cpp +++ b/src/Win32_Interop/Win32_QFork.cpp @@ -21,7 +21,6 @@ */ #include "win32_types.h" - #include "Win32_FDAPI.h" #include @@ -42,7 +41,9 @@ #include "Win32_SmartHandle.h" #include "Win32_Service.h" #include "Win32_CommandLine.h" -#include "..\redisLog.h" +#include "Win32_RedisLog.h" +#include "Win32_StackTrace.h" +#include "Win32_ThreadControl.h" #include #include @@ -52,6 +53,7 @@ #include #include #include + using namespace std; #ifndef PAGE_REVERT_TO_FILE_MAP @@ -188,9 +190,9 @@ struct QForkControl { QForkControl* g_pQForkControl; HANDLE g_hQForkControlFileMap; -HANDLE g_hForkedProcess; +HANDLE g_hForkedProcess = 0; DWORD g_systemAllocationGranularity; -int g_SlaveExitCode = 0; // For slave process +int g_ChildExitCode = 0; // For child process bool ReportSpecialSystemErrors(int error) { switch (error) @@ -246,27 +248,27 @@ bool ReportSpecialSystemErrors(int error) { } } -BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { +BOOL QForkChildInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { try { SmartHandle shParent( OpenProcess(SYNCHRONIZE | PROCESS_DUP_HANDLE, TRUE, ParentProcessID), string("Could not open parent process")); SmartHandle shMMFile(shParent, QForkConrolMemoryMapHandle); - SmartFileView sfvMasterQForkControl( + SmartFileView sfvParentQForkControl( shMMFile, FILE_MAP_COPY, - string("Could not map view of QForkControl in slave. Is system swap file large enough?")); - g_pQForkControl = sfvMasterQForkControl; + string("Could not map view of QForkControl in child. Is system swap file large enough?")); + g_pQForkControl = sfvParentQForkControl; - // duplicate handles and stuff into control structure (master protected by PAGE_WRITECOPY) - SmartHandle dupHeapFileHandle(shParent, sfvMasterQForkControl->heapMemoryMapFile); + // duplicate handles and stuff into control structure (parent protected by PAGE_WRITECOPY) + SmartHandle dupHeapFileHandle(shParent, sfvParentQForkControl->heapMemoryMapFile); g_pQForkControl->heapMemoryMapFile = dupHeapFileHandle; - SmartHandle dupForkedProcessReady(shParent,sfvMasterQForkControl->forkedProcessReady); + SmartHandle dupForkedProcessReady(shParent, sfvParentQForkControl->forkedProcessReady); g_pQForkControl->forkedProcessReady = dupForkedProcessReady; - SmartHandle dupOperationComplete(shParent,sfvMasterQForkControl->operationComplete); + SmartHandle dupOperationComplete(shParent, sfvParentQForkControl->operationComplete); g_pQForkControl->operationComplete = dupOperationComplete; - SmartHandle dupOperationFailed(shParent,sfvMasterQForkControl->operationFailed); + SmartHandle dupOperationFailed(shParent, sfvParentQForkControl->operationFailed); g_pQForkControl->operationFailed = dupOperationFailed; // create section handle on MM file @@ -280,7 +282,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { 0, #endif LODWORD(mmSize), - string("Could not open file mapping object in slave")); + string("Could not open file mapping object in child")); g_pQForkControl->heapMemoryMap = sfmhMapFile; @@ -306,9 +308,9 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { // execute requested operation if (g_pQForkControl->typeOfOperation == OperationType::otRDB) { - g_SlaveExitCode = do_rdbSave(g_pQForkControl->globalData.filename); + g_ChildExitCode = do_rdbSave(g_pQForkControl->globalData.filename); } else if (g_pQForkControl->typeOfOperation == OperationType::otAOF) { - g_SlaveExitCode = do_aofSave(g_pQForkControl->globalData.filename); + g_ChildExitCode = do_aofSave(g_pQForkControl->globalData.filename); } else if (g_pQForkControl->typeOfOperation == OperationType::otSocket) { LPWSAPROTOCOL_INFO lpProtocolInfo = (LPWSAPROTOCOL_INFO) g_pQForkControl->globalData.protocolInfo; int pipe_write_fd = fdapi_open_osfhandle((intptr_t)g_pQForkControl->globalData.pipe_write_handle, _O_APPEND); @@ -321,7 +323,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { WSA_FLAG_OVERLAPPED); } - g_SlaveExitCode = do_socketSave(g_pQForkControl->globalData.fds, + g_ChildExitCode = do_socketSave(g_pQForkControl->globalData.fds, g_pQForkControl->globalData.numfds, g_pQForkControl->globalData.clientids, pipe_write_fd); @@ -337,21 +339,18 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) { } catch(std::system_error syserr) { if (ReportSpecialSystemErrors(syserr.code().value()) == false) { - ::redisLog(REDIS_WARNING, "QForkSlaveInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what()); - g_pQForkControl = NULL; - if (g_pQForkControl != NULL) { - if (g_pQForkControl->operationFailed != NULL) { - SetEvent(g_pQForkControl->operationFailed); - } - } - return FALSE; + ::redisLog(REDIS_WARNING, "QForkChildInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what()); } } catch(std::runtime_error runerr) { - ::redisLog(REDIS_WARNING, "QForkSlaveInit: runtime error caught. message=%s\n", runerr.what()); + ::redisLog(REDIS_WARNING, "QForkChildInit: runtime error caught. message=%s\n", runerr.what()); + } + + if (g_pQForkControl != NULL) { + if (g_pQForkControl->operationFailed != NULL) { + SetEvent(g_pQForkControl->operationFailed); + } g_pQForkControl = NULL; - SetEvent(g_pQForkControl->operationFailed); - return FALSE; } return FALSE; } @@ -409,7 +408,7 @@ string GetWorkingDirectory() { return g_MMFDir; } -BOOL QForkMasterInit( __int64 maxheapBytes ) { +BOOL QForkParentInit(__int64 maxheapBytes) { try { // allocate file map for qfork control so it can be passed to the forked process g_hQForkControlFileMap = CreateFileMappingW( @@ -505,13 +504,7 @@ BOOL QForkMasterInit( __int64 maxheapBytes ) { "CreateFileW failed."); } - // There is a strange random failure toawrds the end of mapping the heap in the forked process in the VEH if - // the underlying MMF is not larger than the MM space we are using. This seems to be some sort of - // memory->file allocation granularity issue. Increasing the size of the file (by 16MB) takes care of the - // issue in all cases. - const size_t extraMMF = 64 * cAllocationGranularity; - - SIZE_T mmSize = g_pQForkControl->availableBlocksInHeap * cAllocationGranularity + extraMMF; + SIZE_T mmSize = g_pQForkControl->availableBlocksInHeap * cAllocationGranularity; g_pQForkControl->heapMemoryMap = CreateFileMappingW( g_pQForkControl->heapMemoryMapFile, @@ -600,14 +593,14 @@ BOOL QForkMasterInit( __int64 maxheapBytes ) { } catch(std::system_error syserr) { if (ReportSpecialSystemErrors(syserr.code().value()) == false) { - ::redisLog(REDIS_WARNING, "QForkMasterInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what()); + ::redisLog(REDIS_WARNING, "QForkParentInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what()); } } catch(std::runtime_error runerr) { - ::redisLog(REDIS_WARNING, "QForkMasterInit: runtime error caught. message=%s\n", runerr.what()); + ::redisLog(REDIS_WARNING, "QForkParentInit: runtime error caught. message=%s\n", runerr.what()); } catch(...) { - ::redisLog(REDIS_WARNING, "QForkMasterInit: other exception caught.\n"); + ::redisLog(REDIS_WARNING, "QForkParentInit: other exception caught.\n"); } return FALSE; } @@ -642,15 +635,24 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) { else { DWORD err = GetLastError(); - ::redisLog(REDIS_WARNING, "MapViewOfFileEx failed with error 0x%08X.\n", err); + ::redisLog(REDIS_WARNING, "\n\n=== REDIS BUG REPORT START: Cut & paste starting from here ==="); + ::redisLog(REDIS_WARNING, "--- FATAL ERROR MAPPING VIEW OF MAP FILE"); + ::redisLog(REDIS_WARNING, "\t MapViewOfFileEx failed with error 0x%08X.", err); ::redisLog(REDIS_WARNING, "\t startOfMapping 0x%p", startOfMapping); - ::redisLog(REDIS_WARNING, "\t heapStart 0x%p\n", heapStart); - ::redisLog(REDIS_WARNING, "\t heapEnd 0x%p\n", heapEnd); - ::redisLog(REDIS_WARNING, "\t failing access location 0x%p\n", failingMemoryAddress); - ::redisLog(REDIS_WARNING, "\t offset into mmf to start mapping 0x%p\n", mmfOffset); - ::redisLog(REDIS_WARNING, "\t start of new mapping 0x%p\n", startOfMapping); + ::redisLog(REDIS_WARNING, "\t heapStart 0x%p", heapStart); + ::redisLog(REDIS_WARNING, "\t heapEnd 0x%p", heapEnd); + ::redisLog(REDIS_WARNING, "\t failing access location 0x%p", failingMemoryAddress); + ::redisLog(REDIS_WARNING, "\t offset into mmf to start mapping 0x%p", mmfOffset); + ::redisLog(REDIS_WARNING, "\t start of new mapping 0x%p", startOfMapping); ::redisLog(REDIS_WARNING, "\t bytes to map 0x%p\n", bytesToMap); - ::redisLog(REDIS_WARNING, "\t continuing exception handler search\n"); + if (err == 0x000005AF) { + ::redisLog(REDIS_WARNING, "The system paging file is too small for this operation to complete."); + ::redisLog(REDIS_WARNING, "See https://github.com/MSOpenTech/redis/wiki/Memory-Configuration"); + ::redisLog(REDIS_WARNING, "for more information on configuring the system paging file for Redis."); + } + ::redisLog(REDIS_WARNING, "\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n"); + // Call exit to avoid executing the Unhandled Exceptiont Handler since we don't need a call stack + exit(1); } } } @@ -660,7 +662,8 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) { // QFork API StartupStatus QForkStartup(int argc, char** argv) { - bool foundSlaveFlag = false; + bool foundChildFlag = false; + int sentinelMode = checkForSentinelMode(argc, argv); HANDLE QForkConrolMemoryMapHandle = NULL; DWORD PPID = 0; __int64 maxheapBytes = -1; @@ -672,8 +675,8 @@ StartupStatus QForkStartup(int argc, char** argv) { g_systemAllocationGranularity = si.dwAllocationGranularity; if (g_argMap.find(cQFork) != g_argMap.end()) { - // slave command line looks like: --QFork [QForkConrolMemoryMap handle] [parent process id] - foundSlaveFlag = true; + // Child command line looks like: --QFork [QForkConrolMemoryMap handle] [parent process id] + foundChildFlag = true; char* endPtr; QForkConrolMemoryMapHandle = (HANDLE)strtoul(g_argMap[cQFork].at(0).at(0).c_str(),&endPtr,10); char* end = NULL; @@ -732,11 +735,13 @@ StartupStatus QForkStartup(int argc, char** argv) { */ int64_t maxMemoryPlusHalf = (3 * maxmemoryBytes) / 2; if( maxmemoryBytes != -1 ) { - maxheapBytes = (maxheapBytes > maxMemoryPlusHalf) ? maxheapBytes : maxMemoryPlusHalf; + if (maxheapBytes < maxMemoryPlusHalf) { + maxheapBytes = maxMemoryPlusHalf; + } } - if( maxheapBytes == -1 ) - { - if (checkForSentinelMode(argc, argv)) { + + if( maxheapBytes == -1 ) { + if (sentinelMode == 1) { // Sentinel mode does not need a large heap. This conserves disk space and page file reservation requirements. maxheapBytes = cSentinelHeapSize; } else { @@ -748,16 +753,16 @@ StartupStatus QForkStartup(int argc, char** argv) { } } - if (foundSlaveFlag) { + if (foundChildFlag) { LPVOID exceptionHandler = AddVectoredExceptionHandler( 1, VectoredHeapMapper ); StartupStatus retVal = StartupStatus::ssFAILED; try { - retVal = QForkSlaveInit( QForkConrolMemoryMapHandle, PPID ) ? StartupStatus::ssSLAVE_EXIT : StartupStatus::ssFAILED; + retVal = QForkChildInit(QForkConrolMemoryMapHandle, PPID) ? StartupStatus::ssCHILD_EXIT : StartupStatus::ssFAILED; } catch (...) { } RemoveVectoredExceptionHandler(exceptionHandler); return retVal; } else { - return QForkMasterInit(maxheapBytes) ? StartupStatus::ssCONTINUE_AS_MASTER : StartupStatus::ssFAILED; + return QForkParentInit(maxheapBytes) ? StartupStatus::ssCONTINUE_AS_PARENT : StartupStatus::ssFAILED; } } @@ -832,7 +837,7 @@ void CopyForkOperationData(OperationType type, LPVOID globalData, int sizeOfGlob throw std::system_error( GetLastError(), system_category(), - "BeginForkOperation: VirtualProtect failed"); + "BeginForkOperation: VirtualProtect failed for the fork control map"); } if (VirtualProtect( g_pQForkControl->heapStart, @@ -842,7 +847,7 @@ void CopyForkOperationData(OperationType type, LPVOID globalData, int sizeOfGlob throw std::system_error( GetLastError(), system_category(), - "BeginForkOperation: VirtualProtect failed"); + "BeginForkOperation: VirtualProtect failed for the heap"); } } @@ -896,19 +901,20 @@ void CreateChildProcess(PROCESS_INFORMATION *pi, char* logfile, DWORD dwCreation throw system_error( GetLastError(), system_category(), - "Problem creating slave process" ); + "Problem creating child process" ); } g_hForkedProcess = pi->hProcess; } typedef void (*CHILD_PID_HOOK)(DWORD pid); -BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalData, DWORD* childPID, uint32_t dictHashSeed, char* logfile, CHILD_PID_HOOK pidHook = NULL) { +pid_t BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalData, uint32_t dictHashSeed, char* logfile, CHILD_PID_HOOK pidHook = NULL) { PROCESS_INFORMATION pi; try { pi.hProcess = INVALID_HANDLE_VALUE; + pi.dwProcessId = -1; - if(pidHook != NULL) { + if (pidHook != NULL) { CreateChildProcess(&pi, logfile, CREATE_SUSPENDED); pidHook(pi.dwProcessId); CopyForkOperationData(type, globalData, sizeOfGlobalData, dictHashSeed); @@ -918,7 +924,6 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD CreateChildProcess(&pi, logfile, 0); } - *childPID = pi.dwProcessId; CloseHandle(pi.hThread); // wait for "forked" process to map memory @@ -929,7 +934,7 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD "Forked Process did not respond in a timely manner."); } - return TRUE; + return pi.dwProcessId; } catch(std::system_error syserr) { ::redisLog(REDIS_WARNING, "BeginForkOperation: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what()); @@ -940,34 +945,32 @@ BOOL BeginForkOperation(OperationType type, LPVOID globalData, int sizeOfGlobalD catch(...) { ::redisLog(REDIS_WARNING, "BeginForkOperation: other exception caught.\n"); } - if(pi.hProcess != INVALID_HANDLE_VALUE) { + if (pi.hProcess != INVALID_HANDLE_VALUE) { TerminateProcess(pi.hProcess, 1); } - return FALSE; + return -1; } -BOOL BeginForkOperation_Rdb( +pid_t BeginForkOperation_Rdb( char *filename, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile) { strcpy_s(g_pQForkControl->globalData.filename, filename); - return BeginForkOperation(otRDB, globalData, sizeOfGlobalData, childPID, dictHashSeed, logfile); + return BeginForkOperation(otRDB, globalData, sizeOfGlobalData, dictHashSeed, logfile); } -BOOL BeginForkOperation_Aof( +pid_t BeginForkOperation_Aof( char *filename, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile) { strcpy_s(g_pQForkControl->globalData.filename, filename); - return BeginForkOperation(otAOF, globalData, sizeOfGlobalData, childPID, dictHashSeed, logfile); + return BeginForkOperation(otAOF, globalData, sizeOfGlobalData, dictHashSeed, logfile); } void BeginForkOperation_Socket_PidHook(DWORD dwProcessId) { @@ -978,14 +981,13 @@ void BeginForkOperation_Socket_PidHook(DWORD dwProcessId) { } } -BOOL BeginForkOperation_Socket( +pid_t BeginForkOperation_Socket( int *fds, int numfds, uint64_t *clientids, int pipe_write_fd, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile) { @@ -1001,7 +1003,6 @@ BOOL BeginForkOperation_Socket( return BeginForkOperation(otSocket, globalData, sizeOfGlobalData, - childPID, dictHashSeed, logfile, BeginForkOperation_Socket_PidHook); @@ -1016,8 +1017,20 @@ OperationStatus GetForkOperationStatus() { return OperationStatus::osFAILED; } - if (WaitForSingleObject(g_pQForkControl->forkedProcessReady, 0) == WAIT_OBJECT_0) { - return OperationStatus::osINPROGRESS; + if (g_hForkedProcess && WaitForSingleObject(g_pQForkControl->forkedProcessReady, 0) == WAIT_OBJECT_0) { + // Verify if the child process is still running + if (WaitForSingleObject(g_hForkedProcess, 0) == WAIT_OBJECT_0) { + // The child process is not running, close the handle and report the status + // setting the operationFailed event + CloseHandle(g_hForkedProcess); + g_hForkedProcess = 0; + if (g_pQForkControl->operationFailed != NULL) { + SetEvent(g_pQForkControl->operationFailed); + } + return OperationStatus::osFAILED; + } else { + return OperationStatus::osINPROGRESS; + } } return OperationStatus::osUNSTARTED; @@ -1034,8 +1047,8 @@ BOOL AbortForkOperation() system_category(), "EndForkOperation: Killing forked process failed."); } - g_hForkedProcess = 0; CloseHandle(g_hForkedProcess); + g_hForkedProcess = 0; } return EndForkOperation(NULL); @@ -1117,7 +1130,7 @@ void RejoinCOWPages(HANDLE mmHandle, byte* mmStart, size_t mmSize) { throw std::system_error( GetLastError(), system_category(), - "RejoinCOWPages: MapViewOfFileEx failed. Please upgrade your OS to Win8 or newer."); + "RejoinCOWPages: MapViewOfFileEx failed."); } } } @@ -1136,7 +1149,7 @@ BOOL EndForkOperation(int * pExitCode) { } if (pExitCode != NULL) { - GetExitCodeProcess(g_hForkedProcess, (DWORD*)pExitCode); + GetExitCodeProcess(g_hForkedProcess, (DWORD*)pExitCode); } CloseHandle(g_hForkedProcess); @@ -1319,6 +1332,8 @@ extern "C" InitTimeFunctions(); ParseCommandLineArguments(argc, argv); SetupLogging(); + StackTraceInit(); + InitThreadControl(); } catch (system_error syserr) { exit(-1); } catch (runtime_error runerr) { @@ -1367,16 +1382,16 @@ extern "C" if (IsPersistenceAvailable() == TRUE) { StartupStatus status = QForkStartup(argc, argv); - if (status == ssCONTINUE_AS_MASTER) { + if (status == ssCONTINUE_AS_PARENT) { int retval = redis_main(argc, argv); QForkShutdown(); return retval; - } else if (status == ssSLAVE_EXIT) { - // slave is done - clean up and exit + } else if (status == ssCHILD_EXIT) { + // child is done - clean up and exit QForkShutdown(); - return g_SlaveExitCode; + return g_ChildExitCode; } else if (status == ssFAILED) { - // master or slave failed initialization + // parent or child failed initialization return 1; } else { // unexpected status return diff --git a/src/Win32_Interop/Win32_QFork.h b/src/Win32_Interop/Win32_QFork.h index 1bd49287..160c237f 100644 --- a/src/Win32_Interop/Win32_QFork.h +++ b/src/Win32_Interop/Win32_QFork.h @@ -45,8 +45,8 @@ typedef enum operationStatus { typedef enum startupStatus { ssFAILED = 0, // Something went wrong, exit program with error. - ssCONTINUE_AS_MASTER = 1, // Master qfork initialization complete, continue as master instance. Call QForkShutdown when exiting. - ssSLAVE_EXIT = 2 // Slave completed operation. Call QForkShutdown and exit. + ssCONTINUE_AS_PARENT = 1, // Parent qfork initialization complete, continue as parent instance. Call QForkShutdown when exiting. + ssCHILD_EXIT = 2 // Child completed operation. Call QForkShutdown and exit. } StartupStatus; #define MAX_GLOBAL_DATA 10000 @@ -65,31 +65,28 @@ typedef struct QForkBeginInfo { StartupStatus QForkStartup(int argc, char** argv); BOOL QForkShutdown(); -// For master process use only -BOOL BeginForkOperation_Rdb( +// For parent process use only +pid_t BeginForkOperation_Rdb( char* fileName, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile); -BOOL BeginForkOperation_Aof( +pid_t BeginForkOperation_Aof( char* fileName, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile); -BOOL BeginForkOperation_Socket( +pid_t BeginForkOperation_Socket( int *fds, int numfds, uint64_t *clientids, int pipe_write_fd, LPVOID globalData, int sizeOfGlobalData, - DWORD* childPID, unsigned __int32 dictHashSeed, char* logfile); diff --git a/src/RedisLog.c b/src/Win32_Interop/Win32_RedisLog.c similarity index 97% rename from src/RedisLog.c rename to src/Win32_Interop/Win32_RedisLog.c index 6d870f38..9778cf6a 100644 --- a/src/RedisLog.c +++ b/src/Win32_Interop/Win32_RedisLog.c @@ -20,16 +20,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "win32_Interop/win32_types.h" -#include "redisLog.h" +#include "Win32_types.h" +#include "Win32_RedisLog.h" #include #include #include #include #include -#include "redis.h" -#include "win32_Interop/win32Fixes.h" -#include "win32_Interop/Win32_EventLog.h" +#include "../redis.h" +#include "Win32Fixes.h" +#include "Win32_EventLog.h" #include #include diff --git a/src/redisLog.h b/src/Win32_Interop/Win32_RedisLog.h similarity index 100% rename from src/redisLog.h rename to src/Win32_Interop/Win32_RedisLog.h diff --git a/src/Win32_Interop/Win32_StackTrace.cpp b/src/Win32_Interop/Win32_StackTrace.cpp new file mode 100644 index 00000000..97895d6b --- /dev/null +++ b/src/Win32_Interop/Win32_StackTrace.cpp @@ -0,0 +1,219 @@ +/* +* Copyright (c), Microsoft Open Technologies, Inc. +* All rights reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "Win32_StackTrace.h" +#include "Win32_RedisLog.h" +#include +#include +#include + +static IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*) malloc(sizeof(IMAGEHLP_SYMBOL64) + MAX_PATH*sizeof(TCHAR)); +static IMAGEHLP_LINE64 line; +static BOOLEAN processingException = FALSE; +static CHAR modulePath[MAX_PATH]; +static LPTOP_LEVEL_EXCEPTION_FILTER defaultTopLevelExceptionHandler = NULL; + +static const char* exceptionDescription(const DWORD& code) +{ + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION"; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; + case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT"; + case EXCEPTION_DATATYPE_MISALIGNMENT: return "EXCEPTION_DATATYPE_MISALIGNMENT"; + case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND"; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO"; + case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT"; + case EXCEPTION_FLT_INVALID_OPERATION: return "EXCEPTION_FLT_INVALID_OPERATION"; + case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW"; + case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK"; + case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW"; + case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION"; + case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR"; + case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO"; + case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW"; + case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION"; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "EXCEPTION_NONCONTINUABLE_EXCEPTION"; + case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION"; + case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP"; + case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW"; + default: return "UNKNOWN EXCEPTION"; + } +} + +/* Returns the index of the last backslash in the file path */ +int GetFilenameStart(CHAR* path) { + int pos = 0; + int found = 0; + if (path != NULL) { + while (path[pos] != '\0' && pos < MAX_PATH) { + if (path[pos] == '\\') { + found = pos + 1; + } + ++pos; + } + } + + return found; +} + +#ifdef _WIN64 +void LogStackTrace() { + BOOL result; + HANDLE thread; + HANDLE process; + CONTEXT context; + STACKFRAME64 stack; + ULONG frame; + DWORD64 dw64Displacement; + DWORD dwDisplacement; + + memset(&stack, 0, sizeof(STACKFRAME64)); + memset(pSymbol, '\0', sizeof(*pSymbol) + MAX_PATH); + memset(&modulePath[0], '\0', sizeof(modulePath)); + line.LineNumber = 0; + + RtlCaptureContext(&context); + process = GetCurrentProcess(); + thread = GetCurrentThread(); + dw64Displacement = 0; + stack.AddrPC.Offset = context.Rip; + stack.AddrPC.Mode = AddrModeFlat; + stack.AddrStack.Offset = context.Rsp; + stack.AddrStack.Mode = AddrModeFlat; + stack.AddrFrame.Offset = context.Rbp; + stack.AddrFrame.Mode = AddrModeFlat; + + for (frame = 0;; frame++){ + result = StackWalk64( + IMAGE_FILE_MACHINE_AMD64, + process, + thread, + &stack, + &context, + NULL, + SymFunctionTableAccess64, + SymGetModuleBase64, + NULL + ); + + pSymbol->MaxNameLength = MAX_PATH; + pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + + SymGetSymFromAddr64(process, stack.AddrPC.Offset, &dw64Displacement, pSymbol); + SymGetLineFromAddr64(process, stack.AddrPC.Offset, &dwDisplacement, &line); + + DWORD64 moduleBase = SymGetModuleBase64(process, stack.AddrPC.Offset); + if (moduleBase) + { + GetModuleFileNameA((HINSTANCE) moduleBase, modulePath, MAX_PATH); + } + + redisLog(REDIS_WARNING | REDIS_LOG_RAW, "%s!%s(%s:%d)(0x%08LX, 0x%08LX, 0x%08LX, 0x%08LX)\n", + &modulePath[GetFilenameStart(modulePath)], + pSymbol->Name, + line.FileName, + line.LineNumber, + stack.Params[0], + stack.Params[1], + stack.Params[2], + stack.Params[3] + ); + + if (!result) { + break; + } + } +} +#else +void LogStackTrace() {} +#endif + +void StackTraceInfo() { + redisLog(REDIS_WARNING, "--- STACK TRACE"); + LogStackTrace(); +} + +void ServerInfo() { + redisLog(REDIS_WARNING, "--- INFO OUTPUT"); + // Call antirez routine to log the info output + redisLogRaw(REDIS_WARNING | REDIS_LOG_RAW, genRedisInfoString("all")); +} + +void BugReportEnd(){ + redisLogRaw(REDIS_WARNING, + "\n=== REDIS BUG REPORT END. Make sure to include from START to END. ===\n\n" + " Please report this bug by following the instructions at:\n\n" + " http://github.com/MSOpenTech/redis/wiki/Submitting-an-Issue\n\n" + " Suspect RAM error? Use redis-server --test-memory to verify it.\n\n" + ); +} + +LONG WINAPI UnhandledExceptiontHandler(PEXCEPTION_POINTERS info) { + if (!processingException) { + try { + const char* exDescription = "Exception code not available"; + processingException = true; + if (info->ExceptionRecord != NULL && info->ExceptionRecord->ExceptionCode != NULL) { + exDescription = exceptionDescription(info->ExceptionRecord->ExceptionCode); + } + + // Call antirez routine to log the start of the bug report + bugReportStart(); + redisLog(REDIS_WARNING, "--- %s", exDescription); + StackTraceInfo(); + //ServerInfo(); + BugReportEnd(); + processingException = false; + } + catch (...) {}; + } + + if (defaultTopLevelExceptionHandler != NULL) { + defaultTopLevelExceptionHandler(info); + } + + return EXCEPTION_CONTINUE_SEARCH; +} + +/* Handler to trap abort() calls */ +extern "C" void AbortHandler(int signal_number) { + bugReportStart(); + redisLog(REDIS_WARNING, "--- ABORT"); + StackTraceInfo(); + BugReportEnd(); +} + +void InitSymbols() { + // Preload symbols so they will be available in case of out-of-memory exception + SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + HANDLE process = GetCurrentProcess(); + SymInitialize(process, NULL, TRUE); +} + +void StackTraceInit(void) { + InitSymbols(); + // Global handler for unhandled exceptions + defaultTopLevelExceptionHandler = SetUnhandledExceptionFilter(UnhandledExceptiontHandler); + // Handler for abort() + signal(SIGABRT, &AbortHandler); +} diff --git a/src/Win32_Interop/Win32_StackTrace.h b/src/Win32_Interop/Win32_StackTrace.h new file mode 100644 index 00000000..36638d5f --- /dev/null +++ b/src/Win32_Interop/Win32_StackTrace.h @@ -0,0 +1,32 @@ +/* +* Copyright (c), Microsoft Open Technologies, Inc. +* All rights reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#include "win32_types.h" +#include + +void StackTraceInit(void); + +extern "C" typedef char *sds; +extern "C" sds genRedisInfoString(char *section); +extern "C" void bugReportStart(void); \ No newline at end of file diff --git a/src/Win32_Interop/Win32_ThreadControl.c b/src/Win32_Interop/Win32_ThreadControl.c new file mode 100644 index 00000000..d9b06479 --- /dev/null +++ b/src/Win32_Interop/Win32_ThreadControl.c @@ -0,0 +1,111 @@ +/* + * Copyright (c), Microsoft Open Technologies, Inc. + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + + +volatile LONG g_NumWorkerThreads = 0; + +// Safe mode means the threads are not touching the heap, or they are suspended because of an explicit suspension request +// Threads in safe mode because they are not touching the heap will block if trying to transition to unsafe mode while a suspension is requested +volatile LONG g_NumWorkerThreadsInSafeMode = 0; + +volatile LONG g_SuspensionRequested = 0; +HANDLE g_hResumeFromSuspension; + +CRITICAL_SECTION g_ThreadControlMutex; + + +void InitThreadControl() { + InitializeCriticalSection(&g_ThreadControlMutex); + g_hResumeFromSuspension = CreateEvent(NULL, TRUE, TRUE, NULL); + if (!g_hResumeFromSuspension) { + exit(GetLastError()); + } +} + +void IncrementWorkerThreadCount() { + EnterCriticalSection(&g_ThreadControlMutex); + g_NumWorkerThreads++; + LeaveCriticalSection(&g_ThreadControlMutex); +} + +void DecrementWorkerThreadCount() { + EnterCriticalSection(&g_ThreadControlMutex); + g_NumWorkerThreads--; + LeaveCriticalSection(&g_ThreadControlMutex); +} + + +// Returns TRUE if threads are already in safe mode or suspended +BOOL SuspensionCompleted() { + BOOL result; + EnterCriticalSection(&g_ThreadControlMutex); + result = (g_NumWorkerThreadsInSafeMode == g_NumWorkerThreads); + LeaveCriticalSection(&g_ThreadControlMutex); + return result; +} + +// This is meant to be called from the main thread only. +void RequestSuspension() { + if (!g_SuspensionRequested) { + if (!ResetEvent(g_hResumeFromSuspension)) { + exit(GetLastError()); + } + _InterlockedOr(&g_SuspensionRequested, 1); + } +} + +void ResumeFromSuspension() { + // This is meant to be called from the main thread only. + assert(g_SuspensionRequested && SuspensionCompleted()); + + _InterlockedAnd(&g_SuspensionRequested, 0); + if (!SetEvent(g_hResumeFromSuspension)) { + exit(GetLastError()); + } +} + +void WorkerThread_EnterSafeMode() { + EnterCriticalSection(&g_ThreadControlMutex); + g_NumWorkerThreadsInSafeMode++; + LeaveCriticalSection(&g_ThreadControlMutex); +} + +void WorkerThread_ExitSafeMode() { + for(;;) { + EnterCriticalSection(&g_ThreadControlMutex); + if (g_SuspensionRequested) { + LeaveCriticalSection(&g_ThreadControlMutex); + if (WaitForSingleObject(g_hResumeFromSuspension, INFINITE) != WAIT_OBJECT_0) { + exit(GetLastError()); + } + continue; + } else { + g_NumWorkerThreadsInSafeMode--; + LeaveCriticalSection(&g_ThreadControlMutex); + break; + } + } +} + diff --git a/msvs/RedisLog.h b/src/Win32_Interop/Win32_ThreadControl.h similarity index 75% rename from msvs/RedisLog.h rename to src/Win32_Interop/Win32_ThreadControl.h index 13ba4f7f..d79d5e12 100644 --- a/msvs/RedisLog.h +++ b/src/Win32_Interop/Win32_ThreadControl.h @@ -19,19 +19,25 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #pragma once -/* Log levels */ -#define REDIS_DEBUG 0 -#define REDIS_VERBOSE 1 -#define REDIS_NOTICE 2 -#define REDIS_WARNING 3 -#define REDIS_LOG_RAW (1<<10) /* Modifier to log without timestamp */ +#ifdef __cplusplus +extern "C" { +#endif -#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */ -void redisLog(int level, const char *fmt, ...); -void redisLogRaw(int level, const char *msg); -void redisLogFromHandler(int level, const char *msg); +void InitThreadControl(); +void IncrementWorkerThreadCount(); +void DecrementWorkerThreadCount(); +void RequestSuspension(); +BOOL SuspensionCompleted(); +void ResumeFromSuspension(); -void SetVerbosity(int verbosity); \ No newline at end of file +void WorkerThread_EnterSafeMode(); +void WorkerThread_ExitSafeMode(); + + +#ifdef __cplusplus +} +#endif diff --git a/src/Win32_Interop/Win32_dlmalloc.c b/src/Win32_Interop/Win32_dlmalloc.c index b4559c8e..fded5803 100644 --- a/src/Win32_Interop/Win32_dlmalloc.c +++ b/src/Win32_Interop/Win32_dlmalloc.c @@ -1702,10 +1702,6 @@ static FORCEINLINE void* win32mmap(size_t size) { #else void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); #endif - if( ptr == NULL ) - { - printf( "VirtualAlloc/COWAlloc fail!\n"); - } return (ptr != 0)? ptr: MFAIL; } @@ -1716,10 +1712,6 @@ static FORCEINLINE void* win32direct_mmap(size_t size) { #else void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE); #endif - if( ptr == NULL ) - { - printf( "VirtualAlloc/COWAlloc fail!\n"); - } return (ptr != 0)? ptr: MFAIL; } diff --git a/src/Win32_Interop/Win32_service.cpp b/src/Win32_Interop/Win32_service.cpp index d6ab2036..0387dd7c 100644 --- a/src/Win32_Interop/Win32_service.cpp +++ b/src/Win32_Interop/Win32_service.cpp @@ -68,7 +68,7 @@ this should preceed the other arguments passed to redis. For instance: #include #include #include -#include "..\redisLog.h" +#include "Win32_RedisLog.h" #include "Win32_CommandLine.h" using namespace std; @@ -483,10 +483,10 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam) { main(argc, argv); for (int a = 0; a < argc; a++) { - delete argv[a]; + delete[] argv[a]; argv[a] = nullptr; } - delete argv; + delete[] argv; argv = nullptr; SetEvent(g_ServiceStoppedEvent); diff --git a/src/Win32_Interop/win32_rfdmap.cpp b/src/Win32_Interop/win32_rfdmap.cpp index e447cbcc..2375a6a6 100644 --- a/src/Win32_Interop/win32_rfdmap.cpp +++ b/src/Win32_Interop/win32_rfdmap.cpp @@ -22,139 +22,126 @@ #include "win32_types.h" - #include "win32_rfdmap.h" RFDMap& RFDMap::getInstance() { - static RFDMap instance; // Instantiated on first use. Guaranteed to be destroyed. + static RFDMap instance; // Instantiated on first use. Guaranteed to be destroyed. return instance; } -RFDMap::RFDMap() { maxRFD = minRFD; }; +RFDMap::RFDMap() { + InitializeCriticalSection(&mutex); + maxRFD = minRFD; +} RFD RFDMap::getNextRFDAvailable() { - if( RFDRecyclePool.empty() == false ) { - int RFD = RFDRecyclePool.front(); - RFDRecyclePool.pop(); - return RFD; - } else { - maxRFD = minRFD + (int)SocketToRFDMap.size() + (int)PosixFDToRFDMap.size(); - return maxRFD; - } + RFD rfd; + EnterCriticalSection(&mutex); + if (RFDRecyclePool.empty() == false) { + rfd = RFDRecyclePool.front(); + RFDRecyclePool.pop(); + } else { + maxRFD = minRFD + (int) SocketToRFDMap.size() + (int) PosixFDToRFDMap.size(); + rfd = maxRFD; + } + LeaveCriticalSection(&mutex); + return rfd; } RFD RFDMap::addSocket(SOCKET s) { - if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) { - return invalidRFD; - } - - RFD rfd = getNextRFDAvailable(); - SocketToRFDMap[s] = rfd; - RFDToSocketMap[rfd] = s; - return rfd; + RFD rfd; + EnterCriticalSection(&mutex); + if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) { + rfd = invalidRFD; + } else { + rfd = getNextRFDAvailable(); + SocketToRFDMap[s] = rfd; + RFDToSocketMap[rfd] = s; + } + LeaveCriticalSection(&mutex); + return rfd; } -void RFDMap::removeSocket(SOCKET s) { - S2RFDIterator mit = SocketToRFDMap.find(s); - if(mit == SocketToRFDMap.end()) { -// redisLog( REDIS_DEBUG, "RFDMap::removeSocket() - failed to find socket!" ); - return; +void RFDMap::removeSocket(SOCKET s) { + EnterCriticalSection(&mutex); + S2RFDIterator mit = SocketToRFDMap.find(s); + if (mit != SocketToRFDMap.end()) { + RFD rfd = (*mit).second; + RFDRecyclePool.push(rfd); + RFDToSocketMap.erase(rfd); + SocketToRFDMap.erase(s); } - RFD rfd = (*mit).second; - RFDRecyclePool.push(rfd); - RFDToSocketMap.erase(rfd); - SocketToRFDMap.erase(s); + LeaveCriticalSection(&mutex); } RFD RFDMap::addPosixFD(int posixFD) { - if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) { -// redisLog( REDIS_DEBUG, "RFDMap::addPosixFD() - posixFD already exists!" ); - return invalidRFD; - } - - RFD rfd = getNextRFDAvailable(); - PosixFDToRFDMap[posixFD] = rfd; - RFDToPosixFDMap[rfd] = posixFD; - return rfd; + RFD rfd; + EnterCriticalSection(&mutex); + if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) { + rfd = invalidRFD; + } else { + rfd = getNextRFDAvailable(); + PosixFDToRFDMap[posixFD] = rfd; + RFDToPosixFDMap[rfd] = posixFD; + } + LeaveCriticalSection(&mutex); + return rfd; } -void RFDMap::removePosixFD(int posixFD) { - PosixFD2RFDIterator mit = PosixFDToRFDMap.find(posixFD); - if(mit == PosixFDToRFDMap.end()) { -// redisLog( REDIS_DEBUG, "RFDMap::removePosixFD() - failed to find posix FD!" ); - return; +void RFDMap::removePosixFD(int posixFD) { + EnterCriticalSection(&mutex); + PosixFD2RFDIterator mit = PosixFDToRFDMap.find(posixFD); + if (mit != PosixFDToRFDMap.end()) { + RFD rfd = (*mit).second; + RFDRecyclePool.push(rfd); + RFDToPosixFDMap.erase(rfd); + PosixFDToRFDMap.erase(posixFD); } - RFD rfd = (*mit).second; - RFDRecyclePool.push(rfd); - RFDToPosixFDMap.erase(rfd); - PosixFDToRFDMap.erase(posixFD); + LeaveCriticalSection(&mutex); } SOCKET RFDMap::lookupSocket(RFD rfd) { - if (RFDToSocketMap.find(rfd) != RFDToSocketMap.end()) { - return RFDToSocketMap[rfd]; - } else { -// redisLog( REDIS_DEBUG, "RFDMap::lookupSocket() - failed to find socket!" ); - return INVALID_SOCKET; - } + SOCKET socket = INVALID_SOCKET; + EnterCriticalSection(&mutex); + if (RFDToSocketMap.find(rfd) != RFDToSocketMap.end()) { + socket = RFDToSocketMap[rfd]; + } + LeaveCriticalSection(&mutex); + return socket; } int RFDMap::lookupPosixFD(RFD rfd) { - if (RFDToPosixFDMap.find(rfd) != RFDToPosixFDMap.end()) { - return RFDToPosixFDMap[rfd]; - } else if (rfd >= 0 && rfd <= 2) { - return rfd; - } - else { -// redisLog( REDIS_DEBUG, "RFDMap::lookupPosixFD() - failed to find posix FD!" ); - return -1; - } + int posixFD = -1; + EnterCriticalSection(&mutex); + if (RFDToPosixFDMap.find(rfd) != RFDToPosixFDMap.end()) { + posixFD = RFDToPosixFDMap[rfd]; + } else if (rfd >= 0 && rfd <= 2) { + posixFD = rfd; + } + LeaveCriticalSection(&mutex); + return posixFD; } -RFD RFDMap::lookupRFD(SOCKET s) { - if (SocketToRFDMap.find(s) != SocketToRFDMap.end()) { - return SocketToRFDMap[s]; - } else { -// redisLog( REDIS_DEBUG, "RFDMap::lookupFD() - failed to map SOCKET to RFD!" ); - return invalidRFD; - } -} - -RFD RFDMap::lookupRFD(int posixFD) { - if (PosixFDToRFDMap.find(posixFD) != PosixFDToRFDMap.end()) { - return PosixFDToRFDMap[posixFD]; - } else { -// redisLog( REDIS_DEBUG, "RFDMap::lookupFD() - failed to map posixFD to RFD!" ); - return invalidRFD; - } -} - -RFD RFDMap::getMinRFD() { - return minRFD; -} - -RFD RFDMap::getMaxRFD() { - return maxRFD; -} - -bool RFDMap::SetSocketState( SOCKET s, RedisSocketState state ) -{ +bool RFDMap::SetSocketState(SOCKET s, RedisSocketState state) { + bool result = false; + EnterCriticalSection(&mutex); S2StateIterator sit = SocketToStateMap.find(s); - if(sit != SocketToStateMap.end() ) { + if (sit != SocketToStateMap.end()) { SocketToStateMap[s] = state; - return true; - } else { - return false; + result = true; } + LeaveCriticalSection(&mutex); + return result; } -bool RFDMap::GetSocketState( SOCKET s, RedisSocketState& state ) -{ +bool RFDMap::GetSocketState(SOCKET s, RedisSocketState& state) { + bool result = false; + EnterCriticalSection(&mutex); S2StateIterator sit = SocketToStateMap.find(s); - if(sit != SocketToStateMap.end() ) { + if (sit != SocketToStateMap.end()) { state = SocketToStateMap[s]; - return true; - } else { - return false; + result = true; } + LeaveCriticalSection(&mutex); + return result; } diff --git a/src/Win32_Interop/win32_rfdmap.h b/src/Win32_Interop/win32_rfdmap.h index 7625132e..227a0274 100644 --- a/src/Win32_Interop/win32_rfdmap.h +++ b/src/Win32_Interop/win32_rfdmap.h @@ -23,15 +23,12 @@ #pragma once #include - #define INCL_WINSOCK_API_PROTOTYPES 0 // Important! Do not include Winsock API definitions to avoid conflicts with API entry points defnied below. #include #include "ws2tcpip.h" - -//#include - #include #include + using namespace std; typedef struct { @@ -69,65 +66,56 @@ public: private: RFDMap(); - RFDMap(RFDMap const&); // Don't implement to guarantee singleton semantics - void operator=(RFDMap const&); // Don't implement to guarantee singleton semantics + RFDMap(RFDMap const&); // Don't implement to guarantee singleton semantics + void operator=(RFDMap const&); // Don't implement to guarantee singleton semantics private: - SocketToRFDMapType SocketToRFDMap; - SocketToStateMapType SocketToStateMap; + SocketToRFDMapType SocketToRFDMap; + SocketToStateMapType SocketToStateMap; PosixFDToRFDMapType PosixFDToRFDMap; - RFDToSocketMapType RFDToSocketMap; - RFDToPosixFDMapType RFDToPosixFDMap; - RFDRecyclePoolType RFDRecyclePool; - -public: - const static int minRFD = 3; // 0, 1 and 2 are reserved for stdin, stdout and stderr - RFD maxRFD; - const static int invalidRFD = -1; + RFDToSocketMapType RFDToSocketMap; + RFDToPosixFDMapType RFDToPosixFDMap; + RFDRecyclePoolType RFDRecyclePool; private: - /* Gets the next available Redis File Descriptor. Redis File Descriptors are always - non-negative integers, with the first three being reserved for stdin(0), - stdout(1) and stderr(2). */ - RFD getNextRFDAvailable(); + const static int minRFD = 3; // 0, 1 and 2 are reserved for stdin, stdout and stderr + RFD maxRFD; + CRITICAL_SECTION mutex; public: - /* Adds a socket to the socket map. Returns the redis file descriptor value for - the socket. Returns invalidRFD if the socket is already added to the - collection. */ - RFD addSocket(SOCKET s); + const static int invalidRFD = -1; - /* Removes a socket from the list of sockets. Also removes the associated - file descriptor. */ - void removeSocket(SOCKET s); +private: + /* Gets the next available Redis File Descriptor. Redis File Descriptors are always + non-negative integers, with the first three being reserved for stdin(0), + stdout(1) and stderr(2). */ + RFD getNextRFDAvailable(); - /* Adds a posixFD (used with low-level CRT posix file functions) to the posixFD map. Returns +public: + /* Adds a socket to the socket map. Returns the redis file descriptor value for + the socket. Returns invalidRFD if the socket is already added to the + collection. */ + RFD addSocket(SOCKET s); + + /* Removes a socket from the list of sockets. Also removes the associated + file descriptor. */ + void removeSocket(SOCKET s); + + /* Adds a posixFD (used with low-level CRT posix file functions) to the posixFD map. Returns the redis file descriptor value for the posixFD. Returns invalidRFD if the posicFD is already added to the collection. */ - RFD addPosixFD(int posixFD); + RFD addPosixFD(int posixFD); - /* Removes a socket from the list of sockets. Also removes the associated - file descriptor. */ - void removePosixFD(int posixFD); - - /* Returns the socket associated with a file descriptor. */ - SOCKET lookupSocket(RFD rfd); + /* Removes a socket from the list of sockets. Also removes the associated + file descriptor. */ + void removePosixFD(int posixFD); /* Returns the socket associated with a file descriptor. */ - int lookupPosixFD(RFD rfd); + SOCKET lookupSocket(RFD rfd); - /* Returns the RFD associated with a socket. */ - RFD lookupRFD(SOCKET s); + /* Returns the socket associated with a file descriptor. */ + int lookupPosixFD(RFD rfd); - /* Returns the RFD associated with a posix FD. */ - RFD lookupRFD(int posixFD); - - /* Returns the smallest RFD available */ - RFD getMinRFD(); - - /* Returns the largest FD allocated so far */ - RFD getMaxRFD(); - - bool SetSocketState( SOCKET s, RedisSocketState state ); - bool GetSocketState( SOCKET s, RedisSocketState& state ); + bool SetSocketState(SOCKET s, RedisSocketState state); + bool GetSocketState(SOCKET s, RedisSocketState& state); }; diff --git a/src/Win32_Interop/win32_types.h b/src/Win32_Interop/win32_types.h index 5241ed79..d0368b28 100644 --- a/src/Win32_Interop/win32_types.h +++ b/src/Win32_Interop/win32_types.h @@ -51,17 +51,17 @@ typedef __int64 PORT_LONGLONG; typedef unsigned __int64 PORT_ULONGLONG; typedef double PORT_LONGDOUBLE; -#if defined(_WIN64) +#ifdef _WIN64 typedef __int64 ssize_t; typedef __int64 PORT_LONG; typedef unsigned __int64 PORT_ULONG; #else - typedef _W64 long ssize_t; - typedef _W64 long PORT_LONG; - typedef _W64 unsigned long PORT_ULONG; + typedef long ssize_t; + typedef long PORT_LONG; + typedef unsigned long PORT_ULONG; #endif -#if defined(_WIN64) +#ifdef _WIN64 #define PORT_LONG_MAX _I64_MAX #define PORT_LONG_MIN _I64_MIN #define PORT_ULONG_MAX _UI64_MAX @@ -72,6 +72,6 @@ typedef double PORT_LONGDOUBLE; #endif /* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - +#define MAX_SIZE_T (~(size_t)0) +typedef int pid_t; \ No newline at end of file diff --git a/src/Win32_Interop/win32_wsiocp.c b/src/Win32_Interop/win32_wsiocp.c index f4ea61cd..ee9ed7a8 100644 --- a/src/Win32_Interop/win32_wsiocp.c +++ b/src/Win32_Interop/win32_wsiocp.c @@ -31,7 +31,6 @@ #include #include - static void *iocpState; static HANDLE iocph; static fnGetSockState * aeGetSockState; @@ -94,7 +93,7 @@ int aeWinQueueAccept(int listenfd) { return -1; } - return TRUE; + return 0; } /* listen using extension function to get faster accepts */ @@ -126,7 +125,7 @@ int aeWinListen(int rfd, int backlog) { /* return the queued accept socket */ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { aeSockState *sockstate; - int acceptsock; + int acceptfd; int result; SOCKADDR *plocalsa; SOCKADDR *premotesa; @@ -139,7 +138,6 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { return SOCKET_ERROR; } - areq = sockstate->reqs; if (areq == NULL) { errno = EWOULDBLOCK; @@ -148,9 +146,9 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { sockstate->reqs = areq->next; - acceptsock = (int)areq->accept; + acceptfd = (int)areq->accept; - result = FDAPI_UpdateAcceptContext(acceptsock); + result = FDAPI_UpdateAcceptContext(acceptfd); if (result == SOCKET_ERROR) { errno = WSAGetLastError(); return SOCKET_ERROR; @@ -158,7 +156,7 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { locallen = *len; FDAPI_GetAcceptExSockaddrs( - acceptsock, + acceptfd, areq->buf, 0, sizeof(struct sockaddr_storage), @@ -170,10 +168,10 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { memcpy(sa, premotesa, locallen); *len = locallen; - aeWinSocketAttach(acceptsock); + aeWinSocketAttach(acceptfd); // Save remote address to support aeWinGetPeerName() - if ((acceptsockstate = aeGetExistingSockState(iocpState, acceptsock)) == NULL) { + if ((acceptsockstate = aeGetExistingSockState(iocpState, acceptfd)) == NULL) { errno = WSAEINVAL; return SOCKET_ERROR; } @@ -187,7 +185,7 @@ int aeWinAccept(int fd, struct sockaddr *sa, socklen_t *len) { return SOCKET_ERROR; } - return acceptsock; + return acceptfd; } int aeWinGetPeerName(int fd, struct sockaddr *addr, socklen_t * addrlen) { diff --git a/src/Win32_Interop/win32fixes.c b/src/Win32_Interop/win32fixes.c index 3f310d48..6aef31d0 100644 --- a/src/Win32_Interop/win32fixes.c +++ b/src/Win32_Interop/win32fixes.c @@ -20,6 +20,7 @@ #include #include //#include +#include "Win32_ThreadControl.h" /* Redefined here to avoid redis.h so it can be used in other projects */ #define REDIS_NOTUSED(V) ((void) V) @@ -149,12 +150,16 @@ typedef struct thread_params /* Proxy function by windows thread requirements */ static unsigned __stdcall win32_proxy_threadproc(void *arg) { + IncrementWorkerThreadCount(); + __try { + thread_params *p = (thread_params *) arg; + p->func(p->arg); - thread_params *p = (thread_params *) arg; - p->func(p->arg); - - /* Dealocate params */ - free(p); + /* Dealocate params */ + free(p); + } __finally { + DecrementWorkerThreadCount(); + } _endthreadex(0); return 0; @@ -679,7 +684,7 @@ int truncate(const char *path, PORT_LONGLONG length) { toTruncate = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (toTruncate != INVALID_HANDLE_VALUE) { newSize.QuadPart = length; - if (FALSE == SetFilePointerEx(toTruncate, newSize, NULL, FILE_BEGIN)) { + if (FALSE == (SetFilePointerEx(toTruncate, newSize, NULL, FILE_BEGIN) && SetEndOfFile(toTruncate))) { errno = ENOENT; return -1; } else { diff --git a/src/Win32_Interop/win32fixes.h b/src/Win32_Interop/win32fixes.h index 7137b184..bf4aefe0 100644 --- a/src/Win32_Interop/win32fixes.h +++ b/src/Win32_Interop/win32fixes.h @@ -178,7 +178,6 @@ int getrusage(int who, struct rusage * rusage); #endif /*SIG_SETMASK*/ typedef void (*__p_sig_fn_t)(int); -typedef DWORD pid_t; #ifndef _SIGSET_T_ #define _SIGSET_T_ diff --git a/src/aof.c b/src/aof.c index d70e44e4..c8597f25 100644 --- a/src/aof.c +++ b/src/aof.c @@ -220,14 +220,14 @@ void stopAppendOnly(void) { server.aof_state = REDIS_AOF_OFF; /* rewrite operation in progress? kill it, wait child exit */ if (server.aof_child_pid != -1) { - redisLog(REDIS_NOTICE, "Killing running AOF rewrite child: %Id", /* PORTABILITY FIX %ld -> %Id */ + redisLog(REDIS_NOTICE, "Killing running AOF rewrite child: %Id", WIN_PORT_FIX /* %ld -> %Id */ (PORT_LONG) server.aof_child_pid); #ifdef _WIN32 AbortForkOperation(); #else { int statloc; - if (kill(server.aof_child_pid,SIGUSR1) != -1) + if (kill(server.aof_child_pid,SIGUSR1) != -1) wait3(&statloc,0,NULL); } #endif @@ -1289,36 +1289,6 @@ void aofClosePipes(void) { * finally will rename(2) the temp file in the actual file name. * The the new file is reopened as the new append only file. Profit! */ -#ifdef _WIN32 -int rewriteAppendOnlyFileBackground(void) { - PORT_LONGLONG start; - char tmpfile[256]; - - if (server.aof_child_pid != -1) return REDIS_ERR; - start = ustime(); - - snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid()); - if (BeginForkOperation_Aof(tmpfile, &server, sizeof(server), &server.aof_child_pid, dictGetHashFunctionSeed(), server.logfile) == FALSE) { - redisLog(REDIS_WARNING, - "Can't rewrite append only file in background: fork: %s", - strerror(errno)); - return REDIS_ERR; - } - server.stat_fork_time = ustime()-start; - - redisLog(REDIS_NOTICE, - "Background append only file rewriting started by pid %d",server.aof_child_pid); - server.aof_rewrite_scheduled = 0; - server.aof_rewrite_time_start = time(NULL); - updateDictResizePolicy(); - /* We set appendseldb to -1 in order to force the next call to the - * feedAppendOnlyFile() to issue a SELECT command, so the differences - * accumulated by the parent into server.aof_rewrite_buf will start - * with a SELECT statement and it will be safe to merge. */ - server.aof_selected_db = -1; - return REDIS_OK; -} -#else int rewriteAppendOnlyFileBackground(void) { pid_t childpid; PORT_LONGLONG start; @@ -1326,13 +1296,21 @@ int rewriteAppendOnlyFileBackground(void) { if (server.aof_child_pid != -1) return REDIS_ERR; if (aofCreatePipes() != REDIS_OK) return REDIS_ERR; start = ustime(); + +#ifndef _WIN32 if ((childpid = fork()) == 0) { +#endif char tmpfile[256]; - /* Child */ +#ifndef _WIN32 + /* Child */ closeListeningSockets(0); redisSetProcTitle("redis-aof-rewrite"); +#endif snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid()); +#ifdef _WIN32 + childpid = BeginForkOperation_Aof(tmpfile, &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile); +#else if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) { size_t private_dirty = zmalloc_get_private_dirty(); @@ -1346,6 +1324,7 @@ int rewriteAppendOnlyFileBackground(void) { exitFromChild(1); } } else { +#endif /* Parent */ server.stat_fork_time = ustime()-start; server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */ @@ -1369,10 +1348,11 @@ int rewriteAppendOnlyFileBackground(void) { server.aof_selected_db = -1; replicationScriptCacheFlush(); return REDIS_OK; +#ifndef _WIN32 } +#endif return REDIS_OK; /* unreached */ } -#endif void bgrewriteaofCommand(redisClient *c) { if (server.aof_child_pid != -1) { diff --git a/src/bio.c b/src/bio.c index e187942d..381fa9b1 100644 --- a/src/bio.c +++ b/src/bio.c @@ -64,6 +64,7 @@ #include "bio.h" #ifdef _WIN32 #include "win32_Interop/win32fixes.h" +#include "Win32_Interop/Win32_ThreadControl.h" #endif static pthread_t bio_threads[REDIS_BIO_NUM_OPS]; @@ -158,6 +159,7 @@ void *bioProcessBackgroundJobs(void *arg) { #endif pthread_mutex_lock(&bio_mutex[type]); + /* Block SIGALRM so we are sure that only the main thread will * receive the watchdog signal. */ sigemptyset(&sigset); @@ -171,7 +173,11 @@ void *bioProcessBackgroundJobs(void *arg) { /* The loop always starts with the lock hold. */ if (listLength(bio_jobs[type]) == 0) { + WIN32_ONLY(WorkerThread_EnterSafeMode()); pthread_cond_wait(&bio_condvar[type],&bio_mutex[type]); + WIN32_ONLY(pthread_mutex_unlock(&bio_mutex[type])); + WIN32_ONLY(WorkerThread_ExitSafeMode()); + WIN32_ONLY(pthread_mutex_lock(&bio_mutex[type])); continue; } /* Pop the job from the queue. */ diff --git a/src/debug.c b/src/debug.c index dbf162ec..14b4f424 100644 --- a/src/debug.c +++ b/src/debug.c @@ -481,8 +481,12 @@ void _redisAssertWithInfo(redisClient *c, robj *o, char *estr, char *file, int l void _redisPanic(char *msg, char *file, int line) { bugReportStart(); redisLog(REDIS_WARNING,"------------------------------------------------"); +#ifdef _WIN32 + redisLog(REDIS_WARNING, "Fatal Error: %s #%s:%d", msg, file, line); +#else redisLog(REDIS_WARNING,"!!! Software Failure. Press left mouse button to continue"); redisLog(REDIS_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line); +#endif #ifdef HAVE_BACKTRACE redisLog(REDIS_WARNING,"(forcing SIGSEGV in order to print the stack trace)"); #endif diff --git a/src/latency.c b/src/latency.c index d978cfad..68b2acd3 100644 --- a/src/latency.c +++ b/src/latency.c @@ -547,7 +547,7 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { } graph = sdscatprintf(graph, - "%s - high %Iu ms, low %Iu ms (all time high %Iu ms)\n", event, /* PORTABILITY FIX %ld -> %Id, %lu -> %Iu */ + "%s - high %Iu ms, low %Iu ms (all time high %Iu ms)\n", event, WIN_PORT_FIX /* %ld -> %Id, %lu -> %Iu */ (PORT_ULONG) max, (PORT_ULONG) min, (PORT_ULONG) ts->max); for (j = 0; j < LATENCY_GRAPH_COLS; j++) graph = sdscatlen(graph,"-",1); diff --git a/src/memtest.c b/src/memtest.c index f45e2cf0..f361d88e 100644 --- a/src/memtest.c +++ b/src/memtest.c @@ -228,12 +228,21 @@ void memtest_compare_times(PORT_ULONG *m, size_t bytes, int pass, int times) { void memtest_test(size_t megabytes, int passes) { size_t bytes = megabytes * 1024 * 1024; +#ifdef _WIN32 + PORT_ULONG *m = VirtualAllocEx( + GetCurrentProcess(), + NULL, + bytes, + MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, + PAGE_READWRITE); +#else PORT_ULONG *m = malloc(bytes); +#endif int pass = 0; if (m == NULL) { - fprintf(stderr,"Unable to allocate %Iu megabytes: %s", - megabytes,strerror(errno)); WIN_PORT_FIX /* %zu -> %Iu */ + fprintf(stderr,"Unable to allocate %Iu megabytes: %s", WIN_PORT_FIX /* %zu -> %Iu */ + megabytes,strerror(errno)); exit(1); } while (pass != passes) { diff --git a/src/object.c b/src/object.c index 3f0cea17..2b21ebd2 100644 --- a/src/object.c +++ b/src/object.c @@ -140,7 +140,7 @@ robj *createStringObjectFromLongDouble(PORT_LONGDOUBLE value, int humanfriendly) * way that is "non surprising" for the user (that is, most small * decimal numbers will be represented in a way that when converted * back into a string are exactly the same as what the user typed.) */ - len = snprintf(buf,sizeof(buf),"%.15Lf",value); WIN_PORT_FIX /* %.17 -> %.15 on Windows the magic number is 15 */ + len = snprintf(buf,sizeof(buf),"%.15Lf",value); WIN_PORT_FIX /* %.17 -> %.15 on Windows the magic number is 15 */ /* Now remove trailing zeroes after the '.' */ if (strchr(buf,'.') != NULL) { char *p = buf+len-1; diff --git a/src/rdb.c b/src/rdb.c index f3fdacb7..76d2dcfa 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -788,24 +788,6 @@ werr: return REDIS_ERR; } -#ifdef _WIN32 -int rdbSaveBackground(char *filename) { - PORT_LONGLONG start; - start = ustime(); - server.dirty_before_bgsave = server.dirty; - if (BeginForkOperation_Rdb(filename, &server, sizeof(server), &server.rdb_child_pid, dictGetHashFunctionSeed(), server.logfile)) { - server.stat_fork_time = ustime()-start; - server.rdb_child_type = REDIS_RDB_CHILD_TYPE_DISK; - updateDictResizePolicy(); - return REDIS_OK; - } else { - redisLog(REDIS_WARNING,"Can't save in background: fork: %s", strerror(errno)); - return REDIS_ERR; - } -} - -#else - int rdbSaveBackground(char *filename) { pid_t childpid; PORT_LONGLONG start; @@ -816,6 +798,9 @@ int rdbSaveBackground(char *filename) { server.lastbgsave_try = time(NULL); start = ustime(); +#ifdef _WIN32 + childpid = BeginForkOperation_Rdb(filename, &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile); +#else if ((childpid = fork()) == 0) { int retval; @@ -834,6 +819,7 @@ int rdbSaveBackground(char *filename) { } exitFromChild((retval == REDIS_OK) ? 0 : 1); } else { +#endif /* Parent */ server.stat_fork_time = ustime()-start; server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */ @@ -850,10 +836,11 @@ int rdbSaveBackground(char *filename) { server.rdb_child_type = REDIS_RDB_CHILD_TYPE_DISK; updateDictResizePolicy(); return REDIS_OK; +#ifndef _WIN32 } +#endif return REDIS_OK; /* unreached */ } -#endif void rdbRemoveTempFile(pid_t childpid) { char tmpfile[256]; @@ -1482,7 +1469,9 @@ int rdbSaveToSlavesSockets(void) { /* Create the child process. */ start = ustime(); -#ifndef _WIN32 +#ifdef _WIN32 + childpid = BeginForkOperation_Socket(fds, numfds, clientids, pipefds[1], &server, sizeof(server), dictGetHashFunctionSeed(), server.logfile); +#else if ((childpid = fork()) == 0) { /* Child */ int retval; @@ -1549,12 +1538,6 @@ int rdbSaveToSlavesSockets(void) { zfree(clientids); exitFromChild((retval == REDIS_OK) ? 0 : 1); } else { -#else // #ifndef _WIN32 - if (!BeginForkOperation_Socket(fds, numfds, clientids, pipefds[1], &server, sizeof(server), &server.rdb_child_pid, dictGetHashFunctionSeed(), server.logfile)) { - redisLog(REDIS_WARNING,"Can't save in background: fork: %s", strerror(errno)); - return REDIS_ERR; - } else { - childpid = server.rdb_child_pid; #endif /* Parent */ zfree(clientids); /* Not used by parent. Free ASAP. */ @@ -1576,7 +1559,9 @@ int rdbSaveToSlavesSockets(void) { updateDictResizePolicy(); zfree(fds); return REDIS_OK; +#ifndef _WIN32 } +#endif return REDIS_OK; /* unreached */ } diff --git a/src/redis-check-dump.c b/src/redis-check-dump.c index 075e599f..5a238940 100644 --- a/src/redis-check-dump.c +++ b/src/redis-check-dump.c @@ -57,28 +57,29 @@ /* File maping used in redis-check-dump */ /* mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); */ void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { - HANDLE h; - void *data; + HANDLE h; + void *data; - (void)offset; + (void) offset; - if ((flags != MAP_SHARED) || (prot != PROT_READ)) { - /* Not supported in this port */ - return MAP_FAILED; + if ((flags != MAP_SHARED) || (prot != PROT_READ)) { + /* Not supported in this port */ + return MAP_FAILED; }; - h = CreateFileMapping((HANDLE)_get_osfhandle(fd), - NULL,PAGE_READONLY,0,0,NULL); + h = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL); + if (!h) { + return MAP_FAILED; + } - if (!h) return MAP_FAILED; + data = MapViewOfFileEx(h, FILE_MAP_READ, 0, 0, length, start); + CloseHandle(h); - data = MapViewOfFileEx(h, FILE_MAP_READ,0,0,length,start); + if (!data) { + return MAP_FAILED; + } - CloseHandle(h); - - if (!data) return MAP_FAILED; - - return data; + return data; } /* Unmap file mapping */ diff --git a/src/redis.c b/src/redis.c index 9bfc66c4..2939df42 100644 --- a/src/redis.c +++ b/src/redis.c @@ -29,6 +29,10 @@ #ifdef _WIN32 #include "win32_Interop\win32_util.h" +#include "Win32_Interop\Win32_FDAPI.h" +#include "Win32_Interop\Win32_ThreadControl.h" +#include +#define LOG_LOCAL0 0 #endif #include "redis.h" @@ -39,11 +43,7 @@ #include #include -#ifdef _WIN32 -#include -#define LOG_LOCAL0 0 -#include "redisLog.h" -#else +#ifndef _WIN32 #include #include #include @@ -60,10 +60,8 @@ #include #include #include +#ifndef _WIN32 #include - -#ifdef _WIN32 -#include "Win32_Interop\Win32_FDAPI.h" #endif /* Our shared "common" objects */ @@ -1148,10 +1146,10 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData if (!server.sentinel_mode) { run_with_period(5000) { redisLog(REDIS_VERBOSE, - "%Iu clients connected (%Iu slaves), %Iu bytes in use", + "%Iu clients connected (%Iu slaves), %Iu bytes in use", WIN_PORT_FIX /* %zu -> %Iu */ listLength(server.clients)-listLength(server.slaves), listLength(server.slaves), - zmalloc_used_memory()); WIN_PORT_FIX /* %zu -> %Iu */ + zmalloc_used_memory()); } } @@ -1172,19 +1170,23 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData /* Check if a background saving or AOF rewrite in progress terminated. */ if (server.rdb_child_pid != -1 || server.aof_child_pid != -1) { #ifdef _WIN32 - if (GetForkOperationStatus() == osCOMPLETE || GetForkOperationStatus() == osFAILED) { - int exitCode; - int bySignal; - bySignal = (int)(GetForkOperationStatus() == osFAILED); - redisLog(REDIS_WARNING, (bySignal ? "fork operation failed" : "fork operation complete")); - EndForkOperation(&exitCode); - if (server.rdb_child_pid != -1) { - backgroundSaveDoneHandler(exitCode, bySignal); - } else { - backgroundRewriteDoneHandler(exitCode, bySignal); - } - updateDictResizePolicy(); - } + if (GetForkOperationStatus() == osCOMPLETE || GetForkOperationStatus() == osFAILED) { + RequestSuspension(); + if (SuspensionCompleted()) { + int exitCode; + int bySignal; + bySignal = (int)(GetForkOperationStatus() == osFAILED); + redisLog(REDIS_WARNING, (bySignal ? "fork operation failed" : "fork operation complete")); + EndForkOperation(&exitCode); + ResumeFromSuspension(); + if (server.rdb_child_pid != -1) { + backgroundSaveDoneHandler(exitCode, bySignal); + } else { + backgroundRewriteDoneHandler(exitCode, bySignal); + } + updateDictResizePolicy(); + } + } #else int statloc; pid_t pid; @@ -1453,23 +1455,8 @@ void initServerConfig(void) { server.saveparams = NULL; server.loading = 0; server.logfile = zstrdup(REDIS_DEFAULT_LOGFILE); -#ifdef _WIN32 - // this is handled before redis_main() in Win32_QFork.cpp:::SetupLogging() - /* - if (RunningAsService()) { - server.syslog_enabled = 1; - server.syslog_ident = zstrdup(GetServiceName()); - } else { - server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT); - server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED; - } - setSyslogEnabled(server.syslog_enabled); - setSyslogIdent(server.syslog_ident); - */ -#else - server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED; + server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED; server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT); -#endif server.syslog_facility = LOG_LOCAL0; server.daemonize = REDIS_DEFAULT_DAEMONIZE; server.aof_state = REDIS_AOF_OFF; @@ -2731,12 +2718,14 @@ sds genRedisInfoString(char *section) { "os:%s %s %s\r\n" "arch_bits:%d\r\n" "multiplexing_api:%s\r\n" +#ifndef _WIN32 "gcc_version:%d.%d.%d\r\n" +#endif "process_id:%ld\r\n" "run_id:%s\r\n" "tcp_port:%d\r\n" #ifdef _WIN32 - "uptime_in_seconds:%lld\r\n" /* BUGBUG: fix %lld */ + "uptime_in_seconds:%lld\r\n" "uptime_in_days:%lld\r\n" #else "uptime_in_seconds:%jd\r\n" @@ -2757,10 +2746,12 @@ sds genRedisInfoString(char *section) { #endif server.arch_bits, aeGetApiName(), +#ifndef _WIN32 #ifdef __GNUC__ __GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__, #else 0,0,0, +#endif #endif (PORT_LONG) getpid(), server.runid, @@ -2902,7 +2893,7 @@ sds genRedisInfoString(char *section) { "aof_current_size:%lld\r\n" "aof_base_size:%lld\r\n" "aof_pending_rewrite:%d\r\n" - "aof_buffer_length:%Iu\r\n" + "aof_buffer_length:%Iu\r\n" WIN_PORT_FIX /* %zu -> %Iu */ "aof_rewrite_buffer_length:%lu\r\n" "aof_pending_bio_fsync:%llu\r\n" "aof_delayed_fsync:%lu\r\n", @@ -2912,7 +2903,7 @@ sds genRedisInfoString(char *section) { sdslen(server.aof_buf), aofRewriteBufferSize(), bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC), - server.aof_delayed_fsync); WIN_PORT_FIX /* %zu -> %Iu */ + server.aof_delayed_fsync); } if (server.loading) { @@ -3688,9 +3679,17 @@ void loadDataFromDisk(void) { } void redisOutOfMemoryHandler(size_t allocation_size) { - redisLog(REDIS_WARNING,"Out Of Memory allocating %Iu bytes!", - allocation_size); WIN_PORT_FIX /* %zu -> %Iu */ +#ifdef _WIN32 + bugReportStart(); + redisLog(REDIS_WARNING, "Out Of Memory allocating %Iu bytes.", /* %zu -> %Iu */ + allocation_size); + // Call abort() instead of forcing an access violation in redisPanic + abort(); +#else + redisLog(REDIS_WARNING,"Out Of Memory allocating %zu bytes!", + allocation_size); redisPanic("Redis aborting for OUT OF MEMORY"); +#endif } void redisSetProcTitle(char *title) { diff --git a/src/redis.h b/src/redis.h index 4f724ab6..9eb187fa 100644 --- a/src/redis.h +++ b/src/redis.h @@ -73,7 +73,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */ #include "latency.h" /* Latency monitor API */ #include "sparkline.h" /* ASII graphs API */ -#include "redisLog.h" /* moved logging for hiredis and RedisCli usage /* +#include "Win32_Interop/Win32_RedisLog.h" /* moved logging for hiredis and RedisCli usage /* /* Error codes */ #define REDIS_OK 0 @@ -94,7 +94,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */ #define REDIS_SHARED_INTEGERS 10000 #define REDIS_SHARED_BULKHDR_LEN 32 #ifdef _WIN32 -// see redisLog.h +// see Win32_RedisLog.h #else #define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */ #endif @@ -314,7 +314,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */ #define REDIS_SORTKEY_MAX 1024 #ifdef _WIN32 -// see redisLog.h +// see Win32_RedisLog.h #else /* Log levels */ #define REDIS_DEBUG 0 diff --git a/src/replication.c b/src/replication.c index f8b06285..e6110575 100644 --- a/src/replication.c +++ b/src/replication.c @@ -283,7 +283,7 @@ void replicationFeedMonitors(redisClient *c, list *monitors, int dictid, robj ** for (j = 0; j < argc; j++) { if (argv[j]->encoding == REDIS_ENCODING_INT) { - cmdrepr = sdscatprintf(cmdrepr, "\"%Id\"", (PORT_LONG) argv[j]->ptr); /* PORTABILITY FIX %ld -> %Id */ + cmdrepr = sdscatprintf(cmdrepr, "\"%Id\"", (PORT_LONG) argv[j]->ptr); WIN_PORT_FIX /* %ld -> %Id */ } else { cmdrepr = sdscatrepr(cmdrepr,(char*)argv[j]->ptr, sdslen(argv[j]->ptr)); @@ -1041,7 +1041,7 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) { "MASTER <-> SLAVE sync: receiving streamed RDB from master"); } else { usemark = 0; - server.repl_transfer_size = IF_WIN32(strtoll,strtol)(buf+1,NULL,10); + server.repl_transfer_size = IF_WIN32(strtoll,strtol)(buf+1,NULL,10); /* BUGBUG: verify for 32bit support */ redisLog(REDIS_NOTICE, "MASTER <-> SLAVE sync: receiving %lld bytes from master", (PORT_LONGLONG) server.repl_transfer_size); diff --git a/src/scripting.c b/src/scripting.c index ab5f959f..9cec41fa 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -612,11 +612,12 @@ void scriptingEnableGlobalsProtection(lua_State *lua) { /* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html. * Modified to be adapted to Redis. */ + s[j++]="local dbg=debug\n"; s[j++]="local mt = {}\n"; s[j++]="setmetatable(_G, mt)\n"; s[j++]="mt.__newindex = function (t, n, v)\n"; - s[j++]=" if debug.getinfo(2) then\n"; - s[j++]=" local w = debug.getinfo(2, \"S\").what\n"; + s[j++]=" if dbg.getinfo(2) then\n"; + s[j++]=" local w = dbg.getinfo(2, \"S\").what\n"; s[j++]=" if w ~= \"main\" and w ~= \"C\" then\n"; s[j++]=" error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n"; s[j++]=" end\n"; @@ -624,11 +625,12 @@ void scriptingEnableGlobalsProtection(lua_State *lua) { s[j++]=" rawset(t, n, v)\n"; s[j++]="end\n"; s[j++]="mt.__index = function (t, n)\n"; - s[j++]=" if debug.getinfo(2) and debug.getinfo(2, \"S\").what ~= \"C\" then\n"; + s[j++]=" if dbg.getinfo(2) and dbg.getinfo(2, \"S\").what ~= \"C\" then\n"; s[j++]=" error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n"; s[j++]=" end\n"; s[j++]=" return rawget(t, n)\n"; s[j++]="end\n"; + s[j++]="debug = nil\n"; s[j++]=NULL; for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j])); @@ -732,10 +734,11 @@ void scriptingInit(void) { * information about the caller, that's what makes sense from the point * of view of the user debugging a script. */ { - char *errh_func = "function __redis__err__handler(err)\n" - " local i = debug.getinfo(2,'nSl')\n" + char *errh_func = "local dbg = debug\n" + "function __redis__err__handler(err)\n" + " local i = dbg.getinfo(2,'nSl')\n" " if i and i.what == 'C' then\n" - " i = debug.getinfo(3,'nSl')\n" + " i = dbg.getinfo(3,'nSl')\n" " end\n" " if i then\n" " return i.source .. ':' .. i.currentline .. ': ' .. err\n" diff --git a/src/sentinel.c b/src/sentinel.c index 4c9d1737..9e7050ed 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -776,7 +776,7 @@ void sentinelRunPendingScripts(void) { CloseHandle( pi.hThread ); sentinel.running_scripts++; - sentinelEvent(REDIS_DEBUG, "+script-child", NULL, "%ld", (long) sj->pid); /* BUGBUG: fix %ld */ + sentinelEvent(REDIS_DEBUG, "+script-child", NULL, "%Id", (PORT_LONG) sj->pid); WIN_PORT_FIX /* %ld -> %Id */ } else { sentinelEvent(REDIS_WARNING,"-script-error",NULL, "%s %d %d", sj->argv[0], 99, 0); @@ -845,8 +845,8 @@ void sentinelCollectTerminatedScripts(void) { if(WaitForSingleObject(sj->hScriptProcess,0) == WAIT_OBJECT_0) { GetExitCodeProcess(sj->hScriptProcess,&exitCode); - sentinelEvent(REDIS_DEBUG,"-script-child",NULL,"%ld %d %d", - (long) sj->pid, exitCode, 0); /* BUGBUG: fix %ld */ + sentinelEvent(REDIS_DEBUG, "-script-child", NULL, "%Id %d %d", WIN_PORT_FIX /* %ld -> %Id*/ + (PORT_LONG) sj->pid, exitCode, 0); /* at this point the process ID may be recycled by Windows */ CloseHandle(sj->hScriptProcess); @@ -932,8 +932,8 @@ void sentinelKillTimedoutScripts(void) { if (sj->flags & SENTINEL_SCRIPT_RUNNING && (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME) { - sentinelEvent(REDIS_WARNING, "-script-timeout", NULL, "%s %ld", - sj->argv[0], (long) sj->pid); /* BUGBUG */ + sentinelEvent(REDIS_WARNING, "-script-timeout", NULL, "%s %Id", WIN_PORT_FIX /* %ld -> %Id*/ + sj->argv[0], (PORT_LONG) sj->pid); #ifdef _WIN32 TerminateProcess(sj->hScriptProcess,1); #else @@ -1607,16 +1607,16 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { /* sentinel down-after-milliseconds */ if (master->down_after_period != SENTINEL_DEFAULT_DOWN_AFTER) { line = sdscatprintf(sdsempty(), - "sentinel down-after-milliseconds %s %ld", - master->name, (long) master->down_after_period); /* BUGBUG */ + "sentinel down-after-milliseconds %s %Id", WIN_PORT_FIX /* %ld -> %Id*/ + master->name, (PORT_LONG) master->down_after_period); rewriteConfigRewriteLine(state,"sentinel",line,1); } /* sentinel failover-timeout */ if (master->failover_timeout != SENTINEL_DEFAULT_FAILOVER_TIMEOUT) { line = sdscatprintf(sdsempty(), - "sentinel failover-timeout %s %ld", - master->name, (long) master->failover_timeout); /* BUGBUG */ + "sentinel failover-timeout %s %Id", WIN_PORT_FIX /* %ld -> %Id*/ + master->name, (PORT_LONG) master->failover_timeout); rewriteConfigRewriteLine(state,"sentinel",line,1); } diff --git a/src/zmalloc.c b/src/zmalloc.c index 6a5dbce5..35880a08 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -131,8 +131,8 @@ pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER; #endif static void zmalloc_default_oom(size_t size) { - fprintf(stderr, "zmalloc: Out of memory trying to allocate %Iu bytes\n", - size); WIN_PORT_FIX /* %zu -> %Iu */ + fprintf(stderr, "zmalloc: Out of memory trying to allocate %Iu bytes\n", WIN_PORT_FIX /* %zu -> %Iu */ + size); fflush(stderr); abort(); } diff --git a/tests/integration/aof.tcl b/tests/integration/aof.tcl index f41a8603..d352d2a4 100644 --- a/tests/integration/aof.tcl +++ b/tests/integration/aof.tcl @@ -88,8 +88,9 @@ tags {"aof"} { test "Bad format: Server should have logged an error" { set pattern "*Bad file format reading the append only file*" set retry 10 + #WIN_PORT_FIX 'tail -n1' -> 'tail -1' while {$retry} { - set result [exec tail -n1 < [dict get $srv stdout]] + set result [exec tail -1 < [dict get $srv stdout]] if {[string match $pattern $result]} { break } @@ -113,8 +114,9 @@ tags {"aof"} { test "Unfinished MULTI: Server should have logged an error" { set pattern "*Unexpected end of file reading the append only file*" set retry 10 + #WIN_PORT_FIX 'tail -n1' -> 'tail -1' while {$retry} { - set result [exec tail -n1 < [dict get $srv stdout]] + set result [exec tail -1 < [dict get $srv stdout]] if {[string match $pattern $result]} { break } @@ -137,8 +139,9 @@ tags {"aof"} { test "Short read: Server should have logged an error" { set pattern "*Unexpected end of file reading the append only file*" set retry 10 + #WIN_PORT_FIX 'tail -n1' -> 'tail -1' while {$retry} { - set result [exec tail -n1 < [dict get $srv stdout]] + set result [exec tail -1 < [dict get $srv stdout]] if {[string match $pattern $result]} { break } diff --git a/tests/unit/aofrw.tcl b/tests/unit/aofrw.tcl index a2d74168..4acbdcd5 100644 --- a/tests/unit/aofrw.tcl +++ b/tests/unit/aofrw.tcl @@ -69,8 +69,9 @@ start_server {tags {"aofrw"}} { r bgrewriteaof r config set appendonly no r exec + #WIN_PORT_FIX 'tail -n5' -> 'tail -5' wait_for_condition 50 100 { - [string match {*Killing*AOF*child*} [exec tail -n5 < [srv 0 stdout]]] + [string match {*Killing*AOF*child*} [exec tail -5 < [srv 0 stdout]]] } else { fail "Can't find 'Killing AOF child' into recent logs" }