Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion be/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,14 @@ endif()
# NOTE(amos): This should come before -lc -lm to interpose symbols correctly.
if (GLIBC_COMPATIBILITY)
add_subdirectory(${SRC_DIR}/glibc-compatibility)
set(DORIS_LINK_LIBS ${DORIS_LINK_LIBS} glibc-compatibility-explicit glibc-compatibility)
# Keep lance_c here instead of COMMON_THIRDPARTY: placing its required libm there
# would resolve -lm symbol before Doris compatibility is scanned, preventing
# the linker from selecting Doris' optimized implementations.
set(DORIS_LINK_LIBS ${DORIS_LINK_LIBS}
glibc-compatibility-explicit
glibc-compatibility
-lm
lance_c)
endif()

if (NOT OS_MACOSX)
Expand Down
6 changes: 4 additions & 2 deletions be/cmake/thirdparty.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,12 @@ add_thirdparty(arrow_flight_sql LIB64)
add_thirdparty(arrow_dataset LIB64)
add_thirdparty(arrow_acero LIB64)
add_thirdparty(parquet LIB64)
add_thirdparty(lance_c LIB64 NOTADD)
# liblance_c.a contains compiler_builtins cbrt symbols. Place libm before it
# so the final linker resolves C math symbols from the system library first.
add_thirdparty(lance_c LIB64 NOTADD)
list(APPEND COMMON_THIRDPARTY m lance_c)
if (NOT GLIBC_COMPATIBILITY)
list(APPEND COMMON_THIRDPARTY m lance_c)
endif()
add_thirdparty(brpc LIB64)
add_thirdparty(rocksdb)
add_thirdparty(cyrus-sasl LIBNAME "lib/libsasl2.a")
Expand Down
20 changes: 18 additions & 2 deletions be/src/glibc-compatibility/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ if (GLIBC_COMPATIBILITY)
list(APPEND glibc_compatibility_sources musl/getentropy.c)
endif()

set(lance_compatibility_sources
musl/execvpe.c
musl/posix_spawn_file_actions.c
musl/posix_spawnp.c
musl/preadv.c
musl/splice.c
)
list(REMOVE_ITEM glibc_compatibility_sources ${lance_compatibility_sources})

# Need to omit frame pointers to match the performance of glibc
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")

Expand All @@ -65,9 +74,16 @@ if (GLIBC_COMPATIBILITY)
# before ASAN shadow memory is initialized, causing SIGSEGV. Skip custom memcpy in
# this case and fall back to glibc's memcpy.
if (ARCH_ARM AND (CMAKE_BUILD_TYPE STREQUAL "ASAN_UT" OR CMAKE_BUILD_TYPE STREQUAL "ASAN"))
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c)
add_library(glibc-compatibility-explicit OBJECT
musl/getrandom.c
${lance_compatibility_sources}
)
else()
add_library(glibc-compatibility-explicit OBJECT musl/getrandom.c ${MEMCPY_SOURCE})
add_library(glibc-compatibility-explicit OBJECT
musl/getrandom.c
${MEMCPY_SOURCE}
${lance_compatibility_sources}
)
endif()
target_compile_options(glibc-compatibility-explicit PRIVATE -fPIC)
add_library(glibc-compatibility STATIC ${glibc_compatibility_sources})
Expand Down
55 changes: 55 additions & 0 deletions be/src/glibc-compatibility/musl/execvpe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static char* strchrnul_compat(const char* str, int ch) {
const char* found = strchr(str, ch);
return (char*)(found ? found : str + strlen(str));
}

int __execvpe(const char* file, char* const argv[], char* const envp[]) {
const char* path = getenv("PATH");
int seen_eacces = 0;

errno = ENOENT;
if (!*file) return -1;
if (strchr(file, '/')) return execve(file, argv, envp);
if (!path) path = "/usr/local/bin:/bin:/usr/bin";

size_t file_len = strnlen(file, NAME_MAX + 1);
if (file_len > NAME_MAX) {
errno = ENAMETOOLONG;
return -1;
}
size_t path_len = strnlen(path, PATH_MAX - 1) + 1;

const char* cursor;
const char* end;
for (cursor = path;; cursor = end) {
char candidate[path_len + file_len + 1];
Comment thread
linrrzqqq marked this conversation as resolved.
end = strchrnul_compat(cursor, ':');
if (end - cursor >= path_len) {
if (!*end++) break;
continue;
}
memcpy(candidate, cursor, end - cursor);
candidate[end - cursor] = '/';
memcpy(candidate + (end - cursor) + (end > cursor), file, file_len + 1);
execve(candidate, argv, envp);
switch (errno) {
case EACCES:
seen_eacces = 1;
// Fall through.
case ENOENT:
case ENOTDIR:
break;
default:
return -1;
}
if (!*end++) break;
}
if (seen_eacces) errno = EACCES;
return -1;
}
20 changes: 20 additions & 0 deletions be/src/glibc-compatibility/musl/fdop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <sys/types.h>

