Plug-in Writer’s 4.x Migration Guide

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

20-November-2013

                                                       Andrew Hanushevsky                     


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

©2004-2013 by the Board of Trustees of the Leland Stanford, Jr., University

All Rights Reserved

Produced under contract DE-AC02-76-SFO0515 with the Department of Energy

This code is open-sourced under a GNU Lesser General Public license.

For LGPL terms and conditions see http://www.gnu.org/licenses/


 

1       Introduction. 4

2       Versioning Is Now Mandatory. 4

3       IPV6: Socket and Network Interface Changes. 5

3.1      Deprecated Classes. 5

3.1.1        XrdNetPeer. 5

3.1.2        XrdSysDNS. 6

3.2      Deleted Classes. 7

3.3      Modified Classes. 7

3.3.1        XrdLink. 7

3.3.2        XrdProtocol_Config. 7

3.3.3        XrdSecEntity. 7

3.3.4        XrdSecInterface. 8

4       Summary of Plug-In Changes For Ideal Migration. 8

5       Class Enhancements. 9

5.1      XrdOss Enhancement 9

5.2      XrdOssDF Enhancements. 9

5.3      XrdOucErrInfo Enhancements. 10

5.4      XrdSecEntity Enhancements. 11

5.5      XrdSfsInterface Enhancements. 11

 


1        Introduction

 

This major release of xrootd/cmsd provides full IPV6 support with IPV4 compatibility. As such, it is no longer ABI compatible in two major respects:

1)     Classes dealing with sockets and the network interfaces have substantially changed, and

2)     The security interface has changed so as to provide a consistent connection context.

 

Additionally, several classes used by plug-in writers (e.g. XrdOucErrInfo) as well as abstract plug-in classes have received new methods to enhance the interface. As such they are not ABI compatible. However, defaults are provided for virtual methods so only a recompilation is required. This document outlines the enhanced interfaces to allow you to further optimize the various plug-ins.

 

2        Versioning Is Now Mandatory

 

Because version 4.x no longer is ABI backwards compatible, it is necessary to require that each plug-in include version information so that the plug-in loader can detect incompatible interfaces. You must include versioning information whether or not you make any changes to your code. While a simple recompilation against the version 4.x source code base is likely to be sufficient; versioning information allows the plug-in manager verify that you have at least carried out that step.

 

Use the XrdVERSIONINFO macro defined in XrdVersion.hh to include version information in your plug-in. The exact method is described in each header file that defines the plug-in interface. Header files and the corresponding plug-ins are shown below.

 

Header file

Corresponding Plug-in

Related Directive

XrdAccAuthorize.hh

Authorization

ofs.authlib

XrdCks.hh

Checksum manager

ofs.ckslib

XrdCksCalc.hh

Checksum calculator

ofs.ckslib

XrdClMonitor.hh

Client-side monitoring

n/a

XrdCmsClient.hh

Cluster Manager

ofs.cmslib

XrdOss.hh

Physical file system

ofs.osslib

XrdOssStatInfo.hh

Alternate stat()

oss.stalib

XrdOucName2Name.hh

Name-to-name

oss.namelib

XrdProtocol.hh

Protocol

xrd.protocol

Header file

Corresponding Plug-in

Related Directive

XrdSecInterface

Authentication

sec.protocol

XrdSfsInterface

Logical file system

xrootd.fslib

 

3        IPV6: Socket and Network Interface Changes

3.1      Deprecated Classes

3.1.1       XrdNetPeer

The XrdNetPeer class is now deprecated but exists for backward compatibility; but may require source code changes if it is used in certain ways.

 

This class embedded an IPV4 structure, sockaddr, and was changed to use XrdNetSockAddr which defines a larger structure suitable for IPV6. To prevent programs from unknowingly using the smaller structure, the member name InetAddr, used for the sockaddr structure, was changed to trigger a compilation error. You should make sure you are not taking the size of the smaller structure when copying network addresses. Specifically, the member InetAddr referred to the sockaddr structure. This has been changed so that the member

