in src/s3fs.cpp [3742:3870]
static int s3fs_check_service()
{
S3FS_PRN_INFO("check services.");
// At first time for access OSS, we check IAM role if it sets.
if(!ps3fscred->CheckIAMCredentialUpdate()){
S3FS_PRN_CRIT("Failed to initialize IAM credential.");
return EXIT_FAILURE;
}
S3fsCurl s3fscurl;
int res;
if(0 > (res = s3fscurl.CheckBucket(get_realpath("/").c_str()))){
// get response code
long responseCode = s3fscurl.GetLastResponseCode();
// check wrong endpoint, and automatically switch endpoint
if(300 <= responseCode && responseCode < 500){
// check region error(for putting message or retrying)
const std::string* body = s3fscurl.GetBodyData();
/*
std::string expectregion;
std::string expectendpoint;
if(check_region_error(body->c_str(), body->size(), expectregion)){
// [NOTE]
// If endpoint is not specified(using us-east-1 region) and
// an error is encountered accessing a different region, we
// will retry the check on the expected region.
// see) https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro
//
if(is_specified_endpoint){
const char* tmp_expect_ep = expectregion.c_str();
S3FS_PRN_CRIT("The bucket region is not '%s', it is correctly '%s'. You should specify 'endpoint=%s' option.", endpoint.c_str(), tmp_expect_ep, tmp_expect_ep);
}else{
// current endpoint is wrong, so try to connect to expected region.
S3FS_PRN_CRIT("Failed to connect region '%s'(default), so retry to connect region '%s'.", endpoint.c_str(), expectregion.c_str());
endpoint = expectregion;
if(S3fsCurl::GetSignatureType() == V4_ONLY ||
S3fsCurl::GetSignatureType() == V1_OR_V4){
if(s3host == "http://s3.amazonaws.com"){
s3host = "http://s3-" + endpoint + ".amazonaws.com";
}else if(s3host == "https://s3.amazonaws.com"){
s3host = "https://s3-" + endpoint + ".amazonaws.com";
}
}
// retry to check with new endpoint
s3fscurl.DestroyCurlHandle();
res = s3fscurl.CheckBucket();
responseCode = s3fscurl.GetLastResponseCode();
}
}else
*/
std::string expecthost;
if(check_endpoint_error(body->c_str(), body->size(), expecthost)){
S3FS_PRN_CRIT("Failed to connect host '%s'(default), so retry to connect host '%s'.", s3host.c_str(), expecthost.c_str());
if(!strncasecmp(s3host.c_str(), "https://", 8)){
s3host = "https://" + expecthost;
} else {
s3host = "http://" + expecthost;
}
// extract region from host for sigv4
// The region of the government cloud/financial cloud may not be derived from the domain name
// https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11186623.0.0.13ad12c1N7PoaV
if(!strncasecmp(expecthost.c_str(), "oss-", 4)){
std::size_t found;
if ((found = expecthost.find_first_of(".")) != std::string::npos) {
endpoint = expecthost.substr(4, found - 4);
}
S3FS_PRN_CRIT("Extract region '%s' from expecthost.", endpoint.c_str());
}
// retry to check with new host
s3fscurl.DestroyCurlHandle();
res = s3fscurl.CheckBucket(get_realpath("/").c_str());
responseCode = s3fscurl.GetLastResponseCode();
}
}
// try signature v2
/*
if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::GetSignatureType() == V1_OR_V4){
// switch sigv2
S3FS_PRN_CRIT("Failed to connect by sigv4, so retry to connect by signature version 2.");
S3fsCurl::SetSignatureType(V1_ONLY);
// retry to check with sigv2
s3fscurl.DestroyCurlHandle();
res = s3fscurl.CheckBucket();
responseCode = s3fscurl.GetLastResponseCode();
}
*/
// check errors(after retrying)
// [NOTE]
// When mounting a bucket, an error code is returned and the mount fails.
// However, when mounting a prefix, success should be returned if the prefix does not exist.
//
if(0 > res && responseCode != 200 && responseCode != 301){
// parse error message if existed
std::string errMessage;
const std::string* body = s3fscurl.GetBodyData();
check_error_message(body->c_str(), body->size(), errMessage);
bool is_failure = true;
if(responseCode == 400){
S3FS_PRN_CRIT("Failed to check bucket and directory for mount point : Bad Request(host=%s, message=%s)", s3host.c_str(), errMessage.c_str());
}else if(responseCode == 403){
S3FS_PRN_CRIT("Failed to check bucket and directory for mount point : Invalid Credentials(host=%s, message=%s)", s3host.c_str(), errMessage.c_str());
}else if (responseCode == 404) {
std::string value;
if(simple_parse_xml(body->c_str(), body->size(), "Code", value)) {
if(value == "NoSuchBucket") {
S3FS_PRN_CRIT("Failed to check bucket : Bucket not found(host=%s, message=%s)", s3host.c_str(), errMessage.c_str());
} else {
is_failure = false;
}
}
}else{
S3FS_PRN_CRIT("Failed to check bucket and directory for mount point : Unable to connect(host=%s, message=%s)", s3host.c_str(), errMessage.c_str());
}
if (is_failure) {
return EXIT_FAILURE;
}
}
}
S3FS_MALLOCTRIM(0);
return EXIT_SUCCESS;
}