From: navarro Date: Tue, 11 Sep 2012 12:03:31 +0000 (+0200) Subject: Add a function ls to storage X-Git-Tag: v3_8~146^2~73 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/089f7e843d3f07571c398fb880550fdc6ff3c8e1 Add a function ls to storage --- diff --git a/include/msg/msg.h b/include/msg/msg.h index 44c79a4b93..fdfda0f8e7 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -80,6 +80,7 @@ XBT_PUBLIC(int) MSG_file_stat(msg_file_t fd, s_msg_stat_t *buf); XBT_PUBLIC(void) MSG_file_free_stat(s_msg_stat_t *stat); XBT_PUBLIC(int) MSG_file_unlink(msg_file_t fd); +XBT_PUBLIC(xbt_dict_t) MSG_file_ls(const char *mount, const char *path); /************************** AS Router handling ************************************/ XBT_PUBLIC(const char *) MSG_as_router_get_property_value(const char* asr, const char *name); diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index 4066388515..830b33d7d2 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -457,6 +457,7 @@ XBT_PUBLIC(smx_file_t) simcall_file_open(const char* storage, const char* path, XBT_PUBLIC(int) simcall_file_close(smx_file_t fp); XBT_PUBLIC(int) simcall_file_stat(smx_file_t fd, s_file_stat_t *buf); XBT_PUBLIC(int) simcall_file_unlink(smx_file_t fd); +XBT_PUBLIC(xbt_dict_t) simcall_file_ls(const char* mount, const char* path); /************************** AS router **********************************/ XBT_PUBLIC(xbt_dict_t) SIMIX_asr_get_properties(const char *name); diff --git a/include/xbt/str.h b/include/xbt/str.h index 865ea28b4b..39ecbd69e2 100644 --- a/include/xbt/str.h +++ b/include/xbt/str.h @@ -49,6 +49,8 @@ XBT_PUBLIC(char *) xbt_str_diff(const char *a, const char *b); XBT_PUBLIC(char *) xbt_str_from_file(FILE * file); +XBT_PUBLIC(int) xbt_str_start_with(const char* str, const char* start); + #define DJB2_HASH_FUNCTION //#define FNV_HASH_FUNCTION diff --git a/src/include/surf/surf.h b/src/include/surf/surf.h index 66345cc99b..475f9daf36 100644 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@ -97,6 +97,7 @@ typedef struct surf_action { #endif surf_file_t file; /**< surf_file_t for storage model */ s_file_stat_t stat; /**< surf_file_t for storage model */ + xbt_dict_t ls_dict; } s_surf_action_t; typedef struct surf_action_lmm { @@ -224,6 +225,7 @@ typedef struct surf_storage_model_extension_public { surf_action_t(*write) (void *storage, const void* ptr, size_t size, size_t nmemb, surf_file_t stream); surf_action_t(*stat) (void *storage, surf_file_t stream); surf_action_t(*unlink) (void *storage, surf_file_t stream); + surf_action_t(*ls) (void *storage, const char *path); void* (*create_resource) (const char* id, const char* model, const char* type_id, const char *content); } s_surf_model_extension_storage_t; @@ -258,6 +260,8 @@ typedef struct surf_workstation_model_extension_public { surf_action_t(*write) (void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream); surf_action_t(*stat) (void *workstation, surf_file_t stream); surf_action_t(*unlink) (void *workstation, surf_file_t stream); + surf_action_t(*ls) (void *workstation, const char* mount, const char *path); + int (*link_shared) (const void *link); xbt_dict_t(*get_properties) (const void *resource); void* (*link_create_resource) (const char *name, diff --git a/src/msg/msg_io.c b/src/msg/msg_io.c index 2b03f677a7..1932908a44 100644 --- a/src/msg/msg_io.c +++ b/src/msg/msg_io.c @@ -130,3 +130,27 @@ int MSG_file_unlink(msg_file_t fd) xbt_free(fd); return res; } + +/** \ingroup msg_file_management + * \brief Search for file + * + * \param mount is the mount point where find the file is located + * \param path the file regex to find + * \return a xbt_dict_t of file where key is the name of file and the + * value the msg_stat_t corresponding to the key + */ +xbt_dict_t MSG_file_ls(const char *mount, const char *path) +{ + xbt_assert(path,"You must set path"); + int size = strlen(path); + if(size && path[size-1] != '/') + { + char *new_path = bprintf("%s/",path); + XBT_DEBUG("Change '%s' for '%s'",path,new_path); + xbt_dict_t dict = simcall_file_ls(mount, new_path); + xbt_free(new_path); + return dict; + } + + return simcall_file_ls(mount, path); +} diff --git a/src/simix/smx_io.c b/src/simix/smx_io.c index 7e6f53da2e..23aa928069 100644 --- a/src/simix/smx_io.c +++ b/src/simix/smx_io.c @@ -243,10 +243,58 @@ smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd) return action; } +//SIMIX FILE LS +void SIMIX_pre_file_ls(smx_simcall_t simcall) +{ + smx_action_t action = SIMIX_file_ls(simcall->issuer, + simcall->file_ls.mount, simcall->file_ls.path); + xbt_fifo_push(action->simcalls, simcall); + simcall->issuer->waiting_action = action; +} +smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char *path) +{ + smx_action_t action; + smx_host_t host = process->smx_host; + /* check if the host is active */ + if (surf_workstation_model->extension.workstation.get_state(host->host) != SURF_RESOURCE_ON) { + THROWF(host_error, 0, "Host %s failed, you cannot call this function", + host->name); + } + + action = xbt_mallocator_get(simix_global->action_mallocator); + action->type = SIMIX_ACTION_IO; + action->name = NULL; +#ifdef HAVE_TRACING + action->category = NULL; +#endif + + action->io.host = host; + action->io.surf_io = surf_workstation_model->extension.workstation.ls(host->host,mount,path); + + surf_workstation_model->action_data_set(action->io.surf_io, action); + XBT_DEBUG("Create io action %p", action); + return action; +} + +static void free_file_stat(void *p) +{ + file_stat_t fs = p; + xbt_free(fs->date); + xbt_free(fs->group); + xbt_free(fs->time); + xbt_free(fs->user); + xbt_free(fs->user_rights); + xbt_free(fs); +} + void SIMIX_post_io(smx_action_t action) { xbt_fifo_item_t i; smx_simcall_t simcall; + char* key; + xbt_dict_cursor_t cursor = NULL; + s_file_stat_t *dst = NULL; + s_file_stat_t *src = NULL; xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) { switch (simcall->call) { @@ -254,26 +302,44 @@ void SIMIX_post_io(smx_action_t action) simcall->file_open.result = xbt_new(s_smx_file_t,1); simcall->file_open.result->surf_file = (action->io.surf_io)->file; break; + case SIMCALL_FILE_CLOSE: xbt_free(simcall->file_close.fp); simcall->file_close.result = 0; break; + case SIMCALL_FILE_WRITE: simcall->file_write.result = (action->io.surf_io)->cost; break; + case SIMCALL_FILE_READ: simcall->file_read.result = (action->io.surf_io)->cost; break; + case SIMCALL_FILE_STAT: simcall->file_stat.result = 0; - s_file_stat_t *dst = &(simcall->file_stat.buf); - s_file_stat_t *src = &((action->io.surf_io)->stat); + dst = &(simcall->file_stat.buf); + src = &((action->io.surf_io)->stat); file_stat_copy(src,dst); break; + case SIMCALL_FILE_UNLINK: xbt_free(simcall->file_unlink.fd); simcall->file_unlink.result = 0; break; + + case SIMCALL_FILE_LS: + xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){ + // if there is a stat we have to duplicate it + if(src){ + dst = xbt_new0(s_file_stat_t,1); + file_stat_copy(src, dst); + xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,free_file_stat); + } + } + simcall->file_ls.result = (action->io.surf_io)->ls_dict; + break; + default: break; } diff --git a/src/simix/smx_io_private.h b/src/simix/smx_io_private.h index 6f7d361573..b7df26c0c9 100644 --- a/src/simix/smx_io_private.h +++ b/src/simix/smx_io_private.h @@ -16,6 +16,7 @@ void SIMIX_pre_file_open(smx_simcall_t simcall); void SIMIX_pre_file_close(smx_simcall_t simcall); void SIMIX_pre_file_stat(smx_simcall_t simcall); void SIMIX_pre_file_unlink(smx_simcall_t simcall); +void SIMIX_pre_file_ls(smx_simcall_t simcall); smx_action_t SIMIX_file_read(smx_process_t process, void* ptr, size_t size, size_t nmemb, smx_file_t stream); smx_action_t SIMIX_file_write(smx_process_t process, const void* ptr, size_t size, size_t nmemb, smx_file_t stream); @@ -23,6 +24,7 @@ smx_action_t SIMIX_file_open(smx_process_t process, const char* storage, const c smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fp); smx_action_t SIMIX_file_stat(smx_process_t process, smx_file_t fd, s_file_stat_t buf); smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd); +smx_action_t SIMIX_file_ls(smx_process_t process, const char *mount, const char *path); void SIMIX_post_io(smx_action_t action); void SIMIX_io_destroy(smx_action_t action); diff --git a/src/simix/smx_smurf.c b/src/simix/smx_smurf.c index e8c8e2e812..4a679f81a6 100644 --- a/src/simix/smx_smurf.c +++ b/src/simix/smx_smurf.c @@ -536,6 +536,10 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value) SIMIX_pre_file_unlink(simcall); break; + case SIMCALL_FILE_LS: + SIMIX_pre_file_ls(simcall); + break; + case SIMCALL_ASR_GET_PROPERTIES: simcall->asr_get_properties.result = SIMIX_asr_get_properties(simcall->asr_get_properties.name); diff --git a/src/simix/smx_smurf_private.h b/src/simix/smx_smurf_private.h index 1f879470eb..a269fd55d1 100644 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@ -95,6 +95,7 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_OPEN),\ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_CLOSE),\ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_STAT), \ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_UNLINK),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_LS),\ SIMCALL_ENUM_ELEMENT(SIMCALL_ASR_GET_PROPERTIES) @@ -581,6 +582,12 @@ typedef struct s_smx_simcall { int result; } file_unlink; + struct { + const char *mount; + const char *path; + xbt_dict_t result; + } file_ls; + struct { const char* name; xbt_dict_t result; diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 4a8a1eb131..8fb5b34e81 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -1618,6 +1618,24 @@ int simcall_file_unlink(smx_file_t fd) return simcall->file_unlink.result; } +/** + * \ingroup simix_file_management + * + */ +xbt_dict_t simcall_file_ls(const char* mount, const char* path) +{ + smx_simcall_t simcall = SIMIX_simcall_mine(); + simcall->call = SIMCALL_FILE_LS; + simcall->file_ls.mount = mount; + simcall->file_ls.path = path; + if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */ + simcall->file_ls.result = NULL; + + SIMIX_simcall_push(simcall->issuer); + + return simcall->file_ls.result; +} + /* ************************************************************************** */ /** @brief returns a printable string representing a simcall */ diff --git a/src/surf/storage.c b/src/surf/storage.c index 9983513271..107208bdb7 100644 --- a/src/surf/storage.c +++ b/src/surf/storage.c @@ -38,6 +38,7 @@ static xbt_dynar_t storage_list; static xbt_dict_t parse_storage_content(char *filename, unsigned long *used_size); static void storage_action_state_set(surf_action_t action, e_surf_action_state_t state); static surf_action_t storage_action_execute (void *storage, double size, e_surf_action_storage_type_t type); +static void free_storage_content(void *p); static surf_action_t storage_action_stat(void *storage, surf_file_t stream) { @@ -47,6 +48,48 @@ static surf_action_t storage_action_stat(void *storage, surf_file_t stream) return action; } +static surf_action_t storage_action_ls(void *storage, const char* path) +{ + surf_action_t action = storage_action_execute(storage,0, LS); + action->ls_dict = NULL; + xbt_dict_t ls_dict = xbt_dict_new(); + + char* key; + surf_stat_t data = NULL; + xbt_dict_cursor_t cursor = NULL; + + xbt_dynar_t dyn = NULL; + char* file = NULL; + + // foreach file int the storage + xbt_dict_foreach(((storage_t)storage)->content,cursor,key,data){ + // Search if file start with the prefix 'path' + if(xbt_str_start_with(key,path)){ + file = &key[strlen(path)]; + + // Split file with '/' + dyn = xbt_str_split(file,"/"); + file = xbt_dynar_get_as(dyn,0,char*); + + // file + if(xbt_dynar_length(dyn) == 1){ + xbt_dict_set(ls_dict,file,&(data->stat),NULL); + } + // Directory + else + { + // if directory does not exist yet in dict + if(!xbt_dict_get_or_null(ls_dict,file)); + xbt_dict_set(ls_dict,file,NULL,NULL); + } + xbt_dynar_free(&dyn); + } + } + + action->ls_dict = ls_dict; + return action; +} + static surf_action_t storage_action_unlink(void *storage, surf_file_t stream) { surf_action_t action = storage_action_execute(storage,0, UNLINK); @@ -156,6 +199,7 @@ static surf_action_t storage_action_execute (void *storage, double size, e_surf_ case CLOSE: case STAT: case UNLINK: + case LS: break; case READ: lmm_expand(storage_maxmin_system, STORAGE->constraint_read, @@ -461,6 +505,7 @@ static void surf_storage_model_init_internal(void) surf_storage_model->extension.storage.write = storage_action_write; surf_storage_model->extension.storage.stat = storage_action_stat; surf_storage_model->extension.storage.unlink = storage_action_unlink; + surf_storage_model->extension.storage.ls = storage_action_ls; surf_storage_model->extension.storage.create_resource = storage_create_resource; if (!storage_maxmin_system) { diff --git a/src/surf/storage_private.h b/src/surf/storage_private.h index 5900e8fb3d..c62f265fe8 100644 --- a/src/surf/storage_private.h +++ b/src/surf/storage_private.h @@ -45,7 +45,7 @@ typedef struct storage { } s_storage_t, *storage_t; typedef enum { - READ=0, WRITE, STAT, OPEN, CLOSE, UNLINK + READ=0, WRITE, STAT, OPEN, CLOSE, UNLINK, LS } e_surf_action_storage_type_t; typedef struct surf_action_storage { diff --git a/src/surf/workstation.c b/src/surf/workstation.c index c92801b35d..30d3365fe9 100644 --- a/src/surf/workstation.c +++ b/src/surf/workstation.c @@ -351,6 +351,14 @@ static surf_action_t ws_action_unlink(void *workstation, surf_file_t stream) return model->extension.storage.unlink(st, stream); } +static surf_action_t ws_action_ls(void *workstation, const char* mount, const char *path) +{ + XBT_DEBUG("LS on mount '%s' and file '%s'",mount, path); + storage_t st = find_storage_on_mount_list(workstation, mount); + surf_model_t model = st->generic_resource.model; + return model->extension.storage.ls(st, path); +} + static void surf_workstation_model_init_internal(void) { surf_workstation_model = surf_model_init(); @@ -409,6 +417,7 @@ static void surf_workstation_model_init_internal(void) surf_workstation_model->extension.workstation.write = ws_action_write; surf_workstation_model->extension.workstation.stat = ws_action_stat; surf_workstation_model->extension.workstation.unlink = ws_action_unlink; + surf_workstation_model->extension.workstation.ls = ws_action_ls; } void surf_workstation_model_init_current_default(void) diff --git a/src/xbt/xbt_str.c b/src/xbt/xbt_str.c index 746092e008..a8d06e7bc1 100644 --- a/src/xbt/xbt_str.c +++ b/src/xbt/xbt_str.c @@ -903,6 +903,28 @@ char *xbt_str_from_file(FILE * file) return res; } +/* @brief Retrun 1 if string 'str' starts with string 'start' + * + * \param str a string + * \param start the string to search in str + * + * \return 1 if 'str' starts with 'start' + */ +int xbt_str_start_with(const char* str, const char* start) +{ + int i; + size_t l_str = strlen(str); + size_t l_start = strlen(start); + + if(l_start > l_str) return 0; + + for(i = 0; i< l_start; i++){ + if(str[i] != start[i]) return 0; + } + + return 1; +} + #ifdef SIMGRID_TEST #include "xbt/str.h"