Add support for non-glibc systems

MaxScale can now be built on systems that use an alternative libc
implementation e.g. musl.
This commit is contained in:
Markus Mäkelä
2017-07-28 14:14:47 +03:00
parent 782b8db2aa
commit 854c4a1ed3
17 changed files with 104 additions and 77 deletions

View File

@ -39,19 +39,12 @@
#include <pwd.h>
#include <maxscale/version.h>
#include <maxscale/maxadmin.h>
#ifdef HISTORY
#include <histedit.h>
#endif
#include <maxscale/maxadmin.h>
/*
* We need a common.h file that is included by every component.
*/
#if !defined(STRERROR_BUFLEN)
#define STRERROR_BUFLEN 512
#endif
#define MAX_PASSWORD_LEN 80
static int connectUsingUnixSocket(const char *socket);
@ -441,27 +434,22 @@ connectUsingUnixSocket(const char *socket_path)
}
else
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Could not set SO_PASSCRED: %s\n",
strerror_r(errno, errbuf, sizeof(errbuf)));
fprintf(stderr, "Could not set SO_PASSCRED: %s\n", strerror(errno));
close(so);
so = -1;
}
}
else
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Unable to connect to MaxScale at %s: %s\n",
socket_path, strerror_r(errno, errbuf, sizeof(errbuf)));
socket_path, strerror(errno));
close(so);
so = -1;
}
}
else
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Unable to create socket: %s\n",
strerror_r(errno, errbuf, sizeof(errbuf)));
fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
}
return so;
@ -505,18 +493,15 @@ connectUsingInetSocket(const char *hostname, const char *port,
}
else
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Unable to connect to MaxScale at %s, %s: %s\n",
hostname, port, strerror_r(errno, errbuf, sizeof(errbuf)));
hostname, port, strerror(errno));
close(so);
so = -1;
}
}
else
{
char errbuf[STRERROR_BUFLEN];
fprintf(stderr, "Unable to create socket: %s\n",
strerror_r(errno, errbuf, sizeof(errbuf)));
fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
}
return so;
@ -532,7 +517,7 @@ connectUsingInetSocket(const char *hostname, const char *port,
static int
setipaddress(struct in_addr *a, const char *p)
{
#ifdef __USE_POSIX
struct addrinfo *ai = NULL, hint;
int rc;
struct sockaddr_in * res_addr;
@ -557,28 +542,6 @@ setipaddress(struct in_addr *a, const char *p)
return 1;
}
#else
struct hostent *h;
spinlock_acquire(&tmplock);
h = gethostbyname(p);
spinlock_release(&tmplock);
if (h == NULL)
{
if ((a->s_addr = inet_addr(p)) == -1)
{
return 0;
}
}
else
{
/* take the first one */
memcpy(a, h->h_addr, h->h_length);
return 1;
}
#endif
return 0;
}

View File

@ -3,6 +3,7 @@
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckIncludeFiles)
include(CheckCXXSourceCompiles)
check_include_files(arpa/inet.h HAVE_ARPA_INET)
check_include_files(crypt.h HAVE_CRYPT)
@ -69,11 +70,6 @@ if(NOT HAVE_LIBM)
message(FATAL_ERROR "Could not find libm")
endif()
find_library(HAVE_LIBDL NAMES dl)
if(NOT HAVE_LIBDL)
message(FATAL_ERROR "Could not find libdl")
endif()
find_library(HAVE_LIBRT NAMES rt)
if(NOT HAVE_LIBRT)
message(FATAL_ERROR "Could not find librt")
@ -83,3 +79,17 @@ find_library(HAVE_LIBPTHREAD NAMES pthread)
if(NOT HAVE_LIBPTHREAD)
message(FATAL_ERROR "Could not find libpthread")
endif()
# The XSI version of strerror_r return an int and the GNU version a char*
check_cxx_source_compiles("
#define _GNU_SOURCE 1
#include <string.h>\n
int main(){\n
char errbuf[200];\n
return strerror_r(13, errbuf, sizeof(errbuf)) == errbuf;\n
}\n"
HAVE_GLIBC)
if(HAVE_GLIBC)
add_definitions(-DHAVE_GLIBC=1)
endif()

