nfs-ganesha 1.4

api_symlink.c

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <fcntl.h>
00007 #include <u_signed64.h>
00008 #include <hpssclapiext.h>
00009 #include <api_internal.h>
00010 
00011 /*
00012  *  For determining if a returned access ticket is NULL.
00013  */
00014 
00015 TYPE_TOKEN_HPSS null_ticket;
00016 
00017 #if HPSS_MAJOR_VERSION < 7
00018 
00019 static int
00020 HPSSFSAL_Common_Symlink(apithrdstate_t * ThreadContext,
00021                         hpss_reqid_t RequestID,
00022                         ns_ObjHandle_t * ObjHandle,
00023                         TYPE_CRED_HPSS * Ucred,
00024                         char *Path,
00025                         api_cwd_stack_t * CwdStack,
00026                         char *Contents,
00027                         ns_ObjHandle_t * HandleOut, hpss_Attrs_t * AttrsOut)
00028 {
00029   static char function_name[] = "HPSSFSAL_Common_Symlink";
00030 
00031 #if HPSS_MAJOR_VERSION == 5
00032   volatile long error = 0;      /* return error */
00033 #elif HPSS_MAJOR_VERSION >= 6
00034   signed32 error = 0;           /* return error */
00035 #endif
00036 
00037   call_type_t call_type;        /* interface to call */
00038   TYPE_TOKEN_HPSS ta;           /* security token */
00039   ns_ObjHandle_t parent_handle; /* parent object handle */
00040   u_signed64 parent_attr_bits;  /* object attribute bits */
00041   hpss_Attrs_t parent_attrs;    /* new object attributes */
00042   char *file;                   /* name of the new object */
00043   char *parent;                 /* name of existing parent */
00044   ns_ObjHandle_t new_handle;    /* new object handle */
00045   ns_ObjHandle_t ret_handle;    /* returned new object handle */
00046   u_signed64 new_attr_bits;     /* object attribute bits */
00047   hpss_Attrs_t new_attrs;       /* new object attributes */
00048 
00049   /*
00050    * Allocate memory for object name and parent
00051    */
00052 
00053   file = (char *)malloc(HPSS_MAX_FILE_NAME);
00054   if(file == NULL)
00055     return (-ENOMEM);
00056 
00057   parent = (char *)malloc(HPSS_MAX_PATH_NAME);
00058   if(parent == NULL)
00059     {
00060       free(file);
00061       return (-ENOMEM);
00062     }
00063 
00064   /*
00065    * Divide the object component from the rest of the path
00066    */
00067 
00068   error = API_DivideFilePath(Path, parent, file);
00069 
00070   free(parent);
00071   if(error != 0)
00072     {
00073       free(file);
00074       return (error);
00075     }
00076 
00077   /*
00078    * Traverse the path to the parent and get
00079    * it's attributes and handle.
00080    */
00081 
00082   (void)memset(&ta, 0, sizeof(TYPE_TOKEN_HPSS));
00083   (void)memset(&parent_handle, 0, sizeof(parent_handle));
00084   (void)memset(&parent_attrs, 0, sizeof(parent_attrs));
00085 
00086   parent_attr_bits = API_AddRegisterValues(cast64m(0),
00087                                            CORE_ATTR_TYPE,
00088                                            CORE_ATTR_FILESET_TYPE,
00089                                            CORE_ATTR_FILESET_ID,
00090                                            CORE_ATTR_GATEWAY_UUID,
00091                                            CORE_ATTR_DM_HANDLE,
00092                                            CORE_ATTR_DM_HANDLE_LENGTH, -1);
00093 
00094   error = API_TraversePath(ThreadContext,
00095                            RequestID,
00096                            Ucred,
00097                            ObjHandle,
00098                            Path,
00099                            CwdStack,
00100                            API_CHASE_ALL,
00101                            0,
00102                            0,
00103                            cast64m(0),
00104                            parent_attr_bits,
00105                            API_NULL_CWD_STACK,
00106                            NULL, NULL, &parent_handle, &parent_attrs, &ta, NULL, NULL);
00107 
00108   if(error == 0)
00109     error = -EEXIST;
00110   else if(error == -ENOENT && memcmp(&ta, &null_ticket, sizeof(ta)) != 0)
00111     error = 0;
00112   else
00113     {
00114       API_DEBUG_FPRINTF(DebugFile, &RequestID,
00115                         "%s: Could not find object.\n", function_name);
00116     }
00117 
00118   if(error == 0)
00119     {
00120 
00121       /*
00122        * Call this function to determine which interface
00123        * to call (DMAP Gateway or the Core Server) depending
00124        * on if the object is DMAP mapped, which version of
00125        * the library this is, what type of DMAP file set
00126        * this is (sync or backup).
00127        */
00128 #if HPSS_MAJOR_VERSION == 5
00129       call_type = API_DetermineCall(parent_attrs.FilesetType, (long *)&error);
00130 #elif HPSS_MAJOR_VERSION == 6
00131       call_type = API_DetermineCall(parent_attrs.FilesetType, &error);
00132 #endif
00133 
00134       if(call_type == API_CALL_DMG)
00135         {
00136           /*
00137            * Here we are being called by a non-gateway client and
00138            * trying to link a object in a DMAP file set.
00139            */
00140 
00141 #if defined (API_DMAP_SUPPORT) && !defined (API_DMAP_GATEWAY)
00142 
00143           error = API_dmg_Symlink(ThreadContext, RequestID, Ucred, &parent_attrs.GatewayUUID, parent_attrs.FilesetId, parent_attrs.DMHandle, parent_attrs.DMHandleLength, file, Contents, NULL, /* not used */
00144                                   NULL);        /* not used */
00145 #else
00146           error = EACCES;
00147           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00148                             "%s: No dmap support compiled in.\n", function_name);
00149 #endif
00150 
00151         }
00152       else if(call_type == API_CALL_HPSS)
00153         {
00154           /*
00155            * Here we are being call by either a gateway client
00156            * or a non-gateway client trying to link a object
00157            * in a non-DMAP file set.
00158            */
00159 
00160           error = API_core_MkSymLink(ThreadContext,
00161                                      RequestID,
00162                                      Ucred,
00163                                      &parent_handle,
00164                                      file,
00165                                      &parent_attrs.FilesetId, Contents, &new_handle);
00166 
00167           if(error != 0)
00168             {
00169               API_DEBUG_FPRINTF(DebugFile, &RequestID,
00170                                 "%s: can't make symlink, error=%d\n,",
00171                                 function_name, error);
00172             }
00173 
00174         }
00175 
00176       /*
00177        * Call type is not DMG or HPSS.
00178        */
00179 
00180       else
00181         {
00182           if(error == 0)
00183             error = EIO;
00184 
00185           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00186                             "%s: Bad case from DetermineCall().\n", function_name);
00187         }
00188 
00189       /*
00190        * If requested, return the vattr for the newly created
00191        * link
00192        */
00193 
00194       if(error == 0 && AttrsOut != (hpss_Attrs_t *) NULL)
00195         {
00196           new_attr_bits = cast64m(0);
00197           new_attr_bits = API_AddAllRegisterValues(MAX_CORE_ATTR_INDEX);
00198           (void)memset(&ret_handle, 0, sizeof(ret_handle));
00199           (void)memset(&new_attrs, 0, sizeof(new_attrs));
00200           (void)memset(&ta, 0, sizeof(ta));
00201 
00202           error = API_TraversePath(ThreadContext,
00203                                    RequestID,
00204                                    Ucred,
00205                                    &new_handle,
00206                                    NULL,
00207                                    API_NULL_CWD_STACK,
00208                                    API_CHASE_NONE,
00209                                    0,
00210                                    0,
00211                                    new_attr_bits,
00212                                    cast64m(0),
00213                                    API_NULL_CWD_STACK,
00214                                    &ret_handle, &new_attrs, NULL, NULL, &ta, NULL, NULL);
00215 
00216           if(error != 0)
00217             {
00218               API_DEBUG_FPRINTF(DebugFile, &RequestID,
00219                                 "%s: Could not get attributes.\n", function_name);
00220             }
00221           else
00222             {
00223               *AttrsOut = new_attrs;
00224               *HandleOut = new_handle;
00225             }
00226         }
00227     }
00228 
00229   free(file);
00230   return (error);
00231 }
00232 #else                           /* from v7 */
00233 
00234 static int
00235 HPSSFSAL_Common_Symlink(apithrdstate_t * ThreadContext,
00236                         hpss_reqid_t RequestID,
00237                         ns_ObjHandle_t * ObjHandle,
00238                         sec_cred_t * Ucred,
00239                         char *Path,
00240                         api_cwd_stack_t * CwdStack,
00241                         char *Contents,
00242                         ns_ObjHandle_t * HandleOut, hpss_Attrs_t * AttrsOut)
00243 {
00244   static char function_name[] = "Common_Symlink";
00245   signed32 error = 0;           /* return error */
00246   ns_ObjHandle_t parent_handle; /* parent object handle */
00247   char *file;                   /* name of the new object */
00248   char *parentpath;             /* name of existing parent */
00249   hpss_AttrBits_t attr_bits;    /* parent attributes bits */
00250   hpss_Attrs_t attrs;           /* parent attributes */
00251   ns_ObjHandle_t *hndl_ptr = ObjHandle; /* parent handle pointer */
00252   ns_ObjHandle_t new_handle;    /* new object handle */
00253   ns_ObjHandle_t ret_handle;    /* returned new object handle */
00254   u_signed64 new_attr_bits;     /* object attribute bits */
00255   hpss_Attrs_t new_attrs;       /* new object handle */
00256 
00257   /*
00258    * Allocate memory for object name and parent name
00259    */
00260 
00261   file = (char *)malloc(HPSS_MAX_FILE_NAME);
00262   if(file == NULL)
00263     return (-ENOMEM);
00264 
00265   parentpath = (char *)malloc(HPSS_MAX_PATH_NAME);
00266   if(parentpath == NULL)
00267     {
00268       free(file);
00269       return (-ENOMEM);
00270     }
00271 
00272   /*
00273    * Divide the object component from the rest of the path
00274    */
00275 
00276   if((error = API_DivideFilePath(Path, parentpath, file)) != 0)
00277     {
00278       free(file);
00279       free(parentpath);
00280       return (error);
00281     }
00282 
00283   if(API_PATH_NEEDS_TRAVERSAL(parentpath))
00284     {
00285       /*
00286        * If there is a path provided then, then lookup
00287        * the parent handle
00288        */
00289 
00290       attr_bits = API_AddRegisterValues(cast64m(0), CORE_ATTR_TYPE, -1);
00291 
00292       memset(&parent_handle, 0, sizeof(parent_handle));
00293       memset(&attrs, '\0', sizeof(attrs));
00294 
00295       /*
00296        * Traverse the path to the parent and get it's handle.
00297        */
00298 
00299       error = API_TraversePath(ThreadContext,
00300                                RequestID,
00301                                Ucred,
00302                                ObjHandle,
00303                                parentpath,
00304                                CwdStack,
00305                                API_CHASE_ALL,
00306                                0,
00307                                0,
00308                                attr_bits,
00309                                cast64m(0),
00310                                API_NULL_CWD_STACK,
00311                                &parent_handle,
00312                                &attrs,
00313                                (ns_ObjHandle *) NULL, (hpss_Attrs_t *) NULL, NULL, NULL);
00314 
00315       if(error == 0)
00316         {
00317           if(attrs.Type != NS_OBJECT_TYPE_DIRECTORY)
00318             error = -ENOTDIR;
00319           else
00320             {
00321               hndl_ptr = &parent_handle;
00322             }
00323         }
00324     }
00325   else if(API_PATH_IS_ROOT(parentpath))
00326     {
00327       /* If needed, use the root handle */
00328       error = API_InitRootHandle(ThreadContext, RequestID, &hndl_ptr);
00329     }
00330 
00331   if(error == 0)
00332     {
00333       error = API_core_MkSymLink(ThreadContext,
00334                                  RequestID, Ucred, hndl_ptr, file, Contents, &new_handle);
00335 
00336       if(error != 0)
00337         {
00338           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00339                             "%s: can't make symlink, error=%d\n,", function_name, error);
00340         }
00341     }
00342 
00343   /*
00344    * If requested, return the vattr for the newly created link
00345    */
00346 
00347   if(error == 0 && AttrsOut != (hpss_Attrs_t *) NULL)
00348     {
00349       new_attr_bits = API_VAttrAttrBits;
00350       (void)memset(&ret_handle, 0, sizeof(ret_handle));
00351       (void)memset(&new_attrs, 0, sizeof(new_attrs));
00352 
00353       error = API_TraversePath(ThreadContext,
00354                                RequestID,
00355                                Ucred,
00356                                &new_handle,
00357                                NULL,
00358                                API_NULL_CWD_STACK,
00359                                API_CHASE_NONE,
00360                                0,
00361                                0,
00362                                new_attr_bits,
00363                                cast64m(0),
00364                                API_NULL_CWD_STACK,
00365                                &ret_handle, &new_attrs, NULL, NULL, NULL, NULL);
00366 
00367       if(error != 0)
00368         {
00369           API_DEBUG_FPRINTF(DebugFile, &RequestID,
00370                             "%s: Could not get attributes.\n", function_name);
00371         }
00372       else
00373         {
00374           *AttrsOut = new_attrs;
00375           *HandleOut = ret_handle;
00376         }
00377     }
00378 
00379   free(file);
00380   free(parentpath);
00381 
00382   return (error);
00383 }
00384 
00385 #endif
00386 
00387 int HPSSFSAL_SymlinkHandle(ns_ObjHandle_t * ObjHandle,  /* IN - Handle of existing file */
00388                            char *Contents,      /* IN - Desired contents of the link */
00389                            char *Path,  /* IN - New name of the symbolic link */
00390                            TYPE_CRED_HPSS * Ucred,      /* IN - pointer to user credentials */
00391                            ns_ObjHandle_t * HandleOut,  /* OUT - Handle of crfeated link */
00392                            hpss_Attrs_t * AttrsOut)     /* OUT - symbolic link attributes */
00393 {
00394   long error = 0;
00395   apithrdstate_t *threadcontext;
00396   hpss_reqid_t rqstid;
00397   TYPE_CRED_HPSS *ucred_ptr;
00398 
00399   API_ENTER("HPSSFSAL_SymlinkHandle");
00400 
00401   /*
00402    *  Initialize the thread if not already initialized.
00403    *  Get a pointer back to the thread specific context.
00404    */
00405 
00406   error = API_ClientAPIInit(&threadcontext);
00407   if(error != 0)
00408     API_RETURN(error);
00409 
00410   /*
00411    *  Check that the object handle is not NULL.
00412    */
00413 
00414   if(ObjHandle == (ns_ObjHandle_t *) NULL)
00415     API_RETURN(-EINVAL);
00416 
00417   /*
00418    *  We need an path to create the new symlink
00419    */
00420 
00421   if(Path == NULL)
00422     API_RETURN(-EFAULT);
00423 
00424   if(*Path == '\0')
00425     API_RETURN(-ENOENT);
00426 
00427   /*
00428    * Need to have contents for the symlink
00429    */
00430 
00431   if(Contents == NULL)
00432     API_RETURN(-EFAULT);
00433 
00434   /*
00435    *  If user credentials were not passed, use the ones in the
00436    *  current thread context.
00437    */
00438 
00439   if(Ucred == (TYPE_CRED_HPSS *) NULL)
00440     ucred_ptr = &threadcontext->UserCred;
00441   else
00442     ucred_ptr = Ucred;
00443 
00444   /*
00445    *  Get a valid request id.
00446    */
00447 
00448   rqstid = API_GetUniqueRequestID();
00449 
00450   /*
00451    * Call HPSSFSAL_Common_Symlink() to perform the majority of the common symbolic 
00452    * link processing.
00453    */
00454 
00455   error = HPSSFSAL_Common_Symlink(threadcontext,
00456                                   rqstid,
00457                                   ObjHandle,
00458                                   ucred_ptr,
00459                                   Path,
00460                                   API_NULL_CWD_STACK, Contents, HandleOut, AttrsOut);
00461 
00462   API_RETURN(error);
00463 }