·       Intet.Addr refers to the union of IPV4 and IPV6 sockaddr structures,

·       Inet.v4 refers to an IPV4 sockaddr structure, and

·       Inet.v6 refers to an IPV6 sockaddr structure.

 

If you are not sensitive to the size of the sockaddr structure, then you can simply replace all occurrences of InetAddr to be Inet.Addr.

 

In general, calls to methods using the XrdNetPeer class as an argument for TCP sockets should switch to using equivalent methods based on the XrdNetAddr class, if available. Specifically, review the usage of

·       XrdLink::Alloc()

·       XrdNet::Accept() and

·       XrdNet::Connect()

 

The XrdLink::Alloc method must now pass an XrdNetAddr object instead of an XrdNetPeer object. Code review indicated that this method would not be called by any known plug-ins. Hence, it was deemed safe to make it incompatible.

 

The XrdNet methods accepting XrdNetPeer objects are still supported for UDP sockets but deprecated for TCP sockets. For TCP sockets, you should switch to the equivalent method that accepts an XrdNetAddr object.

 

3.1.2       XrdSysDNS

The XrdSysDNS class is now deprecated and essentially obsolete. It is still provided for backward compatibly but is no longer supported. This class works only in IPV4 contexts. It has been replaced by four address-format agnostic classes:

·       XrdNetAddr (which inherits XrdNetAddrInfo),

·       XrdNetSockAddr, and

·       XrdNetUtils.

 

All uses of XrdSysDNS should convert to using one or more of the new classes. Specifically,

 

XrdSysDNS Method

Replacement (Single)

Replacement (Multiple)

getAddrName()

XrdNetAddr::Set()

XrdNetUtils::GetAddrs() or XrdNetUtils::Hosts()

getHostAddr()

XrdNetAddr::Set()

XrdNetUtils::GetAddrs() or XrdNetUtils::Hosts()

getHostID()

XrdNetAddrInfo::Format()

 

getHostName()

XrdNetAddr::Set()

XrdNetUtils::GetAddrs() or XrdNetUtils::Hosts()

getHostName()

XrdNetUtils::MyHostName() for current host

 

getPort()

XrdNetUtils::ServPort()

 

getProtoID()

XrdNetUtils::ProtoID()

 

Host2Dest()

XrdNetAddr::Set()

 

Host2IP()

IPV4 specific no replacement

 

IP2String()

XrdNetAddrInfo::Format()

 

IPAddr()

IPV4 specific no replacement

 

IPFormat()

XrdNetAddrInfo::Format()

 

isDomain()

XrdNetUtils::Match()

 

isLoopback()

XrdNetAddrInfo::isLoopBack()

 

isMatch()

XrdNetUtils::Match()

 

Peername()

XrdNetAddr::Set()

 

setPort()

XrdNetAddr::Set()

 

 

3.2      Deleted Classes

The XrdNetLink and XrdNetWork classes have been deleted from the distribution. These were never officially made available in the public headers and were never used by the base code.

3.3      Modified Classes

3.3.1       XrdLink

 

XrdLink Method

Nature of change

Alloc()

no longer accepts XrdNetPeer; you must pass XrdNetAddr

Host()

no longer returns an optional sockaddr copy; use AddrInfo() or NetAddr() to obtain the address

Name()

no longer returns an optional sockaddr copy; use AddrInfo() or NetAddr() to obtain the address

 

3.3.2       XrdProtocol_Config

 

The class XrdProtocol_Config contained the socket address describing the server’s IP address using the member myAddr has been sized for IPV6 using a union. While the variable name has not changed, programs referring to this variable should use the urAddr variable instead. Otherwise, programs should be sensitive that the socket address may be IPV4 or IPV6.

3.3.3       XrdSecEntity

The XrdSecEntity object has changed, as follows:

