-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rgw: setup locks for libopenssl #20390
Changes from all commits
4e30277
55dde3d
112ba0b
08c4c05
4667937
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#include "rgw_http_client_curl.h" | ||
#include <mutex> | ||
#include <vector> | ||
#include <curl/curl.h> | ||
|
||
#include "rgw_common.h" | ||
#define dout_context g_ceph_context | ||
#define dout_subsys ceph_subsys_rgw | ||
|
||
#ifdef WITH_CURL_OPENSSL | ||
#include <openssl/crypto.h> | ||
#endif | ||
|
||
#if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L | ||
namespace openssl { | ||
|
||
class RGWSSLSetup | ||
{ | ||
std::vector <std::mutex> locks; | ||
public: | ||
RGWSSLSetup(int n) : locks (n){} | ||
|
||
void set_lock(int id){ | ||
try { | ||
locks.at(id).lock(); | ||
} catch (std::out_of_range& e) { | ||
dout(0) << __func__ << "failed to set locks" << dendl; | ||
} | ||
} | ||
|
||
void clear_lock(int id){ | ||
try { | ||
locks.at(id).unlock(); | ||
} catch (std::out_of_range& e) { | ||
dout(0) << __func__ << "failed to unlock" << dendl; | ||
} | ||
} | ||
}; | ||
|
||
|
||
void rgw_ssl_locking_callback(int mode, int id, const char *file, int line) | ||
{ | ||
static RGWSSLSetup locks(CRYPTO_num_locks()); | ||
if (mode & CRYPTO_LOCK) | ||
locks.set_lock(id); | ||
else | ||
locks.clear_lock(id); | ||
} | ||
|
||
unsigned long rgw_ssl_thread_id_callback(){ | ||
return (unsigned long)pthread_self(); | ||
} | ||
|
||
void init_ssl(){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment here as above-- it may be slightly more clear moving the ifdefs inside of the function body, but it's your call. |
||
CRYPTO_set_id_callback((unsigned long (*) ()) rgw_ssl_thread_id_callback); | ||
CRYPTO_set_locking_callback(rgw_ssl_locking_callback); | ||
} | ||
|
||
} /* namespace openssl */ | ||
#endif // WITH_CURL_OPENSSL | ||
|
||
|
||
namespace rgw { | ||
namespace curl { | ||
|
||
static void check_curl() | ||
{ | ||
#ifndef HAVE_CURL_MULTI_WAIT | ||
derr << "WARNING: libcurl doesn't support curl_multi_wait()" << dendl; | ||
derr << "WARNING: cross zone / region transfer performance may be affected" << dendl; | ||
#endif | ||
} | ||
|
||
#if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L | ||
void init_ssl() { | ||
::openssl::init_ssl(); | ||
} | ||
|
||
bool fe_inits_ssl(boost::optional <const fe_map_t&> m, long& curl_global_flags){ | ||
if (m) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not necessary, but notice that if you turned this into a guard: ...then the whole function doesn't need to be in an if-block. Up to you! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we also have to return false when we later find out that ssl_certificate is not set. |
||
for (const auto& kv: *m){ | ||
if (kv.first == "civetweb" || kv.first == "beast"){ | ||
std::string cert; | ||
kv.second->get_val("ssl_certificate","", &cert); | ||
if (!cert.empty()){ | ||
/* TODO this flag is no op for curl > 7.57 */ | ||
curl_global_flags &= ~CURL_GLOBAL_SSL; | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
#endif // WITH_CURL_OPENSSL | ||
|
||
std::once_flag curl_init_flag; | ||
|
||
void setup_curl(boost::optional<const fe_map_t&> m) { | ||
check_curl(); | ||
|
||
long curl_global_flags = CURL_GLOBAL_ALL; | ||
|
||
#if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L | ||
if (!fe_inits_ssl(m, curl_global_flags)) | ||
init_ssl(); | ||
#endif | ||
|
||
std::call_once(curl_init_flag, curl_global_init, curl_global_flags); | ||
rgw_setup_saved_curl_handles(); | ||
} | ||
|
||
void cleanup_curl() { | ||
rgw_release_all_curl_handles(); | ||
curl_global_cleanup(); | ||
} | ||
|
||
} /* namespace curl */ | ||
} /* namespace rgw */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
/* | ||
* Ceph - scalable distributed file system | ||
* | ||
* Copyright (C) 2018 SUSE Linux GmBH | ||
* | ||
* This is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License version 2.1, as published by the Free Software | ||
* Foundation. See file COPYING. | ||
* | ||
*/ | ||
#ifndef RGW_HTTP_CLIENT_CURL_H | ||
#define RGW_HTTP_CLIENT_CURL_H | ||
|
||
#include <map> | ||
#include <boost/optional.hpp> | ||
#include "rgw_frontend.h" | ||
|
||
namespace rgw { | ||
namespace curl { | ||
using fe_map_t = std::multimap <std::string, RGWFrontendConfig *>; | ||
|
||
void setup_curl(boost::optional<const fe_map_t&> m); | ||
void cleanup_curl(); | ||
} | ||
} | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Insert my usual nit against C style casts here. ;-)