Skip to content

Commit

Permalink
[XrdCl] Use XrdSysXAttr in LocalFileHandler.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmichal committed Oct 16, 2019
1 parent 41db979 commit 0b1cee4
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 85 deletions.
46 changes: 33 additions & 13 deletions src/XrdCl/XrdClFile.cc
Expand Up @@ -466,15 +466,20 @@ namespace XrdCl
// Set extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::SetXAttr( const std::vector<xattr_t> &attrs,
std::vector<XAttrStatus> *&result,
std::vector<XAttrStatus> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = SetXAttr( attrs, &handler, timeout );
XRootDStatus st = SetXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
std::vector<XAttrStatus> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;

return st;
}

//------------------------------------------------------------------------
Expand All @@ -494,15 +499,20 @@ namespace XrdCl
// Get extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::GetXAttr( const std::vector<std::string> &attrs,
std::vector<XAttr> *&result,
std::vector<XAttr> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = GetXAttr( attrs, &handler, timeout );
XRootDStatus st = GetXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
std::vector<XAttr> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;

return st;
}

//------------------------------------------------------------------------
Expand All @@ -522,15 +532,20 @@ namespace XrdCl
// Delete extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::DelXAttr( const std::vector<std::string> &attrs,
std::vector<XAttrStatus> *&result,
std::vector<XAttrStatus> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = DelXAttr( attrs, &handler, timeout );
XRootDStatus st = DelXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
std::vector<XAttrStatus> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;

return st;
}