View File

@ -33,7 +33,8 @@ MXS_BEGIN_DECLS
#define DEFAULT_ADMIN_HTTP_PORT 8989
#define DEFAULT_ADMIN_HOST "::"
#define _RELEASE_STR_LENGTH 256 /**< release len */
#define RELEASE_STR_LENGTH 256
#define SYSNAME_LEN 256
#define MAX_ADMIN_USER_LEN 1024
#define MAX_ADMIN_PW_LEN 1024
#define MAX_ADMIN_HOST_LEN 1024
@ -189,8 +190,8 @@ typedef struct
bool config_check; /**< Only check config */
int n_threads; /**< Number of polling threads */
char *version_string; /**< The version string of embedded db library */
char release_string[_RELEASE_STR_LENGTH]; /**< The release name string of the system */
char sysname[_UTSNAME_SYSNAME_LENGTH]; /**< The OS name of the system */
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
uint8_t mac_sha1[SHA_DIGEST_LENGTH]; /**< The SHA1 digest of an interface MAC address */
unsigned long id; /**< MaxScale ID */
unsigned int n_nbpoll; /**< Tune number of non-blocking polls */

View File

@ -21,6 +21,7 @@
#include <math.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/un.h>
MXS_BEGIN_DECLS

View File

@ -11506,7 +11506,7 @@ else
fi
if test "${enable_maxscale}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DMAXSCALE -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_OMIT_ATTACH -DSQLITE_OMIT_REINDEX -DSQLITE_OMIT_AUTOVACUUM -DSQLITE_OMIT_PRAGMA"
OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS -DMAXSCALE -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_OMIT_ATTACH -DSQLITE_OMIT_REINDEX -DSQLITE_OMIT_AUTOVACUUM -DSQLITE_OMIT_PRAGMA"
fi
#########

View File

@ -69,7 +69,6 @@ target_link_libraries(maxscale-common
ssl
pthread
crypt
dl
crypto
inih
z
@ -81,6 +80,13 @@ target_link_libraries(maxscale-common
${MICROHTTPD_LIBRARIES}
)
find_library(HAVE_LIBDL NAMES dl)
if (HAVE_LIBDL)
# libdl just exposes libc functionality on most systems. This means that if
# we can't find it, it's likely that libc already exposes the symbols.
target_link_libraries(maxscale-common dl)
endif()
add_dependencies(maxscale-common pcre2 connector-c)
set_target_properties(maxscale-common PROPERTIES VERSION "1.0.0")
install_module(maxscale-common core)

View File

@ -513,6 +513,24 @@ bool admin_linux_account_enabled(const char *uname)
return rv;
}
#define MXS_CRYPT_SIZE 60
void mxs_crypt(const char* password, const char* salt, char* output)
{
#if HAVE_GLIBC
thread_local struct crypt_data cdata;
cdata.initialized = 0;
char* pw = crypt_r(password, salt, &cdata);
snprintf(output, MXS_CRYPT_SIZE, "%s", pw);
#else
static SPINLOCK mxs_crypt_lock = SPINLOCK_INIT;
spinlock_acquire(&mxs_crypt_lock);
char* pw = crypt(password, salt);
snprintf(output, MXS_CRYPT_SIZE, "%s", pw);
spinlock_release(&mxs_crypt_lock);
#endif
}
/**
* Add insecure remote (network) user.
*
@ -523,9 +541,8 @@ bool admin_linux_account_enabled(const char *uname)
*/
const char *admin_add_inet_user(const char *uname, const char* password)
{
struct crypt_data cdata;
cdata.initialized = 0;
char *cpassword = crypt_r(password, ADMIN_SALT, &cdata);
char cpassword[MXS_CRYPT_SIZE];
mxs_crypt(password, ADMIN_SALT, cpassword);
return admin_add_user(&inet_users, INET_USERS_FILE_NAME, uname, cpassword);
}
@ -581,9 +598,10 @@ admin_verify_inet_user(const char *username, const char *password)
if (pw)
{
struct crypt_data cdata;
cdata.initialized = 0;
if (strcmp(pw, crypt_r(password, ADMIN_SALT, &cdata)) == 0)
char cpassword[MXS_CRYPT_SIZE];
mxs_crypt(password, ADMIN_SALT, cpassword);
if (strcmp(pw, cpassword) == 0)
{
rv = true;
}

View File

@ -2251,7 +2251,7 @@ config_get_release_string(char* release)
};
bool have_distribution;
char distribution[_RELEASE_STR_LENGTH] = "";
char distribution[RELEASE_STR_LENGTH] = "";
int fd;
have_distribution = false;
@ -2328,7 +2328,7 @@ config_get_release_string(char* release)
+5 and -8 below cut the file name part out of the
full pathname that corresponds to the mask as above.
*/
new_to = strncpy(distribution, found.gl_pathv[0] + 5, _RELEASE_STR_LENGTH - 1);
new_to = strncpy(distribution, found.gl_pathv[0] + 5, RELEASE_STR_LENGTH - 1);
new_to += 8;
*new_to++ = ':';
*new_to++ = ' ';
@ -2348,7 +2348,7 @@ config_get_release_string(char* release)
}
have_distribution = true;
strncpy(release, new_to, _RELEASE_STR_LENGTH);
strncpy(release, new_to, RELEASE_STR_LENGTH);
}
}
}

