Skip to content

Commit

Permalink
[XrdCl] Report last error if metalink runs out of replicas, fixes #1071
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmichal committed Jan 17, 2020
1 parent 8b603ee commit 494395b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 31 deletions.
53 changes: 28 additions & 25 deletions src/XProtocol/XProtocol.hh
Expand Up @@ -380,6 +380,7 @@ enum XErrorCode {
kXR_BadPayload, // 3026
kXR_AttrNotFound, // 3027
kXR_TLSRequired, // 3028
kXR_noReplicas, // 3029
kXR_ERRFENCE, // Always last valid errcode + 1
kXR_noErrorYet = 10000
};
Expand Down Expand Up @@ -1005,31 +1006,32 @@ public:
static int mapError(int rc)
{if (rc < 0) rc = -rc;
switch(rc)
{case ENOENT: return kXR_NotFound;
case EINVAL: return kXR_ArgInvalid;
case EPERM: return kXR_NotAuthorized;
case EACCES: return kXR_NotAuthorized;
case EIO: return kXR_IOError;
case ENOMEM: return kXR_NoMemory;
case ENOBUFS: return kXR_NoMemory;
case ENOSPC: return kXR_NoSpace;
case ENAMETOOLONG: return kXR_ArgTooLong;
case ENETUNREACH: return kXR_noserver;
case ENOTBLK: return kXR_NotFile;
case EISDIR: return kXR_isDirectory;
case EEXIST: return kXR_InvalidRequest;
case ETXTBSY: return kXR_inProgress;
case ENODEV: return kXR_FSError;
case EFAULT: return kXR_ServerError;
case EDOM: return kXR_ChkSumErr;
case EDQUOT: return kXR_overQuota;
case EILSEQ: return kXR_SigVerErr;
case ERANGE: return kXR_DecryptErr;
case EUSERS: return kXR_Overloaded;
case EROFS: return kXR_fsReadOnly;
case ENOATTR: return kXR_AttrNotFound;
case EPROTOTYPE: return kXR_TLSRequired;
default: return kXR_FSError;
{case ENOENT: return kXR_NotFound;
case EINVAL: return kXR_ArgInvalid;
case EPERM: return kXR_NotAuthorized;
case EACCES: return kXR_NotAuthorized;
case EIO: return kXR_IOError;
case ENOMEM: return kXR_NoMemory;
case ENOBUFS: return kXR_NoMemory;
case ENOSPC: return kXR_NoSpace;
case ENAMETOOLONG: return kXR_ArgTooLong;
case ENETUNREACH: return kXR_noserver;
case ENOTBLK: return kXR_NotFile;
case EISDIR: return kXR_isDirectory;
case EEXIST: return kXR_InvalidRequest;
case ETXTBSY: return kXR_inProgress;
case ENODEV: return kXR_FSError;
case EFAULT: return kXR_ServerError;
case EDOM: return kXR_ChkSumErr;
case EDQUOT: return kXR_overQuota;
case EILSEQ: return kXR_SigVerErr;
case ERANGE: return kXR_DecryptErr;
case EUSERS: return kXR_Overloaded;
case EROFS: return kXR_fsReadOnly;
case ENOATTR: return kXR_AttrNotFound;
case EPROTOTYPE: return kXR_TLSRequired;
case EADDRNOTAVAIL: return kXR_noReplicas;
default: return kXR_FSError;
}
}

Expand Down Expand Up @@ -1065,6 +1067,7 @@ static int toErrno( int xerr )
case kXR_BadPayload: return EINVAL;
case kXR_AttrNotFound: return ENOATTR;
case kXR_TLSRequired: return EPROTOTYPE;
case kXR_noReplicas: return EADDRNOTAVAIL;
default: return ENOMSG;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/XrdCl/XrdClMetalinkRedirector.cc
Expand Up @@ -322,7 +322,7 @@ namespace XrdCl
// get the redirect location
std::string replica;
if( !GetReplica( msg, replica ).IsOK() )
return GetErrorMsg( msg, "No more replicas to try.", kXR_NotFound );
return GetErrorMsg( msg, "Metalink: no more replicas to try.", kXR_noReplicas );
Message *resp = new Message( sizeof(ServerResponse) );
ServerResponse* response =
reinterpret_cast<ServerResponse*>( resp->GetBuffer() );
Expand Down
12 changes: 7 additions & 5 deletions src/XrdCl/XrdClXRootDMsgHandler.cc
Expand Up @@ -1320,11 +1320,10 @@ namespace XrdCl
if( pStatus.code == errErrorResponse )
{
st->errNo = rsp->body.error.errnum;
char *errmsg = new char[rsp->hdr.dlen-3];
errmsg[rsp->hdr.dlen-4] = 0;
memcpy( errmsg, rsp->body.error.errmsg, rsp->hdr.dlen-4 );
std::string errmsg( rsp->body.error.errmsg, rsp->hdr.dlen-4 );
if( st->errNo == kXR_noReplicas )
errmsg += " Last seen error: " + pLastError.ToString();
st->SetErrorMessage( errmsg );
delete [] errmsg;
}
else if( pStatus.code == errRedirect )
st->SetErrorMessage( pRedirectUrl );
Expand Down Expand Up @@ -2126,7 +2125,10 @@ namespace XrdCl
if( status.IsOK() )
return;

pLastError = status;
bool noreplicas = ( status.code == errErrorResponse &&
status.errNo == kXR_noReplicas );

if( !noreplicas ) pLastError = status;

Log *log = DefaultEnv::GetLog();
log->Debug( XRootDMsg, "[%s] Handling error while processing %s: %s.",
Expand Down

0 comments on commit 494395b

Please sign in to comment.