Beispiel #1
0
static int file_make_mmap(apr_bucket *e, apr_size_t filelength,
                           apr_off_t fileoffset, apr_pool_t *p)
{
    apr_bucket_file *a = e->data;
    apr_mmap_t *mm;

    if (!a->can_mmap) {
        return 0;
    }

    if (filelength > APR_MMAP_LIMIT) {
        if (apr_mmap_create(&mm, a->fd, fileoffset, APR_MMAP_LIMIT,
                            APR_MMAP_READ, p) != APR_SUCCESS)
        {
            return 0;
        }
        apr_bucket_split(e, APR_MMAP_LIMIT);
        filelength = APR_MMAP_LIMIT;
    }
    else if ((filelength < APR_MMAP_THRESHOLD) ||
             (apr_mmap_create(&mm, a->fd, fileoffset, filelength,
                              APR_MMAP_READ, p) != APR_SUCCESS))
    {
        return 0;
    }
    apr_bucket_mmap_make(e, mm, 0, filelength);
    file_bucket_destroy(a);
    return 1;
}
Beispiel #2
0
static void test_mmap_create(abts_case *tc, void *data)
{
    apr_status_t rv;

    rv = apr_mmap_create(&themmap, thefile, 0, (apr_size_t) thisfinfo.size, 
		                 APR_MMAP_READ, p);
    ABTS_PTR_NOTNULL(tc, themmap);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}
Beispiel #3
0
		int load( const char* filename )
		{
			free( resource );
			apr_file_t* newfile;
			apr_file_open( &newfile, filename, APR_READ, APR_OS_DEFAULT, mempool );
			apr_finfo_t finfo;
			apr_file_info_get( &finfo, APR_FINFO_SIZE, newfile );
			apr_mmap_t* mmap;
			apr_mmap_create( &mmap, newfile, 0, finfo.size, APR_MMAP_READ, mempool );
			resource = (char*)malloc( finfo.size );
			memcpy( resource, mmap->mm, finfo.size );
			apr_mmap_delete( mmap );
		}
Beispiel #4
0
static void cache_the_file(cmd_parms *cmd, const char *filename, int mmap)
{
    a_server_config *sconf;
    a_file *new_file;
    a_file tmp;
    apr_file_t *fd = NULL;
    apr_status_t rc;
    const char *fspec;

    fspec = ap_server_root_relative(cmd->pool, filename);
    if (!fspec) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, APLOGNO(00794)
                     "invalid file path "
                     "%s, skipping", filename);
        return;
    }
    if ((rc = apr_stat(&tmp.finfo, fspec, APR_FINFO_MIN,
                                 cmd->temp_pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00795)
                     "unable to stat(%s), skipping", fspec);
        return;
    }
    if (tmp.finfo.filetype != APR_REG) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00796)
                     "%s isn't a regular file, skipping", fspec);
        return;
    }
    if (tmp.finfo.size > AP_MAX_SENDFILE) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00797)
                     "%s is too large to cache, skipping", fspec);
        return;
    }

    rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD,
                       APR_OS_DEFAULT, cmd->pool);
    if (rc != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00798)
                     "unable to open(%s, O_RDONLY), skipping", fspec);
        return;
    }
    apr_file_inherit_set(fd);

    /* WooHoo, we have a file to put in the cache */
    new_file = apr_pcalloc(cmd->pool, sizeof(a_file));
    new_file->finfo = tmp.finfo;

#if APR_HAS_MMAP
    if (mmap) {
        /* MMAPFile directive. MMAP'ing the file
         * XXX: APR_HAS_LARGE_FILES issue; need to reject this request if
         * size is greater than MAX(apr_size_t) (perhaps greater than 1M?).
         */
        if ((rc = apr_mmap_create(&new_file->mm, fd, 0,
                                  (apr_size_t)new_file->finfo.size,
                                  APR_MMAP_READ, cmd->pool)) != APR_SUCCESS) {
            apr_file_close(fd);
            ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, APLOGNO(00799)
                         "unable to mmap %s, skipping", filename);
            return;
        }
        apr_file_close(fd);
        new_file->is_mmapped = TRUE;
    }
#endif
#if APR_HAS_SENDFILE
    if (!mmap) {
        /* CacheFile directive. Caching the file handle */
        new_file->is_mmapped = FALSE;
        new_file->file = fd;
    }