1)     It now includes a pointer to the XrdNetAddrInfo object that describes the connection details of the end-point that is associated with the entity description as member addrInfo.

2)     In order to better accommodate this additions, the layout has slightly changed.

 

In order to assist authorization and other host address sensitive plug-ins, each supported security plug-in now sets the addrInfo member to point to a copy of the XrdNetAddrInfo object passed when requesting a new instance of the protocol. The default authorization plug-in has been changed to capitalize on this new information. Similar changes should be made to all private security plug-ins. Failure to set the addrInfo member will likely result in a SEGV.

 

Additionally, the hostname member of the XrdSecEntity object has been documented to contain either a hostname or an ASCII IP address. This was always true. With the addition of the addrInfo member, one can now obtain the actual hostname (i.e. via the XrdNetAddrInfo object). However, that use is discouraged unless absolutely necessary. This is to prevent defeating the “nodnr” network directive option.

3.3.4       XrdSecInterface

The security interfaces have substantially changed. All interfaces that used to accept a sockaddr structure now only accept the XrdNetAddrInfo object (for example, the XrdSecProtocol<p>Object function).

 

4        Summary of Plug-In Changes For Ideal Migration

 

The changes that you should make to your plug-ins are:

1)     Substitute XrdNetAddr for any use of sockaddr. If that is not possible, at the very least, use XrdNetSockAddr instead.

2)     After converting remove, if possible, redundant include files “arpa/inet.h”, “netinet/in.h”, “sys/socket.hh” and similar include files.

3)     Convert from using XrdSysDNS to a combination of XrdNetAddr and XrdNetUtils.

4)     Private security plug-ins must set the addrInfo member in XrdSecEntity.

5)     If one of your plug-ins relied on the host member in XrdSecEntity to contain an actual host name, it should be changed to get the actual host using the addrInfo field. Please be aware that the host member never consistently pointed to a real host name as it was sensitive to the presence of the nodnr option on the xrd.network directive.

6)     All plug-ins must now contain version information. This has become mandatory. Use the XrdVERSIONINFO macro defined in XrdVersion.hh to include version information in your plug-in.

 


 

5        Class Enhancements

 

The following classes have been enhanced with new methods that provide more flexibility and opportunities to increase performance.

·       XrdOss

·       XrdOssDF

·       XrdOucErrInfo

·       XrdSecEntity

·       XrdSfsInterface (XrdSfsDirectory, XrdSfsFile, and XrdSfsFileSystem)

 

5.1      XrdOss Enhancement

The following new methods have been added to XrdOss, the abstract class that defines the physical storage system interface:

FSctl()

This interface allows you to send arbitrary request data from the logical file system to the physical storage system and optionally receive a result. It is intended to be used for custom implementations of the logical and physical storage system plug-ins to perform operations that are not captured by any existing method. The default implementation returns –ENOTSUP.

 

5.2      XrdOssDF Enhancements

The following new methods have been added to XrdOssDF, the abstract class that defines the physical storage system file and directory interface:

Fctl()

This interface allows you to send arbitrary request data from the logical file system to the physical storage system and optionally receive a result relative to a particular file or directory. It is intended to be used for custom implementations of the logical and physical storage system plug-ins to perform operations that are not captured by any existing method. The default implementation returns

–ENOTSUP.

 

ReadV()

This method allows efficient handling of a vector read request. It is only meant for files. The logical file system invokes this method when it is asked to handle a file vector read. The default implementation unrolls the vector of read requests and calls Read() on each element.


 

StatRet()

This method allows the caller to set a pointer to a stat structure; implicitly requesting that for each directory entry returned by Readdir() that the buffer be filled out with the results of stat() against that entry. This is meant to dramatically reduce the latency required to obtain entry attributes of a directory entry. The default implementation returns –ENOTSUP which forces the caller to manually obtain such information.

 

WriteV()

