00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ad_panfs.h"
00010 #include <string.h>
00011 #include <pan_fs_client_cw_mode.h>
00012 #define TEMP_BUFFER_SIZE 64
00013
00014 void ADIOI_PANFS_Open(ADIO_File fd, int *error_code)
00015 {
00016 char* value;
00017 int perm, old_mask, amode, flag;
00018 static char myname[] = "ADIOI_PANFS_OPEN";
00019
00020 if (fd->perm == ADIO_PERM_NULL) {
00021 old_mask = umask(022);
00022 umask(old_mask);
00023 perm = ~old_mask & 0666;
00024 }
00025 else perm = fd->perm;
00026
00027 amode = 0;
00028 if (fd->access_mode & ADIO_CREATE)
00029 {
00030 pan_fs_client_layout_agg_type_t layout_type = PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT;
00031 unsigned long int layout_stripe_unit = 0;
00032 unsigned long int layout_parity_stripe_width = 0;
00033 unsigned long int layout_parity_stripe_depth = 0;
00034 unsigned long int layout_total_num_comps = 0;
00035 pan_fs_client_layout_visit_t layout_visit_policy = PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN;
00036 int myrank;
00037
00038 MPI_Comm_rank(fd->comm, &myrank);
00039
00040 *error_code = MPI_SUCCESS;
00041 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00042 ADIOI_Info_get(fd->info, "panfs_layout_type", MPI_MAX_INFO_VAL,
00043 value, &flag);
00044 if (flag) {
00045 layout_type = strtoul(value,NULL,10);
00046 }
00047 ADIOI_Info_get(fd->info, "panfs_layout_stripe_unit", MPI_MAX_INFO_VAL,
00048 value, &flag);
00049 if (flag) {
00050 layout_stripe_unit = strtoul(value,NULL,10);
00051 }
00052 ADIOI_Info_get(fd->info, "panfs_layout_total_num_comps", MPI_MAX_INFO_VAL,
00053 value, &flag);
00054 if (flag) {
00055 layout_total_num_comps = strtoul(value,NULL,10);
00056 }
00057 ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_width", MPI_MAX_INFO_VAL,
00058 value, &flag);
00059 if (flag) {
00060 layout_parity_stripe_width = strtoul(value,NULL,10);
00061 }
00062 ADIOI_Info_get(fd->info, "panfs_layout_parity_stripe_depth", MPI_MAX_INFO_VAL,
00063 value, &flag);
00064 if (flag) {
00065 layout_parity_stripe_depth = strtoul(value,NULL,10);
00066 }
00067 ADIOI_Info_get(fd->info, "panfs_layout_visit_policy", MPI_MAX_INFO_VAL,
00068 value, &flag);
00069 if (flag) {
00070 layout_visit_policy = strtoul(value,NULL,10);
00071 }
00072 ADIOI_Free(value);
00073
00074 amode = amode | O_CREAT;
00075
00076 if ((layout_type < PAN_FS_CLIENT_LAYOUT_TYPE__DEFAULT) ||
00077 (layout_type > PAN_FS_CLIENT_LAYOUT_TYPE__RAID10))
00078 {
00079 FPRINTF(stderr, "%s: panfs_layout_type is not a valid value: %u.\n", myname, layout_type);
00080 MPI_Abort(MPI_COMM_WORLD, 1);
00081 }
00082 if ((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) &&
00083 ((layout_stripe_unit == 0) || (layout_total_num_comps == 0)))
00084 {
00085 if(layout_stripe_unit == 0)
00086 {
00087 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);
00088 }
00089 if(layout_total_num_comps == 0)
00090 {
00091 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);
00092 }
00093 MPI_Abort(MPI_COMM_WORLD, 1);
00094 }
00095 if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE)
00096 {
00097 if ((layout_stripe_unit == 0) ||
00098 (layout_parity_stripe_width == 0) ||
00099 (layout_parity_stripe_depth == 0) ||
00100 (layout_total_num_comps == 0))
00101 {
00102 if(layout_stripe_unit == 0)
00103 {
00104 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);
00105 }
00106 if(layout_total_num_comps == 0)
00107 {
00108 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);
00109 }
00110 if(layout_parity_stripe_width == 0)
00111 {
00112 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);
00113 }
00114 if(layout_parity_stripe_depth == 0)
00115 {
00116 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);
00117 }
00118 MPI_Abort(MPI_COMM_WORLD, 1);
00119 }
00120 if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) ||
00121 (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET))
00122 {
00123 FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy);
00124 MPI_Abort(MPI_COMM_WORLD, 1);
00125 }
00126 }
00127 if (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)
00128 {
00129 if ((layout_stripe_unit == 0) || (layout_total_num_comps == 0))
00130 {
00131 if(layout_stripe_unit == 0)
00132 {
00133 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);
00134 }
00135 if(layout_total_num_comps == 0)
00136 {
00137 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);
00138 }
00139 MPI_Abort(MPI_COMM_WORLD, 1);
00140 }
00141 if ((layout_visit_policy < PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN) ||
00142 (layout_visit_policy > PAN_FS_CLIENT_LAYOUT_VISIT__ROUND_ROBIN_WITH_HASHED_OFFSET))
00143 {
00144 FPRINTF(stderr, "%s: panfs_layout_visit_policy is not a valid value: %u.\n", myname, layout_visit_policy);
00145 MPI_Abort(MPI_COMM_WORLD, 1);
00146 }
00147 }
00148
00149
00150
00151
00152 if((layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0) || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE)
00153 || (layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)) {
00154 pan_fs_client_layout_create_args_t file_create_args;
00155 int fd_dir;
00156 char* slash;
00157 struct stat stat_buf;
00158 int err;
00159 char *path;
00160
00161
00162
00163
00164
00165
00166
00167
00168 err = stat(fd->filename,&stat_buf);
00169 if((err == -1) && (errno != ENOENT))
00170 {
00171 FPRINTF(stderr,"%s: Unexpected I/O Error calling stat() on PanFS file: %s.\n", myname, strerror(errno));
00172 MPI_Abort(MPI_COMM_WORLD, 1);
00173 }
00174 else if (err == 0)
00175 {
00176 FPRINTF(stderr,"%s: Cannot create PanFS file with ioctl when file already exists.\n", myname);
00177 MPI_Abort(MPI_COMM_WORLD, 1);
00178 }
00179 else
00180 {
00181
00182
00183 path = ADIOI_Strdup(fd->filename);
00184 slash = strrchr(path, '/');
00185 if (!slash)
00186 ADIOI_Strncpy(path, ".", 2);
00187 else {
00188 if (slash == path)
00189 *(path + 1) = '\0';
00190 else *slash = '\0';
00191 }
00192
00193
00194 bzero(&file_create_args,sizeof(pan_fs_client_layout_create_args_t));
00195
00196 fd_dir = open(path, O_RDONLY);
00197 if (fd_dir < 0) {
00198 FPRINTF(stderr, "%s: I/O Error opening parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno));
00199 MPI_Abort(MPI_COMM_WORLD, 1);
00200 }
00201 else
00202 {
00203 char *file_name_ptr = fd->filename;
00204 slash = strrchr(fd->filename, '/');
00205 if (slash)
00206 {
00207 file_name_ptr = slash + 1;
00208 }
00209
00210 file_create_args.mode = perm;
00211 file_create_args.version = PAN_FS_CLIENT_LAYOUT_VERSION;
00212 file_create_args.flags = PAN_FS_CLIENT_LAYOUT_CREATE_F__NONE;
00213 ADIOI_Strncpy(file_create_args.filename, file_name_ptr, strlen(fd->filename)+1);
00214 file_create_args.layout.agg_type = layout_type;
00215 file_create_args.layout.layout_is_valid = 1;
00216 if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE)
00217 {
00218 file_create_args.layout.u.raid1_5_parity_stripe.total_num_comps = layout_total_num_comps;
00219 file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_width = layout_parity_stripe_width;
00220 file_create_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth = layout_parity_stripe_depth;
00221 file_create_args.layout.u.raid1_5_parity_stripe.stripe_unit = layout_stripe_unit;
00222 file_create_args.layout.u.raid1_5_parity_stripe.layout_visit_policy = layout_visit_policy;
00223 }
00224 else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID0)
00225 {
00226 file_create_args.layout.u.raid0.total_num_comps = layout_total_num_comps;
00227 file_create_args.layout.u.raid0.stripe_unit = layout_stripe_unit;
00228 }
00229 else if(layout_type == PAN_FS_CLIENT_LAYOUT_TYPE__RAID10)
00230 {
00231 file_create_args.layout.u.raid10.total_num_comps = layout_total_num_comps;
00232 file_create_args.layout.u.raid10.stripe_unit = layout_stripe_unit;
00233 file_create_args.layout.u.raid10.layout_visit_policy = layout_visit_policy;
00234 }
00235 err = ioctl(fd_dir, PAN_FS_CLIENT_LAYOUT_CREATE_FILE, &file_create_args);
00236 if (err < 0) {
00237 FPRINTF(stderr, "%s: I/O Error doing ioctl on parent directory to create PanFS file using ioctl: %s.\n", myname, strerror(errno));
00238 MPI_Abort(MPI_COMM_WORLD, 1);
00239 }
00240 err = close(fd_dir);
00241 }
00242 ADIOI_Free(path);
00243 }
00244 }
00245 else
00246 {
00247 int create_fd = open(fd->filename,amode,perm);
00248 if(create_fd != -1)
00249 {
00250 close(create_fd);
00251 }
00252 else
00253 {
00254 FPRINTF(stderr, "%s: I/O Error creating PanFS file using open: %s.\n", myname, strerror(errno));
00255 MPI_Abort(MPI_COMM_WORLD, 1);
00256 }
00257 }
00258 }
00259 if (fd->access_mode & ADIO_RDONLY)
00260 amode = amode | O_RDONLY;
00261 if (fd->access_mode & ADIO_WRONLY)
00262 amode = amode | O_WRONLY;
00263 if (fd->access_mode & ADIO_RDWR)
00264 amode = amode | O_RDWR;
00265 if (fd->access_mode & ADIO_EXCL)
00266 amode = amode | O_EXCL;
00267
00268 value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
00269 ADIOI_Info_get(fd->info, "panfs_concurrent_write", MPI_MAX_INFO_VAL,
00270 value, &flag);
00271 if (flag) {
00272 unsigned long int concurrent_write = strtoul(value,NULL,10);
00273 if(concurrent_write == 1)
00274 {
00275 amode = amode | O_CONCURRENT_WRITE;
00276 }
00277 }
00278 ADIOI_Free(value);
00279
00280 fd->fd_sys = open(fd->filename, amode, perm);
00281 fd->fd_direct = -1;
00282
00283 if (fd->fd_sys != -1)
00284 {
00285 int rc;
00286 char temp_buffer[TEMP_BUFFER_SIZE];
00287 pan_fs_client_layout_query_args_t file_query_args;
00288 bzero(&file_query_args,sizeof(pan_fs_client_layout_query_args_t));
00289 file_query_args.version = PAN_FS_CLIENT_LAYOUT_VERSION;
00290 rc = ioctl(fd->fd_sys, PAN_FS_CLIENT_LAYOUT_QUERY_FILE, &file_query_args);
00291 if (rc < 0)
00292 {
00293
00294 ADIOI_Info_set(fd->info, "panfs_layout_type", "PAN_FS_CLIENT_LAYOUT_TYPE__INVALID");
00295 }
00296 else
00297 {
00298 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.agg_type);
00299 ADIOI_Info_set(fd->info, "panfs_layout_type", temp_buffer);
00300 if (file_query_args.layout.layout_is_valid == 1)
00301 {
00302 switch (file_query_args.layout.agg_type)
00303 {
00304 case PAN_FS_CLIENT_LAYOUT_TYPE__RAID0:
00305 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.stripe_unit);
00306 ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
00307 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid0.total_num_comps);
00308 ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
00309 break;
00310 case PAN_FS_CLIENT_LAYOUT_TYPE__RAID1_5_PARITY_STRIPE:
00311 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.stripe_unit);
00312 ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
00313 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_width);
00314 ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_width", temp_buffer);
00315 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.parity_stripe_depth);
00316 ADIOI_Info_set(fd->info, "panfs_layout_parity_stripe_depth", temp_buffer);
00317 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.total_num_comps);
00318 ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
00319 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid1_5_parity_stripe.layout_visit_policy);
00320 ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer);
00321 break;
00322 case PAN_FS_CLIENT_LAYOUT_TYPE__RAID10:
00323 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.stripe_unit);
00324 ADIOI_Info_set(fd->info, "panfs_layout_stripe_unit", temp_buffer);
00325 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.total_num_comps);
00326 ADIOI_Info_set(fd->info, "panfs_layout_total_num_comps", temp_buffer);
00327 ADIOI_Snprintf(temp_buffer,TEMP_BUFFER_SIZE,"%u",file_query_args.layout.u.raid10.layout_visit_policy);
00328 ADIOI_Info_set(fd->info, "panfs_layout_visit_policy", temp_buffer);
00329 break;
00330 default:
00331 break;
00332 }
00333 }
00334 }
00335 }
00336
00337 if ((fd->fd_sys != -1) && (fd->access_mode & ADIO_APPEND))
00338 fd->fp_ind = fd->fp_sys_posn = lseek(fd->fd_sys, 0, SEEK_END);
00339
00340 if (fd->fd_sys == -1) {
00341 if (errno == ENAMETOOLONG)
00342 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00343 MPIR_ERR_RECOVERABLE, myname,
00344 __LINE__, MPI_ERR_BAD_FILE,
00345 "**filenamelong",
00346 "**filenamelong %s %d",
00347 fd->filename,
00348 strlen(fd->filename));
00349 else if (errno == ENOENT)
00350 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00351 MPIR_ERR_RECOVERABLE, myname,
00352 __LINE__, MPI_ERR_NO_SUCH_FILE,
00353 "**filenoexist",
00354 "**filenoexist %s",
00355 fd->filename);
00356 else if (errno == ENOTDIR || errno == ELOOP)
00357 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00358 MPIR_ERR_RECOVERABLE,
00359 myname, __LINE__,
00360 MPI_ERR_BAD_FILE,
00361 "**filenamedir",
00362 "**filenamedir %s",
00363 fd->filename);
00364 else if (errno == EACCES) {
00365 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00366 MPIR_ERR_RECOVERABLE, myname,
00367 __LINE__, MPI_ERR_ACCESS,
00368 "**fileaccess",
00369 "**fileaccess %s",
00370 fd->filename );
00371 }
00372 else if (errno == EROFS) {
00373
00374 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00375 MPIR_ERR_RECOVERABLE, myname,
00376 __LINE__, MPI_ERR_READ_ONLY,
00377 "**ioneedrd", 0 );
00378 }
00379 else {
00380 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
00381 MPIR_ERR_RECOVERABLE, myname,
00382 __LINE__, MPI_ERR_IO, "**io",
00383 "**io %s", strerror(errno));
00384 }
00385 }
00386 else *error_code = MPI_SUCCESS;
00387 }