Changeset 250 for trunk


Ignore:
Timestamp:
05/05/11 00:00:24 (13 years ago)
Author:
tim
Message:

added key caching
readded SK caching
fixed races and deadlocks

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/devel/TODO

    r238 r250  
    4646Add fields/methods for accessing security descriptors in pyregfi
    4747
    48 Key caching
    49 
    50 Add function to obtain path list from iterator
    51 
    5248convert MTIME structure to uint64_t if possible
    5349
  • trunk/include/regfi.h

    r249 r250  
    141141/******************************************************************************/
    142142
    143 /* Flags determining whether or not to cache various record types internally */
    144 #define REGFI_CACHE_SK             0
     143/* Flags determining how many records to cache internally */
     144#define REGFI_CACHE_SK_MAX         64
     145#define REGFI_CACHE_NK_MAX         1024
    145146
    146147/* This maximum depth is described here:
     
    815816  pthread_rwlock_t hbins_lock;
    816817
    817   /* SK record cached since they're repeatedly reused */
     818  /* Small number of SK records cached */
    818819  lru_cache* sk_cache;
    819820
    820821  /* Need exclusive access for LRUs, since lookups make changes */
    821822  pthread_mutex_t sk_lock;
     823
     824  /* Limited number of keys cached */
     825  lru_cache* nk_cache;
     826
     827  /* Need exclusive access for LRUs, since lookups make changes */
     828  pthread_mutex_t nk_lock;
    822829
    823830  /* Needed to protect various talloc calls */
  • trunk/lib/lru_cache.c

    r184 r250  
    151151{
    152152  ht->secret = 0;
    153   talloc_free(ht);
     153  talloc_unlink(NULL, ht);
    154154}
    155155
     
    257257    e->index_len = index_len;
    258258
    259     /* Insert at beginning of chain, in a vaguely LRU style */
    260259    e->next = ht->table[hash];
    261260    ht->table[hash] = e;
  • trunk/lib/regfi.c

    r249 r250  
    13431343  int32_t max_size;
    13441344
     1345  if(file->nk_cache != NULL)
     1346  {
     1347    /* First, check to see if we have this key in our cache */
     1348    if(!regfi_lock(file, &file->mem_lock, "regfi_load_nk"))
     1349      return NULL;
     1350    regfi_lock(file, &file->nk_lock, "regfi_load_nk");
     1351   
     1352    nk = (REGFI_NK*)lru_cache_find(file->nk_cache, &offset, 4);
     1353    if(nk != NULL)
     1354      nk = talloc_reference(NULL, nk);
     1355
     1356    regfi_unlock(file, &file->nk_lock, "regfi_load_nk");
     1357    regfi_unlock(file, &file->mem_lock, "regfi_load_nk");
     1358    if(nk != NULL)
     1359      return nk;
     1360  }
     1361
     1362  /* Not cached currently, proceed with loading it */
    13451363  max_size = regfi_calc_maxsize(file, offset);
    13461364  if (max_size < 0)
     
    13711389      else
    13721390        nk->values = NULL;
    1373 
    13741391    }
    13751392    else
     
    14211438  }
    14221439
     1440  if(file->nk_cache != NULL)
     1441  {
     1442    /* All is well, so let us cache this key for later */
     1443    if(!regfi_lock(file, &file->mem_lock, "regfi_load_nk"))
     1444      return NULL;
     1445    regfi_lock(file, &file->nk_lock, "regfi_load_nk");
     1446   
     1447    lru_cache_update(file->nk_cache, &offset, 4, nk);
     1448   
     1449    regfi_unlock(file, &file->nk_lock, "regfi_load_nk");
     1450    regfi_unlock(file, &file->mem_lock, "regfi_load_nk");
     1451  }
     1452
    14231453  return nk;
    14241454}
     
    14401470    return regfi_parse_sk(file, offset, max_size, strict);
    14411471
    1442   if(!regfi_lock(file, &file->sk_lock, "regfi_load_sk"))
    1443     return NULL;
     1472  if(!regfi_lock(file, &file->mem_lock, "regfi_load_sk"))
     1473    return NULL;
     1474  regfi_lock(file, &file->sk_lock, "regfi_load_sk");
    14441475
    14451476  /* First look if we have already parsed it */
     
    14481479  /* Bail out if we have previously cached a parse failure at this offset. */
    14491480  if(ret_val == (void*)REGFI_OFFSET_NONE)
    1450     return NULL;
     1481  {
     1482    ret_val = NULL;
     1483    goto unlock;
     1484  }
    14511485
    14521486  if(ret_val == NULL)
     
    14571491      failure_ptr = talloc(NULL, uint32_t);
    14581492      if(failure_ptr == NULL)
    1459         return NULL;
     1493        goto unlock;
     1494
    14601495      *(uint32_t*)failure_ptr = REGFI_OFFSET_NONE;
    14611496      lru_cache_update(file->sk_cache, &offset, 4, failure_ptr);
     
    14631498      /* Let the cache be the only owner of this */
    14641499      talloc_unlink(NULL, failure_ptr);
    1465       return NULL;
    1466     }
    1467   }
    1468 
    1469   if(!regfi_unlock(file, &file->sk_lock, "regfi_load_sk"))
    1470   {
    1471     talloc_unlink(NULL, ret_val);
    1472     return NULL;
    1473   }
     1500    }
     1501  }
     1502
     1503 unlock:
     1504  regfi_unlock(file, &file->sk_lock, "regfi_load_sk");
     1505  regfi_unlock(file, &file->mem_lock, "regfi_load_sk");
    14741506
    14751507  return ret_val;
     
    15651597  pthread_rwlock_destroy(&file->hbins_lock);
    15661598  pthread_mutex_destroy(&file->sk_lock);
     1599  pthread_mutex_destroy(&file->nk_lock);
     1600  pthread_mutex_destroy(&file->mem_lock);
    15671601
    15681602  return 0;
     
    16291663  }
    16301664
     1665  if(pthread_mutex_init(&rb->nk_lock, NULL) != 0)
     1666  {
     1667    regfi_log_add(REGFI_LOG_ERROR, "Failed to create nk_lock mutex.");
     1668    goto fail;
     1669  }
     1670
    16311671  if(pthread_mutex_init(&rb->mem_lock, NULL) != 0)
    16321672  {
     
    16621702  cache_secret = 0x15DEAD05^time(NULL)^(getpid()<<16);
    16631703
    1664   if(REGFI_CACHE_SK)
    1665     rb->sk_cache = lru_cache_create_ctx(rb, 64, cache_secret, true);
    1666   else
    1667     rb->sk_cache = NULL;
     1704  rb->sk_cache = NULL;
     1705  if(REGFI_CACHE_SK_MAX > 0)
     1706    rb->sk_cache = lru_cache_create_ctx(rb, REGFI_CACHE_SK_MAX,
     1707                                        cache_secret, true);
     1708
     1709  rb->nk_cache = NULL;
     1710  if(REGFI_CACHE_NK_MAX > 0)
     1711    rb->nk_cache = lru_cache_create_ctx(rb, REGFI_CACHE_NK_MAX,
     1712                                        cache_secret, true);
    16681713
    16691714  /* success */
     
    16751720  pthread_rwlock_destroy(&rb->hbins_lock);
    16761721  pthread_mutex_destroy(&rb->sk_lock);
     1722  pthread_mutex_destroy(&rb->nk_lock);
    16771723  pthread_mutex_destroy(&rb->mem_lock);
    16781724
     
    20102056{
    20112057  const REGFI_NK* ret_val = NULL;
    2012   if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key"))
    2013     return ret_val;
    20142058
    20152059  ret_val = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
    2016 
    2017   regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key"); 
    20182060  return ret_val;
    20192061}
     
    21382180  void_stack_iterator* iter;
    21392181  const REGFI_ITER_POSITION* cur;
    2140   uint16_t k;
    2141 
    2142   ret_val = talloc_array(NULL, REGFI_NK*, void_stack_size(i->key_positions)+2);
     2182  uint16_t k, num_keys;
     2183
     2184  num_keys = void_stack_size(i->key_positions)+1;
     2185  ret_val = talloc_array(NULL, REGFI_NK*, num_keys+1);
    21432186  if(ret_val == NULL)
    21442187    return NULL;
     
    21502193    return NULL;
    21512194  }
    2152  
     2195
     2196  k=0;
     2197  for(cur=void_stack_iterator_next(iter);
     2198      cur != NULL; cur=void_stack_iterator_next(iter))
     2199  {
     2200    ret_val[k++] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true);
     2201  }
     2202  ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
     2203  void_stack_iterator_free(iter);
     2204
    21532205  if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_cur_path"))
    21542206  {
     
    21572209  }
    21582210
    2159   for(cur=void_stack_iterator_next(iter), k=0;
    2160       cur != NULL; cur=void_stack_iterator_next(iter), k++)
    2161   {
    2162     ret_val[k] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true);
     2211  for(k=0; k<num_keys; k++)
    21632212    talloc_reparent(NULL, ret_val, ret_val[k]);
    2164   }
    2165   ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
    2166   talloc_reparent(NULL, ret_val, ret_val[k]);
    21672213
    21682214  regfi_unlock(i->f, &i->f->mem_lock, "regfi_cur_path");
    2169   void_stack_iterator_free(iter);
    2170 
    2171   ret_val[++k] = NULL;
     2215
     2216  ret_val[k] = NULL;
    21722217  return (const REGFI_NK**)ret_val;
    21732218}
Note: See TracChangeset for help on using the changeset viewer.