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);
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);
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
#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 {
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;
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,
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);
+}
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) {
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;
}
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);
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);
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);
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)
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;
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 */
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)
{
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);
case CLOSE:
case STAT:
case UNLINK:
+ case LS:
break;
case READ:
lmm_expand(storage_maxmin_system, STORAGE->constraint_read,
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) {
} 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 {
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();
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)
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"