/** * * cache_inode_client_init: Init the ressource necessary for the cache inode management on the client handside. * * Init the ressource necessary for the cache inode management on the client handside. * * @param pclient [OUT] the pointer to the client to be initiated. * @param param [IN] the parameter for this cache client. * @param thread_index [IN] an integer related to the 'position' of the thread, from 0 to Nb_Workers -1 * * @return 0 if successful, 1 if failed. * */ int cache_inode_client_init(cache_inode_client_t * pclient, cache_inode_client_parameter_t param, int thread_index, void *pworker_data) { LRU_status_t lru_status; char name[256]; if(thread_index < SMALL_CLIENT_INDEX) sprintf(name, "Cache Inode Worker #%d", thread_index); else if(thread_index == SMALL_CLIENT_INDEX) sprintf(name, "Cache Inode Small Client"); else sprintf(name, "Cache Inode NLM Async #%d", thread_index - NLM_THREAD_INDEX); pclient->attrmask = param.attrmask; pclient->nb_prealloc = param.nb_prealloc_entry; pclient->nb_pre_dir_data = param.nb_pre_dir_data; pclient->nb_pre_parent = param.nb_pre_parent; pclient->nb_pre_state_v4 = param.nb_pre_state_v4; pclient->expire_type_attr = param.expire_type_attr; pclient->expire_type_link = param.expire_type_link; pclient->expire_type_dirent = param.expire_type_dirent; pclient->grace_period_attr = param.grace_period_attr; pclient->grace_period_link = param.grace_period_link; pclient->grace_period_dirent = param.grace_period_dirent; pclient->use_test_access = param.use_test_access; pclient->getattr_dir_invalidation = param.getattr_dir_invalidation; pclient->pworker = pworker_data; pclient->use_cache = param.use_cache; pclient->retention = param.retention; pclient->max_fd_per_thread = param.max_fd_per_thread; /* introducing desynchronisation for GC */ pclient->time_of_last_gc = time(NULL) + thread_index * 20; pclient->call_since_last_gc = thread_index * 20; pclient->time_of_last_gc_fd = time(NULL); MakePool(&pclient->pool_entry, pclient->nb_prealloc, cache_entry_t, NULL, NULL); NamePool(&pclient->pool_entry, "%s Entry Pool", name); if(!IsPoolPreallocated(&pclient->pool_entry)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Entry Pool", name); return 1; } MakePool(&pclient->pool_entry_symlink, pclient->nb_prealloc, cache_inode_symlink_t, NULL, NULL); NamePool(&pclient->pool_entry_symlink, "%s Entry Symlink Pool", name); if(!IsPoolPreallocated(&pclient->pool_entry_symlink)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Entry Symlink Pool", name); return 1; } MakePool(&pclient->pool_dir_data, pclient->nb_pre_dir_data, cache_inode_dir_data_t, NULL, NULL); NamePool(&pclient->pool_dir_data, "%s Dir Data Pool", name); if(!IsPoolPreallocated(&pclient->pool_dir_data)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Dir Data Pool", name); return 1; } MakePool(&pclient->pool_parent, pclient->nb_pre_parent, cache_inode_parent_entry_t, NULL, NULL); NamePool(&pclient->pool_parent, "%s Parent Link Pool", name); if(!IsPoolPreallocated(&pclient->pool_parent)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Parent Link Pool", name); return 1; } MakePool(&pclient->pool_state_v4, pclient->nb_pre_state_v4, state_t, NULL, NULL); NamePool(&pclient->pool_state_v4, "%s State V4 Pool", name); if(!IsPoolPreallocated(&pclient->pool_state_v4)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s State V4 Pool", name); return 1; } /* TODO: warning - entries in this pool are never released! */ MakePool(&pclient->pool_state_owner, pclient->nb_pre_state_v4, state_owner_t, NULL, NULL); NamePool(&pclient->pool_state_owner, "%s Open Owner Pool", name); if(!IsPoolPreallocated(&pclient->pool_state_owner)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Open Owner Pool", name); return 1; } /* TODO: warning - entries in this pool are never released! */ MakePool(&pclient->pool_nfs4_owner_name, pclient->nb_pre_state_v4, state_nfs4_owner_name_t, NULL, NULL); NamePool(&pclient->pool_nfs4_owner_name, "%s Open Owner Name Pool", name); if(!IsPoolPreallocated(&pclient->pool_nfs4_owner_name)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Open Owner Name Pool", name); return 1; } #ifdef _USE_NFS4_1 /* TODO: warning - entries in this pool are never released! */ MakePool(&pclient->pool_session, pclient->nb_pre_state_v4, nfs41_session_t, NULL, NULL); NamePool(&pclient->pool_session, "%s Session Pool", name); if(!IsPoolPreallocated(&pclient->pool_session)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Session Pool", name); return 1; } #endif /* _USE_NFS4_1 */ MakePool(&pclient->pool_key, pclient->nb_prealloc, cache_inode_fsal_data_t, NULL, NULL); NamePool(&pclient->pool_key, "%s Key Pool", name); if(!IsPoolPreallocated(&pclient->pool_key)) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s Key Pool", name); return 1; } param.lru_param.name = name; if((pclient->lru_gc = LRU_Init(param.lru_param, &lru_status)) == NULL) { LogCrit(COMPONENT_CACHE_INODE, "Can't init %s lru gc", name); return 1; } /* Everything was ok, return 0 */ return 0; } /* cache_inode_client_init */
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_configurable_lru"); char buf[LENBUF]; int ok = 1; int hrc = 0; int rc = 0; int expected_rc; char c; char *p; int key; LRU_status_t status = 0; LRU_list_t *plru; LRU_parameter_t param; param.nb_entry_prealloc = PREALLOC; param.entry_to_str = print_entry; param.clean_entry = clean_entry; param.name = "Test"; BuddyInit(NULL); if((plru = LRU_Init(param, &status)) == NULL) { LogTest("Test ECHOUE : Mauvaise init"); exit(1); } /* * * La syntaxe d'un test est * 'i key rc' : invalide l'entree avec la clef key * 'n key rc' : cree une nouvelle entree avec la clef key * 'g key rc' : passage du garbage collector (key ne sert a rien) * 'p key rc' : imprime le LRU (key et rc ne servent a rien). * * Une ligne qui debute par '#' est un commentaire * Une ligne qui debute par un espace ou un tab est une ligne vide [meme si il y a des trucs derriere.. :-( ] * Une ligne vide (juste un CR) est une ligne vide (cette citation a recu le Premier Prix lors du Festival International * de la Tautologie de Langue Francaise (FITLF), a Poully le Marais, en Aout 2004) * */ LogTest("============ Debut de l'interactif ================="); while(ok) { /* Code interactif, pompe sur le test rbt de Jacques */ fputs("> ", stdout); if((p = fgets(buf, LENBUF, stdin)) == NULL) { LogTest("fin des commandes"); ok = 0; continue; } if((p = strchr(buf, '\n')) != NULL) *p = '\0'; rc = sscanf(buf, "%c %d %d", &c, &key, &expected_rc); if(c == '#') { /* # indique un commentaire */ continue; } else if(c == ' ' || c == '\t' || rc == -1) { /* Cas d'une ligne vide */ if(rc > 1) LogTest("Erreur de syntaxe : mettre un diese au debut d'un commentaire"); continue; } else { if(rc != 3) { LogTest("Erreur de syntaxe : sscanf retourne %d au lieu de 3", rc); continue; } LogTest("---> %c %d %d", c, key, expected_rc); } switch (c) { case 'i': /* set overwrite */ LogTest("invalidate %d --> %d ?", key, expected_rc); hrc = do_invalidate(plru, key); if(hrc != expected_rc) LogTest(">>>> ERREUR: invalidate %d : %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK invalidate %d", key); break; case 'n': /* test */ LogTest("new %d --> %d ?", key, expected_rc); hrc = do_new(plru, key); if(hrc != expected_rc) LogTest(">>>> ERREUR: new %d : %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK new %d", key); break; case 'g': /* set no overwrite */ LogTest("gc %d --> %d ?", key, expected_rc); hrc = do_gc(plru); if(hrc != expected_rc) LogTest(">>>> ERREUR: gc %d: %d != %d (expected)", key, hrc, expected_rc); else LogTest(">>>> OK new %d", key); break; case 'p': /* Print */ LRU_Print(plru); break; default: /* syntaxe error */ LogTest("ordre '%c' non-reconnu", c); break; } } LogTest("===================================================="); LogTest("Test reussi : tous les tests sont passes avec succes"); exit(0); return; } /* main */
fsal_status_t MFSL_Init(mfsl_parameter_t * init_info /* IN */ ) { unsigned long i = 0; unsigned int rc = 0; pthread_attr_t attr_thr; LRU_status_t lru_status; /* Keep the parameter in mind */ mfsl_param = *init_info; /* Init for thread parameter (mostly for scheduling) */ pthread_attr_init(&attr_thr); pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE); /* Allocate the synclet related structure */ if((mfsl_async_synclet_thrid = gsh_malloc(init_info->nb_synclet * sizeof(pthread_t))) == NULL) MFSL_return(ERR_FSAL_NOMEM, errno); if((synclet_data = gsh_calloc(init_info->nb_synclet, sizeof(mfsl_synclet_data_t))) == NULL) MFSL_return(ERR_FSAL_NOMEM, errno); for(i = 0; i < init_info->nb_synclet; i++) { synclet_data[i].my_index = i; if(pthread_cond_init(&synclet_data[i].op_condvar, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if(pthread_mutex_init(&synclet_data[i].mutex_op_condvar, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if(pthread_mutex_init(&synclet_data[i].mutex_op_lru, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if((synclet_data[i].op_lru = LRU_Init(mfsl_param.lru_param, &lru_status)) == NULL) MFSL_return(ERR_FSAL_INVAL, 0); synclet_data[i].passcounter = 0; } /* for */ /* Now start the threads */ if((rc = pthread_create(&mfsl_async_adt_thrid, &attr_thr, mfsl_async_asynchronous_dispatcher_thread, (void *)NULL)) != 0) MFSL_return(ERR_FSAL_SERVERFAULT, -rc); for(i = 0; i < init_info->nb_synclet; i++) { if((rc = pthread_create(&mfsl_async_synclet_thrid[i], &attr_thr, mfsl_async_synclet_thread, (void *)i)) != 0) MFSL_return(ERR_FSAL_SERVERFAULT, -rc); } if(!mfsl_async_hash_init()) MFSL_return(ERR_FSAL_SERVERFAULT, 0); /* Regular Exit */ MFSL_return(ERR_FSAL_NO_ERROR, 0); }
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_lru"); LRU_list_t *plru; LRU_parameter_t param; LRU_entry_t *entry = NULL; LRU_entry_t *kept_entry = NULL; LRU_status_t status = 0; int i = 0; char strtab[MAXTEST][10]; param.nb_entry_prealloc = PREALLOC; param.entry_to_str = print_entry; param.clean_entry = clean_entry; param.lp_name = "Test"; BuddyInit(NULL); if((plru = LRU_Init(param, &status)) == NULL) { LogTest("Test FAILED: Bad Init"); exit(1); } for(i = 0; i < MAXTEST; i++) { LogTest("Added entry %d", i); sprintf(strtab[i], "%d", i); if((entry = LRU_new_entry(plru, &status)) == NULL) { LogTest("Test FAILED: bad entry add, status = %d", status); exit(1); } entry->buffdata.pdata = strtab[i]; entry->buffdata.len = strlen(strtab[i]); if(i == KEPT_ENTRY) kept_entry = entry; } /* printing the table */ LRU_Print(plru); LRU_invalidate(plru, kept_entry); if(isFullDebug(COMPONENT_LRU)) LRU_Print(plru); if(LRU_gc_invalid(plru, NULL) != LRU_LIST_SUCCESS) { LogTest("Test FAILED: bad gc"); exit(1); } LRU_Print(plru); /* Tous les tests sont ok */ LogTest("\n-----------------------------------------"); LogTest("Test succeeded: all tests pass successfully"); exit(0); } /* main */