Exemplo n.º 1
0
static int
ketama_roller( ketama_continuum* contptr, char* filename, int roller_flag )
{
    key_t key;
    continuum_resource resource;

    // if we have a string like "key:0x1234" that means we want to set up the infastructure 
    // but leave continuum creation until we manually add servers with ketama_add_server
    char cont_filename[PATH_MAX];
    time_t fmodtime;
    snprintf(cont_filename, sizeof(cont_filename), "%s", filename);
    key = get_key(cont_filename, &fmodtime);
    if ( key == -1 ) {
        snprintf( k_error, sizeof(k_error), "Ketama: ketama_roll failed to make a valid key from %s.\n", filename );
        syslog1( LOG_INFO, k_error );
        return 0;
    }

    // try to find an existsing resource with a shared memory segment in the array of tracked resources, or create a new attachment resource
    if ( !get_shm_resource(key, &resource) ) {
        snprintf( k_error, sizeof(k_error), "Ketama: ketama_roller failed to get a valid resource.\n" );
        syslog1( LOG_INFO, k_error  );
        return 0;
    }

    // if the continuum is not stale or new, end here and track the resource if we somehow missed tracking it
    if ( (resource.data->fmodtime == fmodtime) && (resource.data->cont_version != 0) ) {
        **contptr = resource;
        track_shm_resource(resource);
        syslog( LOG_DEBUG, "Ketama: ketama_roll() successfully found a valid shared memory segment at %p with ID: %lu and key: %lu, stored into %p.\n", 
            resource.data, (long unsigned int) resource.shmid, (long unsigned int) resource.key, *contptr);
        return 1;
    }

    // detach from the shared memory segment so that we can attach again in ketama_create to initialize the continuum
    if ( ketama_shmdt(resource.data) == -1 ) {
        snprintf( k_error, sizeof(k_error), "Ketama: ketama_roll failed to detatch from shared memory with errno: %d.\n", errno );
        syslog1( LOG_INFO, k_error );
    }

    // if we've already attempted to run ketama_create then that subroutine failed and we want to fail out
    if ( roller_flag != 0) {
        snprintf( k_error, sizeof(k_error), "Ketama: ketama_create_continuum failed to create a valid continuum.\n" );
        syslog1( LOG_INFO, k_error );
        return 0;
    }

    // attempt to run ketama_create continuum
    if ( !ketama_create_continuum( key, filename, contptr ) ) {
        snprintf( k_error, sizeof(k_error), "Ketama: ketama_create_continuum failed!\n" );
        syslog1( LOG_INFO, k_error );
        return 0;
    }

    // if we reach this point then we've created the continuum and reran ketama_roll to check its validity, so just log this and exit
    syslog1( LOG_INFO, "Ketama: ketama_create_continuum successfully finished.\n" );
    return 1;
}
Exemplo n.º 2
0
Arquivo: ketama.c Projeto: lsm/zir
int
ketama_roll( ketama_continuum* contptr, char* filename )
{
    strcpy( k_error, "" );

    key_t key;
    int shmid;
    int *data;
    int sem_set_id;

//     setlogmask( LOG_UPTO ( LOG_NOTICE | LOG_ERR | LOG_INFO ) );
//     openlog( "ketama", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1 );

    key = ftok( filename, 'R' );
    if ( key == -1 )
    {
        sprintf( k_error, "Invalid filename specified: %s", filename );
        return 0;
    }

    *contptr = malloc( sizeof( continuum ) );
    (*contptr)->numpoints = 0;
    (*contptr)->array = 0;
    (*contptr)->modtime = 0;

    sem_set_id = ketama_sem_init( key );

    int sanity = 0;
    while ( semctl( sem_set_id, 0, GETVAL, 0 ) == 2 )
    {
        // wait for the continuum creator to finish, but don't block others
        usleep( 5 );

        // if we are waiting for > 1 second, take drastic action:
        if(++sanity > 1000000)
	{
            usleep( rand()%50000 );
            ketama_sem_unlock( sem_set_id );
	    break;
        }
    }

    time_t modtime = file_modtime( filename );
    time_t* fmodtime = 0;
    while ( !fmodtime || modtime != *fmodtime )
    {
        shmid = shmget( key, MC_SHMSIZE, 0 ); // read only attempt.
        data = shmat( shmid, (void *)0, SHM_RDONLY );

        if ( data == (void *)(-1) || (*contptr)->modtime != 0 )
        {
            ketama_sem_lock( sem_set_id );

//          if ( (*contptr)->modtime == 0 )
//              syslog( LOG_INFO, "Shared memory empty, creating and populating...\n" );
//          else
//              syslog( LOG_INFO, "Server definitions changed, reloading...\n" );

            if ( !ketama_create_continuum( key, filename ) )
            {
//                 strcpy( k_error, "Ketama_create_continuum() failed!" );
                ketama_sem_unlock( sem_set_id );
                return 0;
            }
/*          else
                syslog( LOG_INFO, "ketama_create_continuum() successfully finished.\n" );*/
    
            shmid = shmget( key, MC_SHMSIZE, 0 ); // read only attempt.
            data = shmat( shmid, (void *)0, SHM_RDONLY );
            ketama_sem_unlock( sem_set_id );
        }
    
        if ( data == (void *)(-1) )
        {
            strcpy( k_error, "Failed miserably to get pointer to shmemdata!" );
            return 0;
        }

        (*contptr)->numpoints = *data;
        (*contptr)->modtime = ++data;
        (*contptr)->array = data + sizeof( void* );
        fmodtime = (time_t*)( (*contptr)->modtime );
    }

    return 1;
}