#endif

    new_file->filename = fspec;
    apr_rfc822_date(new_file->mtimestr, new_file->finfo.mtime);
    apr_snprintf(new_file->sizestr, sizeof new_file->sizestr, "%" APR_OFF_T_FMT, new_file->finfo.size);

    sconf = ap_get_module_config(cmd->server->module_config, &file_cache_module);
    apr_hash_set(sconf->fileht, new_file->filename, strlen(new_file->filename), new_file);

}
Beispiel #5
0
svn_error_t *
svn_atomic_namespace__create(svn_atomic_namespace__t **ns,
                             const char *name,
                             apr_pool_t *result_pool)
{
  apr_status_t apr_err;
  svn_error_t *err;
  apr_file_t *file;
  apr_mmap_t *mmap;
  const char *shm_name, *lock_name;
  apr_finfo_t finfo;

  apr_pool_t *subpool = svn_pool_create(result_pool);

  /* allocate the namespace data structure
   */
  svn_atomic_namespace__t *new_ns = apr_pcalloc(result_pool, sizeof(**ns));

  /* construct the names of the system objects that we need
   */
  shm_name = apr_pstrcat(subpool, name, SHM_NAME_SUFFIX, NULL);
  lock_name = apr_pstrcat(subpool, name, MUTEX_NAME_SUFFIX, NULL);

  /* initialize the lock objects
   */
  SVN_ERR(svn_atomic__init_once(&mutex_initialized, init_thread_mutex, NULL,
                                result_pool));

  new_ns->mutex.pool = result_pool;
  SVN_ERR(svn_io_file_open(&new_ns->mutex.lock_file, lock_name,
                           APR_READ | APR_WRITE | APR_CREATE,
                           APR_OS_DEFAULT,
                           result_pool));

  /* Make sure the last user of our lock file will actually remove it.
   * Please note that only the last file handle begin closed will actually
   * remove the underlying file (see docstring for apr_file_remove).
   */
  apr_pool_cleanup_register(result_pool, &new_ns->mutex,
                            delete_lock_file,
                            apr_pool_cleanup_null);

  /* Prevent concurrent initialization.
   */
  SVN_ERR(lock(&new_ns->mutex));

  /* First, make sure that the underlying file exists.  If it doesn't
   * exist, create one and initialize its content.
   */
  err = svn_io_file_open(&file, shm_name,
                          APR_READ | APR_WRITE | APR_CREATE,
                          APR_OS_DEFAULT,
                          result_pool);
  if (!err)
    {
      err = svn_io_stat(&finfo, shm_name, APR_FINFO_SIZE, subpool);
      if (!err && finfo.size < sizeof(struct shared_data_t))
        {
           /* Zero all counters, values and names.
            */
           struct shared_data_t initial_data;
           memset(&initial_data, 0, sizeof(initial_data));
           err = svn_io_file_write_full(file, &initial_data,
                                        sizeof(initial_data), NULL,
                                        subpool);
        }
    }

  /* Now, map it into memory.
   */
  if (!err)
    {
      apr_err = apr_mmap_create(&mmap, file, 0, sizeof(*new_ns->data),
                                APR_MMAP_READ | APR_MMAP_WRITE , result_pool);
      if (!apr_err)
        new_ns->data = mmap->mm;
      else
        err = svn_error_createf(apr_err, NULL,
                                _("MMAP failed for file '%s'"), shm_name);
    }

  svn_pool_destroy(subpool);

  if (!err && new_ns->data)
    {
      /* Detect severe cases of corruption (i.e. when some outsider messed
       * with our data file)
       */
      if (new_ns->data->count > MAX_ATOMIC_COUNT)
        return svn_error_create(SVN_ERR_CORRUPTED_ATOMIC_STORAGE, 0,
                       _("Number of atomics in namespace is too large."));

      /* Cache the number of existing, complete entries.  There can't be
       * incomplete ones from other processes because we hold the mutex.
       * Our process will also not access this information since we are
       * either being called from within svn_atomic__init_once or by
       * svn_atomic_namespace__create for a new object.
       */
      new_ns->min_used = new_ns->data->count;
      *ns = new_ns;
    }

  /* Unlock to allow other processes may access the shared memory as well.
   */
  return unlock(&new_ns->mutex, err);
}
Beispiel #6
0
static int jk2_shm_create(jk_env_t *env, jk_shm_t *shm)
{
    int rc;
    apr_file_t *file;
    apr_finfo_t finfo;
    apr_mmap_t *aprMmap;
    apr_pool_t *globalShmPool;

    globalShmPool= (apr_pool_t *)env->getAprPool( env );

    if( globalShmPool==NULL )
        return JK_FALSE;

    /* Check if the scoreboard is in a note. That's the only way we
       can get HP-UX to work
    */
    apr_pool_userdata_get( & shm->image, "mod_jk_shm",globalShmPool );
    if( shm->image!=NULL ) {
        shm->head = (jk_shm_head_t *)shm->image;

        if( shm->mbean->debug > 0 )
            env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
                          "shm.create(): GLOBAL_SHM  %#lx\n", shm->image );
        return JK_OK;
    } else {
        if( shm->mbean->debug > 0 )
            env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
                          "shm.create(): NO GLOBAL_SHM  %#lx\n", shm->image );
    }
    

    /* First make sure the file exists and is big enough
     */
    rc=apr_file_open( &file, shm->fname,
                      APR_READ | APR_WRITE | APR_CREATE | APR_BINARY,
                      APR_OS_DEFAULT, globalShmPool);
    if (rc!=JK_OK) {
        char error[256];
        apr_strerror( rc, error, 256 );
        
        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                      "shm.create(): error opening file %s %d %s\n",
                      shm->fname, rc, error );
        shm->privateData=NULL;
        return rc;
    } 

    rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file);

    if( shm->mbean->debug > 0 )
        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
                      "shm.create(): file open %s %d %d\n", shm->fname, shm->size, finfo.size );

    if( finfo.size < shm->size ) {
        char bytes[1024];
        apr_size_t toWrite = (apr_size_t)(shm->size-finfo.size);
        apr_off_t off=0;
        
        memset( bytes, 0, 1024 );        
        apr_file_seek( file, APR_END, &off);

        while( toWrite > 0 ) {
            apr_size_t written;
            rc=apr_file_write_full(file, bytes, 1024, &written);
            if( rc!=APR_SUCCESS ) {
                env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                              "shm.create(): Can't write %s %d %s\n",
                              shm->fname, errno, strerror( errno ));
                return JK_ERR;
            }
            if( toWrite < written  ){
                toWrite=0;
            }else{
                toWrite-=written;
            }
        }
        
        rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file);
    }
     
    /* Now mmap it
     */
    rc=apr_mmap_create( &aprMmap,  file, (apr_off_t)0,
                        (apr_size_t)finfo.size, APR_MMAP_READ | APR_MMAP_WRITE,
                        globalShmPool );
    if( rc!=JK_OK ) {
        char error[256];
        apr_strerror( rc, error, 256 );
        
        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                      "shm.create(): error creating %s %d %d %#lx %s\n",
                      shm->fname, finfo.size, rc, globalShmPool, error );
        shm->privateData=NULL;
        return rc;
    }

    shm->privateData=aprMmap;

    apr_mmap_offset(& shm->image, aprMmap, (apr_off_t)0);

    apr_pool_userdata_set( shm->image, "mod_jk_shm", NULL, globalShmPool );
        
    shm->head = (jk_shm_head_t *)shm->image;

    if( shm->image==NULL ) {
        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                      "shm.create(): No base memory %s\n", shm->fname);
        return JK_ERR;
    }

    return JK_OK;
}
Beispiel #7
0
/**
 * \brief get file content of given tile
 *
 * fills the mapcache_tile::data of the given tile with content stored in the file
 * \private \memberof mapcache_cache_disk
 * \sa mapcache_cache::tile_get()
 */
