From 4ba0c2fee8aeeb85986fcfb6c983c8beb3763bdc Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Fri, 11 Oct 2019 18:38:52 +0300 Subject: [PATCH] common,msg,kv: Use Windows or portable function alternatives Some functions are unavailable on Windows. We'll add some platform checks, using either portable functions, either the Windows specific ones: * utimes -> utime * strerror_r -> strerror_s * poll -> WSAPoll * sendmsg -> WSASend * switch to portable time format specifiers * fcntl -> ioctlsocket, when setting up non-blocking sockets * /dev/urandom -> BCryptGenRandom * sysconf(_SC_PAGESIZE) -> GetSystemInfo() * define compat_mkdir, handling the fact that mkdir doesn't accept the mode argument on Windows Signed-off-by: Lucian Petrut --- src/CMakeLists.txt | 2 +- src/auth/Crypto.cc | 20 +++++++++++++++- src/common/HeartbeatMap.cc | 3 ++- src/common/compat.cc | 5 +++- src/common/page.cc | 14 +++++++++++ src/include/compat.h | 6 +++++ src/include/utime.h | 4 ++-- src/kv/MemDB.cc | 2 +- src/kv/RocksDBStore.cc | 2 +- src/msg/async/PosixStack.cc | 45 ++++++++++++++++++++++++++++++++++++ src/msg/async/net_handler.cc | 9 ++++++++ 11 files changed, 104 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dfce966222f73..c3f7e4016f444 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -434,7 +434,7 @@ if(WITH_DPDK) endif() if(WIN32) - list(APPEND ceph_common_deps ws2_32 mswsock) + list(APPEND ceph_common_deps ws2_32 mswsock bcrypt) list(APPEND ceph_common_deps dlfcn_win32) endif() diff --git a/src/auth/Crypto.cc b/src/auth/Crypto.cc index 1827b5a7de857..2dda80e2b04b5 100644 --- a/src/auth/Crypto.cc +++ b/src/auth/Crypto.cc @@ -84,8 +84,26 @@ void CryptoRandom::get_bytes(char *buf, int len) } } -#else // !HAVE_GETENTROPY +#elif defined(_WIN32) // !HAVE_GETENTROPY +#include + +CryptoRandom::CryptoRandom() : fd(0) {} +CryptoRandom::~CryptoRandom() = default; + +void CryptoRandom::get_bytes(char *buf, int len) +{ + auto ret = BCryptGenRandom ( + NULL, + (unsigned char*)buf, + len, + BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (ret != 0) { + throw std::system_error(ret, std::system_category()); + } +} + +#else // !HAVE_GETENTROPY && !_WIN32 // open /dev/urandom once on construction and reuse the fd for all reads CryptoRandom::CryptoRandom() : fd{open_urandom()} diff --git a/src/common/HeartbeatMap.cc b/src/common/HeartbeatMap.cc index 7e5b814063275..aef9677d9fac3 100644 --- a/src/common/HeartbeatMap.cc +++ b/src/common/HeartbeatMap.cc @@ -12,6 +12,7 @@ * */ +#include #include #include "HeartbeatMap.h" @@ -173,7 +174,7 @@ void HeartbeatMap::check_touch_file() if (path.length() && is_healthy()) { int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_CLOEXEC, 0644); if (fd >= 0) { - ::utimes(path.c_str(), NULL); + ::utime(path.c_str(), NULL); ::close(fd); } else { ldout(m_cct, 0) << "unable to touch " << path << ": " diff --git a/src/common/compat.cc b/src/common/compat.cc index 23fe2fa0e9def..a8d57bd7758f5 100644 --- a/src/common/compat.cc +++ b/src/common/compat.cc @@ -201,7 +201,10 @@ int sched_setaffinity(pid_t pid, size_t cpusetsize, char *ceph_strerror_r(int errnum, char *buf, size_t buflen) { -#ifdef STRERROR_R_CHAR_P +#ifdef _WIN32 + strerror_s(buf, buflen, errnum); + return buf; +#elif defined(STRERROR_R_CHAR_P) return strerror_r(errnum, buf, buflen); #else if (strerror_r(errnum, buf, buflen)) { diff --git a/src/common/page.cc b/src/common/page.cc index 7a252a60ba17b..e3dc34a43c136 100644 --- a/src/common/page.cc +++ b/src/common/page.cc @@ -1,5 +1,9 @@ #include +#ifdef _WIN32 +#include +#endif + namespace ceph { // page size crap, see page.h @@ -12,7 +16,17 @@ namespace ceph { return n; } + #ifdef _WIN32 + unsigned _get_page_size() { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; + } + + unsigned _page_size = _get_page_size(); + #else unsigned _page_size = sysconf(_SC_PAGESIZE); + #endif unsigned long _page_mask = ~(unsigned long)(_page_size - 1); unsigned _page_shift = _get_bits_of(_page_size - 1); diff --git a/src/include/compat.h b/src/include/compat.h index 334d60eeace79..8a855c188110c 100644 --- a/src/include/compat.h +++ b/src/include/compat.h @@ -280,6 +280,10 @@ int lchown(const char *path, uid_t owner, gid_t group); #ifdef __cplusplus } + +// Windows' mkdir doesn't accept a mode argument. +#define compat_mkdir(pathname, mode) mkdir(pathname) + #endif // O_CLOEXEC is not defined on Windows. Since handles aren't inherited @@ -287,6 +291,8 @@ int lchown(const char *path, uid_t owner, gid_t group); // flag as a no-op. #define O_CLOEXEC 0 +#define compat_mkdir(pathname, mode) mkdir(pathname, mode) + #endif /* WIN32 */ #endif /* !CEPH_COMPAT_H */ diff --git a/src/include/utime.h b/src/include/utime.h index ab053433e2a03..512149db03e3a 100644 --- a/src/include/utime.h +++ b/src/include/utime.h @@ -485,12 +485,12 @@ public: if (out_date) { char buf[32]; - strftime(buf, sizeof(buf), "%F", &tm); + strftime(buf, sizeof(buf), "%Y-%m-%d", &tm); *out_date = buf; } if (out_time) { char buf[32]; - strftime(buf, sizeof(buf), "%T", &tm); + strftime(buf, sizeof(buf), "%H:%M:%S", &tm); *out_time = buf; } diff --git a/src/kv/MemDB.cc b/src/kv/MemDB.cc index 1f5740a34a592..1618b2551acc6 100644 --- a/src/kv/MemDB.cc +++ b/src/kv/MemDB.cc @@ -147,7 +147,7 @@ int MemDB::_init(bool create) int r; dout(1) << __func__ << dendl; if (create) { - r = ::mkdir(m_db_path.c_str(), 0700); + r = compat_mkdir(m_db_path.c_str(), 0700); if (r < 0) { r = -errno; if (r != -EEXIST) { diff --git a/src/kv/RocksDBStore.cc b/src/kv/RocksDBStore.cc index 030ca7fed8ab9..f4956b649fb08 100644 --- a/src/kv/RocksDBStore.cc +++ b/src/kv/RocksDBStore.cc @@ -319,7 +319,7 @@ int RocksDBStore::create_db_dir() unique_ptr dir; env->NewDirectory(path, &dir); } else { - int r = ::mkdir(path.c_str(), 0755); + int r = compat_mkdir(path.c_str(), 0755); if (r < 0) r = -errno; if (r < 0 && r != -EEXIST) { diff --git a/src/msg/async/PosixStack.cc b/src/msg/async/PosixStack.cc index a7a7fc41dd0f6..be6c617383b97 100644 --- a/src/msg/async/PosixStack.cc +++ b/src/msg/async/PosixStack.cc @@ -72,6 +72,7 @@ class PosixConnectedSocketImpl final : public ConnectedSocketImpl { // return the sent length // < 0 means error occurred + #ifndef _WIN32 static ssize_t do_sendmsg(int fd, struct msghdr &msg, unsigned len, bool more) { size_t sent = 0; @@ -150,6 +151,50 @@ class PosixConnectedSocketImpl final : public ConnectedSocketImpl { return static_cast(sent_bytes); } + #else + ssize_t send(bufferlist &bl, bool more) override + { + size_t total_sent_bytes = 0; + auto pb = std::cbegin(bl.buffers()); + uint64_t left_pbrs = bl.get_num_buffers(); + while (left_pbrs) { + WSABUF msgvec[IOV_MAX]; + uint64_t size = std::min(left_pbrs, IOV_MAX); + left_pbrs -= size; + unsigned msglen = 0; + for (auto iov = msgvec; iov != msgvec + size; iov++) { + iov->buf = const_cast(pb->c_str()); + iov->len = pb->length(); + msglen += pb->length(); + ++pb; + } + DWORD sent_bytes = 0; + DWORD flags = 0; + if (more) + flags |= MSG_PARTIAL; + + int ret_val = WSASend(_fd, msgvec, size, &sent_bytes, flags, NULL, NULL); + if (ret_val) + return -ret_val; + + total_sent_bytes += sent_bytes; + if (static_cast(sent_bytes) < msglen) + break; + } + + if (total_sent_bytes) { + bufferlist swapped; + if (total_sent_bytes < bl.length()) { + bl.splice(total_sent_bytes, bl.length()-total_sent_bytes, &swapped); + bl.swap(swapped); + } else { + bl.clear(); + } + } + + return static_cast(total_sent_bytes); + } + #endif void shutdown() override { ::shutdown(_fd, SHUT_RDWR); } diff --git a/src/msg/async/net_handler.cc b/src/msg/async/net_handler.cc index 2b4e646d559a4..1f99979eec42a 100644 --- a/src/msg/async/net_handler.cc +++ b/src/msg/async/net_handler.cc @@ -67,6 +67,14 @@ int NetHandler::set_nonblock(int sd) int flags; int r = 0; + #ifdef _WIN32 + ULONG mode = 1; + r = ioctlsocket(sd, FIONBIO, &mode); + if (r) { + lderr(cct) << __func__ << " ioctlsocket(FIONBIO) failed: " << r << dendl; + return -r; + } + #else /* Set the socket nonblocking. * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ @@ -80,6 +88,7 @@ int NetHandler::set_nonblock(int sd) lderr(cct) << __func__ << " fcntl(F_SETFL,O_NONBLOCK): " << cpp_strerror(r) << dendl; return -r; } + #endif return 0; } -- 2.39.5