root/ompi/mca/io/romio321/romio/adio/ad_panfs/ad_panfs_open.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_PANFS_Open

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *   ad_panfs_open.c
   4  *
   5  *   Copyright (C) 2001 University of Chicago.
   6  *   See COPYRIGHT notice in top-level directory.
   7  */
   8 
   9 #include "ad_panfs.h"
  10 #include <string.h>
  11 #include <pan_fs_client_cw_mode.h>
  12 #define TEMP_BUFFER_SIZE 64
  13 
  14 void ADIOI_PANFS_Open(ADIO_File fd, int *error_code)
  15 {
  16     char* value;
  17     int perm, old_mask, amode, flag;
  18     static char myname[] = "ADIOI_PANFS_OPEN";
  19 
  20     if (fd->perm == ADIO_PERM_NULL) {
  21         old_mask = umask(022);
  22         umask(old_mask);
  23         perm = ~old_mask & 0666;
  24     }
  25     else perm = fd->perm;
  26 
  27     amode = 0;
  28     if (fd->access_mode & ADIO_CREATE)
  29     {
  30         pan_fs_client_layout_agg_type_t layout_type = PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT;
  31         unsigned long int layout_stripe_unit = 0;
  32         unsigned long int layout_parity_stripe_width = 0;
  33         unsigned long int layout_parity_stripe_depth = 0; 
  34         unsigned long int layout_total_num_comps = 0;
  35         pan_fs_client_layout_visit_t layout_visit_policy  = PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN;
  36         int myrank;
  37 
  38         MPI_Comm_rank(fd->comm, &myrank);
  39 
  40         *error_code = MPI_SUCCESS;
  41         value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
  42         ADIOI_Info_get(fd->info, "panfs_layout_type", MPI_MAX_INFO_VAL, 
  43                  value, &flag);
  44         if (flag) {
  45             layout_type = strtoul(value,NULL,10);
  46         }
  47         ADIOI_Info_get(fd->info, "panfs_layout_stripe_unit", MPI_MAX_INFO_VAL, 
  48                  value, &flag);
  49         if (flag) {
  50             layout_stripe_unit = strtoul(value,NULL,10);
  51         }
  52         ADIOI_Info_get(fd->info, "panfs_layout_total_num_comps", MPI_MAX_INFO_VAL, 
  53                  value, &flag);
  54         if (flag) {
  55             layout_total_num_comps = strtoul(value,NULL,10);
  56         }
  57         ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_width", MPI_MAX_INFO_VAL, 
  58                  value, &flag);
  59         if (flag) {
  60             layout_parity_stripe_width = strtoul(value,NULL,10);
  61         }
  62         ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_depth", MPI_MAX_INFO_VAL, 
  63                  value, &flag);
  64         if (flag) {
  65             layout_parity_stripe_depth = strtoul(value,NULL,10);
  66         }
  67         ADIOI_Info_get(fd->info, "panfs_layout_visit_policy", MPI_MAX_INFO_VAL, 
  68                  value, &flag);
  69         if (flag) {
  70             layout_visit_policy = strtoul(value,NULL,10);
  71         }
  72         ADIOI_Free(value);
  73 
  74         amode = amode | O_CREAT;
  75         /* Check for valid set of hints */
  76         if ((layout_type < PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT) ||
  77            (layout_type > PAN_FS_CLIENT_LAYOUT_TYPE__RAID10))
  78         {
  79             FPRINTF(stderr, "%s: panfs_layout_type is not a valid value: %u.\n", myname, layout_type);
  80             MPI_Abort(MPI_COMM_WORLD, 1);
  81         }
  82         if ((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) &&
  83            ((layout_stripe_unit == 0) || (layout_total_num_comps == 0)))
  84         {
  85             if(layout_stripe_unit == 0)
  86             {
  87                 FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID0 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
  88             }
  89             if(layout_total_num_comps == 0)
  90             {
  91                 FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID0 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
  92             }
  93             MPI_Abort(MPI_COMM_WORLD, 1);
  94         }
  95         if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE)
  96         {
  97             if ((layout_stripe_unit == 0) ||
  98                (layout_parity_stripe_width == 0) ||
  99                (layout_parity_stripe_depth == 0) ||
 100                (layout_total_num_comps == 0))
 101             {
 102                 if(layout_stripe_unit == 0)
 103                 {
 104                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 105                 }
 106                 if(layout_total_num_comps == 0)
 107                 {
 108                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 109                 }
 110                 if(layout_parity_stripe_width == 0)
 111                 {
 112                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_parity_stripe_width hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 113                 }
 114                 if(layout_parity_stripe_depth == 0)
 115                 {
 116                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_parity_stripe_depth hint which is necessary to specify a valid RAID5 parity stripe layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 117                 }
 118                 MPI_Abort(MPI_COMM_WORLD, 1);
 119            }
 120            if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) ||
 121               (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET))
 122            {
 123                 FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy);
 124                 MPI_Abort(MPI_COMM_WORLD, 1);
 125            }
 126         }
 127         if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)
 128         {
 129             if ((layout_stripe_unit == 0) || (layout_total_num_comps == 0))
 130             {
 131                 if(layout_stripe_unit == 0)
 132                 {
 133                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_stripe_unit hint which is necessary to specify a valid RAID10 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 134                 }
 135                 if(layout_total_num_comps == 0)
 136                 {
 137                     FPRINTF(stderr, "%s: MPI_Info does not contain the panfs_layout_total_num_comps hint which is necessary to specify a valid RAID10 layout to the PAN_FS_CLIENT_LAYOUT_CREATE_FILE ioctl.\n", myname);
 138                 }
 139                 MPI_Abort(MPI_COMM_WORLD, 1);
 140             }
 141             if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) ||
 142               (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET))
 143             {
 144                 FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy);
 145                 MPI_Abort(MPI_COMM_WORLD, 1);
 146             }
 147         }
 148         /* Create the file via ioctl() or open(). ADIOI_PANFS_Open's caller 
 149          * already optimizes performance by only calling this function with
 150          * ADIO_CREATE on rank 0.  Therefore, we don't need to worry about 
 151          * implementing that optimization here. */
 152         if((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE) 
 153                 || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)) {
 154             pan_fs_client_layout_create_args_t file_create_args;    
 155             int fd_dir;
 156             char* slash;
 157             struct stat stat_buf;
 158             int err;
 159             char *path;
 160 
 161             /* Check that the file does not exist before
 162              * trying to create it.  The ioctl itself should
 163              * be able to handle this condition.  Currently,
 164              * the ioctl will return successfully if the file
 165              * has been previously created.  Filed bug 33862
 166              * to track the problem.
 167              */
 168             err = stat(fd->filename,&stat_buf);
 169             if((err == -1) && (errno != ENOENT))
 170             {
 171                 FPRINTF(stderr,"%s: Unexpected I/O Error calling stat() on PanFS file: %s.\n", myname, strerror(errno));
 172                 MPI_Abort(MPI_COMM_WORLD, 1);
 173             }
 174             else if (err == 0)
 175             {
 176                 FPRINTF(stderr,"%s: Cannot create PanFS file with ioctl when file already exists.\n", myname);
 177                 MPI_Abort(MPI_COMM_WORLD, 1);
 178             }
 179             else
 180             {
 181                 /* (err == -1) && (errno == ENOENT) */
 182                 /* File does not exist */
 183                 path = ADIOI_Strdup(fd->filename);
 184                 slash = strrchr(path, '/');
 185                 if (!slash)
 186                     ADIOI_Strncpy(path, ".", 2);
 187                 else {
 188                     if (slash == path) 
 189                         *(path + 1) = '\0';
 190                     else *slash = '\0';
 191                 }
 192 
 193                 /* create PanFS object */
 194                 memset(&file_create_args,0,sizeof(pan_fs_client_layout_create_args_t));
 195                 /* open directory */
 196                 fd_dir = open(path, O_RDONLY);
 197                 if (fd_dir < 0) {
 198                     FPRINTF(stderr, "%s: I/O Error opening parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno));
 199                     MPI_Abort(MPI_COMM_WORLD, 1);
 200                 }
 201                 else
 202                 {
 203                     char *file_name_ptr = fd->filename;
 204                     slash = strrchr(fd->filename, '/');
 205                     if (slash)
 206                     {
 207                         file_name_ptr = slash + 1;
 208                     }
 209                     /* create file in the directory */
 210                     file_create_args.mode = perm;
 211                     file_create_args.version = PAN_FS_CLIENT_LAYOUT_VERSION;
 212                     file_create_args.flags = PAN_FS_CLIENT_LAYOUT_CREATE_F__NONE;
 213                     ADIOI_Strncpy(file_create_args.filename, file_name_ptr, strlen(fd->filename)+1); 
 214                     file_create_args.layout.agg_type = layout_type;
 215                     file_create_args.layout.layout_is_valid = 1;
 216                     if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE)
 217                     {
 218                         file_create_args.layout.u.raid1_5_parity_stripe.total_num_comps = layout_total_num_comps;
 219                         file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_width   = layout_parity_stripe_width;
 220                         file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth   = layout_parity_stripe_depth;
 221                         file_create_args.layout.u.raid1_5_parity_stripe.stripe_unit     = layout_stripe_unit;
 222                         file_create_args.layout.u.raid1_5_parity_stripe.layout_visit_policy   = layout_visit_policy;
 223                     }
 224                     else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0)
 225                     {
 226                         file_create_args.layout.u.raid0.total_num_comps = layout_total_num_comps;
 227                         file_create_args.layout.u.raid0.stripe_unit     = layout_stripe_unit;
 228                     }
 229                     else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)
 230                     {
 231                         file_create_args.layout.u.raid10.total_num_comps     = layout_total_num_comps;
 232                         file_create_args.layout.u.raid10.stripe_unit         = layout_stripe_unit;
 233                         file_create_args.layout.u.raid10.layout_visit_policy = layout_visit_policy;
 234                     }
 235                     err = ioctl(fd_dir, PAN_FS_CLIENT_LAYOUT_CREATE_FILE, &file_create_args);
 236                     if (err < 0) {
 237                         FPRINTF(stderr, "%s: I/O Error doing ioctl on parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno));
 238                         MPI_Abort(MPI_COMM_WORLD, 1);
 239                     }
 240                     err = close(fd_dir);
 241                 }
 242                 ADIOI_Free(path);
 243             }
 244         }
 245         else
 246         {
 247             int create_fd = open(fd->filename,amode,perm);
 248             if(create_fd != -1)
 249             {
 250                 close(create_fd);
 251             }
 252             else
 253             {
 254                 FPRINTF(stderr, "%s: I/O Error creating PanFS file using open: %s.\n", myname, strerror(errno));
 255                 MPI_Abort(MPI_COMM_WORLD, 1);
 256             }
 257         }
 258     }
 259     if (fd->access_mode & ADIO_RDONLY)
 260         amode = amode | O_RDONLY;
 261     if (fd->access_mode & ADIO_WRONLY)
 262         amode = amode | O_WRONLY;
 263     if (fd->access_mode & ADIO_RDWR)
 264         amode = amode | O_RDWR;
 265     if (fd->access_mode & ADIO_EXCL)
 266         amode = amode | O_EXCL;
 267 
 268         value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
 269         ADIOI_Info_get(fd->info, "panfs_concurrent_write", MPI_MAX_INFO_VAL, 
 270                      value, &flag);
 271         if (flag) {
 272         unsigned long int concurrent_write = strtoul(value,NULL,10);
 273         if(concurrent_write == 1)
 274         {
 275             amode = amode | O_CONCURRENT_WRITE;
 276         }
 277         }
 278         ADIOI_Free(value);
 279 
 280     fd->fd_sys = open(fd->filename, amode, perm);
 281     fd->fd_direct = -1;
 282 
 283     if (fd->fd_sys != -1)
 284     {
 285         int rc;
 286         char temp_buffer[TEMP_BUFFER_SIZE];
 287         pan_fs_client_layout_query_args_t file_query_args;
 288         memset(&file_query_args,0,sizeof(pan_fs_client_layout_query_args_t));
 289         file_query_args.version = PAN_FS_CLIENT_LAYOUT_VERSION;
 290         rc = ioctl(fd->fd_sys, PAN_FS_CLIENT_LAYOUT_QUERY_FILE, &file_query_args);
 291         if (rc < 0)
 292         {
 293             /* Error - set layout type to unknown */
 294                 ADIOI_Info_set(fd->info, "panfs_layout_type", "PAN_FS_CLIENT_LAYOUT_TYPE__INVALID");
 295         }
 296         else 
 297         {
 298             ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.agg_type);
 299             ADIOI_Info_set(fd->info, "panfs_layout_type", temp_buffer);
 300             if (file_query_args.layout.layout_is_valid == 1)
 301             {
 302                 switch (file_query_args.layout.agg_type)
 303                 {
 304                     case PAN_FS_CLIENT_LAYOUT_TYPE__RAID0:
 305                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.stripe_unit);
 306                         ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
 307                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.total_num_comps);
 308                         ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
 309                         break;
 310                     case PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE:
 311                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.stripe_unit);
 312                         ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
 313                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_width);
 314                         ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_width", temp_buffer);
 315                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth);
 316                         ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_depth", temp_buffer);
 317                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.total_num_comps);
 318                         ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
 319                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.layout_visit_policy);
 320                         ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer);
 321                         break;
 322                     case PAN_FS_CLIENT_LAYOUT_TYPE__RAID10:
 323                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.stripe_unit);
 324                         ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
 325                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.total_num_comps);
 326                         ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
 327                         ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.layout_visit_policy);
 328                         ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer);
 329                         break;
 330                     case PAN_FS_CLIENT_LAYOUT_TYPE__INVALID:
 331                     case PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT:
 332                         MPI_Info_set(fd->info, "panfs_layout_type",
 333                                 "PAN_FS_CLIENT_LAYOUT_TYPE__INVALID");
 334                   default:
 335                           break;
 336                 }
 337             }
 338         }
 339     }
 340 
 341     if ((fd->fd_sys != -1) && (fd->access_mode & ADIO_APPEND))
 342         fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END);
 343 
 344     if (fd->fd_sys == -1) {
 345         *error_code = ADIOI_Err_create_code(myname, fd->filename, errno);
 346     }
 347     else *error_code = MPI_SUCCESS;
 348 }

/* [<][>][^][v][top][bottom][index][help] */