static int _mapcache_cache_disk_get(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
{
  char *filename;
  apr_file_t *f;
  apr_finfo_t finfo;
  apr_status_t rv;
  apr_size_t size;
  apr_mmap_t *tilemmap;
  mapcache_cache_disk *cache = (mapcache_cache_disk*)pcache;

  cache->tile_key(ctx, cache, tile, &filename);
  if(GC_HAS_ERROR(ctx)) {
    return MAPCACHE_FAILURE;
  }
  ctx->log(ctx,MAPCACHE_DEBUG,"checking for tile %s",filename);
  if((rv=apr_file_open(&f, filename,
#ifndef NOMMAP
                       APR_FOPEN_READ, APR_UREAD | APR_GREAD,
#else
                       APR_FOPEN_READ|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,APR_OS_DEFAULT,
#endif
                       ctx->pool)) == APR_SUCCESS) {
    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE|APR_FINFO_MTIME, f);
    if(!finfo.size) {
      ctx->set_error(ctx, 500, "tile %s has no data",filename);
      return MAPCACHE_FAILURE;
    }

    size = finfo.size;
    /*
     * at this stage, we have a handle to an open file that contains data.
     * idealy, we should aquire a read lock, in case the data contained inside the file
     * is incomplete (i.e. if another process is currently writing to the tile).
     * currently such a lock is not set, as we don't want to loose performance on tile accesses.
     * any error that might happen at this stage should only occur if the tile isn't already cached,
     * i.e. normally only once.
     */
    tile->mtime = finfo.mtime;
    tile->encoded_data = mapcache_buffer_create(size,ctx->pool);

#ifndef NOMMAP

    rv = apr_mmap_create(&tilemmap,f,0,finfo.size,APR_MMAP_READ,ctx->pool);
    if(rv != APR_SUCCESS) {
      char errmsg[120];
      ctx->set_error(ctx, 500,  "mmap error: %s",apr_strerror(rv,errmsg,120));
      return MAPCACHE_FAILURE;
    }
    tile->encoded_data->buf = tilemmap->mm;
    tile->encoded_data->size = tile->encoded_data->avail = finfo.size;
#else
    //manually add the data to our buffer
    apr_file_read(f,(void*)tile->encoded_data->buf,&size);
    tile->encoded_data->size = size;
    tile->encoded_data->avail = size;
#endif
    apr_file_close(f);
    if(tile->encoded_data->size != finfo.size) {
      ctx->set_error(ctx, 500,  "failed to copy image data, got %d of %d bytes",(int)size, (int)finfo.size);
      return MAPCACHE_FAILURE;
    }
    return MAPCACHE_SUCCESS;
  } else {
    if(APR_STATUS_IS_ENOENT(rv)) {
      /* the file doesn't exist on the disk */
      return MAPCACHE_CACHE_MISS;
    } else {
      char *error = strerror(rv);
      ctx->set_error(ctx, 500,  "failed to open file %s: %s",filename, error);
      return MAPCACHE_FAILURE;
    }
  }
}
Beispiel #8
0
apr_status_t kahanaUtilChecksum( apr_pool_t *p, kCheckSumType_e type, const char **hex_digest, const char *msg, ... )
{
	apr_status_t rc = APR_SUCCESS;
	char *keys = NULL;
	
	if( !( keys = calloc( 0, sizeof( char ) ) ) ){
		rc = APR_ENOMEM;
	}
	else
	{
		va_list args;
		char *key;
		int i, len = 0;
		
		va_start( args, msg );
		while( ( key = va_arg( args, char* ) ) )
		{
			if( ( i = strlen( key ) ) )
			{
				if( !( keys = realloc( keys, len + i + 1 ) ) ){
					rc = APR_ENOMEM;
					len = 0;
					break;
				}
				memcpy( keys + len, key, i );
				len += i;
				keys[len] = '\0';
			}
		}
		va_end( args );
		
		if( len )
		{
			rc = APR_SUCCESS;
			if( type == CHKSUM_STR )
			{
				char *m = NULL;
				
				if( asprintf( &m, "%s", msg ) == -1 ){
					rc = APR_ENOMEM;
				}
				else {
					*hex_digest = kahanaUtilHMACSHA1( p, (unsigned char*)keys, len, (const unsigned char*)m, strlen( m ) );
					free( m );
				}
			}
			else if( type == CHKSUM_FILE )
			{
				apr_file_t *fp = NULL;
				
				if( ( rc = apr_file_open( &fp, msg, APR_READ|APR_BINARY, APR_OS_DEFAULT, p ) ) == APR_SUCCESS )
				{
					apr_finfo_t finfo;
					apr_mmap_t *mm = NULL;

					if( ( rc = apr_file_info_get( &finfo, APR_FINFO_SIZE, fp ) ) == APR_SUCCESS &&
						( rc = apr_mmap_create( &mm, fp, 0, finfo.size, APR_MMAP_READ, p ) ) != APR_SUCCESS ){
						mm = NULL;
					}
					apr_file_close( fp );
					
					if( mm ){
						*hex_digest = kahanaUtilHMACSHA1( p, (unsigned char*)keys, len, mm->mm, finfo.size );
						rc = apr_mmap_delete( mm );
					}
				}
			}
			else {
				rc = APR_BADARG;
			}
		}
		free( keys );
	}
	
	return rc;
}