Skip to content

Commit

Permalink
[XrdCl] Implement fattr.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmichal committed Jun 21, 2019
1 parent 26ac947 commit 44d41ec
Show file tree
Hide file tree
Showing 16 changed files with 1,440 additions and 5 deletions.
2 changes: 1 addition & 1 deletion bindings/python/setup.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ opt = cfg_vars["OPT"]
cfg_vars["OPT"] = " ".join( flag for flag in opt.split() if flag not in ['-Wstrict-prototypes' ${CLANG_PROHIBITED} ] ) + " --std=c++0x"

cflags = cfg_vars["CFLAGS"]
cfg_vars["CFLAGS"] = " ".join( flag for flag in cflags.split() if flag not in ['-Wstrict-prototypes' ${CLANG_PROHIBITED} ] ) + " --std=c++0x"
cfg_vars["CFLAGS"] = " ".join( flag for flag in cflags.split() if flag not in ['-Wstrict-prototypes' ${CLANG_PROHIBITED} ] ) + " --std=c++0x"

py_cflags = cfg_vars["PY_CFLAGS"]
cfg_vars["PY_CFLAGS"] = " ".join( flag for flag in py_cflags.split() if flag not in ['-Wstrict-prototypes' ${CLANG_PROHIBITED} ] ) + " --std=c++0x"
Expand Down
14 changes: 14 additions & 0 deletions docs/man/xrdfs.1
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ Output last part of files to stdout.
.RS 3
Get space statistics for given path.

.RE
\fBxattr\fR \fI<path> <code> <params>\fR
.RS 3
Operation on extended attributes. Codes:
.br
\fIset\fR \fB<attr>\fR Set extended attribute;
<attr> is string of form name=value
.br
\fIget\fR \fB<name>\fR Get extended attribute.
.br
\fIdel\fR \fB<name>\fR Delete extended attribute.
.br
\fIlist\fR List extended attributes.

.SH RETURN CODES
.RE
\fB50\fR : generic error (e.g. config, internal, data, OS)
Expand Down
177 changes: 177 additions & 0 deletions src/XrdCl/XrdClFS.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,174 @@ XRootDStatus DoSpaceInfo( FileSystem *fs,
return XRootDStatus();
}

//------------------------------------------------------------------------------
// Carry out xattr operation
//------------------------------------------------------------------------------
XRootDStatus DoXAttr( FileSystem *fs,
Env *env,
const FSExecutor::CommandParams &args )
{
//----------------------------------------------------------------------------
// Check up the args
//----------------------------------------------------------------------------
Log *log = DefaultEnv::GetLog();
uint32_t argc = args.size();

if( argc < 3 )
{
log->Error( AppMsg, "Wrong number of arguments." );
return XRootDStatus( stError, errInvalidArgs );
}

kXR_char code = 0;
if( args[2] == "set")
code = kXR_fattrSet;
else if( args[2] == "get" )
code = kXR_fattrGet;
else if( args[2] == "del" )
code = kXR_fattrDel;
else if( args[2] == "list" )
code = kXR_fattrList;
else
{
log->Error( AppMsg, "Invalid xattr code." );
return XRootDStatus( stError, errInvalidArgs );
}

std::string path;
if( !BuildPath( path, env, args[1] ).IsOK() )
{
log->Error( AppMsg, "Invalid path." );
return XRootDStatus( stError, errInvalidArgs );
}

//----------------------------------------------------------------------------
// Issue the xattr operation
//----------------------------------------------------------------------------
XRootDStatus status;
switch( code )
{
case kXR_fattrSet:
{
if( argc != 4 )
{
log->Error( AppMsg, "Wrong number of arguments." );
return XRootDStatus( stError, errInvalidArgs );
}

std::string key_value = args[3];
size_t pos = key_value.find( '=' );
std::string key = key_value.substr( 0, pos );
std::string value = key_value.substr( pos + 1 );
std::vector<xattr_t> attrs;
attrs.push_back( std::make_tuple( key, value ) );

std::vector<XAttrStatus> *result = 0;
XRootDStatus status = fs->SetXAttr( path, attrs, result );
XAttrStatus xst = result->front();
delete result;

if( !xst.status.IsOK() )
status = xst.status;

if( !status.IsOK() )
log->Error( AppMsg, "Unable to xattr set %s %s: %s",
key.c_str(), value.c_str(),
status.ToStr().c_str() );
return status;
}

case kXR_fattrGet:
{
if( argc != 4 )
{
log->Error( AppMsg, "Wrong number of arguments." );
return XRootDStatus( stError, errInvalidArgs );
}

std::string key = args[3];
std::vector<std::string> attrs;
attrs.push_back( key );

std::vector<XAttr> *result = 0;
XRootDStatus status = fs->GetXAttr( path, attrs, result );
XAttr xattr = result->front();
delete result;

if( !xattr.status.IsOK() )
status = xattr.status;

if( !status.IsOK() )
log->Error( AppMsg, "Unable to xattr get %s : %s",
key.c_str(),
status.ToStr().c_str() );
else
{
std::cout << "# file: " << path << '\n';
std::cout << xattr.name << "=\"" << xattr.value << "\"\n";
}

return status;
}

case kXR_fattrDel:
{
if( argc != 4 )
{
log->Error( AppMsg, "Wrong number of arguments." );
return XRootDStatus( stError, errInvalidArgs );
}

std::string key = args[3];
std::vector<std::string> attrs;
attrs.push_back( key );

std::vector<XAttrStatus> *result = 0;
XRootDStatus status = fs->DelXAttr( path, attrs, result );
XAttrStatus xst = result->front();
delete result;

if( !xst.status.IsOK() )
status = xst.status;

if( !status.IsOK() )
log->Error( AppMsg, "Unable to xattr del %s : %s",
key.c_str(),
status.ToStr().c_str() );
return status;
}

case kXR_fattrList:
{
if( argc != 3 )
{
log->Error( AppMsg, "Wrong number of arguments." );
return XRootDStatus( stError, errInvalidArgs );
}

std::vector<std::string> *result = 0;
XRootDStatus status = fs->ListXAttr( path, result );

if( !status.IsOK() )
log->Error( AppMsg, "Unable to xattr list : %s",
status.ToStr().c_str() );
else
{
std::cout << "# file: " << path << '\n';
auto itr = result->begin();
for( ; itr != result->end(); ++itr )
std::cout << *itr << '\n';
delete result;
}

return status;
}

default:
return XRootDStatus( stError, errInvalidAddr );
}
}

