diff --git a/CMakeLists.txt b/CMakeLists.txt index ddc989b7c..aa8bde511 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,20 +6,27 @@ endif() message(STATUS "CMake version: ${CMAKE_VERSION}") -include(macros.cmake) - +include(${CMAKE_SOURCE_DIR}/cmake/macros.cmake) enable_testing() + +# Packaging builds install to /usr and other builds to /usr/local +if(PACKAGE) + set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Prefix prepended to install directories.") +endif() + +# Set default values for cache entries and set the MaxScale version set_variables() set_maxscale_version() -set(CMAKE_INSTALL_PREFIX "/usr/local/mariadb-maxscale" CACHE PATH "Prefix prepended to install directories.") set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") project(MaxScale) -#Disabled for now pending evaluation +# Set the installation layout +include(${CMAKE_SOURCE_DIR}/cmake/install_layout.cmake) + +#Do the platform check include(cmake/CheckPlatform.cmake) check_deps() @@ -37,7 +44,7 @@ if(NOT CURL_FOUND) message(FATAL_ERROR "Failed to locate dependency: libcurl") endif() -set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_INSTALL_PREFIX}/modules) +set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/${MAXSCALE_LIBDIR}) # Make sure the release notes for this release are present if it is a stable one if(${MAXSCALE_VERSION} MATCHES "-stable") @@ -49,10 +56,12 @@ if(${MAXSCALE_VERSION} MATCHES "-stable") endif() file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/server/include) -configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_BINARY_DIR}/server/include/version.h) -configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/server/include/maxscale_test.h) -configure_file(${CMAKE_SOURCE_DIR}/etc/postinst.in ${CMAKE_BINARY_DIR}/postinst) -configure_file(${CMAKE_SOURCE_DIR}/etc/postrm.in ${CMAKE_BINARY_DIR}/postrm) +configure_file(${CMAKE_SOURCE_DIR}/server/include/version.h.in ${CMAKE_BINARY_DIR}/server/include/version.h @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/server/include/gwdirs.h.in ${CMAKE_BINARY_DIR}/server/include/gwdirs.h @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.h.in ${CMAKE_BINARY_DIR}/server/include/maxscale_test.h @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/etc/postinst.in ${CMAKE_BINARY_DIR}/postinst @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/etc/postrm.in ${CMAKE_BINARY_DIR}/postrm @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/server/test/maxscale_test.cnf ${CMAKE_BINARY_DIR}/maxscale.cnf @ONLY) set(FLAGS "-Wall -Wno-unused-variable -Wno-unused-function -fPIC" CACHE STRING "Compilation flags") set(DEBUG_FLAGS "-ggdb -pthread -pipe -Wformat -fstack-protector --param=ssp-buffer-size=4" CACHE STRING "Debug compilation flags") @@ -70,7 +79,7 @@ if(CMAKE_VERSION VERSION_GREATER 2.6) endif() -IF(DEFINED OLEVEL ) +IF(DEFINED OLEVEL) if((OLEVEL GREATER -1) AND (OLEVEL LESS 4) ) set(FLAGS "${FLAGS} -O${OLEVEL}" CACHE STRING "Compilation flags" FORCE) message(STATUS "Optimization level at: ${OLEVEL}") @@ -128,7 +137,7 @@ if(NOT WITHOUT_MAXADMIN) add_subdirectory(client) endif() - +# Generate text versions of some documents execute_process(COMMAND perl ${CMAKE_SOURCE_DIR}/Documentation/format.pl ${CMAKE_SOURCE_DIR}/Documentation/Changelog.md ${CMAKE_BINARY_DIR}/Changelog.txt) @@ -138,23 +147,22 @@ ${CMAKE_SOURCE_DIR}/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md execute_process(COMMAND perl ${CMAKE_SOURCE_DIR}/Documentation/format.pl ${CMAKE_SOURCE_DIR}/Documentation/Upgrading-To-MaxScale-1.1.0.md ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt) -install(FILES ${CMAKE_BINARY_DIR}/Changelog.txt DESTINATION .) -install(FILES ${CMAKE_BINARY_DIR}/ReleaseNotes.txt DESTINATION .) -install(FILES ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt DESTINATION .) -message(STATUS "Installing MaxScale to: ${CMAKE_INSTALL_PREFIX}/") -install(FILES server/MaxScale_template.cnf DESTINATION etc) -install(FILES server/MaxScale_BinlogServer_template.cnf DESTINATION etc) -install(FILES ${ERRMSG} DESTINATION mysql) -install(FILES ${CMAKE_SOURCE_DIR}/COPYRIGHT DESTINATION .) -install(FILES ${CMAKE_SOURCE_DIR}/README DESTINATION .) -install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION .) -install(DIRECTORY DESTINATION log) +install(FILES ${CMAKE_BINARY_DIR}/Changelog.txt DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES ${CMAKE_BINARY_DIR}/ReleaseNotes.txt DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES server/maxscale_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES server/maxscale_binlogserver_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES ${ERRMSG} DESTINATION ${MAXSCALE_VARDIR}/lib/maxscale) +install(FILES ${CMAKE_SOURCE_DIR}/COPYRIGHT DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES ${CMAKE_SOURCE_DIR}/README DESTINATION ${MAXSCALE_SHAREDIR}) +install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${MAXSCALE_SHAREDIR}) # Install startup scripts and ldconfig files if(WITH_SCRIPTS) configure_file(${CMAKE_SOURCE_DIR}/maxscale.conf.in ${CMAKE_BINARY_DIR}/maxscale.conf @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/etc/maxscale.service.in ${CMAKE_BINARY_DIR}/maxscale.service @ONLY) if(DEB_BASED) configure_file(${CMAKE_SOURCE_DIR}/etc/ubuntu/init.d/maxscale.in ${CMAKE_BINARY_DIR}/maxscale @ONLY) else() @@ -163,6 +171,12 @@ if(WITH_SCRIPTS) if(PACKAGE) message(STATUS "maxscale.conf will unpack to: /etc/ld.so.conf.d") message(STATUS "startup scripts will unpack to to: /etc/init.d") + install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION ${MAXSCALE_SHAREDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION ${MAXSCALE_SHAREDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + install(FILES ${CMAKE_BINARY_DIR}/maxscale.service DESTINATION ${MAXSCALE_SHAREDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) else() install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION /etc/init.d PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) @@ -173,35 +187,23 @@ if(WITH_SCRIPTS) endif() endif() +# Only do packaging if configured if(PACKAGE) - install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION . + + # Install the files copied by the postinst script into the share folder + install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION . + install(FILES ${CMAKE_BINARY_DIR}/maxscale.conf DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - install(FILES ${CMAKE_BINARY_DIR}/postinst DESTINATION . + install(FILES ${CMAKE_BINARY_DIR}/postinst DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - install(FILES ${CMAKE_BINARY_DIR}/postrm DESTINATION . + install(FILES ${CMAKE_BINARY_DIR}/postrm DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) if(${CMAKE_VERSION} VERSION_LESS 2.8.12) message(WARNING "CMake version is ${CMAKE_VERSION}. Building of packages requires version 2.8.12 or greater.") else() - # See if we are on a RPM-capable or DEB-capable system - find_program(RPMBUILD rpmbuild) - find_program(DEBBUILD dpkg-buildpackage) - set(CPACK_GENERATOR "TGZ") - if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) - message(STATUS "Generating RPM packages") - set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") - endif() - - if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) - set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB") - execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE) - set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE}) - set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) - message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") - endif() + # Generic CPack configuration variables set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MaxScale") set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") @@ -212,18 +214,20 @@ if(PACKAGE) set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") - set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm") - set(CPACK_RPM_PACKAGE_RELEASE ${MAXSCALE_BUILD_NUMBER}) - set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postinst) - set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postrm) - set(CPACK_RPM_PACKAGE_NAME "maxscale") - set(CPACK_RPM_PACKAGE_VENDOR "MariaDB Corporation Ab") - set(CPACK_RPM_PACKAGE_LICENSE "GPLv2") - set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc /etc/ld.so.conf.d /etc/init.d /etc/rc.d/init.d") - set(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#") - set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d") - set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d") - set(CPACK_RPM_USER_FILELIST "%ignore /etc") + + # See if we are on a RPM-capable or DEB-capable system + find_program(RPMBUILD rpmbuild) + find_program(DEBBUILD dpkg-buildpackage) + set(CPACK_GENERATOR "TGZ") + + if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) + include(cmake/package_rpm.cmake) + message(STATUS "Generating RPM packages") + elseif(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) + include(cmake/package_deb.cmake) + message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") + endif() + include(CPack) endif() endif() @@ -235,16 +239,14 @@ add_custom_target(buildtests ) add_custom_target(testall - COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR} -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} COMMAND make install - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/testall.cmake COMMENT "Running full test suite..." VERBATIM) add_custom_target(testcore - COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N ${CMAKE_SOURCE_DIR} -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} COMMAND make install - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf COMMAND ctest -R Internal COMMENT "Running core test suite..." VERBATIM) diff --git a/Documentation/About/SETUP.md b/Documentation/About/SETUP.md index 2be316a4d..9cb5dd11b 100644 --- a/Documentation/About/SETUP.md +++ b/Documentation/About/SETUP.md @@ -1,37 +1,25 @@ Installation and startup Untar the binary distribution in the desired location, -e.g. /usr/local/mariadb +e.g. /usr/local/mariadb-maxscale Alternatively build from the source code using the instructions -in the README file and execute make install. +in the [Building MaxScale from Source Code](../Getting-Started/Building-MaxScale-from-Source-Code.md) document. -Simply set the environment variable MAXSCALE_HOME to point to the -MaxScale directory, found inside the path into which the files have been copied, -e.g. MAXSCALE_HOME=/usr/local/mariadb-maxscale - -Also you will need to optionally set LD_LIBRARY_PATH to include the 'lib' folder, -found inside the path into which the files have been copied, -e.g. LD_LIBRARY_PATH=/usr/local/mariadb-maxscale/lib - -Because we need the libmysqld library for parsing we must create a -valid my.cnf file to enable the library to be used. Copy the my.cnf -to $MAXSCALE_HOME/mysql/my.cnf. - -To start MaxScale execute the command 'maxscale' from the bin folder, -e.g. /usr/local/mariadb-maxscale/bin/maxscale +You can start MaxScale using `service maxscale start` or `systemctl start maxscale` if you installed the init.d scripts +or by manually starting the process from the bin folder of the installation directory. Configuration -You need to edit the file MaxScale.cnf in $MAXSCALE_HOME/etc, you should -define the set of server definitions you require, with the addresses -and ports of those servers. Also define the listening ports for your -various services. +You need to create or edit the MaxScale.cnf file in the /etc folder. +Define the services you wish to provide, the set of server definitions +you require, with the addresses and ports of those servers and also +define the listening ports for your various services. -In order to view the internal activity of the gateway you can telnet to +In order to view the internal activity of MaxScale you can either use +the maxadmin client interface with the cli routing module or telnet to the port defined for the telnet listener. Initially you may login with the user name of "admin" and the password "mariadb". Once connected type help for an overview of the commands and help for the more detailed help on commands. Use the add user command to add a new user, this will also remove the admin/mariadb user. - diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 888432fd2..7bc7abee6 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -27,11 +27,9 @@ connection failover| When a connection currently being used between MaxScale and The MaxScale configuration is read from a file which can be located in a number of placing, MaxScale will search for the configuration file in a number of locations. -1. If the environment variable `MAXSCALE_HOME` is set then MaxScale will look for a configuration file called `MaxScale.cnf` in the directory `$MAXSCALE_HOME/etc`. +1. Location given with the --configdir= command line argument -2. If `MAXSCALE_HOME` is not set or the configuration file is not in the location above MaxScale will look for a file in `/etc/MaxScale.cnf`. - -Alternatively MaxScale can be started with the `-c` flag and the path of the MaxScale home directory tree. +2. MaxScale will look for a configuration file called `MaxScale.cnf` in the directory `/etc/MaxScale.cnf` An explicit path to a configuration file can be passed by using the `-f` option to MaxScale. @@ -101,6 +99,46 @@ log_debug=1 To disable the log use the value 0 and to enable it use the value 1. +#### `logdir` + +Set the directory where the logfiles are stored. The folder needs to be both readable and writable by the user running MaxScale. + +``` +logdir=/tmp/ +``` + +#### `datadir` + +Set the directory where the data files used by MaxScale are stored. Modules can write to this directory and for example the binlogrouter uses this folder as the default location for storing binary logs. + +``` +datadir=/home/user/maxscale_data/ +``` + +#### `libdir` + +Set the directory where MaxScale looks for modules. The library director is the only directory that MaxScale uses when it searches for modules. If you have custom modules for MaxScale, make sure you have them in this folder. + +``` +libdir=/home/user/lib64/ +``` + +#### `cachedir` + +Configure the directory MaxScale uses to store cached data. An example of cached data is the authentication data fetched from the backend servers. MaxScale stores this in case a connection to the backend server is not possible. + +``` +cachedir=/tmp/maxscale_cache/ +``` + +#### `language` + +Set the folder where the errmsg.sys file is located in. MaxScale will look for the errmsg.sys file installed with MaxScale from this folder. + +``` +language=/home/user/lang/ +``` + ### Service A service represents the database service that MaxScale offers to the clients. In general a service consists of a set of backend database servers and a routing algorithm that determines how MaxScale decides to send statements or route connections to those backend servers. @@ -540,7 +578,7 @@ Default value is `2`. Write Timeout is the timeout in seconds for each attempt t ## Protocol Modules -The protocols supported by MaxScale are implemented as external modules that are loaded dynamically into the MaxScale core. These modules reside in the directory `$MAXSCALE_HOME/modules`, if the environment variable `$MAXSCALE_HOME` is not set it defaults to `/usr/local/mariadb-maxscale`. It may also be set by passing the `-c` option on the MaxScale command line. +The protocols supported by MaxScale are implemented as external modules that are loaded dynamically into the MaxScale core. These modules reside in the directory `/usr/lib64/maxscale`. The location can be overridden with the `libdir=PATH` parameter under the `[maxscale]` section. It may also be set by passing the `-B PATH` or `--libdir=PATH` option on the MaxScale command line. ### MySQLClient @@ -1274,7 +1312,7 @@ In addition parameters may be added to define patterns to match against to eithe The top filter is a filter module for MaxScale that monitors every SQL statement that passes through the filter. It measures the duration of that statement, the time between the statement being sent and the first result being returned. The top N times are kept, along with the SQL text itself and a list sorted on the execution times of the query is written to a file upon closure of the client session. -The configuration block for the **top** filter requires the minimal filter options in its section within the `MaxScale.cnf` file, stored in `$MAXSCALE_HOME/etc/MaxScale.cnf`. +The configuration block for the **top** filter requires the minimal filter options in its section within the `MaxScale.cnf` file, stored in `/etc/MaxScale.cnf`. ``` [MyLogFilter] @@ -1288,15 +1326,17 @@ In addition parameters may be added to define patterns to match against to eithe ## Encrypting Passwords -Passwords stored in the MaxScale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key. +Passwords stored in the MaxScale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key. The default location MaxScale stores the keys is `/var/cache/maxscale`. - maxkeys $MAXSCALE_HOME/etc/.secrets +``` +maxkeys /var/cache/maxscale/.secrets +``` Changing the encryption key for MaxScale will invalidate any currently encrypted keys stored in the MaxScale.cnf file. ### Creating Encrypted Passwords -Encrypted passwords are created by executing the maxpasswd command with the password you require to encrypt as an argument. The environment variable `MAXSCALE_HOME` must be set, or MaxScale must be installed in the default location before maxpasswd can be executed. +Encrypted passwords are created by executing the maxpasswd command with the password you require to encrypt as an argument. maxpasswd MaxScalePw001 61DD955512C39A4A8BC4BB1E5F116705 @@ -1382,7 +1422,7 @@ and short notations ## Error Reporting -MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. MaxScale will log to a set of files in the directory `$MAXSCALE_HOME/log`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor. +MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. By default, MaxScale will log to a set of files in the directory `/var/log/maxscale`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor. ### Troubleshooting diff --git a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md index 24ee54b22..6b84d8d58 100644 --- a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md +++ b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md @@ -62,11 +62,9 @@ shared objects that are loaded on demand. In order for MaxScale to find these modules it will search using a predescribed search path. The rules are: 1. Look in the current directory for the module - 2. Look in $MAXSCALE_HOME/modules - 3. Look in /usr/local/mariadb-maxscale/modules - -Configuration is read by default from the file $MAXSCALE_HOME/etc/MaxScale.cnf, /etc/MaxScale.cnf. An example file is included in in the installation and can be found in the etc/ folder within the MaxScale installation. The default value of MAXSCALE_HOME can be overridden by using the -c flag on the command line. This should be immediately followed by the path to the MaxScale home directory. The -f flag can be used on the command line to set the name and the location of the configuration file. Without path expression the file is read from \$MAXSCALE_HOME/etc directory. + 2. Look in /usr/lib64/maxscale +Configuration is read by default from the file /etc/MaxScale.cnf. An example file is included in in the installation and can be found in the /usr/share/maxscale folder within the MaxScale installation. The -f flag can be used on the command line to set the name and the location of the configuration file. Without path expression the file is read from the /etc directory. ## Administration Of MaxScale diff --git a/Documentation/Reference/Debug-And-Diagnostic-Support.md b/Documentation/Reference/Debug-And-Diagnostic-Support.md index 34fda6653..d9bffa268 100644 --- a/Documentation/Reference/Debug-And-Diagnostic-Support.md +++ b/Documentation/Reference/Debug-And-Diagnostic-Support.md @@ -1711,7 +1711,7 @@ User admin already exists. **MaxScale>**** ** -If you should forget or lose the the account details you may simply remove the passwd file in $MAXSCALE_HOME/etc and the system will revert to the default behavior with admin/mariadb as the account. +If you should forget or lose the the account details you may simply remove the passwd file in /var/cache/maxscale and the system will revert to the default behavior with admin/mariadb as the account. ## Enable/disable log @@ -1745,7 +1745,7 @@ MaxScale generates output of its behavior to four distinct logs, error, messages ## Log contents -By default all log files are located in : $MAXSCALE_HOME/log and named as : +By default all log files are located in : /var/log/maxscale and named as : skygw_errW.log, skygw_msgX.log, skygw_traceY.log and skygw_debugZ.log @@ -1837,7 +1837,7 @@ MariaDB Corporation MaxScale /home/jdoe/bin/develop/log/skygw_msg1.log Tue Dec ### Trace log -Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OSs shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm//skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the $MAXSCALE_HOME/log directory. +Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OSs shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm//skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the /var/log/maxscale directory. Individual trace log entry looks similar to those in other logs but there is some difference too. Some log entries include a number within square brackets to specify which client session they belong to. For example: @@ -1923,11 +1923,11 @@ In the log, session’s life cycle is covered by annotating its beginning and th The log files are located in -$MAXSCALE_HOME/log +/var/log/maxscale by default. If, however, trace and debug logs are enabled, only a soft link is created there. MaxScale process creates a directory under -/dev/shm/ +/dev/shm/maxscale. where it stores the physical trace and debug log files. Link and physical files share the same name. These logs consume the main memory of the host they run on so it is important to archive or remove them periodically to avoid unnecessary main-memory consumption. diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md new file mode 100644 index 000000000..f85382b3c --- /dev/null +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -0,0 +1,26 @@ +# MaxScale Release Notes + +## 1.2 GA + +This document details the changes in version 1.2 since the release of the 1.1.1 GA Release of the MaxScale product. + +###***PLEASE NOTICE: MaxScale installation directories have changed in this version*** +The 1.2 version of MaxScale differs from previos versions in its installation layout. Please take great care when upgrading MaxScale from previous versions to version 1.2. An automatic upgrade will not work due to the severe changes in the installation layout. + +## New Features + +### Non-root MaxScale +You can now run MaxScale as any user. The standard installation of a MaxScale package now creates the maxscale user and the maxscale group. + +### FHS-compliant installation +The 1.2 version of MaxScale now complies to the Filesystem Hierarchy Standard. This means that MAXSCALE_HOME is no longer necessary and directories can be moved to different locations. + +A quick list of changes in installation directories and file names: + + * Binaries go into `/usr/bin` + * Configuration files to `/etc` and the configuration file is now lower case: `maxscale.cnf` + * Logs to `/var/log/maxscale` + * The module and library directory have been combined into a single directory in `/usr/lib64/maxscale`. If you have custom modules please make sure they are located there. + * Data directory is `/var/lib/maxscale`. This is the default location for MaxScale-specific data. + * PID file can be found at `/var/run/maxscale` + diff --git a/Documentation/Tutorials/Administration-Tutorial.md b/Documentation/Tutorials/Administration-Tutorial.md index 0fb0051b5..943ecaa27 100644 --- a/Documentation/Tutorials/Administration-Tutorial.md +++ b/Documentation/Tutorials/Administration-Tutorial.md @@ -26,43 +26,20 @@ It is also possible to start MaxScale by executing the maxscale command itself, Options may be passed to the MaxScale binary that alter this default behavior, this options are documented in the table below. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SwitchLong OptionDescription
-d--nodaemonRun MaxScale attached to the terminal rather than as a daemon process. This is useful for debugging purposes.
-c--homedir=Ignore the environment variable MAXSCALE_HOME and use the supplied argument instead.
-f--config=Use the filename passed as an argument instead of looking in $MAXSCALE_HOME/etc/MaxScale.cnf
-l||--log=Control where logs are written for the debug and trace level log messages. the default is to write these to a shared memory device, however using the -lfile or --log=file option will forced these to be written to regular files. Using -lstdout or --log=stdout will use the standard output for all enabled logs.
-v--versionPrint version information for MaxScale
-?--helpPrint usage information for MaxScale
+Switch|Long Option|Description +------|-----------|----------- +`-d`|`--nodaemon`|enable running in terminal process (default:disabled) +`-f FILE`|`--config=FILE`|relative or absolute pathname of MaxScale configuration file (default:/etc/maxscale.cnf) +`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: shm) +`-L PATH`|`--logdir=PATH`|path to log file directory (default: /var/log/maxscale) +`-D PATH`|`--datadir=PATH`|path to data directory, stored embedded mysql tables (default: /var/cache/maxscale) +`-C PATH`|`--configdir=PATH`|path to configuration file directory (default: /etc/) +`-B PATH`|`--libdir=PATH`|path to module directory (default: /usr/lib64/maxscale) +`-A PATH`|`--cachedir=PATH`|path to cache directory (default: /var/cache/maxscale) +`-s [yes no]`|`--syslog=[yes no]`|log messages to syslog (default:yes) +`-S [yes no]`|`--maxscalelog=[yes no]`|log messages to MaxScale log (default: yes) +`-v`|`--version`|print version info and exit +`-?`|`--help`|show this help ### Stopping MaxScale @@ -79,7 +56,7 @@ or MaxScale will also stop gracefully if it received a hangup signal, to find the process id of the MaxScale server use the ps command or read the contents of the maxscale.pid file located in the same directory as the logs. - $ kill -HUP `cat $MAXSCALE_HOME/log/maxscale.pid` + $ kill -HUP `cat /log/maxscale.pid` In order to shutdown MaxScale using the maxadmin command you may either connect with maxadmin in interactive mode or pass the "shutdown maxscale" command you wish to execute as an argument to maxadmin. @@ -90,6 +67,7 @@ In order to shutdown MaxScale using the maxadmin command you may either connect It is possible to use the maxadmin command to obtain statistics regarding the services that are configured within your MaxScale configuration file. The maxadmin command "list services" will give very basic information regarding the services that are define. This command may be either run in interactive mode or passed on the maxadmin command line. +``` $ maxadmin -pmariadb MaxScale> list services @@ -110,6 +88,7 @@ It is possible to use the maxadmin command to obtain statistics regarding the se --------------------------+----------------------+--------+--------------- MaxScale> +``` It should be noted that network listeners count as a user of the service, therefore there will always be one user per network port in which the service listens. More detail can be obtained by use of the "show service" command which is passed a service name. diff --git a/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md b/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md index d75c6162a..d58ebc32c 100644 --- a/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md +++ b/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md @@ -60,7 +60,7 @@ If you wish to use two different usernames for the two different roles of monito ### Creating Your MaxScale Configuration -MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. +MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory /etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients. diff --git a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md index df57e9390..8717591d8 100644 --- a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md @@ -62,7 +62,7 @@ If you wish to use two different usernames for the two different roles of monito ### Creating Your MaxScale Configuration -MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. +MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory /etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients. diff --git a/Documentation/Tutorials/MaxScale-Information-Schema.md b/Documentation/Tutorials/MaxScale-Information-Schema.md index c8ce5c08a..9872556b3 100644 --- a/Documentation/Tutorials/MaxScale-Information-Schema.md +++ b/Documentation/Tutorials/MaxScale-Information-Schema.md @@ -11,48 +11,59 @@ The service entry needs to define the service name, the type as service and the The specified user, with the password (plain or encrypted via maxpassword utility) is allowed to connect via MySQL protocol. Currently the user can connect to maxinfo from any remote IP and to localhost as well. +``` [MaxInfo] type=service router=maxinfo user=monitor passwd=EBD2F49C3B375812A8CDEBA632ED8BBC +``` The listener section defines the protocol, port and other information needed to create a listener for the service. To listen on a port using the MySQL protocol a section as shown below should be added to the configuration file. +``` [MaxInfo Listener] type=listener service=MaxInfo protocol=MySQLClient port=9003 +``` To listen with the HTTP protocol and hence return JSON documents a section as should below is required. +``` [MaxInfo JSON Listener] type=listener service=MaxInfo protocol=HTTPD port=8003 +``` + If both the MySQL and JSON responses are required then a single service can be configured with both types of listener. As with any other listeners within MaxScale the listeners can be bound to a particular interface by use of the address= parameter. This allows the access to the maxinfo data to be limited to the localhost by adding an address=localhost parameter in the configuration file. +``` [MaxInfo Listener] type=listener service=MaxInfo protocol=MySQLClient address=localhost port=9003 +``` # MySQL Interface to maxinfo The maxinfo supports a small subset of SQL statements in addition to the MySQL status and ping requests. These may be used for simple monitoring of MaxScale. +``` % mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz ping mysqld is alive % mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz status Uptime: 72 Threads: 1 Sessions: 11 % +``` The SQL command used to interact with maxinfo is the show command, a variety of show commands are available and will be described in the following sections. @@ -60,6 +71,7 @@ The SQL command used to interact with maxinfo is the show command, a variety of The show variables command will display a set of name and value pairs for a number of MaxScale system variables. +``` mysql> show variables; +--------------------+-------------------------+ | Variable_name | Value | @@ -77,9 +89,11 @@ The show variables command will display a set of name and value pairs for a numb 9 rows in set (0.02 sec) mysql> +``` The show variables command can also accept a limited like clause. This like clause must either be a literal string to match, a pattern starting with a %, a pattern ending with a % or a string with a % at both the start and the end. +``` mysql> show variables like 'version'; +---------------+----------------+ | Variable_name | Value | @@ -116,11 +130,13 @@ The show variables command can also accept a limited like clause. This like clau 3 rows in set (0.02 sec) mysql> +``` ## Show status The show status command displays a set of status counters, as with show variables the show status command can be passed a simplified like clause to limit the values returned. +``` mysql> show status; +---------------------------+-------+ | Variable_name | Value | @@ -151,11 +167,13 @@ The show status command displays a set of status counters, as with show variable 22 rows in set (0.02 sec) mysql> +``` ## Show services The show services command will return a set of basic statistics regarding each of the configured services within MaxScale. +``` mysql> show services; +----------------+----------------+--------------+----------------+ | Service Name | Router Module | No. Sessions | Total Sessions | @@ -172,6 +190,7 @@ The show services command will return a set of basic statistics regarding each o 8 rows in set (0.02 sec) mysql> +``` The show services command does not accept a like clause and will ignore any like clause that is given. @@ -179,6 +198,7 @@ The show services command does not accept a like clause and will ignore any like The show listeners command will return a set of status information for every listener defined within the MaxScale configuration file. +``` mysql> show listeners; +----------------+-----------------+-----------+------+---------+ | Service Name | Protocol Module | Address | Port | State | @@ -196,6 +216,7 @@ The show listeners command will return a set of status information for every lis 9 rows in set (0.02 sec) mysql> +``` The show listeners command will ignore any like clause passed to it. @@ -203,6 +224,7 @@ The show listeners command will ignore any like clause passed to it. The show sessions command returns information on every active session within MaxScale. It will ignore any like clause passed to it. +``` mysql> show sessions; +-----------+---------------+----------------+---------------------------+ | Session | Client | Service | State | @@ -222,11 +244,13 @@ The show sessions command returns information on every active session within Max 11 rows in set (0.02 sec) mysql> +``` ## Show clients The show clients command reports a row for every client application connected to MaxScale. Like clauses are not available of the show clients command. +``` mysql> show clients; +-----------+---------------+---------+---------------------------+ | Session | Client | Service | State | @@ -237,11 +261,13 @@ The show clients command reports a row for every client application connected to 2 rows in set (0.02 sec) mysql> +``` ## Show servers The show servers command returns data for each backend server configured within the MaxScale configuration file. This data includes the current number of connections MaxScale has to that server and the state of that server as monitored by MaxScale. +``` mysql> show servers; +---------+-----------+------+-------------+---------+ | Server | Address | Port | Connections | Status | @@ -254,11 +280,13 @@ The show servers command returns data for each backend server configured within 4 rows in set (0.02 sec) mysql> +``` ## Show modules The show modules command reports the information on the modules currently loaded into MaxScale. This includes the name type and version of each module. It also includes the API version the module has been written against and the current release status of the module. +``` mysql> show modules; +----------------+-------------+---------+-------------+----------------+ | Module Name | Module Type | Version | API Version | Status | @@ -277,12 +305,13 @@ The show modules command reports the information on the modules currently loaded 10 rows in set (0.02 sec) mysql> - +``` ## Show monitors The show monitors command reports each monitor configured within the system and the state of that monitor. +``` mysql> show monitors; +---------------+---------+ | Monitor | Status | @@ -292,12 +321,13 @@ The show monitors command reports each monitor configured within the system and 1 row in set (0.02 sec) mysql> - +``` ## Show eventTimes The show eventTimes command returns a table of statistics that reflect the performance of the event queuing and execution portion of the MaxScale core. +``` mysql> show eventTimes; +---------------+-------------------+---------------------+ | Duration | No. Events Queued | No. Events Executed | @@ -336,6 +366,7 @@ The show eventTimes command returns a table of statistics that reflect the perfo 30 rows in set (0.02 sec) mysql> +``` Each row represents a time interval, in 100ms increments, with the counts representing the number of events that were in the event queue for the length of time that row represents and the number of events that were executing of the time indicated by the row. @@ -347,6 +378,7 @@ The simplified JSON interface takes the URL of the request made to maxinfo and m The /variables URL will return the MaxScale variables, these variables can not be filtered via this interface. +``` $ curl http://maxscale.mariadb.com:8003/variables [ { "Variable_name" : "version", "Value" : "1.0.6-unstable"}, { "Variable_name" : "version_comment", "Value" : "MariaDB MaxScale"}, @@ -358,11 +390,13 @@ The /variables URL will return the MaxScale variables, these variables can not b { "Variable_name" : "MAXSCALE_UPTIME", "Value" : 3948}, { "Variable_name" : "MAXSCALE_SESSIONS", "Value" : 12}] $ +``` ## Status Use of the /status URI will return the status information that would normally be returned by the show status command. No filtering of the status information is available via this interface +``` $ curl http://maxscale.mariadb.com:8003/status [ { "Variable_name" : "Uptime", "Value" : 3831}, { "Variable_name" : "Uptime_since_flush_status", "Value" : 3831}, @@ -387,11 +421,13 @@ Use of the /status URI will return the status information that would normally be { "Variable_name" : "Max_event_queue_time", "Value" : 0}, { "Variable_name" : "Max_event_execution_time", "Value" : 1}] $ +``` ## Services The /services URI returns the data regarding the services defined within the configuration of MaxScale. Two counters are returned, the current number of sessions attached to this service and the total number connected since the service started. +``` $ curl http://maxscale.mariadb.com:8003/services [ { "Service Name" : "Test Service", "Router Module" : "readconnroute", "No. Sessions" : 1, "Total Sessions" : 1}, { "Service Name" : "Split Service", "Router Module" : "readwritesplit", "No. Sessions" : 1, "Total Sessions" : 1}, @@ -402,11 +438,13 @@ The /services URI returns the data regarding the services defined within the con { "Service Name" : "CLI", "Router Module" : "cli", "No. Sessions" : 1, "Total Sessions" : 1}, { "Service Name" : "MaxInfo", "Router Module" : "maxinfo", "No. Sessions" : 5, "Total Sessions" : 20}] $ +``` ## Listeners The /listeners URI will return a JSON array with one entry per listener, each entry is a JSON object that describes the configuration and state of that listener. +``` $ curl http://maxscale.mariadb.com:8003/listeners [ { "Service Name" : "Test Service", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 4006, "State" : "Running"}, { "Service Name" : "Split Service", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 4007, "State" : "Running"}, @@ -418,11 +456,13 @@ The /listeners URI will return a JSON array with one entry per listener, each en { "Service Name" : "MaxInfo", "Protocol Module" : "MySQLClient", "Address" : "*", "Port" : 9003, "State" : "Running"}, { "Service Name" : "MaxInfo", "Protocol Module" : "HTTPD", "Address" : "*", "Port" : 8003, "State" : "Running"}] $ +``` ## Modules The /modules URI returns data for each plugin that has been loaded into MaxScale. The plugin name, type and version are returned as is the version of the plugin API that the plugin was built against and the release status of the plugin. +``` $ curl http://maxscale.mariadb.com:8003/modules [ { "Module Name" : "HTTPD", "Module Type" : "Protocol", "Version" : "V1.0.1", "API Version" : "1.0.0", "Status" : "In Development"}, { "Module Name" : "maxscaled", "Module Type" : "Protocol", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "GA"}, @@ -435,11 +475,13 @@ The /modules URI returns data for each plugin that has been loaded into MaxScale { "Module Name" : "cli", "Module Type" : "Router", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "GA"}, { "Module Name" : "maxinfo", "Module Type" : "Router", "Version" : "V1.0.0", "API Version" : "1.0.0", "Status" : "Alpha"}] $ +``` ## Sessions The /sessions URI returns a JSON array with an object for each active session within MaxScale. +``` $ curl http://maxscale.mariadb.com:8003/sessions [ { "Session" : "0x1a8e9a0", "Client" : "80.176.79.245", "Service" : "MaxInfo", "State" : "Session ready for routing"}, { "Session" : "0x1a8e6d0", "Client" : "80.240.130.35", "Service" : "MaxInfo", "State" : "Session ready for routing"}, @@ -453,32 +495,38 @@ The /sessions URI returns a JSON array with an object for each active session wi { "Session" : "0x1a5c530", "Client" : , "Service" : "Split Service", "State" : "Listener Session"}, { "Session" : "0x19ac1c0", "Client" : , "Service" : "Test Service", "State" : "Listener Session"}] $ +``` ## Clients The /clients URI is a limited version of the /sessions, in this case it only returns an entry for a session that represents a client connection. +``` $ curl http://maxscale.mariadb.com:8003/clients [ { "Session" : "0x1a90be0", "Client" : "80.176.79.245", "Service" : "MaxInfo", "State" : "Session ready for routing"}, { "Session" : "0x1a8e9a0", "Client" : "127.0.0.1", "Service" : "MaxInfo", "State" : "Session ready for routing"}, { "Session" : "0x1a8e6d0", "Client" : "80.240.130.35", "Service" : "MaxInfo", "State" : "Session ready for routing"}] $ +``` ## Servers The /servers URI is used to retrieve information for each of the servers defined within the MaxScale configuration. This information includes the connection count and the current status as monitored by MaxScale. The connection count is only those connections made by MaxScale to those servers. +``` $ curl http://maxscale.mariadb.com:8003/servers [ { "Server" : "server1", "Address" : "127.0.0.1", "Port" : 3306, "Connections" : 0, "Status" : "Running"}, { "Server" : "server2", "Address" : "127.0.0.1", "Port" : 3307, "Connections" : 0, "Status" : "Down"}, { "Server" : "server3", "Address" : "127.0.0.1", "Port" : 3308, "Connections" : 0, "Status" : "Down"}, { "Server" : "server4", "Address" : "127.0.0.1", "Port" : 3309, "Connections" : 0, "Status" : "Down"}] $ +``` ## Event Times The /event/times URI returns an array of statistics that reflect the performance of the event queuing and execution portion of the MaxScale core. Each element is an object that represents a time bucket, in 100ms increments, with the counts representing the number of events that were in the event queue for the length of time that row represents and the number of events that were executing of the time indicated by the object. +``` $ curl http://maxscale.mariadb.com:8003/event/times [ { "Duration" : "< 100ms", "No. Events Queued" : 64, "No. Events Executed" : 63}, { "Duration" : " 100 - 200ms", "No. Events Queued" : 0, "No. Events Executed" : 0}, @@ -510,3 +558,4 @@ The /event/times URI returns an array of statistics that reflect the performance { "Duration" : "2700 - 2800ms", "No. Events Queued" : 0, "No. Events Executed" : 0}, { "Duration" : "2800 - 2900ms", "No. Events Queued" : 0, "No. Events Executed" : 0}, { "Duration" : "> 3000ms", "No. Events Queued" : 0, "No. Events Executed" : 0}] +``` diff --git a/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md b/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md index aac084f7b..8158bfa76 100644 --- a/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md +++ b/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md @@ -36,6 +36,7 @@ The first user required must be able to select data from the table mysql.user, t 2. Create the user, substituting the username, password and host on which maxscale runs within your environment +``` MariaDB [(none)]> create user '*username*'@'*maxscalehost*' identified by '*password*'; **Query OK, 0 rows affected (0.00 sec)** @@ -45,9 +46,11 @@ MariaDB [(none)]> create user '*username*'@'*maxscalehost*' identified by '*pass MariaDB [(none)]> grant SELECT on mysql.user to '*username*'@'*maxscalehost*'; **Query OK, 0 rows affected (0.03 sec)** +``` Additionally, GRANT SELECT on the mysql.db table and SHOW DATABASES privileges are required in order to load databases name and grants suitable for database name authorization. +``` MariaDB [(none)]> GRANT SELECT ON mysql.db TO 'username'@'maxscalehost'; **Query OK, 0 rows affected (0.00 sec)** @@ -55,9 +58,11 @@ MariaDB [(none)]> GRANT SELECT ON mysql.db TO 'username'@'maxscalehost'; MariaDB [(none)]> GRANT SHOW DATABASES ON *.* TO 'username'@'maxscalehost'; **Query OK, 0 rows affected (0.00 sec)** +``` The second user is used to monitored the state of the cluster. This user, which may be the same username as the first, requires permissions to access the various sources of monitoring data. In order to monitor a replication cluster this user must be granted the roles REPLICATION SLAVE and REPLICATION CLIENT +``` MariaDB [(none)]> grant REPLICATION SLAVE on *.* to '*username*'@'*maxscalehost*'; **Query OK, 0 rows affected (0.00 sec)** @@ -65,220 +70,174 @@ MariaDB [(none)]> grant REPLICATION SLAVE on *.* to '*username*'@'*maxscalehost* MariaDB [(none)]> grant REPLICATION CLIENT on *.* to '*username*'@'*maxscalehost*'; **Query OK, 0 rows affected (0.00 sec)** +``` If you wish to use two different usernames for the two different roles of monitoring and collecting user information then create a different username using the first two steps from above. ## Creating Your MaxScale Configuration -MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb/maxscle/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. +MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory /etc. This is not created as part of the installation process and must be manually created. A template file does exist in the `/usr/share/maxscale` folder that can be use as a basis for your configuration. A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients. +``` [maxscale] - threads=4 +``` Since we are using MySQL Replication and connection routing we want two different ports to which the client application can connect; one that will be directed to the current master within the replication cluster and another that will load balance between the slaves. To achieve this within MaxScale we need to define two services in the ini file; one for the read/write operations that should be executed on the master server and another for connections to one of the slaves. Create a section for each in your MaxScale.ini file and set the type to service, the section names are the names of the services themselves and should be meaningful to the administrator. Names may contain whitespace. +``` [Write Service] - type=service [Read Service] - type=service +``` The router for these two sections is identical, the readconnroute module, also the services should be provided with the list of servers that will be part of the cluster. The server names given here are actually the names of server sections in the configuration file and not the physical hostnames or addresses of the servers. +``` [Write Service] - type=service - router=readconnroute - servers=dbserv1, dbserv2, dbserv3 [Read Service] - type=service - router=readconnroute - servers=dbserv1, dbserv2, dbserv3 +``` In order to instruct the router to which servers it should route we must add router options to the service. The router options are compared to the status that the monitor collects from the servers and used to restrict the eligible set of servers to which that service may route. In our case we use the two options master and slave for our two services. +``` [Write Service] - type=service - router=readconnroute - router_options=master - servers=dbserv1, dbserv2, dbserv3 [Read Service] - type=service - router=readconnroute - router_options=slave - servers=dbserv1, dbserv2, dbserv3 +``` The final step in the service sections is to add the username and password that will be used to populate the user data from the database cluster. There are two options for representing the password, either plain text or encrypted passwords may be used. In order to use encrypted passwords a set of keys must be generated that will be used by the encryption and decryption process. To generate the keys use the maxkeys command and pass the name of the secrets file in which the keys are stored. -% maxkeys /usr/local/mariadb-maxscale/etc/.secrets - -% +``` +maxkeys /usr/local/mariadb-maxscale/etc/.secrets +``` Once the keys have been created the maxpasswd command can be used to generate the encrypted password. -% maxpasswd plainpassword - +``` +maxpasswd plainpassword 96F99AA1315BDC3604B006F427DD9484 - -% +``` The username and password, either encrypted or plain text, are stored in the service section using the user and passwd parameters. +``` [Write Service] - type=service - router=readconnroute - router_options=master - servers=dbserv1, dbserv2, dbserv3 - user=maxscale - passwd=96F99AA1315BDC3604B006F427DD9484 [Read Service] - type=service - router=readconnroute - router_options=slave - servers=dbserv1, dbserv2, dbserv3 - user=maxscale - passwd=96F99AA1315BDC3604B006F427DD9484 +``` This completes the definitions required by the services, however listening ports must be associated with the services in order to allow network connections. This is done by creating a series of listener sections. These sections again are named for the convenience of the administrator and should be of type listener with an entry labeled service which contains the name of the service to associate the listener with. Each service may have multiple listeners. +``` [Write Listener] - type=listener - service=Write Service [Read Listener] - type=listener - service=Read Service +``` A listener must also define the protocol module it will use for the incoming network protocol, currently this should be the MySQLClient protocol for all database listeners. The listener may then supply a network port to listen on and/or a socket within the file system. +``` [Write Listener] - type=listener - service=Write Service - protocol=MySQLClient - port=4306 - socket=/tmp/ClusterMaster [Read Listener] - type=listener - service=Read Service - protocol=MySQLClient - port=4307 +``` An address parameter may be given if the listener is required to bind to a particular network address when using hosts with multiple network addresses. The default behavior is to listen on all network interfaces. The next stage is the configuration is to define the server information. This defines how to connect to each of the servers within the cluster, again a section is created for each server, with the type set to server, the network address and port to connect to and the protocol to use to connect to the server. Currently the protocol for all database connections in MySQLBackend. +``` [dbserv1] - type=server - address=192.168.2.1 - port=3306 - protocol=MySQLBackend [dbserv2] - type=server - address=192.168.2.2 - port=3306 - protocol=MySQLBackend [dbserv3] - type=server - address=192.168.2.3 - port=3306 - protocol=MySQLBackend +``` In order for MaxScale to monitor the servers using the correct monitoring mechanisms a section should be provided that defines the monitor to use and the servers to monitor. Once again a section is created with a symbolic name for the monitor, with the type set to monitor. Parameters are added for the module to use, the list of servers to monitor and the username and password to use when connecting to the the servers with the monitor. +``` [Replication Monitor] - type=monitor - module=mysqlmon - servers=dbserv1, dbserv2, dbserv3 - user=maxscale - passwd=96F99AA1315BDC3604B006F427DD9484 +``` As with the password definition in the server either plain text or encrypted passwords may be used. The final stage in the configuration is to add the option service which is used by the maxadmin command to connect to MaxScale for monitoring and administration purposes. This creates a service section and a listener section. +``` [CLI] - type=service - router=cli [CLI Listener] - type=listener - service=CLI - protocol=maxscaled - address=localhost - port=6603 +``` In the case of the example above it should be noted that an address parameter has been given to the listener, this limits connections to maxadmin commands that are executed on the same machine that hosts MaxScale. @@ -286,14 +245,19 @@ In the case of the example above it should be noted that an address parameter ha Upon completion of the configuration process MaxScale is ready to be started for the first time. This may either be done manually by running the maxscale command or via the service interface. -% maxscale +``` +maxscale +``` or -% service maxscale start +``` +service maxscale start +``` -Check the error log in /usr/local/mariadb-maxscale/log to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured. +Check the error log in /var/log/lomaxscale/ to see if any errors are detected in the configuration file and to confirm MaxScale has been started. Also the maxadmin command may be used to confirm that MaxScale is running and the services, listeners etc have been correctly configured. +``` % maxadmin -pmariadb list services Services. @@ -349,6 +313,7 @@ CLI | maxscaled | localhost | 6603 | Running ---------------------+--------------------+-----------------+-------+-------- % +``` -MaxScale is now ready to start accepting client connections and routing them to the master or slaves within your cluster. Other configuration options are available that can alter the criteria used for routing, these include monitoring the replication lag within the cluster and routing only to slaves that are within a predetermined delay from the current master or using weights to obtain unequal balancing operations. These options may be found in the MaxScale Configuration Guide. More detail on the use of maxadmin can be found in the document "MaxAdmin - The MaxScale Administration & Monitoring Client Application". +MaxScale is now ready to start accepting client connections and routing them to the master or slaves within your cluster. Other configuration options are available that can alter the criteria used for routing, these include monitoring the replication lag within the cluster and routing only to slaves that are within a predetermined delay from the current master or using weights to obtain unequal balancing operations. These options may be found in the MaxScale Configuration Guide. More detail on the use of maxadmin can be found in the document [MaxAdmin - The MaxScale Administration & Monitoring Client Application](Administration-Tutorial.md). diff --git a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md index 54e5412be..b34fcf71e 100644 --- a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md @@ -70,7 +70,7 @@ If you wish to use two different usernames for the two different roles of monito ## Creating Your MaxScale Configuration -MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory $MAXSCALE_HOME/etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. +MaxScale configuration is held in an ini file that is located in the file MaxScale.cnf in the directory /etc, if you have installed in the default location then this file is available in /usr/local/mariadb-maxscale/etc/MaxScale.cnf. This is not created as part of the installation process and must be manually created. A template file does exist within this directory that may be use as a basis for your configuration. A global, maxscale, section is included within every MaxScale configuration file; this is used to set the values of various MaxScale wide parameters, perhaps the most important of these is the number of threads that MaxScale will use to execute the code that forwards requests and handles responses for clients. diff --git a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md index f07fd13a3..3f61638d1 100644 --- a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md +++ b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md @@ -84,7 +84,7 @@ This optional parameter allows for the administrator to define the number of the ### binlogdir -This parameter allows the location that MaxScale uses to store binlog files to be set. If this parameter is not set to a directory name then MaxScale will store the binlog files in the directory $MAXSCALE_HOME/. +This parameter allows the location that MaxScale uses to store binlog files to be set. If this parameter is not set to a directory name then MaxScale will store the binlog files in the directory /var/cache/maxscale/. ### heartbeat diff --git a/Documentation/filters/Query-Log-All-Filter.md b/Documentation/filters/Query-Log-All-Filter.md index e0c71e13f..87ea620c8 100644 --- a/Documentation/filters/Query-Log-All-Filter.md +++ b/Documentation/filters/Query-Log-All-Filter.md @@ -6,7 +6,7 @@ The Query Log All (QLA) filter is a filter module for MaxScale that is ## Configuration -The configuration block for the QLA filter requires the minimal filter options in it's section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf. +The configuration block for the QLA filter requires the minimal filter options in it's section within the MaxScale.cnf file, stored in /etc/MaxScale.cnf. ``` [MyLogFilter] type=filter diff --git a/Documentation/filters/RabbitMQ-Filter.md b/Documentation/filters/RabbitMQ-Filter.md index f23313d0d..4068ceec5 100644 --- a/Documentation/filters/RabbitMQ-Filter.md +++ b/Documentation/filters/RabbitMQ-Filter.md @@ -5,7 +5,7 @@ This filter is designed to extract queries and transform them into a canonical f ## Configuration -The configuration block for the **mqfilter** filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf. Although the filter will start, it will use the default values which only work with a freshly installed RabbitMQ server and use its default values. This setup is mostly intended for testing the filter. +The configuration block for the **mqfilter** filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in /etc/MaxScale.cnf. Although the filter will start, it will use the default values which only work with a freshly installed RabbitMQ server and use its default values. This setup is mostly intended for testing the filter. The following is an example of a mqfilter configuration in the MaxScale.cnf file used for actual logging of queries to a RabbitMQ broker on a different host. diff --git a/Documentation/filters/Regex-Filter.md b/Documentation/filters/Regex-Filter.md index 8a6036c46..7b09ffcae 100644 --- a/Documentation/filters/Regex-Filter.md +++ b/Documentation/filters/Regex-Filter.md @@ -6,7 +6,7 @@ The regex filter is a filter module for MaxScale that is able to rewrite query c # Configuration -The configuration block for the Regex filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf. +The configuration block for the Regex filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in /etc/MaxScale.cnf. ``` [MyRegexFilter] diff --git a/Documentation/filters/Tee-Filter.md b/Documentation/filters/Tee-Filter.md index a8a95a5cc..868886ceb 100644 --- a/Documentation/filters/Tee-Filter.md +++ b/Documentation/filters/Tee-Filter.md @@ -6,7 +6,7 @@ The tee filter is a filter module for MaxScale is a "plumbing" fitting in the Ma # Configuration -The configuration block for the TEE filter requires the minimal filter parameters in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf, that defines the filter to load and the service to send the duplicates to. Currently the tee filter does not support multi-statements. +The configuration block for the TEE filter requires the minimal filter parameters in it’s section within the MaxScale.cnf file, stored in /etc/MaxScale.cnf, that defines the filter to load and the service to send the duplicates to. Currently the tee filter does not support multi-statements. ``` [DataMartFilter] diff --git a/Documentation/filters/Top-N-Filter.md b/Documentation/filters/Top-N-Filter.md index d51ca43db..f52a6bedd 100644 --- a/Documentation/filters/Top-N-Filter.md +++ b/Documentation/filters/Top-N-Filter.md @@ -6,7 +6,7 @@ The top filter is a filter module for MaxScale that monitors every SQL statement # Configuration -The configuration block for the TOP filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in $MAXSCALE_HOME/etc/MaxScale.cnf. +The configuration block for the TOP filter requires the minimal filter options in it’s section within the MaxScale.cnf file, stored in /etc/MaxScale.cnf. ``` [MyLogFilter] diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 755f2eac8..32ab702ea 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -7,4 +7,4 @@ if(HIST) else() message(STATUS "Could not find editline library. MaxAdmin will be built without it.") endif() -install(TARGETS maxadmin DESTINATION bin) +install(TARGETS maxadmin DESTINATION ${MAXSCALE_BINDIR}) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake new file mode 100644 index 000000000..e25bd0a8d --- /dev/null +++ b/cmake/install_layout.cmake @@ -0,0 +1,12 @@ +# Set the install layout +include(GNUInstallDirs) + +set(MAXSCALE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/maxscale CACHE PATH "Library installation path") +set(MAXSCALE_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Executable installation path") +set(MAXSCALE_SHAREDIR ${CMAKE_INSTALL_DATADIR}/maxscale CACHE PATH "Share file installation path, includes licence and readme files") +set(MAXSCALE_DOCDIR ${CMAKE_INSTALL_DOCDIR}/maxscale CACHE PATH "Documentation installation path, text versions only") +set(MAXSCALE_CONFDIR ${CMAKE_INSTALL_SYSCONFDIR} CACHE PATH "Configuration file installation path, this is not usually needed") + +# This is the only hard-coded absolute path +set(MAXSCALE_VARDIR /var CACHE PATH "Data file path (usually /var/)") + diff --git a/macros.cmake b/cmake/macros.cmake similarity index 75% rename from macros.cmake rename to cmake/macros.cmake index b7edfed14..43c366ef6 100644 --- a/macros.cmake +++ b/cmake/macros.cmake @@ -202,68 +202,6 @@ debugmsg("Search returned: ${MYSQL_DIR_LOC}") set(ERRMSG ${ERRMSG_FILE} CACHE FILEPATH "Path to the errmsg.sys file." FORCE) unset(ERRMSG_FILE) - # Find the embedded mysql library - - # if (DEFINED EMBEDDED_LIB) - # if( NOT (IS_DIRECTORY ${EMBEDDED_LIB}) ) - # debugmsg("EMBEDDED_LIB is not a directory: ${EMBEDDED_LIB}") - # if(${CMAKE_VERSION} VERSION_LESS 2.8.12 ) - # set(COMP_VAR PATH) - # else() - # set(COMP_VAR DIRECTORY) - # endif() - # get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR}) - # debugmsg("EMBEDDED_LIB directory component: ${EMBEDDED_LIB}") - # endif() - # debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}") - # endif() - - # if(STATIC_EMBEDDED) - - # debugmsg("Using the static embedded library...") - # set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - # set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - # if (DEFINED EMBEDDED_LIB) - # debugmsg("Searching for libmysqld.a at: ${EMBEDDED_LIB}") - # find_library(EMBEDDED_LIB_STATIC libmysqld.a PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) - # else() - # find_library(EMBEDDED_LIB_STATIC libmysqld.a PATH_SUFFIXES mysql mariadb) - # endif() - # debugmsg("Search returned: ${EMBEDDED_LIB_STATIC}") - - # set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE) - # set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES}) - - # else() - # debugmsg("Using the dynamic embedded library...") - # set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - # set(CMAKE_FIND_LIBRARY_SUFFIXES ".so") - # if (DEFINED EMBEDDED_LIB) - # debugmsg("Searching for libmysqld.so at: ${EMBEDDED_LIB}") - # find_library(EMBEDDED_LIB_DYNAMIC mysqld PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) - # else() - # find_library(EMBEDDED_LIB_DYNAMIC mysqld PATH_SUFFIXES mysql mariadb) - # endif() - # debugmsg("Search returned: ${EMBEDDED_LIB_DYNAMIC}") - # set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE) - # set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES}) - - # endif() - - # unset(EMBEDDED_LIB_DYNAMIC) - # unset(EMBEDDED_LIB_STATIC) - # unset(OLD_SUFFIXES) - - # # Inform the user about the embedded library - # if( (${EMBEDDED_LIB} MATCHES "NOTFOUND") OR (${EMBEDDED_LIB} MATCHES "NOTFOUND")) - # set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") - # message(FATAL_ERROR "Library not found: libmysqld. If your install of MySQL is in a non-default location, please provide the location with -DEMBEDDED_LIB=") - # else() - # get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} REALPATH) - # message(STATUS "Using embedded library: ${EMBEDDED_LIB}") - # endif() - - # Check which init.d script to install if(WITH_SCRIPTS) find_file(RPM_FNC functions PATHS /etc/rc.d/init.d) diff --git a/cmake/package_deb.cmake b/cmake/package_deb.cmake new file mode 100644 index 000000000..90d66d4bc --- /dev/null +++ b/cmake/package_deb.cmake @@ -0,0 +1,6 @@ +# DEB specific CPack configuration parameters +set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB") +set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/postinst;{CMAKE_BINARY_DIR}/postrm") +execute_process(COMMAND dpgk --print-architecture OUTPUT_VARIABLE DEB_ARCHITECTURE) +set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEB_ARCHITECTURE}) +set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) diff --git a/cmake/package_rpm.cmake b/cmake/package_rpm.cmake new file mode 100644 index 000000000..0f65bcdd2 --- /dev/null +++ b/cmake/package_rpm.cmake @@ -0,0 +1,23 @@ +# RPM specific CPack configuration parameters +set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MaxScale") +set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") +set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") +set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") +set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") +set(CPACK_PACKAGE_NAME "maxscale") +set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") +set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) +set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +set(CPACK_RPM_PACKAGE_RELEASE ${MAXSCALE_BUILD_NUMBER}) +set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postinst) +set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postrm) +set(CPACK_RPM_PACKAGE_NAME "maxscale") +set(CPACK_RPM_PACKAGE_VENDOR "MariaDB Corporation Ab") +set(CPACK_RPM_PACKAGE_LICENSE "GPLv2") +set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc /etc/ld.so.conf.d /etc/init.d /etc/rc.d/init.d") +set(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#") +set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d") +set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d") +set(CPACK_RPM_USER_FILELIST "%ignore /etc") diff --git a/cmake/testall.cmake b/cmake/testall.cmake index fedbdf273..65c27fa5a 100644 --- a/cmake/testall.cmake +++ b/cmake/testall.cmake @@ -1,4 +1,5 @@ -execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null 2> /dev/null > /dev/null") +execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -f ${CMAKE_BINARY_DIR}/maxscale.cnf --logdir=${CMAKE_BINARY_DIR}/ --datadir=${CMAKE_BINARY_DIR}/ --cachedir=${CMAKE_BINARY_DIR}/ &> ${CMAKE_BINARY_DIR}/maxscale.output" +OUTPUT_VARIABLE MAXSCALE_OUT) execute_process(COMMAND make test RESULT_VARIABLE RVAL) execute_process(COMMAND killall maxscale) if(NOT RVAL EQUAL 0) diff --git a/etc/init.d/maxscale.in b/etc/init.d/maxscale.in index 88f026e18..70cdf5b3d 100755 --- a/etc/init.d/maxscale.in +++ b/etc/init.d/maxscale.in @@ -18,12 +18,11 @@ ### END INIT INFO ############################################# -# MaxScale HOME, PIDFILE, LIB +# MaxScale PIDFILE and LIB ############################################# -export MAXSCALE_HOME=@CMAKE_INSTALL_PREFIX@ -export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib +export MAXSCALE_PIDFILE=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@/maxscale ############################### # LSB Exit codes (non-Status) @@ -39,7 +38,7 @@ _RETVAL_STATUS_OK=0 _RETVAL_STATUS_NOT_RUNNING=3 # Sanity checks. -[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED +[ -x @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale ] || exit $_RETVAL_NOT_INSTALLED # Source function library. . /etc/rc.d/init.d/functions @@ -52,23 +51,23 @@ RETVAL=0 start() { echo -n $"Starting MaxScale: " - my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale` + my_check=`status -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale` CHECK_RET=$? [ $CHECK_RET -eq 0 ] && echo -n " found $my_check" && success && CHECK_RET=0 - daemon --pidfile $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale >& /dev/null + daemon --pidfile $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale --user=maxscale >& /dev/null RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$servicename if [ $CHECK_RET -ne 0 ]; then sleep 2 - my_check=`status -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale` + my_check=`status -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale` CHECK_RET=$? [ $CHECK_RET -eq 0 ] && echo -n $my_check && success || failure fi - # Return rigth code + # Return right code if [ $RETVAL -ne 0 ]; then failure RETVAL=$_RETVAL_NOT_RUNNING @@ -100,7 +99,7 @@ stop() { reload() { echo -n $"Reloading MaxScale: " - killproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale -HUP + killproc -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale -HUP RETVAL=$? echo } diff --git a/etc/maxscale.service.in b/etc/maxscale.service.in new file mode 100644 index 000000000..50e781f30 --- /dev/null +++ b/etc/maxscale.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=MariaDB MaxScale Database Proxy +After=network.target + +[Service] +Type=forking +PIDFile=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid +ExecStart=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale + +[Install] +WantedBy=multi-user.target diff --git a/etc/postinst.in b/etc/postinst.in index 4bd193958..abf2db1ef 100755 --- a/etc/postinst.in +++ b/etc/postinst.in @@ -1,5 +1,39 @@ #!/bin/sh -cp @CMAKE_INSTALL_PREFIX@/maxscale /etc/init.d/ -cp @CMAKE_INSTALL_PREFIX@/maxscale.conf /etc/ld.so.conf.d/ + +# Create directories +mkdir -p @MAXSCALE_LIBDIR@ +mkdir -p @MAXSCALE_BINDIR@ +mkdir -p @MAXSCALE_SHAREDIR@ +mkdir -p @MAXSCALE_DOCDIR@ +mkdir -p @MAXSCALE_CONFDIR@ +mkdir -p @MAXSCALE_VARDIR@/log/maxscale +mkdir -p @MAXSCALE_VARDIR@/lib/maxscale +mkdir -p @MAXSCALE_VARDIR@/cache/maxscale +mkdir -p @MAXSCALE_VARDIR@/run/maxscale + +# Create MaxScale user +if [ -f "/etc/passwd" -a "$(grep -c 'maxscale' /etc/passwd)" -eq 0 ] +then + useradd -r -s /bin/false maxscale + groupadd maxscale +fi + +# Change the owner of the directories to maxscale:maxscale +chown maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale +chown maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale +chown maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale +chown maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale +chmod 0755 @MAXSCALE_VARDIR@/log/maxscale +chmod 0755 @MAXSCALE_VARDIR@/lib/maxscale +chmod 0755 @MAXSCALE_VARDIR@/cache/maxscale +chmod 0755 @MAXSCALE_VARDIR@/run/maxscale + +# Copy init.d script and ldconfig file +cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale /etc/init.d/ +cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.conf /etc/ld.so.conf.d/ +if [ -d "/usr/lib/systemd/system" ] +then + cp @CMAKE_INSTALL_PREFIX@/@MAXSCALE_SHAREDIR@/maxscale.service /usr/lib/systemd/system +fi /sbin/ldconfig diff --git a/etc/postrm.in b/etc/postrm.in index b1e86fca5..65c0f7116 100755 --- a/etc/postrm.in +++ b/etc/postrm.in @@ -3,4 +3,9 @@ if [ "$1" -eq 0 ] then rm -f /etc/init.d/maxscale rm -f /etc/ld.so.conf.d/maxscale.conf +else + if [ -f "/usr/local/mariadb-maxscale/etc/MaxScale.cnf" ] + then + cp "/usr/local/mariadb-maxscale/etc/MaxScale.cnf" "/etc/maxscale.cnf" + fi fi diff --git a/etc/ubuntu/init.d/maxscale.in b/etc/ubuntu/init.d/maxscale.in index 4d9ac1bed..f23ed144f 100755 --- a/etc/ubuntu/init.d/maxscale.in +++ b/etc/ubuntu/init.d/maxscale.in @@ -21,9 +21,8 @@ # MaxScale HOME, PIDFILE, LIB ############################################# -export MAXSCALE_HOME=@CMAKE_INSTALL_PREFIX@ -export MAXSCALE_PIDFILE=$MAXSCALE_HOME/log/maxscale.pid -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MAXSCALE_HOME/lib +export MAXSCALE_PIDFILE=@MAXSCALE_VARDIR@/run/maxscale/maxscale.pid +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@/maxscale ############################### # LSB Exit codes (non-Status) @@ -39,13 +38,13 @@ _RETVAL_STATUS_OK=0 _RETVAL_STATUS_NOT_RUNNING=3 # Sanity checks. -[ -x $MAXSCALE_HOME/bin/maxscale ] || exit $_RETVAL_NOT_INSTALLED +[ -x @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale ] || exit $_RETVAL_NOT_INSTALLED ################################# # stop/start/status related vars ################################# NAME=maxscale -DAEMON=$MAXSCALE_HOME/bin/maxscale +DAEMON=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale --user=maxscale # Source function library. . /lib/lsb/init-functions @@ -84,7 +83,7 @@ reload() { } maxscale_wait_stop() { - PIDTMP=$(pidofproc -p $MAXSCALE_PIDFILE $MAXSCALE_HOME/bin/maxscale) + PIDTMP=$(pidofproc -p $MAXSCALE_PIDFILE @CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale) kill -TERM "${PIDTMP:-}" 2> /dev/null; if [ -n "${PIDTMP:-}" ] && kill -0 "${PIDTMP:-}" 2> /dev/null; then local i=0 diff --git a/log_manager/CMakeLists.txt b/log_manager/CMakeLists.txt index 3a2aad56c..3dfd883de 100644 --- a/log_manager/CMakeLists.txt +++ b/log_manager/CMakeLists.txt @@ -2,8 +2,8 @@ if(LOG_DEBUG) add_definitions(-DSS_LOG_DEBUG) endif() add_library(log_manager SHARED log_manager.cc) -target_link_libraries(log_manager pthread aio stdc++ utils) -install(TARGETS log_manager DESTINATION lib) +target_link_libraries(log_manager pthread aio stdc++) +install(TARGETS log_manager DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) add_subdirectory(test) endif() diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 3ea1eb028..fc18cc602 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,5 +1,5 @@ -install(FILES nagios/check_maxscale_monitors.pl DESTINATION plugins/nagios) -install(FILES nagios/check_maxscale_resources.pl DESTINATION plugins/nagios) -install(FILES nagios/check_maxscale_threads.pl DESTINATION plugins/nagios) -install(FILES nagios/maxscale_commands.cfg DESTINATION plugins/nagios) -install(FILES nagios/server1.cfg DESTINATION plugins/nagios) +install(FILES nagios/check_maxscale_monitors.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios) +install(FILES nagios/check_maxscale_resources.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios) +install(FILES nagios/check_maxscale_threads.pl DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios) +install(FILES nagios/maxscale_commands.cfg DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios) +install(FILES nagios/server1.cfg DESTINATION ${MAXSCALE_SHAREDIR}/plugins/nagios) diff --git a/query_classifier/CMakeLists.txt b/query_classifier/CMakeLists.txt index 42270cd2c..19820ccdd 100644 --- a/query_classifier/CMakeLists.txt +++ b/query_classifier/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(query_classifier SHARED query_classifier.cc) -install(TARGETS query_classifier DESTINATION lib) +install(TARGETS query_classifier COMPONENT lib DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) add_subdirectory(test) endif() diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 88f6a9c22..a2e9208e8 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,5 +1,5 @@ if(BUILD_TESTS OR BUILD_TOOLS) - add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c externcmd.c) + add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c) if(WITH_JEMALLOC) target_link_libraries(fullcore ${JEMALLOC_LIBRARIES}) elseif(WITH_TCMALLOC) @@ -12,7 +12,7 @@ add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c gw_utils.c utils.c dcb.c load_utils.c session.c service.c server.c poll.c config.c users.c hashtable.c dbusers.c thread.c gwbitmask.c monitor.c adminusers.c secrets.c filter.c modutil.c hint.c - housekeeper.c memlog.c resultset.c externcmd.c) + housekeeper.c memlog.c resultset.c gwdirs.c externcmd.c) if(WITH_JEMALLOC) target_link_libraries(maxscale ${JEMALLOC_LIBRARIES}) @@ -21,15 +21,15 @@ elseif(WITH_TCMALLOC) endif() target_link_libraries(maxscale ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++) -install(TARGETS maxscale DESTINATION bin) +install(TARGETS maxscale DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxkeys maxkeys.c secrets.c utils.c) +add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c) target_link_libraries(maxkeys log_manager utils pthread crypt crypto) -install(TARGETS maxkeys DESTINATION bin) +install(TARGETS maxkeys DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxpasswd maxpasswd.c secrets.c utils.c) +add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c) target_link_libraries(maxpasswd log_manager utils pthread crypt crypto) -install(TARGETS maxpasswd DESTINATION bin) +install(TARGETS maxpasswd DESTINATION ${MAXSCALE_BINDIR}) if(BUILD_TESTS) add_subdirectory(test) diff --git a/server/core/adminusers.c b/server/core/adminusers.c index 64ea5f224..53734e9cc 100644 --- a/server/core/adminusers.c +++ b/server/core/adminusers.c @@ -26,6 +26,7 @@ #include #include #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -119,12 +120,7 @@ char fname[1024], *home; char uname[80], passwd[80]; initialise(); - if ((home = getenv("MAXSCALE_HOME")) != NULL && strlen(home) < 1024){ - sprintf(fname, "%s/etc/passwd", home); - } - else{ - sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd"); - } + sprintf(fname, "%s/passwd", get_datadir()); if ((fp = fopen(fname, "r")) == NULL) return NULL; if ((rval = users_alloc()) == NULL) @@ -155,12 +151,7 @@ FILE *fp; char fname[1024], *home, *cpasswd; initialise(); - if ((home = getenv("MAXSCALE_HOME")) != NULL && strlen(home) < 1024){ - sprintf(fname, "%s/etc/passwd", home); - } - else{ - sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd"); - } + sprintf(fname, "%s/passwd", get_datadir()); if (users == NULL) { @@ -253,15 +244,8 @@ char* admin_remove_user( /** * Open passwd file and remove user from the file. */ - if ((home = getenv("MAXSCALE_HOME")) != NULL && - strnlen(home,PATH_MAX) < PATH_MAX && - strnlen(home,PATH_MAX) > 0) { - sprintf(fname, "%s/etc/passwd", home); - sprintf(fname_tmp, "%s/etc/passwd_tmp", home); - } else { - sprintf(fname, "/usr/local/mariadb-maxscale/etc/passwd"); - sprintf(fname_tmp, "/usr/local/mariadb-maxscale/etc/passwd_tmp"); - } + sprintf(fname, "%s/passwd", get_datadir()); + sprintf(fname_tmp, "%s/passwd_tmp", get_datadir()); /** * Rewrite passwd file from memory. */ diff --git a/server/core/gateway.c b/server/core/gateway.c index 6c505b124..5e17fe04f 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -74,6 +74,8 @@ #include +#include + /** for procname */ #if !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -111,8 +113,6 @@ static char* server_options[] = { const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1; -const char* default_cnf_fname = "etc/MaxScale.cnf"; - static char* server_groups[] = { "embedded", "server", @@ -125,10 +125,11 @@ static char* server_groups[] = { /* The data directory we created for this gateway instance */ static char datadir[PATH_MAX+1] = ""; - +static bool datadir_defined = false; /*< If the datadir was already set */ /* The data directory we created for this gateway instance */ static char pidfile[PATH_MAX+1] = ""; + /** * exit flag for log flusher. */ @@ -150,13 +151,20 @@ static struct option long_options[] = { {"config", required_argument, 0, 'f'}, {"nodaemon", no_argument, 0, 'd'}, {"log", required_argument, 0, 'l'}, + {"logdir", required_argument, 0, 'L'}, + {"datadir", required_argument, 0, 'D'}, + {"configdir",required_argument, 0, 'C'}, + {"libdir",required_argument, 0, 'B'}, + {"cachedir",required_argument, 0, 'A'}, + {"language",required_argument, 0, 'N'}, {"syslog", required_argument, 0, 's'}, - {"maxscalelog", required_argument, 0, 'S'}, + {"maxscalelog",required_argument,0,'S'}, + {"user",required_argument,0,'U'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, '?'}, {0, 0, 0, 0} }; - +static int cnf_preparser(void* data, const char* section, const char* name, const char* value); static void log_flush_shutdown(void); static void log_flush_cb(void* arg); static int write_pid_file(char *); /* write MaxScale pidfile */ @@ -168,6 +176,7 @@ static void write_footer(void); static int ntfw_cb(const char*, const struct stat*, int, struct FTW*); static bool file_is_readable(char* absolute_pathname); static bool file_is_writable(char* absolute_pathname); +bool handle_path_arg(char** dest, char* path, char* arg, bool rd, bool wr); static void usage(void); static char* get_expanded_pathname( char** abs_path, @@ -183,10 +192,9 @@ static bool resolve_maxscale_conf_fname( char** cnf_full_path, char* home_dir, char* cnf_file_arg); -static bool resolve_maxscale_homedir( - char** p_home_dir); -static char* check_dir_access(char* dirname); +static char* check_dir_access(char* dirname,bool,bool); +static int set_user(); /** * Handler for SIGHUP signal. Reload the configuration for the @@ -356,11 +364,10 @@ void datadir_cleanup() { int depth = 1; int flags = FTW_CHDIR|FTW_DEPTH|FTW_MOUNT; - int rc; if (datadir[0] != 0 && access(datadir, F_OK) == 0) { - rc = nftw(datadir, ntfw_cb, depth, flags); + nftw(datadir, ntfw_cb, depth, flags); } } @@ -381,14 +388,13 @@ static bool file_write_footer( FILE* outfile) { bool succp = false; - size_t wbytes1; size_t len1; const char* header_buf1; header_buf1 = "------------------------------------------------------" "\n\n"; len1 = strlen(header_buf1); - wbytes1=fwrite((void*)header_buf1, len1, 1, outfile); + fwrite((void*)header_buf1, len1, 1, outfile); succp = true; @@ -399,9 +405,6 @@ static bool file_write_header( FILE* outfile) { bool succp = false; - size_t wbytes1; - size_t wbytes2; - size_t wbytes3; size_t len1; size_t len2; size_t len3; @@ -445,9 +448,9 @@ static bool file_write_header( #if defined(LAPTOP_TEST) nanosleep(&ts1, NULL); #else - wbytes1=fwrite((void*)header_buf1, len1, 1, outfile); - wbytes2=fwrite((void*)header_buf2, len2, 1, outfile); - wbytes3=fwrite((void*)header_buf3, len3, 1, outfile); + fwrite((void*)header_buf1, len1, 1, outfile); + fwrite((void*)header_buf2, len2, 1, outfile); + fwrite((void*)header_buf3, len3, 1, outfile); #endif succp = true; @@ -490,15 +493,9 @@ static bool resolve_maxscale_conf_fname( * directory. * '-f MaxScale.cnf' */ - home_etc_dir = (char*)malloc(strlen(home_dir)+strlen("/etc")+1); - snprintf(home_etc_dir, - strlen(home_dir)+strlen("/etc")+1, - "%s/etc", - home_dir); *cnf_full_path = get_expanded_pathname(NULL, - home_etc_dir, + home_dir, cnf_file_arg); - free(home_etc_dir); if (*cnf_full_path != NULL) { @@ -577,149 +574,6 @@ return_succp: return succp; } - -static bool resolve_maxscale_homedir( - char** p_home_dir) -{ - bool succp = false; - char* tmp; - char* tmp2; - char* log_context = NULL; - - ss_dassert(*p_home_dir == NULL); - - if (*p_home_dir != NULL) - { - log_context = strdup("Command-line argument"); - tmp = NULL; - goto check_home_dir; - } - /*< - * 1. if home dir wasn't specified by a command-line argument, - * read env. variable MAXSCALE_HOME. - */ - if (getenv("MAXSCALE_HOME") != NULL) - { - tmp = strndup(getenv("MAXSCALE_HOME"), PATH_MAX); - get_expanded_pathname(p_home_dir, tmp, NULL); - - if (*p_home_dir != NULL) - { - log_context = strdup("MAXSCALE_HOME"); - goto check_home_dir; - } - free(tmp); - } - else - { - fprintf(stderr, "\n*\n* Warning : MAXSCALE_HOME environment variable " - "is not set.\n*\n"); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : MAXSCALE_HOME environment " - "variable is not set."))); - } - /*< - * 2. if home dir wasn't specified in MAXSCALE_HOME, - * try access /etc/MaxScale/ - */ - tmp = strdup("/etc/MaxScale"); - get_expanded_pathname(p_home_dir, tmp, NULL); - - if (*p_home_dir != NULL) - { - log_context = strdup("/etc/MaxScale"); - goto check_home_dir; - } - free(tmp); - /*< - * 3. if /etc/MaxScale/MaxScale.cnf didn't exist or wasn't accessible, home - * isn't specified. Thus, try to access $PWD/MaxScale.cnf . - */ - char *pwd = getenv("PWD"); - tmp = strndup(pwd ? pwd : "PWD_NOT_SET", PATH_MAX); - tmp2 = get_expanded_pathname(p_home_dir, tmp, default_cnf_fname); - free(tmp2); /*< full path isn't needed so simply free it */ - - if (*p_home_dir != NULL) - { - log_context = strdup("Current working directory"); - } - -check_home_dir: - if (*p_home_dir != NULL) - { - if (!file_is_readable(*p_home_dir)) - { - char* tailstr = "MaxScale doesn't have read permission " - "to MAXSCALE_HOME."; - char* logstr = (char*)malloc(strlen(log_context)+ - 1+ - strlen(tailstr)+ - 1); - snprintf(logstr, - strlen(log_context)+ - 1+ - strlen(tailstr)+1, - "%s:%s", - log_context, - tailstr); - print_log_n_stderr(true, true, logstr, logstr, 0); - free(logstr); - goto return_succp; - } - -#if WRITABLE_HOME - if (!file_is_writable(*p_home_dir)) - { - char* tailstr = "MaxScale doesn't have write permission " - "to MAXSCALE_HOME. Exiting."; - char* logstr = (char*)malloc(strlen(log_context)+ - 1+ - strlen(tailstr)+ - 1); - snprintf(logstr, - strlen(log_context)+ - 1+ - strlen(tailstr)+1, - "%s:%s", - log_context, - tailstr); - print_log_n_stderr(true, true, logstr, logstr, 0); - free(logstr); - goto return_succp; - } -#endif - if (!daemon_mode) - { - fprintf(stderr, - "Using %s as MAXSCALE_HOME = %s\n", - log_context, - tmp); - } - succp = true; - goto return_succp; - } - -return_succp: - free (tmp); - - - if (log_context != NULL) - { - free(log_context); - } - - if (!succp) - { - char* logstr = "MaxScale was unable to locate home directory " - "with read and write permissions. \n*\n* Exiting."; - print_log_n_stderr(true, true, logstr, logstr, 0); - usage(); - } - return succp; -} - /** * Check read and write accessibility to a directory. * @param dirname directory to be checked @@ -728,8 +582,9 @@ return_succp: * read or write is not permitted. */ static char* check_dir_access( - char* dirname) + char* dirname, bool rd, bool wr) { + char errbuf[PATH_MAX*2]; char* errstr = NULL; if (dirname == NULL) @@ -737,18 +592,27 @@ static char* check_dir_access( errstr = strdup("Directory argument is NULL"); goto retblock; } - - if (!file_is_readable(dirname)) + + if(access(dirname,F_OK) != 0) { - errstr = strdup("MaxScale doesn't have read permission " - "to MAXSCALE_HOME."); + sprintf(errbuf,"Can't access '%s'.",dirname); + errstr = strdup(errbuf); + goto retblock; + } + + if (rd && !file_is_readable(dirname)) + { + sprintf(errbuf,"MaxScale doesn't have read permission " + "to '%s'.",dirname); + errstr = strdup(errbuf); goto retblock; } - if (!file_is_writable(dirname)) + if (wr && !file_is_writable(dirname)) { - errstr = strdup("MaxScale doesn't have write permission " - "to MAXSCALE_HOME. Exiting."); + sprintf(errbuf,"MaxScale doesn't have write permission " + "to '%s'.",dirname); + errstr = strdup(errbuf); goto retblock; } @@ -991,19 +855,27 @@ return_cnf_file_buf: static void usage(void) { fprintf(stderr, - "\nUsage : %s [-h] | [-d] [-c ] [-f ]\n\n" - " -d|--nodaemon enable running in terminal process (default:disabled)\n" - " -c|--homedir=... relative|absolute MaxScale home directory\n" - " -f|--config=... relative|absolute pathname of MaxScale configuration file\n" - " (default: $MAXSCALE_HOME/etc/MaxScale.cnf)\n" - " -l|--log=... log to file shared memory or stdout\n" - " -lfile, -lshm or -lstdout - defaults to shared memory\n" - " -s|--syslog= log messages to syslog." - " True or false - defaults to true\n" - " -S|--maxscalelog= log messages to MaxScale log." - " True or false - defaults to true\n" - " -v|--version print version info and exit\n" - " -?|--help show this help\n" + "\nUsage : %s [OPTION]...\n\n" + " -d, --nodaemon enable running in terminal process (default:disabled)\n" + " -f, --config=FILE relative|absolute pathname of MaxScale configuration file\n" + " (default:/etc/maxscale.cnf)\n" + " -l, --log=[file|shm] log to file or shared memory (default: shm)\n" + " -L, --logdir=PATH path to log file directory\n" + " (default: /var/log/maxscale)\n" + " -A, --cachedir=PATH path to cache directory\n" + " (default: /var/cache/maxscale)\n" + " -B, --libdir=PATH path to module directory\n" + " (default: /usr/lib64/maxscale)\n" + " -C, --configdir=PATH path to configuration file directory\n" + " (default: /etc/)\n" + " -D, --datadir=PATH path to data directory, stored embedded mysql tables\n" + " (default: /var/cache/maxscale)\n" + " -U, --user=USER run MaxScale as another user.\n" + " The user ID and group ID of this user are used to run MaxScale.\n" + " -s, --syslog=[yes|no] log messages to syslog (default:yes)\n" + " -S, --maxscalelog=[yes|no] log messages to MaxScale log (default: yes)\n" + " -v, --version print version info and exit\n" + " -?, --help show this help\n" , progname); } @@ -1028,19 +900,13 @@ static void usage(void) * This is not obvious solution because stderr is often directed to somewhere, * but currently this is the case. * - * The configuration file is by default \/etc/MaxScale.cnf + * The configuration file is by default /etc/maxscale.cnf * The name of configuration file and its location can be specified by * command-line argument. * - * \ is resolved in the following order: - * 1. from '-c ' command-line argument - * 2. from MAXSCALE_HOME environment variable - * 3. /etc/ if MaxScale.cnf is found from there - * 4. current working directory if MaxScale.cnf is found from there - * * \ is resolved in the following order: * 1. from '-f \' command-line argument - * 2. by using default value "MaxScale.cnf" + * 2. by using default value "maxscale.cnf" * */ int main(int argc, char **argv) @@ -1062,9 +928,10 @@ int main(int argc, char **argv) char* cnf_file_path = NULL; /*< conf file, to be freed */ char* cnf_file_arg = NULL; /*< conf filename from cmd-line arg */ void* log_flush_thr = NULL; + char* tmp_path; + char* tmp_var; int option_index; int logtofile = 0; /* Use shared memory or file */ - int logtostdout = 0; /* Use stdout for log output */ int syslog_enabled = 1; /** Log to syslog */ int maxscalelog_enabled = 1; /** Log with MaxScale */ ssize_t log_flush_timeout_ms = 0; @@ -1075,11 +942,13 @@ int main(int argc, char **argv) datadir_cleanup, write_footer, NULL}; + + + sigemptyset(&sigpipe_mask); sigaddset(&sigpipe_mask, SIGPIPE); - progname = *argv; - + sprintf(datadir, "%s", default_datadir); #if defined(FAKE_CODE) memset(conn_open, 0, sizeof(bool)*10240); memset(dcb_fake_write_errno, 0, sizeof(unsigned char)*10240); @@ -1106,7 +975,8 @@ int main(int argc, char **argv) goto return_main; } } - while ((opt = getopt_long(argc, argv, "dc:f:l:vs:S:?", + + while ((opt = getopt_long(argc, argv, "dc:f:l:vs:S:?L:D:C:B:U:A:", long_options, &option_index)) != -1) { bool succp = true; @@ -1116,56 +986,6 @@ int main(int argc, char **argv) /*< Debug mode, maxscale runs in this same process */ daemon_mode = false; break; - - case 'c': - /*< - * Create absolute path pointing to MaxScale home - * directory. User-provided home directory may be - * either absolute or relative. If latter, it is - * expanded and stored in home_dir if succeed. - */ - if (optarg[0] != '-') - { - struct stat sb; - - if (stat(optarg, &sb) != -1 - && (! S_ISDIR(sb.st_mode))) - { - char* logerr = "Home directory argument " - "identifier \'-c\' was specified but " - "the argument didn't specify a valid " - "a directory."; - print_log_n_stderr(true, true, logerr, logerr, 0); - usage(); - succp = false; - } - else - { - get_expanded_pathname(&home_dir, optarg, NULL); - } - } - - if (home_dir != NULL) - { - /*< - * MAXSCALE_HOME is set. - * It is used to assist in finding the modules - * to be loaded into MaxScale. - */ - setenv("MAXSCALE_HOME", home_dir, 1); - } - else - { - char* logerr = "Home directory argument " - "identifier \'-c\' was specified but " - "the argument didn't specify \n a valid " - "home directory or the argument was " - "missing."; - print_log_n_stderr(true, true, logerr, logerr, 0); - usage(); - succp = false; - } - break; case 'f': /*< @@ -1199,8 +1019,6 @@ int main(int argc, char **argv) logtofile = 1; else if (strncasecmp(optarg, "shm", PATH_MAX) == 0) logtofile = 0; - else if (strncasecmp(optarg, "stdout", PATH_MAX) == 0) - logtostdout = 1; else { char* logerr = "Configuration file argument " @@ -1213,6 +1031,43 @@ int main(int argc, char **argv) succp = false; } break; + case 'L': + + if(handle_path_arg(&tmp_path,optarg,NULL,true,false)) + { + logdir = tmp_path; + } + + break; + case 'N': + if(handle_path_arg(&tmp_path,optarg,NULL,true,false)) + { + langdir = tmp_path; + } + break; + case 'D': + sprintf(datadir,"%s",optarg); + maxscaledatadir = strdup(optarg); + datadir_defined = true; + break; + case 'C': + if(handle_path_arg(&tmp_path,optarg,NULL,true,false)) + { + configdir = tmp_path; + } + break; + case 'B': + if(handle_path_arg(&tmp_path,optarg,NULL,true,false)) + { + libdir = tmp_path; + } + break; + case 'A': + if(handle_path_arg(&tmp_path,optarg,NULL,true,true)) + { + cachedir = tmp_path; + } + break; case 'S': if(strstr(optarg,"=")) { @@ -1235,6 +1090,12 @@ int main(int argc, char **argv) syslog_enabled = config_truth_value(optarg); } break; + case 'U': + if(set_user(optarg) != 0) + { + succp = false; + } + break; case '?': usage(); rc = EXIT_SUCCESS; @@ -1514,88 +1375,64 @@ int main(int argc, char **argv) goto return_main; } - /*< - * If MaxScale home directory wasn't set by command-line argument. - * Next, resolve it from environment variable and further on, - * try to use default. + /** + * Resolve the full pathname for configuration file and check for + * read accessibility. */ - if (home_dir == NULL) + char pathbuf[PATH_MAX+1]; + snprintf(pathbuf,PATH_MAX,"%s",configdir ? configdir:default_configdir); + if(pathbuf[strlen(pathbuf)-1] != '/') + strcat(pathbuf,"/"); + + if (!resolve_maxscale_conf_fname(&cnf_file_path, pathbuf, cnf_file_arg)) { - if (!resolve_maxscale_homedir(&home_dir)) - { - ss_dassert(home_dir != NULL); - rc = MAXSCALE_HOMELESS; - goto return_main; - } - sprintf(mysql_home, "%s/mysql", home_dir); - setenv("MYSQL_HOME", mysql_home, 1); + ss_dassert(cnf_file_path == NULL); + rc = MAXSCALE_BADCONFIG; + goto return_main; } - else - { - char* log_context = strdup("Home directory command-line argument"); - char* errstr; - - errstr = check_dir_access(home_dir); - - if (errstr != NULL) - { - char* logstr = (char*)malloc(strlen(log_context)+ - 1+ - strlen(errstr)+ - 1); - - snprintf(logstr, - strlen(log_context)+ - 1+ - strlen(errstr)+1, - "%s: %s", - log_context, - errstr); - - print_log_n_stderr(true, true, logstr, logstr, 0); - - free(errstr); - free(logstr); - rc = MAXSCALE_HOMELESS; - goto return_main; - } - else if (!daemon_mode) - { - fprintf(stderr, - "Using %s as MAXSCALE_HOME = %s\n", - log_context, - home_dir); - } - free(log_context); - } + + ini_parse(cnf_file_path,cnf_preparser,NULL); + + if(!datadir_defined) + sprintf(datadir,"%s",default_datadir); + + + /** Use the cache dir for the mysql folder of the embedded library */ + sprintf(mysql_home, "%s/mysql", cachedir?cachedir:default_cachedir); + setenv("MYSQL_HOME", mysql_home, 1); + /** * Init Log Manager for MaxScale. - * If $MAXSCALE_HOME is set then write the logs into $MAXSCALE_HOME/log. * The skygw_logmanager_init expects to take arguments as passed to main * and proesses them with getopt, therefore we need to give it a dummy * argv[0] */ { char buf[1024]; - char *argv[9]; + char *argv[8]; bool succp; - /** Set log directory under $MAXSCALE_HOME/log */ - sprintf(buf, "%s/log", home_dir); - if(mkdir(buf, 0777) != 0) + /** Use default log directory /var/log/maxscale/ */ + if(logdir == NULL) { - if(errno != EEXIST) + + if(access(default_logdir,F_OK) != 0) + { + if(mkdir(logdir,0555) != 0) { - fprintf(stderr, - "Error: Cannot create log directory: %s\n", - buf); - goto return_main; + fprintf(stderr, + "Error: Cannot create log directory: %s\n", + default_logdir); + goto return_main; } + } + logdir = strdup(default_logdir); } + argv[0] = "MaxScale"; argv[1] = "-j"; - argv[2] = buf; + argv[2] = logdir; if(!syslog_enabled) { @@ -1608,17 +1445,8 @@ int main(int argc, char **argv) } logmanager_enable_syslog(syslog_enabled); logmanager_enable_maxscalelog(maxscalelog_enabled); - if (logtostdout) - { - argv[3] = "-s"; /*< store to shared memory */ - argv[4] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< to shm */ - argv[5] = "-l"; /*< write to syslog */ - argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< to syslog */ - argv[7] = "-o"; - argv[8] = NULL; - succp = skygw_logmanager_init(8, argv); - } - else if (logtofile) + + if (logtofile) { argv[3] = "-l"; /*< write to syslog */ /** Logs that should be syslogged */ @@ -1643,25 +1471,25 @@ int main(int argc, char **argv) goto return_main; } } - /** - * Resolve the full pathname for configuration file and check for - * read accessibility. - */ - if (!resolve_maxscale_conf_fname(&cnf_file_path, home_dir, cnf_file_arg)) - { - ss_dassert(cnf_file_path == NULL); - rc = MAXSCALE_BADCONFIG; - goto return_main; - } - /*< + + + if(cachedir == NULL) + cachedir = strdup(default_cachedir); + if(langdir == NULL) + langdir = strdup(default_langdir); + if(libdir == NULL) + libdir = strdup(default_libdir); + /** * Set a data directory for the mysqld library, we use * a unique directory name to avoid clauses if multiple * instances of the gateway are beign run on the same * machine. */ - sprintf(datadir, "%s/data", home_dir); + if(datadir[strlen(datadir)-1] != '/') + strcat(datadir,"/"); + strcat(datadir,"data"); if(mkdir(datadir, 0777) != 0){ if(errno != EEXIST){ @@ -1671,7 +1499,7 @@ int main(int argc, char **argv) } } - sprintf(datadir, "%s/data/data%d", home_dir, getpid()); + sprintf(datadir, "%s/data%d", datadir, getpid()); if(mkdir(datadir, 0777) != 0){ @@ -1685,31 +1513,41 @@ int main(int argc, char **argv) if (!daemon_mode) { fprintf(stderr, - "Home directory : %s" - "\nConfiguration file : %s" - "\nLog directory : %s/log" - "\nData directory : %s\n\n", - home_dir, + "Configuration file : %s\n" + "Log directory : %s\n" + "Data directory : %s\n" + "Module directory : %s\n" + "Service cache : %s\n\n", cnf_file_path, - home_dir, - datadir); + logdir, + datadir, + libdir, + cachedir); } - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Home directory : %s", - home_dir))); - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Data directory : %s", - datadir))); - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Log directory : %s/log", - home_dir))); - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Configuration file : %s", - cnf_file_path))); + + LOGIF(LM, + (skygw_log_write_flush( + LOGFILE_MESSAGE, + "Configuration file: %s", + cnf_file_path))); + LOGIF(LM, + (skygw_log_write_flush( + LOGFILE_MESSAGE, + "Log directory: %s/", + logdir))); + LOGIF(LM, + (skygw_log_write_flush( + LOGFILE_MESSAGE, + "Data directory: %s", + datadir))); + LOGIF(LM, + (skygw_log_write_flush(LOGFILE_MESSAGE, + "Module directory: %s", + libdir))); + LOGIF(LM, + (skygw_log_write_flush(LOGFILE_MESSAGE, + "Service cache: %s", + cachedir))); /*< Update the server options */ for (i = 0; server_options[i]; i++) @@ -1723,8 +1561,8 @@ int main(int argc, char **argv) { snprintf(language_arg, 11+PATH_MAX+1, - "--language=%s/mysql", - home_dir); + "--language=%s", + langdir); server_options[i] = language_arg; } } @@ -1780,10 +1618,13 @@ int main(int argc, char **argv) } libmysqld_started = TRUE; + if(libdir == NULL) + libdir = strdup(default_libdir); + if (!config_load(cnf_file_path)) { char* fprerr = "Failed to load MaxScale configuration " - "file. Exiting."; + "file. Exiting. See the error log for details."; print_log_n_stderr(false, !daemon_mode, fprerr, fprerr, 0); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, @@ -1980,7 +1821,7 @@ static int write_pid_file(char *home_dir) { int fd = -1; - snprintf(pidfile, PATH_MAX, "%s/log/maxscale.pid", home_dir); + snprintf(pidfile, PATH_MAX, "%smaxscale.pid",default_piddir); fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd == -1) { @@ -2015,3 +1856,135 @@ MaxScaleUptime() { return time(0) - MaxScaleStarted; } + +bool handle_path_arg(char** dest, char* path, char* arg, bool rd, bool wr) +{ + char pathbuffer[PATH_MAX+2]; + char* errstr; + bool rval = false; + + if(path == NULL && arg == NULL) + return rval; + + if(path) + { + snprintf(pathbuffer,PATH_MAX,"%s",path); + if(pathbuffer[strlen(path) - 1] != '/') + { + strcat(pathbuffer,"/"); + } + if(arg && strlen(pathbuffer) + strlen(arg) + 1 < PATH_MAX) + strcat(pathbuffer,arg); + + if((errstr = check_dir_access(pathbuffer,rd,wr)) == NULL) + { + *dest = strdup(pathbuffer); + rval = true; + } + else + { + fprintf(stderr,"%s\n",errstr); + free(errstr); + errstr = NULL; + } + } + + return rval; +} + +/** + * Pre-parse the MaxScale.cnf for config, log and module directories. + * @param data Parameter passed by inih + * @param section Section name + * @param name Parameter name + * @param value Parameter value + * @return 1 in all cases + */ +static int cnf_preparser(void* data, const char* section, const char* name, const char* value) +{ + + char pathbuffer[PATH_MAX]; + char* errstr; + + /** These are read from the configuration file. These will not override + * command line parameters but will override default values. */ + if(strcasecmp(section,"maxscale") == 0) + { + if(strcmp(name, "logdir") == 0) + { + if(logdir == NULL) + handle_path_arg(&logdir,(char*)value,NULL,true,true); + } + else if(strcmp(name, "libdir") == 0) + { + if(libdir == NULL) + handle_path_arg(&libdir,(char*)value,NULL,true,false); + } + else if(strcmp(name, "datadir") == 0) + { + if(!datadir_defined) + { + char* tmp; + if(handle_path_arg(&tmp,(char*)value,NULL,true,false)) + { + sprintf(datadir,"%s",tmp); + maxscaledatadir = strdup(tmp); + datadir_defined = true; + free(tmp); + } + } + } + else if(strcmp(name, "cachedir") == 0) + { + if(cachedir == NULL) + handle_path_arg((char**)&cachedir,(char*)value,NULL,true,false); + } + else if(strcmp(name, "language") == 0) + { + if(langdir == NULL) + handle_path_arg((char**)&langdir,(char*)value,NULL,true,false); + } + } + + return 1; +} + +static int set_user(char* user) +{ + errno = 0; + struct passwd *pwname; + int rval; + + pwname = getpwnam(user); + if(pwname == NULL) + { + printf("Error: Failed to retrieve user information for '%s': %d %s\n", + user,errno,errno == 0 ? "User not found" : strerror(errno)); + return -1; + } + + rval = setgid(pwname->pw_gid); + if(rval != 0) + { + printf("Error: Failed to change group to '%d': %d %s\n", + pwname->pw_gid,errno,strerror(errno)); + return rval; + } + + rval = setuid(pwname->pw_uid); + if(rval != 0) + { + printf("Error: Failed to change user to '%s': %d %s\n", + pwname->pw_name,errno,strerror(errno)); + return rval; + } +#ifdef SS_DEBUG + else + { + printf("Running MaxScale as: %s %d:%d\n",pwname->pw_name,pwname->pw_uid,pwname->pw_gid); + } +#endif + + + return rval; +} diff --git a/server/core/gwdirs.c b/server/core/gwdirs.c new file mode 100644 index 000000000..1fe8af008 --- /dev/null +++ b/server/core/gwdirs.c @@ -0,0 +1,29 @@ +#include + +/** + * Get the directory with all the modules. + * @return The module directory + */ +char* get_libdir() +{ + return libdir?libdir:(char*)default_libdir; +} + +/** + * Get the service cache directory + * @return The path to the cache directory + */ +char* get_cachedir() +{ + return cachedir?cachedir:(char*)default_cachedir; +} + + +/** + * Get the service cache directory + * @return The path to the cache directory + */ +char* get_datadir() +{ + return maxscaledatadir?maxscaledatadir:(char*)default_datadir; +} diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 172f24ad0..9d7d69220 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -104,21 +106,10 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) return realsize; } -char* get_maxscale_home(void) -{ - char* home = getenv("MAXSCALE_HOME"); - if (home == NULL) - { - home = "/usr/local/mariadb-maxscale"; - } - return home; -} - - /** * Load the dynamic library related to a gateway module. The routine * will look for library files in the current directory, - * $MAXSCALE_HOME/modules and /usr/local/mariadb-maxscale/modules. + * the configured folder and /usr/lib64/maxscale. * * @param module Name of the module to load * @param type Type of module, used purely for registration @@ -142,22 +133,17 @@ MODULE_INFO *mod_info = NULL; * * Search of the shared object. */ - snprintf(fname,MAXPATHLEN+1, "./lib%s.so", module); - + + snprintf(fname, MAXPATHLEN+1,"%s/lib%s.so", get_libdir(), module); + if (access(fname, F_OK) == -1) { - home = get_maxscale_home (); - snprintf(fname, MAXPATHLEN+1,"%s/modules/lib%s.so", home, module); - - if (access(fname, F_OK) == -1) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to find library for " - "module: %s.", - module))); - return NULL; - } + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Unable to find library for " + "module: %s. Module dir: %s", + module, get_libdir()))); + return NULL; } if ((dlhandle = dlopen(fname, RTLD_NOW|RTLD_LOCAL)) == NULL) diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index c85dd1d8e..557920dbe 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -31,6 +31,7 @@ #include #include #include +#include int main(int argc, char **argv) { int arg_count = 6; @@ -52,22 +53,21 @@ int main(int argc, char **argv) return 1; } - arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - - if ((home = getenv("MAXSCALE_HOME")) != NULL) + if(access("/var/log/maxscale/maxkeys/",F_OK) != 0) { - arg_vector[2] = (char*)malloc((strlen(home) + strlen("/log"))*sizeof(char)); - sprintf(arg_vector[2],"%s/log",home); + if(mkdir("/var/log/maxscale/maxkeys/",0777) == -1) + { + if(errno != EEXIST) + { + fprintf(stderr,"Error: %d - %s",errno,strerror(errno)); + return 1; + } + } } - else - { - arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log"); - } - arg_vector[3] = "-o"; - arg_vector[4] = "-l"; - arg_vector[5] = "LOGFILE_ERROR"; - arg_vector[6] = NULL; + arg_vector[0] = strdup("logmanager"); + arg_vector[1] = strdup("-j"); + arg_vector[2] = strdup("/var/log/maxscale/maxkeys"); + arg_vector[3] = NULL; skygw_logmanager_init(arg_count,arg_vector); free(arg_vector[2]); free(arg_vector); diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 453aba38f..5c761f378 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -60,18 +60,9 @@ main(int argc, char **argv) return 1; } - arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - - if ((home = getenv("MAXSCALE_HOME")) != NULL) - { - arg_vector[2] = (char*)malloc((strlen(home) + strlen("/log"))*sizeof(char)); - sprintf(arg_vector[2],"%s/log",home); - } - else - { - arg_vector[2] = strdup("/usr/local/mariadb-maxscale/log"); - } + arg_vector[0] = strdup("logmanager"); + arg_vector[1] = strdup("-j"); + arg_vector[2] = strdup("/var/log/maxscale"); arg_vector[3] = "-o"; arg_vector[4] = "-l"; diff --git a/server/core/modutil.c b/server/core/modutil.c index ecd3b51a9..6fa7b3c8b 100644 --- a/server/core/modutil.c +++ b/server/core/modutil.c @@ -841,4 +841,4 @@ int modutil_count_statements(GWBUF* buffer) } return num; -} \ No newline at end of file +} diff --git a/server/core/secrets.c b/server/core/secrets.c index 3eae2cc48..2ec3e75a9 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -22,6 +22,7 @@ #include #include #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -62,7 +63,7 @@ int i; static MAXKEYS * secrets_readKeys() { -char secret_file[255]; +char secret_file[PATH_MAX+1]; char *home; MAXKEYS *keys; struct stat secret_stats; @@ -70,12 +71,7 @@ int fd; int len; static int reported = 0; - home = getenv("MAXSCALE_HOME"); - - if (home == NULL) { - home = "/usr/local/mariadb-maxscale"; - } - snprintf(secret_file, 255, "%s/etc/.secrets", home); + snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir()); /* Try to access secrets file */ if (access(secret_file, R_OK) == -1) diff --git a/server/core/service.c b/server/core/service.c index 4584ded24..5ba5d539d 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -61,6 +61,8 @@ #include #include #include +#include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -112,7 +114,7 @@ SERVICE *service; return NULL; if ((service->router = load_module(router, MODULE_ROUTER)) == NULL) { - char* home = get_maxscale_home(); + char* home = get_libdir(); char* ldpath = getenv("LD_LIBRARY_PATH"); LOGIF(LE, (skygw_log_write_flush( @@ -120,12 +122,13 @@ SERVICE *service; "Error : Unable to load %s module \"%s\".\n\t\t\t" " Ensure that lib%s.so exists in one of the " "following directories :\n\t\t\t " - "- %s/modules\n\t\t\t - %s", + "- %s/modules\n%s%s", MODULE_ROUTER, router, router, home, - ldpath))); + ldpath?"\t\t\t - ":"", + ldpath?ldpath:""))); free(service); return NULL; } @@ -229,11 +232,7 @@ GWPROTOCOL *funcs; { /* Try loading authentication data from file cache */ char *ptr, path[4097]; - strcpy(path, "/usr/local/mariadb-maxscale"); - if ((ptr = getenv("MAXSCALE_HOME")) != NULL) - { - strncpy(path, ptr, 4096); - } + strcpy(path, get_cachedir()); strncat(path, "/", 4096); strncat(path, service->name, 4096); strncat(path, "/.cache/dbusers", 4096); @@ -257,15 +256,11 @@ GWPROTOCOL *funcs; else { /* Save authentication data to file cache */ - char *ptr, path[4097]; + char *ptr, path[PATH_MAX + 1]; int mkdir_rval = 0; - strcpy(path, "/usr/local/mariadb-maxscale"); - if ((ptr = getenv("MAXSCALE_HOME")) != NULL) - { - strncpy(path, ptr, 4096); - } + strcpy(path, get_cachedir()); strncat(path, "/", 4096); - strncat(path, service->name, 4096); + strncat(path, service->name, PATH_MAX); if (access(path, R_OK) == -1) { mkdir_rval = mkdir(path, 0777); @@ -280,7 +275,7 @@ GWPROTOCOL *funcs; mkdir_rval = 0; } - strncat(path, "/.cache", 4096); + strncat(path, "/.cache", PATH_MAX); if (access(path, R_OK) == -1) { mkdir_rval = mkdir(path, 0777); @@ -294,7 +289,7 @@ GWPROTOCOL *funcs; strerror(errno)); mkdir_rval = 0; } - strncat(path, "/dbusers", 4096); + strncat(path, "/dbusers", PATH_MAX); dbusers_save(service->users, path); } if (loaded == 0) diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 5c1f9a8ad..2d32d55b1 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -44,19 +44,4 @@ add_test(Internal-TestUsers test_users) add_test(Internal-TestAdminUsers test_adminusers) add_test(Internal-TestMemlog testmemlog) add_test(TestFeedback testfeedback) -set_tests_properties(Internal-TestMySQLUsers - Internal-TestHash - Internal-TestHint - Internal-TestSpinlock - Internal-TestFilter - Internal-TestBuffer - Internal-TestDCB - Internal-TestModutil - Internal-TestPoll - Internal-TestService - Internal-TestServer - Internal-TestUsers - Internal-TestAdminUsers - Internal-TestMemlog - TestFeedback PROPERTIES ENVIRONMENT MAXSCALE_HOME=${CMAKE_BINARY_DIR}/) set_tests_properties(TestFeedback PROPERTIES TIMEOUT 30) diff --git a/server/core/test/testadminusers.c b/server/core/test/testadminusers.c index ae52bd8b7..f9c34e500 100644 --- a/server/core/test/testadminusers.c +++ b/server/core/test/testadminusers.c @@ -30,7 +30,7 @@ #include #include #include - +#include #include @@ -40,7 +40,7 @@ * Test that the username password admin/mariadb is accepted if no users * have been created and that no other users are accepted * - * WARNING: $MAXSCALE_HOME/etc/passwd must be removed before this test is run + * WARNING: The passwd file must be removed before this test is run */ static int test1() @@ -269,9 +269,8 @@ int result = 0; char *home, buf[1024]; /* Unlink any existing password file before running this test */ - if ((home = getenv("MAXSCALE_HOME")) == NULL || strlen(home) >= 1024) - home = "/usr/local/mariadb-maxscale"; - sprintf(buf, "%s/etc/passwd", home); + + sprintf(buf, "%s/passwd", default_cachedir); if(!is_valid_posix_path(buf)) exit(1); if (strcmp(buf, "/etc/passwd") != 0) diff --git a/server/core/test/testfeedback.c b/server/core/test/testfeedback.c index 6549305c3..3b281537e 100644 --- a/server/core/test/testfeedback.c +++ b/server/core/test/testfeedback.c @@ -73,17 +73,8 @@ int main(int argc, char** argv) char* cnf; hkinit(); - home = getenv("MAXSCALE_HOME"); - if(home == NULL) - { - FAILTEST("MAXSCALE_HOME was not defined."); - } - printf("Home: %s\n",home); - - cnf = malloc(strlen(home) + strlen("/etc/MaxScale.cnf") + 1); - strcpy(cnf,home); - strcat(cnf,"/etc/MaxScale.cnf"); + cnf = strdup("/etc/MaxScale.cnf"); printf("Config: %s\n",cnf); @@ -116,4 +107,4 @@ int main(int argc, char** argv) } mysql_library_end(); return 0; -} \ No newline at end of file +} diff --git a/server/include/gw.h b/server/include/gw.h index 9c8507210..b51bb0e2a 100644 --- a/server/include/gw.h +++ b/server/include/gw.h @@ -1,3 +1,25 @@ +#ifndef _GW_HG +#define _GW_HG + +/* + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright MariaDB Corporation Ab 2013-2014 + */ + + #include #include #include @@ -16,8 +38,8 @@ #include #include #include - #include +#include #define EXIT_FAILURE 1 @@ -65,3 +87,5 @@ int gw_write(DCB *dcb, const void *buf, size_t nbytes); int gw_getsockerrno(int fd); int parse_bindconfig(char *, unsigned short, struct sockaddr_in *); int setipaddress(struct in_addr *, char *); +char* get_libdir(); +#endif diff --git a/server/include/gwdirs.h.in b/server/include/gwdirs.h.in new file mode 100644 index 000000000..66e34426f --- /dev/null +++ b/server/include/gwdirs.h.in @@ -0,0 +1,44 @@ +#ifndef _GW_DIRS_HG +#define _GW_DIRS_HG + +/* + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright MariaDB Corporation Ab 2015 + */ + +#include + +/** Default file locations, configured by CMake */ +static const char* default_cnf_fname = "maxscale.cnf"; +static const char* default_configdir = "/etc/"; +static const char* default_piddir = "/var/run/maxscale/"; +static const char* default_logdir = "/var/log/maxscale/"; +static const char* default_datadir = "/var/lib/maxscale/"; +static const char* default_libdir = "@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@"; +static const char* default_cachedir = "/var/cache/maxscale/"; +static const char* default_langdir = "@MAXSCALE_VARDIR@/lib/maxscale/"; + +static char* configdir = NULL; +static char* logdir = NULL; +static char* libdir = NULL; +static char* cachedir = NULL; +static char* maxscaledatadir = NULL; +static char* langdir = NULL; + +char* get_libdir(); +char* get_datadir(); +char* get_cachedir(); +#endif diff --git a/server/include/modules.h b/server/include/modules.h index 51e10b29d..96d322402 100644 --- a/server/include/modules.h +++ b/server/include/modules.h @@ -68,7 +68,6 @@ extern void unload_all_modules(); extern void printModules(); extern void dprintAllModules(DCB *); extern RESULTSET *moduleGetList(); -extern char *get_maxscale_home(void); extern void module_feedback_send(void*); extern void moduleShowFeedbackReport(DCB *dcb); diff --git a/server/MaxScale_BinlogServer_template.cnf b/server/maxscale_binlogserver_template.cnf similarity index 95% rename from server/MaxScale_BinlogServer_template.cnf rename to server/maxscale_binlogserver_template.cnf index dddd74163..f9cc112aa 100644 --- a/server/MaxScale_BinlogServer_template.cnf +++ b/server/maxscale_binlogserver_template.cnf @@ -1,5 +1,5 @@ # -# Example MaxScale.cnf for the Binlog Server. +# Example maxscale.cnf for the Binlog Server. # # @@ -37,14 +37,13 @@ threads=6 # The MaxScale Binlog Server Service. # # The name of this service will be used as the directory name -# in $MAXSCALE_HOME where the binlogs will be saved. +# in the cache directory where the binlogs will be saved. # If this name is changed, it must be changed in the listener # configuration below. [Binlog_Service] # type must be service # router must be binlogrouter -# (corresponding to the so file in $MAXSCALE_HOME/modules). type=service router=binlogrouter diff --git a/server/MaxScale_template.cnf b/server/maxscale_template.cnf similarity index 100% rename from server/MaxScale_template.cnf rename to server/maxscale_template.cnf diff --git a/server/modules/filter/CMakeLists.txt b/server/modules/filter/CMakeLists.txt index 0af1ea566..6bf6a5daa 100644 --- a/server/modules/filter/CMakeLists.txt +++ b/server/modules/filter/CMakeLists.txt @@ -3,48 +3,48 @@ if(BUILD_RABBITMQ) include_directories(${RABBITMQ_HEADERS}) add_library(mqfilter SHARED mqfilter.c) target_link_libraries(mqfilter query_classifier log_manager utils ${RABBITMQ_LIBRARIES}) - install(TARGETS mqfilter DESTINATION modules) + install(TARGETS mqfilter DESTINATION ${MAXSCALE_LIBDIR}) endif() add_library(regexfilter SHARED regexfilter.c) target_link_libraries(regexfilter log_manager utils) -install(TARGETS regexfilter DESTINATION modules) +install(TARGETS regexfilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(testfilter SHARED testfilter.c) target_link_libraries(testfilter log_manager utils) -install(TARGETS testfilter DESTINATION modules) +install(TARGETS testfilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(qlafilter SHARED qlafilter.c) target_link_libraries(qlafilter log_manager utils) -install(TARGETS qlafilter DESTINATION modules) +install(TARGETS qlafilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(tee SHARED tee.c) target_link_libraries(tee log_manager utils) -install(TARGETS tee DESTINATION modules) +install(TARGETS tee DESTINATION ${MAXSCALE_LIBDIR}) add_library(topfilter SHARED topfilter.c) target_link_libraries(topfilter log_manager utils) -install(TARGETS topfilter DESTINATION modules) +install(TARGETS topfilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(dbfwfilter SHARED dbfwfilter.c) target_link_libraries(dbfwfilter log_manager utils query_classifier) -install(TARGETS dbfwfilter DESTINATION modules) +install(TARGETS dbfwfilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(namedserverfilter SHARED namedserverfilter.c) target_link_libraries(namedserverfilter log_manager utils) -install(TARGETS namedserverfilter DESTINATION modules) +install(TARGETS namedserverfilter DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_SLAVELAG) add_library(slavelag SHARED slavelag.c) target_link_libraries(slavelag log_manager utils query_classifier) - install(TARGETS slavelag DESTINATION modules) + install(TARGETS slavelag DESTINATION ${MAXSCALE_LIBDIR}) endif() if(BUILD_TOOLS) add_executable(ruleparser dbfwfilter.c) target_compile_definitions(ruleparser PUBLIC "BUILD_RULE_PARSER") target_link_libraries(ruleparser ${EMBEDDED_LIB} log_manager utils query_classifier fullcore) - install(TARGETS ruleparser DESTINATION tools) + install(TARGETS ruleparser DESTINATION ${MAXSCALE_BINDIR}) endif() add_subdirectory(hint) diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 2f1bb8ed9..8391ab748 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -2214,15 +2214,13 @@ int main(int argc, char** argv) return 1; } - if((home = getenv("MAXSCALE_HOME")) == NULL) + home = malloc(sizeof(char)*(PATH_MAX+1)); + if(getcwd(home,PATH_MAX) == NULL) { - home = malloc(sizeof(char)*(PATH_MAX+1)); - if(getcwd(home,PATH_MAX) == NULL) - { - free(home); - home = NULL; - } + free(home); + home = NULL; } + printf("Log files written to: %s\n",home?home:"/tpm"); int argc_ = 2; diff --git a/server/modules/filter/hint/CMakeLists.txt b/server/modules/filter/hint/CMakeLists.txt index f47cb637e..c2d5e9ea1 100644 --- a/server/modules/filter/hint/CMakeLists.txt +++ b/server/modules/filter/hint/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(hintfilter SHARED hintfilter.c hintparser.c) -set_target_properties(hintfilter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib) +set_target_properties(hintfilter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${MAXSCALE_LIBDIR}) target_link_libraries(hintfilter ssl log_manager utils) -install(TARGETS hintfilter DESTINATION modules) \ No newline at end of file +install(TARGETS hintfilter DESTINATION ${MAXSCALE_LIBDIR}) diff --git a/server/modules/filter/test/CMakeLists.txt b/server/modules/filter/test/CMakeLists.txt index 50b5c4e0e..cd4f31b92 100644 --- a/server/modules/filter/test/CMakeLists.txt +++ b/server/modules/filter/test/CMakeLists.txt @@ -1,4 +1,3 @@ - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_executable(harness_ui harness_ui.c harness_common.c) add_executable(harness harness_util.c harness_common.c) @@ -25,7 +24,3 @@ add_test(TestTeeRecursion ${CMAKE_CURRENT_SOURCE_DIR}/tee_recursion.sh ${TEST_PASSWORD} ${TEST_HOST} ${TEST_PORT}) - -set_tests_properties(TestHintfilter TestRegexfilter TestFwfilter1 TestFwfilter2 TestTeeRecursion -PROPERTIES -ENVIRONMENT MAXSCALE_HOME=${CMAKE_BINARY_DIR}/) diff --git a/server/modules/filter/test/tee_recursion.sh b/server/modules/filter/test/tee_recursion.sh index 015bb9a8e..82a8080e2 100755 --- a/server/modules/filter/test/tee_recursion.sh +++ b/server/modules/filter/test/tee_recursion.sh @@ -49,8 +49,8 @@ USER=$3 PWD=$4 HOST=$5 PORT=$6 -CONF=$BINDIR/etc/MaxScale.cnf -OLDCONF=$BINDIR/etc/MaxScale.cnf.old +CONF=$BINDIR/etc/maxscale.cnf +OLDCONF=$BINDIR/etc/maxscale.cnf.old MAXPID=$BINDIR/log/$(ls -1 $BINDIR/log|grep maxscale) TEST1=$SRCDIR/server/modules/filter/test/tee_recursion1.cnf TEST2=$SRCDIR/server/modules/filter/test/tee_recursion2.cnf diff --git a/server/modules/monitor/CMakeLists.txt b/server/modules/monitor/CMakeLists.txt index 9f08a5b32..b32f46c30 100644 --- a/server/modules/monitor/CMakeLists.txt +++ b/server/modules/monitor/CMakeLists.txt @@ -1,16 +1,16 @@ add_library(mysqlmon SHARED mysql_mon.c monitor_common.c) target_link_libraries(mysqlmon log_manager utils) -install(TARGETS mysqlmon DESTINATION modules) +install(TARGETS mysqlmon DESTINATION ${MAXSCALE_LIBDIR}) add_library(galeramon SHARED galeramon.c monitor_common.c) target_link_libraries(galeramon log_manager utils) -install(TARGETS galeramon DESTINATION modules) +install(TARGETS galeramon DESTINATION ${MAXSCALE_LIBDIR}) add_library(ndbclustermon SHARED ndbclustermon.c monitor_common.c) target_link_libraries(ndbclustermon log_manager utils) -install(TARGETS ndbclustermon DESTINATION modules) +install(TARGETS ndbclustermon DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_MMMON) add_library(mmmon SHARED mmmon.c monitor_common.c) target_link_libraries(mmmon log_manager utils) - install(TARGETS mmmon DESTINATION modules) + install(TARGETS mmmon DESTINATION ${MAXSCALE_LIBDIR}) endif() diff --git a/server/modules/protocol/CMakeLists.txt b/server/modules/protocol/CMakeLists.txt index fa1c2ab34..4ae3b8f2c 100644 --- a/server/modules/protocol/CMakeLists.txt +++ b/server/modules/protocol/CMakeLists.txt @@ -1,27 +1,27 @@ add_library(MySQLClient SHARED mysql_client.c mysql_common.c) target_link_libraries(MySQLClient log_manager utils) -install(TARGETS MySQLClient DESTINATION modules) +install(TARGETS MySQLClient DESTINATION ${MAXSCALE_LIBDIR}) add_library(MySQLBackend SHARED mysql_backend.c mysql_common.c) target_link_libraries(MySQLBackend log_manager utils) -install(TARGETS MySQLBackend DESTINATION modules) +install(TARGETS MySQLBackend DESTINATION ${MAXSCALE_LIBDIR}) add_library(telnetd SHARED telnetd.c) target_link_libraries(telnetd log_manager utils) -install(TARGETS telnetd DESTINATION modules) +install(TARGETS telnetd DESTINATION ${MAXSCALE_LIBDIR}) add_library(HTTPD SHARED httpd.c) target_link_libraries(HTTPD log_manager utils) -install(TARGETS HTTPD DESTINATION modules) +install(TARGETS HTTPD DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) add_library(testprotocol SHARED testprotocol.c) - install(TARGETS testprotocol DESTINATION modules) + install(TARGETS testprotocol DESTINATION ${MAXSCALE_LIBDIR}) endif() add_library(maxscaled SHARED maxscaled.c) target_link_libraries(maxscaled log_manager utils) -install(TARGETS maxscaled DESTINATION modules) +install(TARGETS maxscaled DESTINATION ${MAXSCALE_LIBDIR}) diff --git a/server/modules/routing/CMakeLists.txt b/server/modules/routing/CMakeLists.txt index 02535b7b9..d51c8260b 100644 --- a/server/modules/routing/CMakeLists.txt +++ b/server/modules/routing/CMakeLists.txt @@ -2,20 +2,20 @@ if(BUILD_TESTS) add_subdirectory(test) add_library(testroute SHARED testroute.c) target_link_libraries(testroute log_manager utils) - install(TARGETS testroute DESTINATION modules) + install(TARGETS testroute DESTINATION ${MAXSCALE_LIBDIR}) endif() add_library(readconnroute SHARED readconnroute.c) target_link_libraries(readconnroute log_manager utils) -install(TARGETS readconnroute DESTINATION modules) +install(TARGETS readconnroute DESTINATION ${MAXSCALE_LIBDIR}) add_library(debugcli SHARED debugcli.c debugcmd.c) target_link_libraries(debugcli log_manager utils) -install(TARGETS debugcli DESTINATION modules) +install(TARGETS debugcli DESTINATION ${MAXSCALE_LIBDIR}) add_library(cli SHARED cli.c debugcmd.c) target_link_libraries(cli log_manager utils) -install(TARGETS cli DESTINATION modules) +install(TARGETS cli DESTINATION ${MAXSCALE_LIBDIR}) add_subdirectory(readwritesplit) add_subdirectory(schemarouter) diff --git a/server/modules/routing/binlog/CMakeLists.txt b/server/modules/routing/binlog/CMakeLists.txt index 4de2a35b4..9a0c245de 100644 --- a/server/modules/routing/binlog/CMakeLists.txt +++ b/server/modules/routing/binlog/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(binlogrouter SHARED blr.c blr_master.c blr_cache.c blr_slave.c blr_file.c) -set_target_properties(binlogrouter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib) +set_target_properties(binlogrouter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${MAXSCALE_LIBDIR}) target_link_libraries(binlogrouter ssl pthread log_manager) -install(TARGETS binlogrouter DESTINATION modules) +install(TARGETS binlogrouter DESTINATION ${MAXSCALE_LIBDIR}) diff --git a/server/modules/routing/binlog/blr_file.c b/server/modules/routing/binlog/blr_file.c index 2473909ec..ca92d6d06 100644 --- a/server/modules/routing/binlog/blr_file.c +++ b/server/modules/routing/binlog/blr_file.c @@ -71,7 +71,7 @@ static void blr_log_header(logfile_id_t file, char *msg, uint8_t *ptr); int blr_file_init(ROUTER_INSTANCE *router) { -char *ptr, path[PATH_MAX], filename[PATH_MAX]; +char *ptr, path[PATH_MAX+1], filename[PATH_MAX+1]; int file_found, n = 1; int root_len, i; DIR *dirp; @@ -79,12 +79,8 @@ struct dirent *dp; if (router->binlogdir == NULL) { - strcpy(path, "/usr/local/mariadb-maxscale"); - if ((ptr = getenv("MAXSCALE_HOME")) != NULL) - { - strncpy(path, ptr,PATH_MAX); - } - strncat(path, "/",PATH_MAX); + strcpy(path, get_datadir()); + strncat(path,"/",PATH_MAX); strncat(path, router->service->name,PATH_MAX); if (access(path, R_OK) == -1) @@ -660,24 +656,20 @@ struct stat statb; void blr_cache_response(ROUTER_INSTANCE *router, char *response, GWBUF *buf) { -char path[4097], *ptr; +char path[PATH_MAX+1], *ptr; int fd; - strcpy(path, "/usr/local/mariadb-maxscale"); - if ((ptr = getenv("MAXSCALE_HOME")) != NULL) - { - strncpy(path, ptr, 4096); - } - strncat(path, "/", 4096); - strncat(path, router->service->name, 4096); + strcpy(path,get_datadir()); + strncat(path,"/",PATH_MAX); + strncat(path, router->service->name, PATH_MAX); if (access(path, R_OK) == -1) mkdir(path, 0777); - strncat(path, "/.cache", 4096); + strncat(path, "/.cache", PATH_MAX); if (access(path, R_OK) == -1) mkdir(path, 0777); strncat(path, "/", 4096); - strncat(path, response, 4096); + strncat(path, response, PATH_MAX); if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) return; @@ -698,19 +690,15 @@ GWBUF * blr_cache_read_response(ROUTER_INSTANCE *router, char *response) { struct stat statb; -char path[4097], *ptr; +char path[PATH_MAX+1], *ptr; int fd; GWBUF *buf; - strcpy(path, "/usr/local/mariadb-maxscale"); - if ((ptr = getenv("MAXSCALE_HOME")) != NULL) - { - strncpy(path, ptr, 4096); - } - strncat(path, "/", 4096); - strncat(path, router->service->name, 4096); - strncat(path, "/.cache/", 4096); - strncat(path, response, 4096); + strcpy(path, get_datadir()); + strncat(path, "/", PATH_MAX); + strncat(path, router->service->name, PATH_MAX); + strncat(path, "/.cache/", PATH_MAX); + strncat(path, response, PATH_MAX); if ((fd = open(path, O_RDONLY)) == -1) return NULL; diff --git a/server/modules/routing/maxinfo/CMakeLists.txt b/server/modules/routing/maxinfo/CMakeLists.txt index 898df9b73..8e07a34a7 100644 --- a/server/modules/routing/maxinfo/CMakeLists.txt +++ b/server/modules/routing/maxinfo/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(maxinfo SHARED maxinfo.c maxinfo_parse.c maxinfo_error.c maxinfo_exec.c) -set_target_properties(maxinfo PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib) +set_target_properties(maxinfo PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${MAXSCALE_LIBDIR}) target_link_libraries(maxinfo pthread log_manager) -install(TARGETS maxinfo DESTINATION modules) +install(TARGETS maxinfo DESTINATION ${MAXSCALE_LIBDIR}) diff --git a/server/modules/routing/readwritesplit/CMakeLists.txt b/server/modules/routing/readwritesplit/CMakeLists.txt index 6960d4c8d..c7e387290 100644 --- a/server/modules/routing/readwritesplit/CMakeLists.txt +++ b/server/modules/routing/readwritesplit/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(readwritesplit SHARED readwritesplit.c) target_link_libraries(readwritesplit ssl pthread log_manager utils query_classifier) -install(TARGETS readwritesplit DESTINATION modules) +install(TARGETS readwritesplit DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) add_subdirectory(test) endif() diff --git a/server/modules/routing/schemarouter/CMakeLists.txt b/server/modules/routing/schemarouter/CMakeLists.txt index 70e6348af..930366f2b 100644 --- a/server/modules/routing/schemarouter/CMakeLists.txt +++ b/server/modules/routing/schemarouter/CMakeLists.txt @@ -1,10 +1,10 @@ add_library(schemarouter SHARED schemarouter.c sharding_common.c) target_link_libraries(schemarouter log_manager utils query_classifier) -install(TARGETS schemarouter DESTINATION modules) +install(TARGETS schemarouter DESTINATION ${MAXSCALE_LIBDIR}) add_library(shardrouter SHARED shardrouter.c svcconn.c sharding_common.c) target_link_libraries(shardrouter log_manager utils query_classifier) -install(TARGETS shardrouter DESTINATION modules) +install(TARGETS shardrouter DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) add_subdirectory(test) diff --git a/server/test/MaxScale_test.cnf b/server/test/maxscale_test.cnf similarity index 90% rename from server/test/MaxScale_test.cnf rename to server/test/maxscale_test.cnf index 06b783ca5..83f52b23c 100644 --- a/server/test/MaxScale_test.cnf +++ b/server/test/maxscale_test.cnf @@ -1,5 +1,10 @@ [maxscale] threads=4 +libdir=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_LIBDIR@ +logdir=@CMAKE_INSTALL_PREFIX@/log +datadir=@CMAKE_INSTALL_PREFIX@/data +cachedir=@CMAKE_INSTALL_PREFIX@/cache +language=@CMAKE_INSTALL_PREFIX@/lib/maxscale/ [feedback] feedback_enable=true