#ifndef __CMS_CLIENT__ #define __CMS_CLIENT__ /******************************************************************************/ /* */ /* X r d C m s C l i e n t . h h */ /* */ /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ class XrdOucEnv; class XrdOucErrInfo; class XrdOucLogger; class XrdOucTList; struct XrdSfsPrep; class XrdSysLogger; /******************************************************************************/ /* R e t u r n C o n v e n t i o n s */ /******************************************************************************/ /* The following return conventions are use by Forward(), Locate(), & Prepare() Return Val Resp.errcode Resp.errtext --------- ------------------- -------- SFS_DATA Length of data. Data to be returned to caller. Action: Caller is provided data as successful response. SFS_ERROR errno Error message text. Action: Caller given error response. SFS_REDIRECT port (0 for default) Host name Action: Caller is redirected to : SFS_STARTED Expected seconds n/a Action: Caller is told to wait for the "expected seconds" for a callback with the result. A callback must follow. See how to do callbacks below. > 0 Wait time (= retval) Reason for wait Action: Caller told to wait retval seconds and retry request. < 0 Error number Error message Action: Same as SFS_ERROR. You should *always* use SFS_ERROR. = 0 Not applicable Not applicable (see below) Action: Forward() -> Return success; request forwarded. Locate() -> Redirection does not apply, operation should be done against local file system. Prepare() -> Return success, request submitted. */ /******************************************************************************/ /* C a l l b a c k C o n v e n t i o n s */ /******************************************************************************/ /* Most operations allow you to return SFS_STARTED to setup a callback. Callback information is contained in the XrdOucErrInfo object passed to Forward(), Locate() and Prepare(); the only methods that can apply callbacks. Use a callback when the operation will take at least several seconds so as to not occupy the calling thread for an excessive amount of time. The actual mechanics of a callback are rather complicated because callbacks are subject to non-causaility if not correctly handled. In order to avoid such issues, you should use the XrdOucCallBack object (see XrdOucCallBack.hh) to test for applicability, setup, and effect a callback. When calling back, you return the same information you would have returned had the execution path been synchronous. From that standpoint callbacks are relatively easy to understand. All you are doing is defering the return of information without occupying a thread while waiting to do so. A typical scenario, using Resp and the original ErrInfo object, would be.... XrdOucCallBack cbObject; // Must be persistent for the callback duration if (XrdOucCallBack::Allowed(Resp)) {cbObject.Init(Resp); Resp.setErrCode(); return SFS_STARTED; // Effect callback response! } Once the thread doing the work has a result, send it via a callback as if the work was done in a synchronous fashion. cbObject->Reply(retValue, ErrCodeValue, ErrTextValue); */ /******************************************************************************/ /* C l a s s X r d C m s C l i e n t */ /******************************************************************************/ class XrdCmsClient { public: //------------------------------------------------------------------------------ //! Notify the cms of a newly added file or a file whose state has changed on //! a data server node. //! //! @param path The logical file name. //! @param Pend When true, the file is scheduled to be present in the future //! (e.g. copied in). //------------------------------------------------------------------------------ virtual void Added(const char *path, int Pend=0) { (void)path; (void)Pend; } //------------------------------------------------------------------------------ //! Configure the client object. //! //! @param cfn The configuration file name. //! @param Parms Any parameters specified in the cmslib directive. If none, //! the pointer may be null. //! @param EnvInfo Environmental information of the caller. //! //! @return Success !0 //! Failure =0 //------------------------------------------------------------------------------ virtual int Configure(const char *cfn, char *Parms, XrdOucEnv *EnvInfo) = 0; //------------------------------------------------------------------------------ //! Relay a meta-operation to all nodes in the cluster. //! //! This method is only used on manager nodes and is enabled by the ofs.forward //! directive. //! //! @param Resp Object where messages are to be returned. //! @param cmd The operation being performed (see table below). //! If it starts with a '+' then a response (2way) is needed. //! Otherwise, a best-effort is all that is all that is required //! and success can always be returned. //! @param arg1 1st argument to cmd. //! @param arg2 2nd argument to cmd, which may be null if none exists. //! @param Env1 Associated environmental information for arg1 (e.g., cgi info //! which can be retrieved by Env1->Env()). //! @param Env2 Associated environmental information for arg2 (e.g., cgi info //! which can be retrieved by Env1->Env()). //! //! //! cmd arg1 arg2 cmd arg1 arg2 //! -------- ------ ------ -------- ------ ------ //! [+]chmod [+]rmdir 0 //! [+]mkdir [+]mv //! [+]mkpath [+]trunc //! [+]rm 0 //! //! @return As explained under "return conventions". //------------------------------------------------------------------------------ virtual int Forward(XrdOucErrInfo &Resp, const char *cmd, const char *arg1=0, const char *arg2=0, XrdOucEnv *Env1=0, XrdOucEnv *Env2=0) { (void)Resp; (void)cmd; (void)arg1; (void)arg2; (void)Env1; (void)Env2; return 0; } //------------------------------------------------------------------------------ //! Check if this client is configured for a manager node. //! //! @return !0 Yes, configured as a manager. //! =0 No. //------------------------------------------------------------------------------ virtual int isRemote() {return myPersona == XrdCmsClient::amRemote;} //------------------------------------------------------------------------------ //! Retrieve file location information. //! //! @param Resp Object where message or response is to be returned. //! @param path The logical path whise location is wanted. //! @param flags One or more of the following: //! //! SFS_O_LOCATE - return the list of servers that have the file. //! Otherwise, redirect to the best server for the file. //! SFS_O_NOWAIT - w/ SFS_O_LOCATE return readily available info. //! Otherwise, select online files only. //! SFS_O_CREAT - file will be created. //! SFS_O_NOWAIT - select server if file is online. //! SFS_O_REPLICA - a replica of the file will be made. //! SFS_O_STAT - only stat() information wanted. //! SFS_O_TRUNC - file will be truncated. //! //! For any the the above, additional flags are passed: //! SFS_O_META - data will not change (inode operation only) //! SFS_O_RESET - reset cached info and recaculate the location(s). //! SFS_O_WRONLY - file will be only written (o/w RDWR or RDONLY). //! SFS_O_RDWR - file may be read and written (o/w WRONLY or RDONLY). //! //! @param Info Associated environmental information for arg2 (e.g., cgi info //! which can be retrieved by Env1->Env()). //! //! @return As explained under "return conventions". //------------------------------------------------------------------------------ virtual int Locate(XrdOucErrInfo &Resp, const char *path, int flags, XrdOucEnv *Info=0) = 0; //------------------------------------------------------------------------------ //! Obtain the list of cmsd's being used by a manager node along with their //! associated index numbers, origin 1. //! //! @return The list of cmsd's being used. The list is considered permanent //! and is not deleted. // Return: A list of managers or null if none exist. //------------------------------------------------------------------------------ virtual XrdOucTList *Managers() {return 0;} //------------------------------------------------------------------------------ //! Start the preparation of a file for future processing. //! //! @param Resp Object where message or response is to be returned. //! @param pargs Information on which and how to prepare the file. //! @param Info Associated environmental information. //! //! @return As explained under "return conventions". //------------------------------------------------------------------------------ virtual int Prepare(XrdOucErrInfo &Resp, XrdSfsPrep &pargs, XrdOucEnv *Info=0) { (void)Resp; (void)pargs; (void)Info; return 0; } //------------------------------------------------------------------------------ //! Notify the cmsd that a file or directory has been deleted. It is only called //! called on a data server node. //! //! @param path The logical file name that was removed. //------------------------------------------------------------------------------ virtual void Removed(const char *path) { (void)path; } //------------------------------------------------------------------------------ //! Resume service after a suspension. //! //! @param Perm When true the resume persist across server restarts. Otherwise, //! it is treated as a temporary request. //------------------------------------------------------------------------------ virtual void Resume (int Perm=1) { (void)Perm; } //------------------------------------------------------------------------------ //! Suspend service. //! //! @param Perm When true the suspend persist across server restarts. //! Otherwise, it is treated as a temporary request. //------------------------------------------------------------------------------ virtual void Suspend(int Perm=1) { (void)Perm; } // The following set of functions can be used to control whether or not clients // are dispatched to this data server based on a virtual resource. The default // implementations do nothing. // //------------------------------------------------------------------------------ //! Enables the Reserve() & Release() methods. //! //! @param n a positive integer that specifies the amount of resource units //! that are available. It may be reset at any time. //! //! @return The previous resource value. This first call returns 0. //------------------------------------------------------------------------------ virtual int Resource(int n) { (void)n; return 0;} //------------------------------------------------------------------------------ //! Decreases the amount of resources available. When the available resources //! becomes non-positive, perform a temporary suspend to prevent additional //! clients from being dispatched to this data server. //! //! @param n The value by which resources are decreased (default 1). //! //! @return The amount of resource left. //------------------------------------------------------------------------------ virtual int Reserve (int n=1) { (void)n; return 0;} //------------------------------------------------------------------------------ //! Increases the amount of resource available. When transitioning from a //! a non-positive to a positive resource amount, perform a resume so that //! additional clients may be dispatched to this data server. //! //! @param n The value to add to the resources available (default 1). The //! total amount is capped by the amount specified by Resource(). //! //! @return The amount of resource left. //------------------------------------------------------------------------------ virtual int Release (int n=1) { (void)n; return 0;} //------------------------------------------------------------------------------ //! Obtain the overall space usage of a cluster. Called only on manager nodes. //! //! @param Resp Object to hold response or error message. //! @param path Associated logical path for the space request. //! @param Info Associated cgi information for path. //! //! @return Space information as defined by the response to kYR_statfs. For a //! typical implementation see XrdCmsNode::do_StatFS(). //------------------------------------------------------------------------------ virtual int Space(XrdOucErrInfo &Resp, const char *path, XrdOucEnv *Info=0) = 0; //------------------------------------------------------------------------------ //! Report utilization of this server. This may be used in lieu of general //! performance metric reporting. For consistent results use only one method. //! //! @param util A value from 0 to 100 representing utilization. Values //! greater than 100 are set to be 100. //! @param alert When true the utilization is forcibly report to the //! cluster managers. Otherwise, reporting is done only when //! it will significantly change server selection. //------------------------------------------------------------------------------ virtual void Utilization(unsigned int util, bool alert=false) {(void)util; (void)alert;} //------------------------------------------------------------------------------ //! Constructor //! //! @param acting The type of function this object is performing. //------------------------------------------------------------------------------ enum Persona {amLocal, //!< Not affiliated with a cluster amRemote, //!< Am a manager and issue redirects amTarget //!< Am a server and field redirects }; XrdCmsClient(Persona acting) : myPersona(acting) {} //------------------------------------------------------------------------------ //! Destructor //------------------------------------------------------------------------------ virtual ~XrdCmsClient() {} protected: Persona myPersona; }; /******************************************************************************/ /* I n s t a n t i a t i o n M o d e F l a g s */ /******************************************************************************/ /*! The following instantiation mode flags are passed to the instantiator (see comments that follow). They may be or'd together, depending on which mode the cms client should operate. They are defined as follows: */ namespace XrdCms { enum {IsProxy = 1, //!< The role is proxy {plus one or more of the below} IsRedir = 2, //!< The role is manager and will redirect users IsTarget = 4, //!< The role is server and will be a redirection target IsMeta = 8 //!< The role is meta {plus one or more of the above} }; } /******************************************************************************/ /* C M S C l i e n t I n s t a n t i a t o r */ /******************************************************************************/ //------------------------------------------------------------------------------ //! Obtain an instance of a configured XrdCmsClient. //! //! The following extern "C" function is called to obtain an instance of the //! XrdCmsClient object. This is only used if the client is an actual plug-in //! as identified by the ofs.cmslib directive. Once the XrdCmsClient object //! is obtained, its Configure() method is called to initialize the object. //! //! @param logger -> XrdSysLogger to be tied to an XrdSysError object for //! any messages. //! @param opMode -> The operational mode as defined by the enum above. There //! are two general types of clients, IsRedir and IsTarget. //! The IsProxy and IsMeta modes are specialization of these //! two basic types. The plug-in must provide an instance of //! the one asked for whether or not they actually do anything. //! //! IsRedir clients are anything other than a data provider //! (i.e., data servers). These clients are expected //! to locate files and redirect a requestor to an //! actual data server. //! //! IsTarget clients are typically data providers (i.e., data //! servers) but may actually do other functions are //! are allowed to redirect as well. //! //! @param myPort -> The server's port number. //! @param theSS -> The object that implements he underlying storage system. //! This object may be passed for historic reasons. //! //! @return Success: a pointer to the appropriate object (IsRedir or IsTarget). //! //! Failure: a null pointer which causes initialization to fail. //------------------------------------------------------------------------------ class XrdOss; typedef XrdCmsClient *(*XrdCmsClient_t)(XrdSysLogger *, int, int, XrdOss *); /*! extern "C" XrdCmsClient *XrdCmsGetClient(XrdSysLogger *Logger, int opMode, int myPort XrdOss *theSS); */ //------------------------------------------------------------------------------ //! Obtain an instance of a default unconfigured XrdCmsClient. //! //! The following function may be called to obtain an instance of the default //! XrdCmsClient object. The Configure() method is *not* called before the //! object is returned. The parameters are the same as those for the function //! XrdCmsGetClient(), above. Note that you need not supply a pointer to the //! underlying storage system, as this is historic in nature. //! //! @return Success: a pointer to the appropriate object (IsRedir or IsTarget). //! //! Failure: a null pointer, neither ISRedir nor IsTarget has been //! specified or there is insufficient memory. //------------------------------------------------------------------------------ namespace XrdCms { XrdCmsClient *GetDefaultClient(XrdSysLogger *Logger, int opMode, int myPort ); } //------------------------------------------------------------------------------ //! Declare compilation version. //! //! Additionally, you *should* declare the xrootd version you used to compile //! your plug-in. //------------------------------------------------------------------------------ /*! #include "XrdVersion.hh" XrdVERSIONINFO(XrdCmsGetClient,); */ #endif