View File

@ -17,7 +17,9 @@
#include <maxscale/cdefs.h>
#ifdef HAVE_GLIBC
#include <execinfo.h>
#endif
#include <ftw.h>
#include <getopt.h>
#include <stdlib.h>
@ -100,6 +102,9 @@ static bool daemon_mode = true;
static const char* maxscale_commit = MAXSCALE_COMMIT;
const char *progname = NULL;
#ifdef HAVE_GLIBC
// getopt_long is a GNU extension
static struct option long_options[] =
{
{"config-check", no_argument, 0, 'c'},
@ -128,6 +133,7 @@ static struct option long_options[] =
{"debug", required_argument, 0, 'g'},
{0, 0, 0, 0}
};
#endif
static bool syslog_configured = false;
static bool maxlog_configured = false;
@ -419,6 +425,7 @@ sigfatal_handler(int i)
"Release string: %s",
maxscale_commit, cnf->sysname, cnf->release_string);
#ifdef HAVE_GLIBC
{
void *addrs[128];
int count = backtrace(addrs, 128);
@ -438,6 +445,7 @@ sigfatal_handler(int i)
backtrace_symbols_fd(addrs, count, fileno(stderr));
}
}
#endif
mxs_log_flush_sync();
@ -1338,8 +1346,12 @@ int main(int argc, char **argv)
}
}
#ifdef HAVE_GLIBC
while ((opt = getopt_long(argc, argv, "dcf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:",
long_options, &option_index)) != -1)
#else
while ((opt = getopt(argc, argv, "dcf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:")) != -1)
#endif
{
bool succp = true;

View File

@ -23,6 +23,7 @@
#include <stdarg.h>
#include <errno.h>
#include <syslog.h>
#include <sched.h>
#include <maxscale/atomic.h>
#include <maxscale/config.h>
@ -705,7 +706,7 @@ void mxs_log_finish(void)
while (lm != NULL && lm->lm_nlinks != 0)
{
release_lock(&lmlock);
pthread_yield();
sched_yield();
acquire_lock(&lmlock);
}
@ -1354,7 +1355,7 @@ static bool logmanager_register(bool writep)
while (lm != NULL && !lm->lm_enabled)
{
release_lock(&lmlock);
pthread_yield();
sched_yield();
acquire_lock(&lmlock);
}
@ -3013,8 +3014,12 @@ int mxs_log_message(int priority,
const char* mxs_strerror(int error)
{
static thread_local char errbuf[MXS_STRERROR_BUFLEN];
#ifdef HAVE_GLIBC
return strerror_r(error, errbuf, sizeof(errbuf));
#else
strerror_r(error, errbuf, sizeof(errbuf));
return errbuf;
#endif
}
json_t* get_log_priorities()

View File

@ -31,6 +31,7 @@
#include <maxscale/paths.h>
#include <maxscale/random_jkiss.h>
#ifdef HAVE_GLIBC
struct option options[] =
{
{
@ -41,6 +42,7 @@ struct option options[] =
},
{ NULL, 0, NULL, 0 }
};
#endif
void print_usage(const char* executable, const char* directory)
{
@ -67,7 +69,11 @@ int main(int argc, char **argv)
const char* directory = get_datadir();
int c;
#ifdef HAVE_GLIBC
while ((c = getopt_long(argc, argv, "h", options, NULL)) != -1)
#else
while ((c = getopt(argc, argv, "h")) != -1)
#endif
{
switch (c)
{

View File

@ -35,6 +35,7 @@
#include "maxscale/secrets.h"
#ifdef HAVE_GLIBC
struct option options[] =
{
{
@ -45,6 +46,7 @@ struct option options[] =
},
{ NULL, 0, NULL, 0 }
};
#endif
void print_usage(const char* executable, const char* directory)
{
@ -107,7 +109,11 @@ int main(int argc, char **argv)
const char* path = get_datadir();
int c;
#ifdef HAVE_GLIBC
while ((c = getopt_long(argc, argv, "h", options, NULL)) != -1)
#else
while ((c = getopt(argc, argv, "h")) != -1)
#endif
{
switch (c)
{

View File

@ -12,7 +12,6 @@
*/
#include "maxscale/messagequeue.hh"
#include <linux/version.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>

View File

@ -18,6 +18,7 @@
#include <fstream>
#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
#include <maxscale/log_manager.h>
#include <maxscale/random_jkiss.h>
@ -79,7 +80,7 @@ void log_messages(uint32_t id, size_t n_generate, int priority)
{
MXS_LOG_MESSAGE(priority, "[%u] Message %lu.", id, i);
pthread_yield();
sched_yield();
}
}

View File

@ -37,7 +37,6 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <netinet/tcp.h>
#include <openssl/sha.h>
@ -989,7 +988,6 @@ static void set_port(struct sockaddr_storage *addr, uint16_t port)
int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr, const char *host, uint16_t port)
{
ss_dassert(type == MXS_SOCKET_NETWORK || type == MXS_SOCKET_LISTENER);
#ifdef __USE_POSIX
struct addrinfo *ai = NULL, hint = {};
int so, rc;
hint.ai_socktype = SOCK_STREAM;
@ -1032,10 +1030,6 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
freeaddrinfo(ai);
}
#else
#error Only the POSIX networking interface is supported
#endif
return so;
}

View File

@ -2020,9 +2020,9 @@ bool blr_send_event(blr_thread_role_t role,
slave->serverid,
binlog_name,
binlog_pos,
thread_self(),
(uint64_t)thread_self(),
ROLETOSTR(role),
slave->lsi_sender_tid,
(uint64_t)slave->lsi_sender_tid,
ROLETOSTR(slave->lsi_sender_role),
gwbuf_length(slave->dcb->writeq), slave->dcb,
slave->router->stats.n_binlogs);

View File

@ -56,6 +56,7 @@ static void printVersion(const char *progname);
static void printUsage(const char *progname);
static int set_encryption_options(ROUTER_INSTANCE *inst, char *key_file, char *aes_algo);
#ifdef HAVE_GLIBC
static struct option long_options[] =
{
{"debug", no_argument, 0, 'd'},
@ -70,7 +71,7 @@ static struct option long_options[] =
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
#endif
char *binlog_check_version = "2.2.1";
int
@ -90,7 +91,11 @@ int main(int argc, char **argv)
char c;
BINLOG_FILE_FIX binlog_file = {0, false, false};
#ifdef HAVE_GLIBC
while ((c = getopt_long(argc, argv, "dVfMHK:A:R:T:?", long_options, &option_index)) >= 0)
#else
while ((c = getopt(argc, argv, "dVfMHK:A:R:T:?")) >= 0)
#endif
{
switch (c)
{