//------------------------------------------------------------------------
Expand All @@ -548,15 +563,20 @@ namespace XrdCl
//------------------------------------------------------------------------
// List extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::ListXAttr( std::vector<XAttr> *&result,
uint16_t timeout )
XRootDStatus File::ListXAttr( std::vector<XAttr> &result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = ListXAttr( &handler, timeout );
XRootDStatus st = ListXAttr( &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
std::vector<XAttr> *resp = 0;
st = MessageUtils::WaitForResponse( &handler, resp );
if( resp ) result.swap( *resp );
delete resp;

return st;
}


Expand Down
10 changes: 5 additions & 5 deletions src/XrdCl/XrdClFile.hh
Expand Up @@ -471,7 +471,7 @@ namespace XrdCl
//! @return : status of the operation
//------------------------------------------------------------------------
XRootDStatus SetXAttr( const std::vector<xattr_t> &attrs,
std::vector<XAttrStatus> *&result,
std::vector<XAttrStatus> &result,
uint16_t timeout = 0 );

//------------------------------------------------------------------------
Expand Down Expand Up @@ -501,7 +501,7 @@ namespace XrdCl
//! @return : status of the operation
//------------------------------------------------------------------------
XRootDStatus GetXAttr( const std::vector<std::string> &attrs,
std::vector<XAttr> *&result,
std::vector<XAttr> &result,
uint16_t timeout = 0 );

//------------------------------------------------------------------------
Expand Down Expand Up @@ -531,7 +531,7 @@ namespace XrdCl
//! @return : status of the operation
//------------------------------------------------------------------------
XRootDStatus DelXAttr( const std::vector<std::string> &attrs,
std::vector<XAttrStatus> *&result,
std::vector<XAttrStatus> &result,
uint16_t timeout = 0 );

//------------------------------------------------------------------------
Expand All @@ -557,8 +557,8 @@ namespace XrdCl
//!
//! @return : status of the operation
//------------------------------------------------------------------------
XRootDStatus ListXAttr( std::vector<XAttr> *&result,
uint16_t timeout = 0 );
XRootDStatus ListXAttr( std::vector<XAttr> &result,
uint16_t timeout = 0 );

//------------------------------------------------------------------------
//! Check if the file is open
Expand Down
96 changes: 47 additions & 49 deletions src/XrdCl/XrdClLocalFileHandler.cc
Expand Up @@ -24,6 +24,9 @@
#include "XrdCl/XrdClFileSystem.hh"
#include "XProtocol/XProtocol.hh"

#include "XrdSys/XrdSysXAttr.hh"
#include "XrdSys/XrdSysFAttr.hh"

#include <string>
#include <memory>
#include <stdexcept>
Expand All @@ -36,8 +39,6 @@
#include <sys/stat.h>
#include <arpa/inet.h>
#include <aio.h>
#include <sys/types.h>
#include <sys/xattr.h>

namespace
{
Expand Down Expand Up @@ -604,20 +605,21 @@ namespace XrdCl
ResponseHandler *handler,
uint16_t timeout )
{
static const std::string prefix = "user.U.";
XrdSysXAttr *xattr = XrdSysFAttr::Xat;

static const std::string prefix = "U.";
std::vector<XAttrStatus> response;

auto itr = attrs.begin();
for( ; itr != attrs.end(); ++itr )
{
std::string name = prefix + std::get<xattr_name>( *itr );
std::string value = std::get<xattr_value>( *itr );

int err = fsetxattr( fd, name.c_str(), value.c_str(), value.size(), 0 );
XRootDStatus status = err ? XRootDStatus( stError, XProtocol::mapError( errno ) ) :
int err = xattr->Set( name.c_str(), value.c_str(), value.size(), 0, fd );
XRootDStatus status = err ? XRootDStatus( stError, XProtocol::mapError( -errno ) ) :
XRootDStatus();

response.push_back( XAttrStatus( name, status ) );
response.push_back( XAttrStatus( name.substr( prefix.size() ), status ) );
}

AnyObject *resp = new AnyObject();
Expand All @@ -633,7 +635,9 @@ namespace XrdCl
ResponseHandler *handler,
uint16_t timeout )
{
static const std::string prefix = "user.U.";
XrdSysXAttr *xattr = XrdSysFAttr::Xat;

static const std::string prefix = "U.";
std::vector<XAttr> response;

auto itr = attrs.begin();
Expand All @@ -642,18 +646,17 @@ namespace XrdCl
std::string name = prefix + *itr;
std::unique_ptr<char[]> buffer;

ssize_t size = fgetxattr( fd, name.c_str(), buffer.get(), 0 );
int size = xattr->Get( name.c_str(), 0, 0, 0, fd );
buffer.reset( new char[size] );

int err = fgetxattr( fd, name.c_str(), buffer.get(), size );
int ret = xattr->Get( name.c_str(), buffer.get(), size, 0, fd );

XRootDStatus status;
std::string value;

if( err != -1 )
value.append( buffer.get(), size );
else
status = XRootDStatus( stError, XProtocol::mapError( errno ) );
if( ret >= 0 )
value.append( buffer.get(), ret );
else if( ret < 0 )
status = XRootDStatus( stError, XProtocol::mapError( -ret ) );

response.push_back( XAttr( *itr, value, status ) );
}
Expand All @@ -671,15 +674,17 @@ namespace XrdCl
ResponseHandler *handler,
uint16_t timeout )
{
static const std::string prefix = "user.U.";
XrdSysXAttr *xattr = XrdSysFAttr::Xat;

static const std::string prefix = "U.";
std::vector<XAttrStatus> response;

auto itr = attrs.begin();
for( ; itr != attrs.end(); ++itr )
{
std::string name = prefix + *itr;
int err = fremovexattr( fd, name.c_str() );
XRootDStatus status = err ? XRootDStatus( stError, XProtocol::mapError( errno ) ) :
std::string name = prefix + *itr;
int err = xattr->Del( name.c_str(), 0, fd );
XRootDStatus status = err ? XRootDStatus( stError, XProtocol::mapError( -errno ) ) :
XRootDStatus();

response.push_back( XAttrStatus( name, status ) );
Expand All @@ -697,47 +702,40 @@ namespace XrdCl
XRootDStatus LocalFileHandler::ListXAttr( ResponseHandler *handler,
uint16_t timeout )
{
static const std::string prefix = "user.U.";
XrdSysXAttr *xattr = XrdSysFAttr::Xat;

std::unique_ptr<char[]> buffer;
ssize_t size = flistxattr( fd , buffer.get(), 0 );
buffer.reset( new char[size] );
int err = flistxattr( fd, buffer.get(), size );
static const std::string prefix = "U.";
std::vector<XAttr> response;

XrdSysXAttr::AList *alist = 0;
int err = xattr->List( &alist, 0, fd, 1 );

if( err == -1 )
if( err < 0 )
{
XRootDStatus *status = new XRootDStatus( stError, XProtocol::mapError( errno ) );
XRootDStatus *status = new XRootDStatus( stError, XProtocol::mapError( -err ) );
return QueueTask( status, 0, handler );
}

std::vector<XAttr> response;
char *ptr = buffer.get();

while( size > 0 )
XrdSysXAttr::AList *ptr = alist;
while( ptr )
{
size_t len = strlen( ptr );
std::string name( ptr, len );
size -= len + 1; // the +1 stands for the null terminating the string
ptr += len + 1; // the +1 stands for the null terminating the string
std::string name( ptr->Name, ptr->Nlen );
int vlen = ptr->Vlen;
ptr = ptr->Next;

if( name.find( prefix ) == 0 )
response.push_back( name );
}

auto itr = response.begin();
for( ; itr != response.end(); ++itr )
{
size = fgetxattr( fd, itr->name.c_str(), 0, 0 );
buffer.reset( new char[size] );
if( name.find( prefix ) != 0 ) continue;

int err = fgetxattr( fd, itr->name.c_str(), buffer.get(), size );
std::unique_ptr<char[]> buffer( new char[vlen] );
int ret = xattr->Get( name.c_str(),
buffer.get(), vlen, 0, fd );

if( err != -1 )
itr->value.append( buffer.get(), size );
else
itr->status = XRootDStatus( stError, XProtocol::mapError( errno ) );
itr->name = itr->name.substr( prefix.size() );
std::string value = ret >= 0 ? std::string( buffer.get(), ret ) :
std::string();
XRootDStatus status = ret >= 0 ? XRootDStatus() :
XRootDStatus( stError, XProtocol::mapError( -ret ) );
response.push_back( XAttr( name.substr( prefix.size() ), value, status ) );
}
xattr->Free( alist );

AnyObject *resp = new AnyObject();
resp->Set( new std::vector<XAttr>( std::move( response ) ) );
Expand Down
24 changes: 6 additions & 18 deletions tests/XrdClTests/FileTest.cc
Expand Up @@ -748,63 +748,51 @@ void FileTest::XAttrTest()
for( auto &a : attributes )
attrs.push_back( std::make_tuple( a.first, a.second ) );

std::vector<XAttrStatus> *result1 = 0;
std::vector<XAttrStatus> result1;
CPPUNIT_ASSERT_XRDST( file.SetXAttr( attrs, result1 ) );

for( auto &xst : *result1 )
for( auto &xst : result1 )
CPPUNIT_ASSERT_XRDST( xst.status );

delete result1;
result1 = 0;

//----------------------------------------------------------------------------
// Test GetXAttr
//----------------------------------------------------------------------------
std::vector<std::string> names;
for( auto &a : attributes )
names.push_back( a.first );

std::vector<XAttr> *result2 = 0;
std::vector<XAttr> result2;
CPPUNIT_ASSERT_XRDST( file.GetXAttr( names, result2 ) );

for( auto &xa : *result2 )
for( auto &xa : result2 )
{
CPPUNIT_ASSERT_XRDST( xa.status );
auto match = attributes.find( xa.name );
CPPUNIT_ASSERT( match != attributes.end() );
CPPUNIT_ASSERT( match->second == xa.value );
}

delete result2;
result2 = 0;

//----------------------------------------------------------------------------
// Test ListXAttr
//----------------------------------------------------------------------------
CPPUNIT_ASSERT_XRDST( file.ListXAttr( result2 ) );

for( auto &xa : *result2 )
for( auto &xa : result2 )
{
CPPUNIT_ASSERT_XRDST( xa.status );
auto match = attributes.find( xa.name );
CPPUNIT_ASSERT( match != attributes.end() );
CPPUNIT_ASSERT( match->second == xa.value );
}

delete result2;
result2 = 0;

//----------------------------------------------------------------------------
// Test DelXAttr
//----------------------------------------------------------------------------
CPPUNIT_ASSERT_XRDST( file.DelXAttr( names, result1 ) );

for( auto &xst : *result1 )
for( auto &xst : result1 )
CPPUNIT_ASSERT_XRDST( xst.status );

delete result1;
result1 = 0;

CPPUNIT_ASSERT_XRDST( file.Close() );
}

Expand Down

0 comments on commit 0b1cee4

Please sign in to comment.