Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a function ls to storage
authornavarro <navarro@caraja.(none)>
Tue, 11 Sep 2012 12:03:31 +0000 (14:03 +0200)
committernavarro <navarro@caraja.(none)>
Tue, 11 Sep 2012 12:14:31 +0000 (14:14 +0200)
14 files changed:
include/msg/msg.h
include/simgrid/simix.h
include/xbt/str.h
src/include/surf/surf.h
src/msg/msg_io.c
src/simix/smx_io.c
src/simix/smx_io_private.h
src/simix/smx_smurf.c
src/simix/smx_smurf_private.h
src/simix/smx_user.c
src/surf/storage.c
src/surf/storage_private.h
src/surf/workstation.c
src/xbt/xbt_str.c

index 44c79a4..fdfda0f 100644 (file)
@@ -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);
index 4066388..830b33d 100644 (file)
@@ -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);
index 865ea28..39ecbd6 100644 (file)
@@ -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
 
index 66345cc..475f9da 100644 (file)
@@ -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,
index 2b03f67..1932908 100644 (file)
@@ -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);
+}
index 7e6f53d..23aa928 100644 (file)
@@ -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;
     }
index 6f7d361..b7df26c 100644 (file)
@@ -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);
index e8c8e2e..4a679f8 100644 (file)
@@ -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);
index 1f87947..a269fd5 100644 (file)
@@ -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;
index 4a8a1eb..8fb5b34 100644 (file)
@@ -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 */
index 9983513..107208b 100644 (file)
@@ -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) {
index 5900e8f..c62f265 100644 (file)
@@ -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 {
index c92801b..30d3365 100644 (file)
@@ -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)
index 746092e..a8d06e7 100644 (file)
@@ -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"