1
1

Support archives .tar, .bz[2,zip], and .gz[ip]

This commit was SVN r27123.
Этот коммит содержится в:
Ralph Castain 2012-08-23 15:38:39 +00:00
родитель 286c610712
Коммит 855c9ae6cf
3 изменённых файлов: 161 добавлений и 34 удалений

Просмотреть файл

@ -46,7 +46,9 @@ BEGIN_C_DECLS
#define ORTE_FILEM_TYPE_FILE 0 #define ORTE_FILEM_TYPE_FILE 0
#define ORTE_FILEM_TYPE_DIR 1 #define ORTE_FILEM_TYPE_DIR 1
#define ORTE_FILEM_TYPE_UNKNOWN 2 #define ORTE_FILEM_TYPE_UNKNOWN 2
#define ORTE_FILEM_TYPE_ARCHIVE 3 #define ORTE_FILEM_TYPE_TAR 3
#define ORTE_FILEM_TYPE_BZIP 4
#define ORTE_FILEM_TYPE_GZIP 5
/** /**
* Type of movement * Type of movement

Просмотреть файл

@ -60,6 +60,7 @@ typedef struct {
char *top; char *top;
char *fullpath; char *fullpath;
int32_t type; int32_t type;
char **link_pts;
opal_list_t outputs; opal_list_t outputs;
} orte_filem_raw_incoming_t; } orte_filem_raw_incoming_t;
OBJ_CLASS_DECLARATION(orte_filem_raw_incoming_t); OBJ_CLASS_DECLARATION(orte_filem_raw_incoming_t);

Просмотреть файл

@ -293,6 +293,7 @@ static int raw_preposition_files(opal_list_t *fset,
char **files=NULL; char **files=NULL;
opal_list_t *file_set; opal_list_t *file_set;
orte_filem_raw_outbound_t *outbound; orte_filem_raw_outbound_t *outbound;
char *cptr;
if (NULL == fset) { if (NULL == fset) {
/* see if any were provided via MCA param */ /* see if any were provided via MCA param */
@ -312,7 +313,32 @@ static int raw_preposition_files(opal_list_t *fset,
for (i=0; NULL != files[i]; i++) { for (i=0; NULL != files[i]; i++) {
fs = OBJ_NEW(orte_filem_base_file_set_t); fs = OBJ_NEW(orte_filem_base_file_set_t);
fs->local_target = strdup(files[i]); fs->local_target = strdup(files[i]);
fs->target_flag = ORTE_FILEM_TYPE_FILE; /* check any suffix for file type */
if (NULL != (cptr = strchr(files[i], '.'))) {
if (0 == strncmp(cptr, ".tar", 4)) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: marking file %s as TAR",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
files[i]));
fs->target_flag = ORTE_FILEM_TYPE_TAR;
} else if (0 == strncmp(cptr, ".bz", 3)) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: marking file %s as BZIP",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
files[i]));
fs->target_flag = ORTE_FILEM_TYPE_BZIP;
} else if (0 == strncmp(cptr, ".gz", 3)) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: marking file %s as GZIP",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
files[i]));
fs->target_flag = ORTE_FILEM_TYPE_GZIP;
} else {
fs->target_flag = ORTE_FILEM_TYPE_FILE;
}
} else {
fs->target_flag = ORTE_FILEM_TYPE_FILE;
}
opal_list_append(file_set, &fs->super); opal_list_append(file_set, &fs->super);
} }
} else { } else {
@ -369,6 +395,36 @@ static int raw_preposition_files(opal_list_t *fset,
#endif #endif
} }
static int create_link(char *my_dir, char *path,
char *link_pt)
{
char *mypath, *fullname;
struct stat buf;
int rc = ORTE_SUCCESS;
/* form the full source path name */
mypath = opal_os_path(false, my_dir, link_pt, NULL);
/* form the full target path name */
fullname = opal_os_path(false, path, link_pt, NULL);
/* there may have been multiple files placed under the
* same directory, so check for existence first
*/
if (0 != stat(fullname, &buf)) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: creating symlink to %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), link_pt));
/* do the symlink */
if (0 != symlink(mypath, fullname)) {
opal_output(0, "%s Failed to symlink %s to %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), mypath, fullname);
rc = ORTE_ERROR;
}
}
free(mypath);
free(fullname);
return rc;
}
static int raw_link_local_files(orte_job_t *jdata) static int raw_link_local_files(orte_job_t *jdata)
{ {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
@ -377,11 +433,9 @@ static int raw_link_local_files(orte_job_t *jdata)
char *my_dir, *path=NULL; char *my_dir, *path=NULL;
orte_proc_t *proc; orte_proc_t *proc;
char *prefix; char *prefix;
char *mypath, *fullname;
int i, rc; int i, rc;
orte_filem_raw_incoming_t *inbnd; orte_filem_raw_incoming_t *inbnd;
opal_list_item_t *item; opal_list_item_t *item;
struct stat buf;
/* check my session directory for files I have received and /* check my session directory for files I have received and
* symlink them to the proc-level session directory of each * symlink them to the proc-level session directory of each
@ -432,37 +486,17 @@ static int raw_link_local_files(orte_job_t *jdata)
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output, OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: checking file %s", "%s filem:raw: checking file %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), inbnd->file)); ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), inbnd->file));
if (opal_path_is_absolute(inbnd->top)) { if (NULL != inbnd->link_pts) {
/* no link to create */ /* cycle thru the link points and create symlinks to them */
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output, for (i=0; NULL != inbnd->link_pts[i]; i++) {
"%s filem:raw: file %s is absolute - no link created", if (ORTE_SUCCESS != (rc = create_link(my_dir, path, inbnd->link_pts[i]))) {
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), inbnd->file)); ORTE_ERROR_LOG(rc);
continue; free(my_dir);
} free(path);
/* form the full source path name - we only need to return rc;
* create a link to the top of the target's stack }
*/
mypath = opal_os_path(false, my_dir, inbnd->top, NULL);
/* form the full target path name */
fullname = opal_os_path(false, path, inbnd->top, NULL);
/* there may have been multiple files placed under the
* same directory, so check for existence first
*/
if (0 != stat(fullname, &buf)) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: creating symlink to %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), inbnd->file));
/* do the symlink */
if (0 != symlink(mypath, fullname)) {
opal_output(0, "%s Failed to symlink %s to %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), mypath, fullname);
free(mypath);
free(fullname);
return ORTE_ERROR;
} }
} }
free(mypath);
free(fullname);
} }
free(path); free(path);
if (NULL != prefix) { if (NULL != prefix) {
@ -470,6 +504,7 @@ static int raw_link_local_files(orte_job_t *jdata)
} }
} }
free(my_dir);
return ORTE_SUCCESS; return ORTE_SUCCESS;
#endif #endif
} }
@ -623,6 +658,52 @@ static void send_complete(char *file, int status)
} }
} }
/* This is a little tricky as the name of the archive doesn't
* necessarily have anything to do with the paths inside it -
* so we have to first query the archive to retrieve that info
*/
static int link_archive(orte_filem_raw_incoming_t *inbnd)
{
FILE *fp;
char *cmd;
char path[MAXPATHLEN];
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: identifying links for archive %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
inbnd->fullpath));
asprintf(&cmd, "tar tf %s", inbnd->fullpath);
fp = popen(cmd, "r");
free(cmd);
if (NULL == fp) {
ORTE_ERROR_LOG(ORTE_ERR_FILE_OPEN_FAILURE);
return ORTE_ERR_FILE_OPEN_FAILURE;
}
while (fgets(path, sizeof(path), fp) != NULL) {
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: path %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
path));
/* if it is an absolute path, then do nothing - the user
* is responsible for knowing where it went
*/
if (opal_path_is_absolute(path)) {
continue;
}
/* take the first element of the path as our
* link point
*/
if (NULL != (cmd = strchr(path, '/'))) {
*cmd = '\0';
}
opal_argv_append_unique_nosize(&inbnd->link_pts, path, false);
}
/* close */
pclose(fp);
return ORTE_SUCCESS;
}
static void recv_files(int status, orte_process_name_t* sender, static void recv_files(int status, orte_process_name_t* sender,
opal_buffer_t* buffer, orte_rml_tag_t tag, opal_buffer_t* buffer, orte_rml_tag_t tag,
void* cbdata) void* cbdata)
@ -746,6 +827,7 @@ static void recv_files(int status, orte_process_name_t* sender,
incoming->fullpath = opal_os_path(false, jobfam_dir, target, NULL); incoming->fullpath = opal_os_path(false, jobfam_dir, target, NULL);
free(jobfam_dir); free(jobfam_dir);
} }
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output, OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s filem:raw: opening target file %s", "%s filem:raw: opening target file %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), incoming->fullpath)); ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), incoming->fullpath));
@ -815,7 +897,10 @@ static void write_handler(int fd, short event, void *cbdata)
opal_list_item_t *item; opal_list_item_t *item;
orte_filem_raw_output_t *output; orte_filem_raw_output_t *output;
int num_written; int num_written;
char *dirname, *cmd;
char homedir[MAXPATHLEN];
int rc;
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output, OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s write:handler writing data to %d", "%s write:handler writing data to %d",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
@ -833,6 +918,43 @@ static void write_handler(int fd, short event, void *cbdata)
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
sink->file)); sink->file));
send_complete(sink->file, ORTE_SUCCESS); send_complete(sink->file, ORTE_SUCCESS);
if (ORTE_FILEM_TYPE_FILE == sink->type) {
/* if it is an absolute path, then no link is required - the
* user is responsible for correctly pointing at it
*
* if it is a file and not an absolute path,
* then just link to the top as this will be the
* name we will want in each proc's session dir
*/
if (!opal_path_is_absolute(sink->top)) {
opal_argv_append_nosize(&sink->link_pts, sink->top);
}
} else {
/* unarchive the file */
if (ORTE_FILEM_TYPE_TAR == sink->type) {
asprintf(&cmd, "tar xf %s", sink->file);
} else if (ORTE_FILEM_TYPE_BZIP == sink->type) {
asprintf(&cmd, "tar xjf %s", sink->file);
} else if (ORTE_FILEM_TYPE_GZIP == sink->type) {
asprintf(&cmd, "tar xzf %s", sink->file);
}
getcwd(homedir, sizeof(homedir));
dirname = opal_dirname(sink->fullpath);
chdir(dirname);
OPAL_OUTPUT_VERBOSE((1, orte_filem_base_output,
"%s write:handler unarchiving file %s with cmd: %s",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
sink->file, cmd));
system(cmd);
chdir(homedir);
free(dirname);
free(cmd);
/* setup the link points */
if (ORTE_SUCCESS != (rc = link_archive(sink))) {
ORTE_ERROR_LOG(rc);
send_complete(sink->file, ORTE_ERR_FILE_WRITE_FAILURE);
}
}
return; return;
} }
num_written = write(sink->fd, output->data, output->numbytes); num_written = write(sink->fd, output->data, output->numbytes);
@ -931,6 +1053,7 @@ static void in_construct(orte_filem_raw_incoming_t *ptr)
ptr->file = NULL; ptr->file = NULL;
ptr->top = NULL; ptr->top = NULL;
ptr->fullpath = NULL; ptr->fullpath = NULL;
ptr->link_pts = NULL;
OBJ_CONSTRUCT(&ptr->outputs, opal_list_t); OBJ_CONSTRUCT(&ptr->outputs, opal_list_t);
} }
static void in_destruct(orte_filem_raw_incoming_t *ptr) static void in_destruct(orte_filem_raw_incoming_t *ptr)
@ -952,6 +1075,7 @@ static void in_destruct(orte_filem_raw_incoming_t *ptr)
if (NULL != ptr->fullpath) { if (NULL != ptr->fullpath) {
free(ptr->fullpath); free(ptr->fullpath);
} }
opal_argv_free(ptr->link_pts);
while (NULL != (item = opal_list_remove_first(&ptr->outputs))) { while (NULL != (item = opal_list_remove_first(&ptr->outputs))) {
OBJ_RELEASE(item); OBJ_RELEASE(item);
} }