//------------------------------------------------------------------------------
// Print help
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -1672,6 +1840,14 @@ XRootDStatus PrintHelp( FileSystem *, Env *,
printf( " spaceinfo path\n" );
printf( " Get space statistics for given path.\n\n" );

printf( " xattr <path> <code> <params> \n" );
printf( " Operation on extended attributes. Codes:\n\n" );
printf( " set <attr> Set extended attribute; <attr> is\n" );
printf( " string of form name=value\n" );
printf( " get <name> Get extended attribute\n" );
printf( " del <name> Delete extended attribute\n" );
printf( " list List extended attributes\n\n" );

return XRootDStatus();
}

Expand Down Expand Up @@ -1700,6 +1876,7 @@ FSExecutor *CreateExecutor( const URL &url )
executor->AddCommand( "cat", DoCat );
executor->AddCommand( "tail", DoTail );
executor->AddCommand( "spaceinfo", DoSpaceInfo );
executor->AddCommand( "xattr", DoXAttr );
return executor;
}

Expand Down
111 changes: 111 additions & 0 deletions src/XrdCl/XrdClFile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,117 @@ namespace XrdCl
return MessageUtils::WaitForResponse( &handler, visa );
}

//------------------------------------------------------------------------
// Set extended attributes - async
//------------------------------------------------------------------------
XRootDStatus File::SetXAttr( const std::vector<xattr_t> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );

return pStateHandler->SetXAttr( attrs, handler, timeout );
}

//------------------------------------------------------------------------
// Set extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::SetXAttr( const std::vector<xattr_t> &attrs,
std::vector<XAttrStatus> *&result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = SetXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
}

//------------------------------------------------------------------------
// Get extended attributes - async
//------------------------------------------------------------------------
XRootDStatus File::GetXAttr( const std::vector<std::string> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );

return pStateHandler->GetXAttr( attrs, handler, timeout );
}

//------------------------------------------------------------------------
// Get extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::GetXAttr( const std::vector<std::string> &attrs,
std::vector<XAttr> *&result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = GetXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
}

//------------------------------------------------------------------------
// Delete extended attributes - async
//------------------------------------------------------------------------
XRootDStatus File::DelXAttr( const std::vector<std::string> &attrs,
ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );

return pStateHandler->DelXAttr( attrs, handler, timeout );
}

//------------------------------------------------------------------------
// Delete extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::DelXAttr( const std::vector<std::string> &attrs,
std::vector<XAttrStatus> *&result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = DelXAttr( attrs, &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
}

//------------------------------------------------------------------------
// List extended attributes - async
//------------------------------------------------------------------------
XRootDStatus File::ListXAttr( ResponseHandler *handler,
uint16_t timeout )
{
if( pPlugIn )
return XRootDStatus( stError, errNotSupported );

return pStateHandler->ListXAttr( handler, timeout );
}

//------------------------------------------------------------------------
// List extended attributes - sync
//------------------------------------------------------------------------
XRootDStatus File::ListXAttr( std::vector<std::string> *&result,
uint16_t timeout )
{
SyncResponseHandler handler;
Status st = ListXAttr( &handler, timeout );
if( !st.IsOK() )
return st;

return MessageUtils::WaitForResponse( &handler, result );
}


//----------------------------------------------------------------------------
// Check if the file is open
//----------------------------------------------------------------------------
Expand Down

0 comments on commit 44d41ec

Please sign in to comment.