#define FDOP_CLOSE 1
#define FDOP_DUP2 2
#define FDOP_OPEN 3
#define FDOP_CHDIR 4
#define FDOP_FCHDIR 5

struct fdop {
struct fdop* next;
struct fdop* prev;
int cmd;
int fd;
int srcfd;
int oflag;
mode_t mode;
char path[];
};
95 changes: 95 additions & 0 deletions be/src/glibc-compatibility/musl/posix_spawn_file_actions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#define _GNU_SOURCE
#include <errno.h>
#include <spawn.h>
#include <stdlib.h>
#include <string.h>

#include "fdop.h"

static struct fdop* first_action(const posix_spawn_file_actions_t* file_actions) {
return (struct fdop*)file_actions->__actions;
}

static void prepend_action(posix_spawn_file_actions_t* file_actions, struct fdop* action) {
action->next = first_action(file_actions);
if (action->next) action->next->prev = action;
action->prev = NULL;
file_actions->__actions = (struct __spawn_action*)action;
}

int posix_spawn_file_actions_init(posix_spawn_file_actions_t* file_actions) {
file_actions->__allocated = 0;
file_actions->__used = 0;
file_actions->__actions = NULL;
return 0;
}

int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t* restrict file_actions,
const char* restrict path) {
struct fdop* action = malloc(sizeof(*action) + strlen(path) + 1);
if (!action) return ENOMEM;
action->cmd = FDOP_CHDIR;
action->fd = -1;
strcpy(action->path, path);
prepend_action(file_actions, action);
return 0;
}

int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* file_actions, int fd) {
if (fd < 0) return EBADF;
struct fdop* action = malloc(sizeof(*action));
if (!action) return ENOMEM;
action->cmd = FDOP_CLOSE;
action->fd = fd;
prepend_action(file_actions, action);
return 0;
}

int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* file_actions, int source_fd,
int target_fd) {
if (source_fd < 0 || target_fd < 0) return EBADF;
struct fdop* action = malloc(sizeof(*action));
if (!action) return ENOMEM;
action->cmd = FDOP_DUP2;
action->srcfd = source_fd;
action->fd = target_fd;
prepend_action(file_actions, action);
return 0;
}

int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t* file_actions, int fd) {
if (fd < 0) return EBADF;
struct fdop* action = malloc(sizeof(*action));
if (!action) return ENOMEM;
action->cmd = FDOP_FCHDIR;
action->fd = fd;
prepend_action(file_actions, action);
return 0;
}

int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* restrict file_actions, int fd,
const char* restrict path, int flags, mode_t mode) {
if (fd < 0) return EBADF;
struct fdop* action = malloc(sizeof(*action) + strlen(path) + 1);
if (!action) return ENOMEM;
action->cmd = FDOP_OPEN;
action->fd = fd;
action->oflag = flags;
action->mode = mode;
strcpy(action->path, path);
prepend_action(file_actions, action);
return 0;
}

int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* file_actions) {
struct fdop* action = first_action(file_actions);
while (action) {
struct fdop* next = action->next;
free(action);
action = next;
}
file_actions->__allocated = 0;
file_actions->__used = 0;
file_actions->__actions = NULL;
return 0;
}
16 changes: 16 additions & 0 deletions be/src/glibc-compatibility/musl/posix_spawnp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <spawn.h>

int __execvpe(const char* file, char* const argv[], char* const envp[]);

int __posix_spawnx(pid_t* restrict result, const char* restrict path,
int (*exec)(const char*, char* const*, char* const*),
const posix_spawn_file_actions_t* file_actions,
const posix_spawnattr_t* restrict attr, char* const argv[restrict],
char* const envp[restrict]);

int posix_spawnp(pid_t* restrict result, const char* restrict file,
const posix_spawn_file_actions_t* file_actions,
const posix_spawnattr_t* restrict attr, char* const argv[restrict],
char* const envp[restrict]) {
return __posix_spawnx(result, file, __execvpe, file_actions, attr, argv, envp);
Comment thread
linrrzqqq marked this conversation as resolved.
}
9 changes: 9 additions & 0 deletions be/src/glibc-compatibility/musl/preadv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#define _DEFAULT_SOURCE
#include <sys/uio.h>
#include <unistd.h>

#include "syscall.h"

ssize_t preadv(int fd, const struct iovec* iov, int count, off_t offset) {
return syscall(SYS_preadv, fd, iov, count, (long)(offset), (long)(offset >> 32));
}
10 changes: 10 additions & 0 deletions be/src/glibc-compatibility/musl/splice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>

#include "syscall.h"

ssize_t splice(int fd_in, off_t* off_in, int fd_out, off_t* off_out, size_t len,
unsigned int flags) {
return syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, flags);
}
Loading