From: Pierre Veyre Date: Tue, 25 Mar 2014 14:22:11 +0000 (+0100) Subject: Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid X-Git-Tag: v3_11~192 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b61e0df4e0f5d85fbc1df364660fc71d9461adc6?hp=362246530b96737425628465f584af5a4a69f2fc Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid --- diff --git a/include/msg/msg.h b/include/msg/msg.h index f7f04a3f82..ec4eca8226 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -97,6 +97,8 @@ XBT_PUBLIC(void) __MSG_file_get_info(msg_file_t fd); XBT_PUBLIC(void) __MSG_file_priv_free(msg_file_priv_t priv); XBT_PUBLIC(const char *) MSG_file_get_name(msg_file_t storage); XBT_PUBLIC(msg_error_t) MSG_file_move(msg_file_t fd, const char* fullpath); +XBT_PUBLIC(msg_error_t) MSG_file_rcopy(msg_file_t fd, msg_host_t host, const char* fullpath); +XBT_PUBLIC(msg_error_t) MSG_file_rmove(msg_file_t fd, msg_host_t host, const char* fullpath); /************************** Storage handling ***********************************/ XBT_PUBLIC(msg_host_t) MSG_get_storage_by_name(const char *name); XBT_PUBLIC(const char *) MSG_storage_get_name(msg_storage_t storage); diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index fb0269864a..6b68336a4f 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -499,6 +499,7 @@ XBT_PUBLIC(xbt_dynar_t) simcall_file_get_info(smx_file_t fd); XBT_PUBLIC(sg_size_t) simcall_file_tell(smx_file_t fd); XBT_PUBLIC(int) simcall_file_seek(smx_file_t fd, sg_size_t offset, int origin); XBT_PUBLIC(int) simcall_file_move(smx_file_t fd, const char* fullpath); +XBT_PUBLIC(int) simcall_file_rcopy(smx_file_t fd, smx_host_t host, const char* fullpath); /***************************** Storage **********************************/ XBT_PUBLIC(sg_size_t) simcall_storage_get_free_size (const char* name); XBT_PUBLIC(sg_size_t) simcall_storage_get_used_size (const char* name); diff --git a/src/include/surf/surf.h b/src/include/surf/surf.h index 324681a49f..16da53a709 100644 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@ -721,6 +721,18 @@ XBT_PUBLIC(int) surf_workstation_file_move(surf_resource_t workstation, surf_fil */ XBT_PUBLIC(int) surf_workstation_file_seek(surf_resource_t workstation, surf_file_t fd, sg_size_t offset, int origin); +/** + * @brief Copy a file to another location on a remote host. + * @details [long description] + * + * @param workstation The surf workstation + * @param fd The file descriptor + * @param host_dest The workstation destination + * @param fullpath The new full path + * + * @return MSG_OK if successful, otherwise MSG_TASK_CANCELED + */ +XBT_PUBLIC(int) surf_workstation_file_rcopy(surf_resource_t workstation, surf_file_t fd, surf_resource_t host_dest, const char* fullpath); /** * @brief [brief description] diff --git a/src/msg/msg_io.c b/src/msg/msg_io.c index fbaf853759..2c2adca044 100644 --- a/src/msg/msg_io.c +++ b/src/msg/msg_io.c @@ -253,6 +253,38 @@ msg_error_t MSG_file_move (msg_file_t fd, const char* fullpath) return simcall_file_move(priv->simdata->smx_file, fullpath); } +/** + * \ingroup msg_file_management + * \brief Copy a file to another location on a remote host. + * \param fd : the file to move + * \param host : the remote host where the file has to be copied + * \param fullpath : the complete path destination on the remote host + * \return If successful, the function returns MSG_OK. Otherwise, it returns + * MSG_TASK_CANCELED. + */ +msg_error_t MSG_file_rcopy (msg_file_t file, msg_host_t host, const char* fullpath) +{ + msg_file_priv_t file_priv = MSG_file_priv(file); + return simcall_file_rcopy(file_priv->simdata->smx_file, host, fullpath); +} + +/** + * \ingroup msg_file_management + * \brief Move a file to another location on a remote host. + * \param fd : the file to move + * \param host : the remote host where the file has to be moved + * \param fullpath : the complete path destination on the remote host + * \return If successful, the function returns MSG_OK. Otherwise, it returns + * MSG_TASK_CANCELED. + */ +msg_error_t MSG_file_rmove (msg_file_t file, msg_host_t host, const char* fullpath) +{ + msg_file_priv_t file_priv = MSG_file_priv(file); + msg_error_t res = simcall_file_rcopy(file_priv->simdata->smx_file, host, fullpath); + simcall_file_unlink(file_priv->simdata->smx_file); + return res; +} + /** * \brief Destroys a file (internal call only) */ diff --git a/src/simix/simcalls.in b/src/simix/simcalls.in index 9c7a7dbbc1..f22c4447a7 100644 --- a/src/simix/simcalls.in +++ b/src/simix/simcalls.in @@ -119,6 +119,7 @@ file_tell True (sg_size_t) (fd, void*, smx_file_t) file_seek True (int) (fd, void*, smx_file_t) (offset, sg_size_t) (origin, int) file_get_info True (void*, xbt_dynar_t) (fd, void*, smx_file_t) file_move True (int) (fd, void*, smx_file_t) (fullpath, const char*) +file_rcopy True (int) (fd, void*, smx_file_t) (host, void*, smx_host_t) (fullpath, const char*) storage_get_free_size True (sg_size_t) (name, const char*) storage_get_used_size True (sg_size_t) (name, const char*) storage_get_properties True (void*, xbt_dict_t) (storage, void*, smx_storage_t) diff --git a/src/simix/simcalls_generated_args_getter_setter.h b/src/simix/simcalls_generated_args_getter_setter.h index 55ba1483c8..1e1c4219a0 100644 --- a/src/simix/simcalls_generated_args_getter_setter.h +++ b/src/simix/simcalls_generated_args_getter_setter.h @@ -1154,6 +1154,24 @@ static inline const char* simcall_file_move__get__fullpath(smx_simcall_t simcall static inline void simcall_file_move__set__fullpath(smx_simcall_t simcall, const char* arg){ simcall->args[1].cc = arg; } +static inline smx_file_t simcall_file_rcopy__get__fd(smx_simcall_t simcall){ + return (smx_file_t) simcall->args[0].dp; +} +static inline void simcall_file_rcopy__set__fd(smx_simcall_t simcall, void* arg){ + simcall->args[0].dp = arg; +} +static inline smx_host_t simcall_file_rcopy__get__host(smx_simcall_t simcall){ + return (smx_host_t) simcall->args[1].dp; +} +static inline void simcall_file_rcopy__set__host(smx_simcall_t simcall, void* arg){ + simcall->args[1].dp = arg; +} +static inline const char* simcall_file_rcopy__get__fullpath(smx_simcall_t simcall){ + return simcall->args[2].cc; +} +static inline void simcall_file_rcopy__set__fullpath(smx_simcall_t simcall, const char* arg){ + simcall->args[2].cc = arg; +} static inline const char* simcall_storage_get_free_size__get__name(smx_simcall_t simcall){ return simcall->args[0].cc; } diff --git a/src/simix/simcalls_generated_body.c b/src/simix/simcalls_generated_body.c index 5e2bf9e0d5..885dc4b46f 100644 --- a/src/simix/simcalls_generated_body.c +++ b/src/simix/simcalls_generated_body.c @@ -1781,6 +1781,23 @@ } return self->simcall.result.i; } + inline static int simcall_BODY_file_rcopy(smx_file_t fd, smx_host_t host, const char* fullpath) { + smx_process_t self = SIMIX_process_self(); + self->simcall.call = SIMCALL_FILE_RCOPY; + memset(&self->simcall.result, 0, sizeof(self->simcall.result)); + memset(self->simcall.args, 0, sizeof(self->simcall.args)); + self->simcall.args[0].dp = (void*) fd; + self->simcall.args[1].dp = (void*) host; + self->simcall.args[2].cc = (const char*) fullpath; + if (self != simix_global->maestro_process) { + XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name, + SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call); + SIMIX_process_yield(self); + } else { + SIMIX_simcall_pre(&self->simcall, 0); + } + return self->simcall.result.i; + } inline static sg_size_t simcall_BODY_storage_get_free_size(const char* name) { smx_process_t self = SIMIX_process_self(); self->simcall.call = SIMCALL_STORAGE_GET_FREE_SIZE; diff --git a/src/simix/simcalls_generated_case.c b/src/simix/simcalls_generated_case.c index 6d7bc913ca..bf5a69959e 100644 --- a/src/simix/simcalls_generated_case.c +++ b/src/simix/simcalls_generated_case.c @@ -551,6 +551,11 @@ case SIMCALL_FILE_MOVE: SIMIX_simcall_answer(simcall); break; +case SIMCALL_FILE_RCOPY: + simcall->result.i = SIMIX_pre_file_rcopy(simcall , (smx_file_t) simcall->args[0].dp, (smx_host_t) simcall->args[1].dp, simcall->args[2].cc); + SIMIX_simcall_answer(simcall); + break; + case SIMCALL_STORAGE_GET_FREE_SIZE: simcall->result.sgsz = SIMIX_pre_storage_get_free_size(simcall , simcall->args[0].cc); SIMIX_simcall_answer(simcall); diff --git a/src/simix/simcalls_generated_enum.h b/src/simix/simcalls_generated_enum.h index 448c05a917..5130bb2a8d 100644 --- a/src/simix/simcalls_generated_enum.h +++ b/src/simix/simcalls_generated_enum.h @@ -118,6 +118,7 @@ SIMCALL_FILE_TELL, SIMCALL_FILE_SEEK, SIMCALL_FILE_GET_INFO, SIMCALL_FILE_MOVE, +SIMCALL_FILE_RCOPY, SIMCALL_STORAGE_GET_FREE_SIZE, SIMCALL_STORAGE_GET_USED_SIZE, SIMCALL_STORAGE_GET_PROPERTIES, diff --git a/src/simix/simcalls_generated_res_getter_setter.h b/src/simix/simcalls_generated_res_getter_setter.h index 052b1f4456..d339060927 100644 --- a/src/simix/simcalls_generated_res_getter_setter.h +++ b/src/simix/simcalls_generated_res_getter_setter.h @@ -491,6 +491,12 @@ static inline int simcall_file_move__get__result(smx_simcall_t simcall){ static inline void simcall_file_move__set__result(smx_simcall_t simcall, int result){ simcall->result.i = result; } +static inline int simcall_file_rcopy__get__result(smx_simcall_t simcall){ + return simcall->result.i; +} +static inline void simcall_file_rcopy__set__result(smx_simcall_t simcall, int result){ + simcall->result.i = result; +} static inline sg_size_t simcall_storage_get_free_size__get__result(smx_simcall_t simcall){ return simcall->result.sgsz; } diff --git a/src/simix/simcalls_generated_string.c b/src/simix/simcalls_generated_string.c index 0f14211855..8ef57bea32 100644 --- a/src/simix/simcalls_generated_string.c +++ b/src/simix/simcalls_generated_string.c @@ -118,6 +118,7 @@ [SIMCALL_FILE_SEEK] = "SIMCALL_FILE_SEEK", [SIMCALL_FILE_GET_INFO] = "SIMCALL_FILE_GET_INFO", [SIMCALL_FILE_MOVE] = "SIMCALL_FILE_MOVE", +[SIMCALL_FILE_RCOPY] = "SIMCALL_FILE_RCOPY", [SIMCALL_STORAGE_GET_FREE_SIZE] = "SIMCALL_STORAGE_GET_FREE_SIZE", [SIMCALL_STORAGE_GET_USED_SIZE] = "SIMCALL_STORAGE_GET_USED_SIZE", [SIMCALL_STORAGE_GET_PROPERTIES] = "SIMCALL_STORAGE_GET_PROPERTIES", diff --git a/src/simix/smx_io.c b/src/simix/smx_io.c index 25c87cf078..b4dc9b8b6f 100644 --- a/src/simix/smx_io.c +++ b/src/simix/smx_io.c @@ -301,6 +301,17 @@ int SIMIX_file_move(smx_process_t process, smx_file_t file, const char* fullpath return surf_workstation_file_move(host, file->surf_file, fullpath); } +int SIMIX_pre_file_rcopy(smx_simcall_t simcall, smx_file_t fd, smx_host_t host, const char* fullpath) +{ + return SIMIX_file_rcopy(simcall->issuer, fd, host, fullpath); +} + +int SIMIX_file_rcopy(smx_process_t process, smx_file_t file, smx_host_t host_dest, const char* fullpath) +{ + smx_host_t host = process->smx_host; + return surf_workstation_file_rcopy(host, file->surf_file, host_dest, fullpath); +} + sg_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name) { return SIMIX_storage_get_free_size(simcall->issuer, name); diff --git a/src/simix/smx_io_private.h b/src/simix/smx_io_private.h index 8a3c38d7db..15e2624341 100644 --- a/src/simix/smx_io_private.h +++ b/src/simix/smx_io_private.h @@ -34,6 +34,7 @@ sg_size_t SIMIX_pre_file_tell(smx_simcall_t simcall, smx_file_t fd); xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd); int SIMIX_pre_file_seek(smx_simcall_t simcall, smx_file_t fd, sg_size_t offset, int origin); int SIMIX_pre_file_move(smx_simcall_t simcall, smx_file_t fd, const char* fullpath); +int SIMIX_pre_file_rcopy(smx_simcall_t simcall, smx_file_t fd, smx_host_t dest, const char* fullpath); smx_action_t SIMIX_file_read(smx_process_t process, smx_file_t fd, sg_size_t size); smx_action_t SIMIX_file_write(smx_process_t process, smx_file_t fd, sg_size_t size); smx_action_t SIMIX_file_open(smx_process_t process, const char* fullpath); @@ -46,6 +47,7 @@ sg_size_t SIMIX_file_tell(smx_process_t process, smx_file_t fd); xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd); int SIMIX_file_seek(smx_process_t process, smx_file_t fd, sg_size_t offset, int origin); int SIMIX_file_move(smx_process_t process, smx_file_t fd, const char* fullpath); +int SIMIX_file_rcopy(smx_process_t process, smx_file_t fd, smx_host_t dest, const char* fullpath); sg_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall,const char* name); sg_size_t SIMIX_storage_get_free_size(smx_process_t process,const char* name); diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index d4ecd2f121..43085e4746 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -1410,6 +1410,16 @@ int simcall_file_move(smx_file_t fd, const char* fullpath) return simcall_BODY_file_move(fd, fullpath); } +/** + * \ingroup simix_file_management + * \brief Copy a file to another location on a remote host. + * + */ +int simcall_file_rcopy(smx_file_t fd, smx_host_t host, const char* fullpath) +{ + return simcall_BODY_file_rcopy(fd, host, fullpath); +} + /** * \ingroup simix_storage_management * \brief Returns the free space size on a given storage element. diff --git a/src/surf/surf_c_bindings.cpp b/src/surf/surf_c_bindings.cpp index 82e93b145c..b34f4eecfc 100644 --- a/src/surf/surf_c_bindings.cpp +++ b/src/surf/surf_c_bindings.cpp @@ -412,6 +412,10 @@ int surf_workstation_file_move(surf_resource_t workstation, surf_file_t fd, cons return get_casted_workstation(workstation)->fileMove(fd, fullpath); } +int surf_workstation_file_rcopy(surf_resource_t workstation, surf_file_t fd, surf_resource_t host_dest, const char* fullpath){ + return get_casted_workstation(workstation)->fileRcopy(fd, host_dest, fullpath); +} + xbt_dynar_t surf_workstation_get_vms(surf_resource_t resource){ return get_casted_workstation(resource)->getVms(); } diff --git a/src/surf/workstation_interface.cpp b/src/surf/workstation_interface.cpp index 60480b9bed..7149daf2ee 100644 --- a/src/surf/workstation_interface.cpp +++ b/src/surf/workstation_interface.cpp @@ -9,6 +9,8 @@ #include "cpu_cas01.hpp" #include "simgrid/sg_config.h" +#include "network_interface.hpp" + XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf, "Logging specific to the SURF workstation module"); @@ -267,7 +269,7 @@ int Workstation::unlink(surf_file_t fd) { XBT_WARN("No such file descriptor. Impossible to unlink"); return 0; } else { -// XBT_INFO("%s %zu", fd->storage, fd->size); + StoragePtr st = findStorageOnMountList(fd->mount); /* Check if the file is on this storage */ if (!xbt_dict_get_or_null(st->p_content, fd->name)){ @@ -367,6 +369,117 @@ int Workstation::fileMove(surf_file_t fd, const char* fullpath){ } } +int Workstation::fileRcopy(surf_file_t fd, surf_resource_t host_dest, const char* fullpath){ + + XBT_DEBUG("Rcopy file %s on %s to %s",fd->name, host_dest->key, fullpath); + + /* Find the host src where the file is located */ + StoragePtr storage = findStorageOnMountList(fd->mount); + const char* host_name_src = (const char*)storage->p_attach; + + /* Find the real host dest where the file will be stored */ + s_mount_t mnt; + unsigned int cursor; + StoragePtr storage_dest = NULL; + const char* host_name_dest; + char *file_mount_name; + size_t longest_prefix_length = 0; + WorkstationPtr dest_ws, src_ws; + + dest_ws = static_cast(surf_workstation_resource_priv(host_dest)); + + xbt_dynar_foreach(dest_ws->p_storage,cursor,mnt) + { + file_mount_name = (char *) xbt_malloc ((strlen(mnt.name)+1)); + strncpy(file_mount_name,fullpath,strlen(mnt.name)+1); + file_mount_name[strlen(mnt.name)] = '\0'; + + if(!strcmp(file_mount_name,mnt.name) && strlen(mnt.name)>longest_prefix_length) + {/* The current mount name is found in the full path and is bigger than the previous*/ + longest_prefix_length = strlen(mnt.name); + storage_dest = static_cast(mnt.storage); + } + free(file_mount_name); + } + if(longest_prefix_length>0) + { /* Mount point found, retrieve the host the storage is attached to */ + host_name_dest = storage_dest->p_attach; + } + else + { + XBT_WARN("Can't find mount point for '%s' on destination host '%s'", fullpath, host_dest->key); + return MSG_TASK_CANCELED; + } + + /* Check that there is a route between src and dest workstations */ + xbt_dynar_t route = NULL; + dest_ws = static_cast(surf_workstation_resource_priv(xbt_lib_get_elm_or_null(host_lib, host_name_dest))); + src_ws = static_cast(surf_workstation_resource_priv(xbt_lib_get_elm_or_null(host_lib, host_name_src))); + + routing_get_route_and_latency(src_ws->p_netElm, dest_ws->p_netElm, &route, NULL); + if(!xbt_dynar_length (route)) + { + XBT_WARN("There is no route between %s and %s. Action has been canceled", src_ws->getName(), dest_ws->getName()); + return MSG_TASK_CANCELED; + } + else + {/* There is a route between src and dest, let's copy the file */ + + /* Read the file on the src side */ + src_ws->read(fd, fd->size); + + /* Send a message from src to dest to simulate data transfer */ + surf_network_model->communicate(src_ws->p_netElm, dest_ws->p_netElm, fd->size, -1.0); + + /* Create the file on the dest side and write data into it*/ + char *mount_name, *path; + path = (char *) xbt_malloc ((strlen(fullpath)-longest_prefix_length+1)); + mount_name = (char *) xbt_malloc ((longest_prefix_length+1)); + /* deduce mount_name and path from fullpath */ + strncpy(mount_name, fullpath, longest_prefix_length+1); + strncpy(path, fullpath+longest_prefix_length, strlen(fullpath)-longest_prefix_length+1); + path[strlen(fullpath)-longest_prefix_length] = '\0'; + mount_name[longest_prefix_length] = '\0'; + /* create the file */ + ActionPtr open_action = storage_dest->open((const char*)mount_name, (const char*)path); + /* write data */ + dest_ws->write(static_cast(open_action)->p_file, fd->size); + dest_ws->close(static_cast(open_action)->p_file); + free(path); + free(mount_name); + XBT_DEBUG("File %s has been copied on %s to %s",fd->name, host_dest->key, fullpath); + return MSG_OK; + } + + + XBT_INFO("SRC %s DEST %s", host_name_src, host_name_dest); + + + +// /* Check that file to copy is local to the src workstation (storage is attached to src workstation) */ +// StoragePtr storage = findStorageOnMountList(fd->mount); +// if(!strcmp((const char*)storage->p_attach, this->getName())) +// { +// /* Check that there is a route between src and dest workstations */ +// xbt_dynar_t route = NULL; +// routing_get_route_and_latency(this->p_netElm, ((WorkstationPtr)host_dest)->p_netElm, &route, NULL); +// if(route){ +// +// ATTENTION DISCUSSION AVEC FRED ! +// return MSG_OK; +// } +// else +// { +// XBT_WARN("There is no route between %s and %s. Action has been canceled", this->getName(), host_dest->key); +// return MSG_TASK_CANCELED; +// } +// } +// else +// { +// XBT_WARN("File %s is not local to %s but to %s. Action has been canceled", fd->name,this->getName(), storage->p_attach); +// return MSG_TASK_CANCELED; +// } +} sg_size_t Workstation::getFreeSize(const char* name) { diff --git a/src/surf/workstation_interface.hpp b/src/surf/workstation_interface.hpp index 473b044a09..c472d377c6 100644 --- a/src/surf/workstation_interface.hpp +++ b/src/surf/workstation_interface.hpp @@ -380,6 +380,17 @@ public: */ virtual int fileMove(surf_file_t fd, const char* fullpath); + /** + * @brief Copy a file to another location on a remote host. + * @details [long description] + * + * @param fd The file descriptor + * @param host_dest The worstation destination + * @param fullpath The new full path + * @return MSG_OK if successful, otherwise MSG_TASK_CANCELED + */ + virtual int fileRcopy(surf_file_t fd, surf_resource_t host_dest, const char* fullpath); + xbt_dynar_t p_storage; RoutingEdgePtr p_netElm; CpuPtr p_cpu;