This method allows efficient handling of a vector write request. It is only meant for files. The logical file system invokes this method when it is asked to handle a file vector write. The default implementation unrolls the vector of write requests and calls Write() on each element. Currently, file vector writes are not supported in the upper layers of the system.

 

5.3      XrdOucErrInfo Enhancements

The following new methods have been added to XrdOucErrInfo, the abstract class that defines the error/data message return path. It is passed to many of the XrdSfsFileSystem methods and is part of the XrdSfsDirectory and XrdSfsFile object. These new methods support the object’s ability to handle information larger than the previously built-in limit of 2048 bytes. This is particularly advantageous when returning redirect information (i.e. target host plus CGI information) from the logical file system interface.

 

extData()

Return true when extended information will be returned (i.e. from an outboard buffer).

 

getUCap()

Returns the contents of the newly added member, ucap, that describes the client’s capabilities. These capabilities can be used to steer client-appropriate processing. For instance, if the client only supports IPV4 network data then only IPV4 addresses or host names should be returned.

 

Reset()

Sets the object to a pristine state and recycles any extended information buffer.

 


 

setErrInfo()

A new variant of this method has been added that allows you to associate an external buffer defined by the XrdOucBuffer class that holds error information or return data. This mechanism must be used to return more than 2048 bytes of information, the previous limit.

 

5.4      XrdSecEntity Enhancements

The following new member has been added to XrdSecEntity, the class that defines the client’s authentication information. It is passed to many of the XrdSfsFileSystem methods.

 

addrInfo

Points to the XrdNetAddrInfo object that describes the client’s internet information (e.g. address, hostname, etc). This object must be used to obtain the client’s true hostname since the host member may contain a hostname or an IP address should the xrd.network directive’s nodnr option be in effect. The latter operation should be used only when necessary in order to not defeat the nodnr option.

 

 

5.5      XrdSfsInterface Enhancements

The following new methods have been added to the XrdSfsInterface specification (i.e. XrdSfsDirectory, XrdSfsFile, XrdSfsFileSystem).

 

XrdSfsDirectory:: autoStat()

This method allows the caller to set a pointer to a stat structure; implicitly requesting that for each directory entry returned by nextEntry() that the buffer be filled out with the results of stat() against that entry. This is meant to dramatically reduce the latency required to obtain entry attributes of a directory entry. The default implementation returns ENOTSUP which forces the caller to manually obtain such information. See XrdOss::StatRet() for the corresponding method at the physical layer.

 

XrdSfsFile:: fctl()

A second variant of fctl() allows a client to pass arbitrary data to the logical file system for a particular file. This is done using the kXR_Qopaqug option to the kXR_query request.

XrdSfsFile::readv()

This method allows efficient handling of a vector read request. It is only meant for files. The logical file system invokes this method when it is asked to handle a file vector read. The default implementation unrolls the vector of read requests and calls read() on each element.

 

XrdSfsFile::SendData()

This method is called for read operations when the file object returns SFS_SFIO_FDVAL in the errinfo.code member in response to a fctl(SFS_FCTL_GETFD) call. Normally, the upper layer would bypass the logical file system if it could obtain the actual file descriptor associated with the file and directly issue sendfile() requests in response to read requests. This can severely constrain what the logical and physical layers can do with an open file descriptor. The SendData() method allows the file descriptor to remain hidden by passing the responsibility to issue the sendfile() call to the logical layer. The default implementation merely returns SFS_OK which causes the read() to be called to complete the request.

 

XrdSfsFile::SetXio

This method may be called to enable exchange buffer I/O for write operations. Exchange buffer I/O lets write() claim ownership over a write buffer in order to accomplish the operation in the background without further copying the data. It can provide better performance for special kinds of workloads.

 

XrdSfsFile::writev()

This method allows efficient handling of a vector write request. It is only meant for files. The logical file system invokes this method when it is asked to handle a file vector write. The default implementation unrolls the vector of write requests and calls write() on each element. Currently, file vector writes are not supported in the upper layers of the system.