int nc__create_mp(const char * path, int ioflags, size_t initialsz, int basepe, size_t *chunksizehintp, int *ncid_ptr) { NC *ncp; int status; void *xp = NULL; int sizeof_off_t = 0; #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif ncp = new_NC(chunksizehintp); if(ncp == NULL) return NC_ENOMEM; #if defined(LOCKNUMREC) /* && _CRAYMPP */ if (status = NC_init_pe(ncp, basepe)) { return status; } #else /* * !_CRAYMPP, only pe 0 is valid */ if(basepe != 0) return NC_EINVAL; #endif assert(ncp->flags == 0); /* Apply default create format. */ if (default_create_format == NC_FORMAT_64BIT) ioflags |= NC_64BIT_OFFSET; if (fIsSet(ioflags, NC_64BIT_OFFSET)) { fSet(ncp->flags, NC_64BIT_OFFSET); sizeof_off_t = 8; } else { sizeof_off_t = 4; } assert(ncp->xsz == ncx_len_NC(ncp,sizeof_off_t)); status = ncio_create(path, ioflags, initialsz, 0, ncp->xsz, &ncp->chunk, &ncp->nciop, &xp); if(status != NC_NOERR) { /* translate error status */ if(status == EEXIST) status = NC_EEXIST; goto unwind_alloc; } fSet(ncp->flags, NC_CREAT); if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) { /* * NC_SHARE implies sync up the number of records as well. * (File format version one.) * Note that other header changes are not shared * automatically. Some sort of IPC (external to this package) * would be used to trigger a call to nc_sync(). */ fSet(ncp->flags, NC_NSYNC); } status = ncx_put_NC(ncp, &xp, sizeof_off_t, ncp->xsz); if(status != NC_NOERR) goto unwind_ioc; add_to_NCList(ncp); if(chunksizehintp != NULL) *chunksizehintp = ncp->chunk; *ncid_ptr = ncp->nciop->fd; return NC_NOERR; unwind_ioc: (void) ncio_close(ncp->nciop, 1); /* N.B.: unlink */ ncp->nciop = NULL; /*FALLTHRU*/ unwind_alloc: free_NC(ncp); return status; }
/* See ncd3dispatch.c for other version */ int NCD3_open(const char * path, int mode, int basepe, size_t *chunksizehintp, int useparallel, void* mpidata, NC_Dispatch* dispatch, NC** ncpp) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; NC* drno = NULL; NCDAPCOMMON* dapcomm = NULL; const char* value; char* tmpname = NULL; if(!nc3dinitialized) nc3dinitialize(); if(path == NULL) return NC_EDAPURL; if(dispatch == NULL) PANIC("NC3D_open: no dispatch table"); /* Setup our NC and NCDAPCOMMON state*/ drno = (NC*)calloc(1,sizeof(NC)); if(drno == NULL) {ncstat = NC_ENOMEM; goto done;} /* compute an ncid */ ncstat = add_to_NCList(drno); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON)); if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;} drno->dispatch = dispatch; drno->dispatchdata = dapcomm; dapcomm->controller = (NC*)drno; dapcomm->cdf.separator = "."; dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT; dapcomm->cdf.cache = createnccache(); #ifdef HAVE_GETRLIMIT { struct rlimit rl; if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) { dapcomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2); } } #endif #ifdef OCCOMPILEBYDEFAULT /* set the compile flag by default */ dapcomm->oc.rawurltext = (char*)emalloc(strlen(path)+strlen("[compile]")+1); strcpy(dapcomm->oc.rawurltext,"[compile]"); strcat(dapcomm->oc.rawurltext, path); #else dapcomm->oc.rawurltext = strdup(path); #endif nc_uriparse(dapcomm->oc.rawurltext,&dapcomm->oc.url); /* parse the client parameters */ nc_uridecodeparams(dapcomm->oc.url); if(!constrainable34(dapcomm->oc.url)) SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE); /* Use libsrc code for storing metadata */ tmpname = nulldup(PSEUDOFILE); /* Now, use the file to create the netcdf file */ if(sizeof(size_t) == sizeof(unsigned int)) ncstat = nc_create(tmpname,NC_CLOBBER,&drno->substrate); else ncstat = nc_create(tmpname,NC_CLOBBER|NC_64BIT_OFFSET,&drno->substrate); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* free the filename so it will automatically go away*/ unlink(tmpname); nullfree(tmpname); /* Avoid fill */ nc_set_fill(drno->substrate,NC_NOFILL,NULL); dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); dapcomm->oc.dapconstraint->projections = nclistnew(); dapcomm->oc.dapconstraint->selections = nclistnew(); /* Parse constraints to make sure they are syntactically correct */ ncstat = parsedapconstraints(dapcomm,dapcomm->oc.url->constraint,dapcomm->oc.dapconstraint); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Complain if we are unconstrainable but have constraints */ if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { if(dapcomm->oc.url->constraint != NULL && strlen(dapcomm->oc.url->constraint) > 0) { nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s", dapcomm->oc.url->constraint); } } /* Construct a url for oc minus any parameters */ dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL, (NC_URIALL ^ NC_URICONSTRAINTS)); /* Pass to OC */ ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} nullfree(dapcomm->oc.urltext); /* clean up */ dapcomm->oc.urltext = NULL; /* process control client parameters */ applyclientparamcontrols3(dapcomm); /* Turn on logging; only do this after oc_open*/ if((value = paramvalue34(dapcomm,"log")) != NULL) { ncloginit(); ncsetlogging(1); nclogopen(value); oc_loginit(); oc_setlogging(1); oc_logopen(value); } /* fetch and build the (almost) unconstrained DDS for use as template */ ncstat = fetchtemplatemetadata3(dapcomm); if(ncstat != NC_NOERR) goto done; /* fetch and build the constrained DDS */ ncstat = fetchconstrainedmetadata3(dapcomm); if(ncstat != NC_NOERR) goto done; #ifdef DEBUG2 fprintf(stderr,"constrained dds: %s\n",dumptree(dapcomm->cdf.ddsroot)); #endif /* The following actions are (mostly) WRT to the constrained tree */ /* Accumulate useful nodes sets */ ncstat = computecdfnodesets3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Fix grids */ ncstat = fixgrids3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Locate and mark usable sequences */ ncstat = sequencecheck3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* suppress variables not in usable sequences */ ncstat = suppressunusablevars3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* apply client parameters */ ncstat = applyclientparams34(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Add (as needed) string dimensions*/ ncstat = addstringdims(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} if(nclistlength(dapcomm->cdf.seqnodes) > 0) { /* Build the sequence related dimensions */ ncstat = defseqdims(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} } /* Define the dimsetplus and dimsetall lists */ ncstat = definedimsets3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Re-compute the dimension names*/ ncstat = computecdfdimnames34(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Deal with zero size dimensions */ ncstat = fixzerodims3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Attempt to use the DODS_EXTRA info to turn one of the dimensions into unlimited. Assume computecdfdimnames34 has already been called. */ ncstat = defrecorddim3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} if(dapcomm->cdf.recorddimname != NULL && nclistlength(dapcomm->cdf.seqnodes) > 0) { /*nclog(NCLOGWARN,"unlimited dimension specified, but sequences exist in DDS");*/ PANIC("unlimited dimension specified, but sequences exist in DDS"); } /* Re-compute the var names*/ ncstat = computecdfvarnames3(dapcomm,dapcomm->cdf.ddsroot,dapcomm->cdf.varnodes); if(ncstat) {THROWCHK(ncstat); goto done;} /* Transfer data from the unconstrained DDS data to the unconstrained DDS */ ncstat = dimimprint3(dapcomm); if(ncstat) goto done; /* Process the constraints to map to the constrained CDF tree */ /* (must follow fixgrids3 */ ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot); if(ncstat != NC_NOERR) goto done; /* Canonicalize the constraint */ ncstat = fixprojections(dapcomm->oc.dapconstraint->projections); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Fill in segment information */ ncstat = qualifyconstraints3(dapcomm->oc.dapconstraint); if(ncstat != NC_NOERR) goto done; /* using the modified constraint, rebuild the constraint string */ if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { /* ignore all constraints */ dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,0); } else { char* constraintstring = buildconstraintstring3(dapcomm->oc.dapconstraint); nc_urisetconstraints(dapcomm->oc.url,constraintstring); nullfree(constraintstring); dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,NC_URICONSTRAINTS); } #ifdef DEBUG fprintf(stderr,"ncdap3: final constraint: %s\n",dapcomm->oc.url->constraint); #endif /* Estimate the variable sizes */ estimatevarsizes3(dapcomm); /* Build the meta data */ ncstat = buildncstructures3(dapcomm); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Do any necessary data prefetch */ if(FLAGSET(dapcomm->controls,NCF_PREFETCH)) { ncstat = prefetchdata3(dapcomm); if(ncstat != NC_NOERR) { del_from_NCList((NC*)drno); /* undefine here */ {THROWCHK(ncstat); goto done;} } } { /* Mark as no longer writable and no longer indef; requires breaking abstraction */ NC* nc; ncstat = NC_check_id(drno->substrate, &nc); /* Mark as no longer writeable */ fClr(nc->nciop->ioflags, NC_WRITE); /* Mark as no longer indef; (do NOT use nc_enddef until diskless is working)*/ fSet(nc->flags, NC_INDEF); } if(ncpp) *ncpp = (NC*)drno; return ncstat; done: if(drno != NULL) NCD3_abort(drno->ext_ncid); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
int nc__open_mp(const char * path, int ioflags, int basepe, size_t *chunksizehintp, int *ncid_ptr) { NC *ncp; int status; #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif ncp = new_NC(chunksizehintp); if(ncp == NULL) return NC_ENOMEM; #if defined(LOCKNUMREC) /* && _CRAYMPP */ if (status = NC_init_pe(ncp, basepe)) { return status; } #else /* * !_CRAYMPP, only pe 0 is valid */ if(basepe != 0) return NC_EINVAL; #endif status = ncio_open(path, ioflags, 0, 0, &ncp->chunk, &ncp->nciop, 0); if(status) goto unwind_alloc; assert(ncp->flags == 0); if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) { /* * NC_SHARE implies sync up the number of records as well. * (File format version one.) * Note that other header changes are not shared * automatically. Some sort of IPC (external to this package) * would be used to trigger a call to nc_sync(). */ fSet(ncp->flags, NC_NSYNC); } status = nc_get_NC(ncp); if(status != NC_NOERR) goto unwind_ioc; add_to_NCList(ncp); if(chunksizehintp != NULL) *chunksizehintp = ncp->chunk; *ncid_ptr = ncp->nciop->fd; return NC_NOERR; unwind_ioc: (void) ncio_close(ncp->nciop, 0); ncp->nciop = NULL; /*FALLTHRU*/ unwind_alloc: free_NC(ncp); return status; }