Retry BucketCheck containing directory paths
This commit is contained in:
parent
e4f85c1e08
commit
16bc44948e
10
src/curl.cpp
10
src/curl.cpp
|
@ -3514,10 +3514,13 @@ int S3fsCurl::GetObjectRequest(const char* tpath, int fd, off_t start, off_t siz
|
|||
return result;
|
||||
}
|
||||
|
||||
int S3fsCurl::CheckBucket()
|
||||
int S3fsCurl::CheckBucket(const char* check_path)
|
||||
{
|
||||
S3FS_PRN_INFO3("check a bucket.");
|
||||
|
||||
if(!check_path || 0 == strlen(check_path)){
|
||||
return -EIO;
|
||||
}
|
||||
if(!CreateCurlHandle()){
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -3526,13 +3529,14 @@ int S3fsCurl::CheckBucket()
|
|||
query_string = "list-type=2";
|
||||
urlargs = "?" + query_string;
|
||||
}
|
||||
|
||||
std::string resource;
|
||||
std::string turl;
|
||||
MakeUrlResource("/", resource, turl);
|
||||
MakeUrlResource(check_path, resource, turl);
|
||||
|
||||
turl += urlargs;
|
||||
url = prepare_url(turl.c_str());
|
||||
path = "/"; // Only check the presence of the bucket, not the entire virtual path.
|
||||
path = check_path;
|
||||
requestHeaders = NULL;
|
||||
responseHeaders.clear();
|
||||
bodydata.Clear();
|
||||
|
|
|
@ -352,7 +352,7 @@ class S3fsCurl
|
|||
int PutRequest(const char* tpath, headers_t& meta, int fd);
|
||||
int PreGetObjectRequest(const char* tpath, int fd, off_t start, off_t size, sse_type_t ssetype, const std::string& ssevalue);
|
||||
int GetObjectRequest(const char* tpath, int fd, off_t start = -1, off_t size = -1);
|
||||
int CheckBucket();
|
||||
int CheckBucket(const char* check_path);
|
||||
int ListBucketRequest(const char* tpath, const char* query);
|
||||
int PreMultipartPostRequest(const char* tpath, headers_t& meta, std::string& upload_id, bool is_copy);
|
||||
int CompleteMultipartPostRequest(const char* tpath, const std::string& upload_id, etaglist_t& parts);
|
||||
|
|
61
src/s3fs.cpp
61
src/s3fs.cpp
|
@ -4029,6 +4029,30 @@ static bool check_endpoint_error(const char* pbody, size_t len, std::string& exp
|
|||
return true;
|
||||
}
|
||||
|
||||
// [NOTE]
|
||||
// This checks whether access to the bucket when s3fs is started.
|
||||
//
|
||||
// The following patterns for mount point are supported by s3fs:
|
||||
// (1) Mount the bucket top
|
||||
// (2) Mount the directory(folder) under the bucket. In this case, there are
|
||||
// the following cases:
|
||||
// (2A) Directories created by clients other than s3fs
|
||||
// (2B) Directory created by s3fs
|
||||
//
|
||||
// At first in this functoin, if user has access to the bucket, the checking
|
||||
// access to the bucket succeeds and this function returns success. However,
|
||||
// if user does not have access to the bucket and has permissions to the
|
||||
// directory, this first check will fail.
|
||||
// But if user specifies the directory for mount point, this function retries
|
||||
// to check with the path containing the directory. And it will be success.
|
||||
//
|
||||
// In the case of (2A), the check will succeed if the bucket allows to access,
|
||||
// but will fail if permissions are granted only to the directory, as it is not
|
||||
// a directory recognized by s3fs. This combination is not supported by s3fs,
|
||||
// so make sure user create the directory before starting s3fs.
|
||||
// In case (2B), if user does not have access to bucket, the first check(to
|
||||
// bucket) fails, but the retry check(with path) succeeds.
|
||||
//
|
||||
static int s3fs_check_service()
|
||||
{
|
||||
S3FS_PRN_INFO("check services.");
|
||||
|
@ -4041,9 +4065,10 @@ static int s3fs_check_service()
|
|||
|
||||
S3fsCurl s3fscurl;
|
||||
int res;
|
||||
if(0 > (res = s3fscurl.CheckBucket())){
|
||||
if(0 > (res = s3fscurl.CheckBucket("/"))){
|
||||
// get response code
|
||||
long responseCode = s3fscurl.GetLastResponseCode();
|
||||
long responseCode = s3fscurl.GetLastResponseCode();
|
||||
bool changed_endpoint = false;
|
||||
|
||||
// check wrong endpoint, and automatically switch endpoint
|
||||
if(300 <= responseCode && responseCode < 500){
|
||||
|
@ -4066,7 +4091,9 @@ static int s3fs_check_service()
|
|||
}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;
|
||||
endpoint = expectregion;
|
||||
changed_endpoint = true;
|
||||
|
||||
if(S3fsCurl::GetSignatureType() == V4_ONLY ||
|
||||
S3fsCurl::GetSignatureType() == V2_OR_V4){
|
||||
if(s3host == "http://s3.amazonaws.com"){
|
||||
|
@ -4075,11 +4102,6 @@ static int s3fs_check_service()
|
|||
s3host = "https://s3-" + endpoint + ".amazonaws.com";
|
||||
}
|
||||
}
|
||||
|
||||
// retry to check with new endpoint
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
res = s3fscurl.CheckBucket();
|
||||
responseCode = s3fscurl.GetLastResponseCode();
|
||||
}
|
||||
}else if(check_endpoint_error(body->str(), body->size(), expectendpoint)){
|
||||
S3FS_PRN_ERR("S3 service returned PermanentRedirect with endpoint: %s", expectendpoint.c_str());
|
||||
|
@ -4087,6 +4109,20 @@ static int s3fs_check_service()
|
|||
}
|
||||
}
|
||||
|
||||
// retry to check with new endpoint
|
||||
if(changed_endpoint){
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
res = s3fscurl.CheckBucket("/");
|
||||
responseCode = s3fscurl.GetLastResponseCode();
|
||||
}
|
||||
|
||||
// retry to check with mount prefix
|
||||
if(300 <= responseCode && responseCode < 500 && !mount_prefix.empty()){
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
res = s3fscurl.CheckBucket(get_realpath("/").c_str());
|
||||
responseCode = s3fscurl.GetLastResponseCode();
|
||||
}
|
||||
|
||||
// try signature v2
|
||||
if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::GetSignatureType() == V2_OR_V4){
|
||||
// switch sigv2
|
||||
|
@ -4095,8 +4131,15 @@ static int s3fs_check_service()
|
|||
|
||||
// retry to check with sigv2
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
res = s3fscurl.CheckBucket();
|
||||
res = s3fscurl.CheckBucket("/");
|
||||
responseCode = s3fscurl.GetLastResponseCode();
|
||||
|
||||
// retry to check with mount prefix
|
||||
if(300 <= responseCode && responseCode < 500 && !mount_prefix.empty()){
|
||||
s3fscurl.DestroyCurlHandle();
|
||||
res = s3fscurl.CheckBucket(get_realpath("/").c_str());
|
||||
responseCode = s3fscurl.GetLastResponseCode();
|
||||
}
|
||||
}
|
||||
|
||||
// check errors(after retrying)
|
||||
|
|
Loading…
Reference in New Issue