Add qlmpi and swap to mckernel (This is rebase commit for merging to development)

This commit is contained in:
Yutaka Ishikawa
2017-07-23 21:19:15 +09:00
committed by Ken Sato
parent 74f15783d2
commit 236a072311
61 changed files with 6638 additions and 24 deletions

View File

@@ -1,22 +1,33 @@
CC=@CC@
MCC=mpicc
BINDIR=@BINDIR@
SBINDIR=@SBINDIR@
prefix=@prefix@
exec_prefix=@exec_prefix@
LIBDIR=@libdir@
MCKERNEL_INCDIR=@MCKERNEL_INCDIR@
MCKERNEL_LIBDIR=@MCKERNEL_LIBDIR@
KDIR ?= @KDIR@
CFLAGS=-Wall -O -I. -I$(VPATH)/arch/${ARCH}
LDFLAGS=@LDFLAGS@
VPATH=@abs_srcdir@
TARGET=mcexec libsched_yield
@uncomment_if_ENABLE_MEMDUMP@TARGET+=eclair
LIBS=@LIBS@
ARCH=@ARCH@
IHKDIR ?= $(VPATH)/../../../ihk/linux/include/
MCEXEC_LIBS=-lmcexec -lrt -lnuma -pthread
ENABLE_QLMPI=@ENABLE_QLMPI@
ifeq ($(ENABLE_QLMPI),yes)
MCEXEC_LIBS += -lmpi
TARGET+= libqlmpi.so ql_server ql_mpiexec_start ql_mpiexec_finalize ql_talker libqlfort.so
endif
all: $(TARGET)
mcexec: mcexec.c libmcexec.a
$(CC) -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -DLIBDIR=\"$(LIBDIR)\" -fPIE -pie -L. -lmcexec -lrt -lnuma -pthread -o $@ $^ $(EXTRA_OBJS)
$(CC) -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) -DLIBDIR=\"$(LIBDIR)\" -fPIE -pie -L. $(MCEXEC_LIBS) -o $@ $^ $(EXTRA_OBJS)
eclair: eclair.c
$(CC) $(CFLAGS) -I${IHKDIR} -o $@ $^ $(LIBS)
@@ -27,6 +38,27 @@ libsched_yield: libsched_yield.c
libmcexec.a::
(cd arch/${ARCH}; make)
libqlmpi.so: qlmpilib.c
$(MCC) $(CFLAGS) $(LDFLAGS) -shared -fPIC -o $@ $<
libqlfort.so: libqlfort.c
$(MCC) $(CFLAGS) $(LDFLAGS) -shared -fPIC -o $@ $< -ldl
ql_server: ql_server.c
$(CC) $(CFLAGS) -o $@ $^
ql_mpiexec_start: ql_mpiexec_start.o md5.o
$(CC) $^ $(CFLAGS) -pthread -o $@
ql_mpiexec_finalize.o: ql_mpiexec_start.c
$(CC) $(CFLAGS) -DQL_MPIEXEC_FINALIZE -c -o $@ $<
ql_mpiexec_finalize: ql_mpiexec_finalize.o md5.o
$(CC) $^ $(CFLAGS) -pthread -o $@
ql_talker: ql_talker.o
$(CC) $^ $(CFLAGS) -o $@
clean::
(cd arch/${ARCH}; make clean)
$(RM) $(TARGET) *.o
@@ -39,5 +71,13 @@ install::
install -m 755 mcexec $(BINDIR)
mkdir -p -m 755 $(MCKERNEL_LIBDIR)
install -m 755 libsched_yield.so.1.0.0 $(MCKERNEL_LIBDIR)
ifeq ($(ENABLE_QLMPI),yes)
install -m 644 ../include/qlmpilib.h $(MCKERNEL_INCDIR)
install -m 755 libqlmpi.so $(MCKERNEL_LIBDIR)
install -m 755 libqlfort.so $(MCKERNEL_LIBDIR)
install -m 755 ql_server $(SBINDIR)
install -m 755 ql_mpiexec_start $(BINDIR)
install -m 755 ql_mpiexec_finalize $(BINDIR)
install -m 755 ql_talker $(SBINDIR)
endif
@uncomment_if_ENABLE_MEMDUMP@install -m 755 eclair $(BINDIR)

101
executer/user/libqlfort.c Normal file
View File

@@ -0,0 +1,101 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
static int *mck_ql_argc;
static char ***mck_ql_argv;
static int (*intel_iargc)();
static int (*intel_getarg)(int *, char *, int, int);
static int (*gfortran_iargc)();
static int (*gfortran_getarg)(int *, char *, int);
static void (*mpi_init)(int *);
static int dl_init_flag;
static inline void
init()
{
if (dl_init_flag)
return;
mck_ql_argc = dlsym(RTLD_NEXT, "mck_ql_argc");
mck_ql_argv = dlsym(RTLD_NEXT, "mck_ql_argv");
intel_iargc = dlsym(RTLD_NEXT, "for_iargc");
intel_getarg = dlsym(RTLD_NEXT, "for_getarg");
gfortran_iargc = dlsym(RTLD_NEXT, "_gfortran_iargc");
gfortran_getarg = dlsym(RTLD_NEXT, "_gfortran_getarg_i4");
mpi_init = dlsym(RTLD_NEXT, "mpi_init_");
dl_init_flag = 1;
}
// for GNU Fortran
int
_gfortran_iargc()
{
init();
if (mck_ql_argc && mck_ql_argv && *mck_ql_argv)
return *mck_ql_argc - 1;
if (gfortran_iargc)
return gfortran_iargc();
return 0;
}
void
_gfortran_getarg_i4(int *n, char *arg, int arg_len)
{
int l;
init();
if (mck_ql_argc && mck_ql_argv && *mck_ql_argv) {
memset(arg, ' ', arg_len);
if (*n < 0 || *n > *mck_ql_argc)
return;
l = strlen((*mck_ql_argv)[*n]);
if (l > arg_len)
l = arg_len;
strncpy(arg, (*mck_ql_argv)[*n], l);
return;
}
if (gfortran_getarg) {
gfortran_getarg(n, arg, arg_len);
return;
}
return;
}
// for Intel Fortran
int
for_iargc()
{
init();
if (mck_ql_argc && mck_ql_argv && *mck_ql_argv)
return *mck_ql_argc - 1;
if (intel_iargc)
return intel_iargc();
return 0;
}
void
for_getarg(int *n, char *arg, int dmy1, int arg_len)
{
int l;
init();
if (mck_ql_argc && mck_ql_argv && *mck_ql_argv) {
memset(arg, ' ', arg_len);
if (*n < 0 || *n > *mck_ql_argc)
return;
l = strlen((*mck_ql_argv)[*n]);
if (l > arg_len)
l = arg_len;
strncpy(arg, (*mck_ql_argv)[*n], l);
return;
}
if (intel_getarg) {
intel_getarg(n, arg, dmy1, arg_len);
return;
}
return;
}

View File

@@ -73,7 +73,12 @@
#include "../../config.h"
#include <numa.h>
#include <numaif.h>
#include <spawn.h>
#include <sys/personality.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "../include/pmi.h"
#include "../include/qlmpi.h"
//#define DEBUG
@@ -1568,6 +1573,37 @@ opendev()
return fd;
}
static void ld_preload_init()
{
char envbuf[PATH_MAX];
char *old_ld_preload;
if (disable_sched_yield) {
sprintf(envbuf, "%s/libsched_yield.so.1.0.0", MCKERNEL_LIBDIR);
__dprintf("%s: %s\n", __FUNCTION__, sched_yield_lib_path);
if (setenv("LD_PRELOAD", envbuf, 1) < 0) {
printf("%s: warning: failed to set LD_PRELOAD for sched_yield\n",
__FUNCTION__);
}
}
/* Set LD_PRELOAD to McKernel specific value */
else if (getenv(ld_preload_envname)) {
if (setenv("LD_PRELOAD", getenv(ld_preload_envname), 1) < 0) {
printf("%s: warning: failed to set LD_PRELOAD environment variable\n",
__FUNCTION__);
}
unsetenv(ld_preload_envname);
}
#ifdef ENABLE_QLMPI
sprintf(envbuf, "%s/libqlfort.so", MCKERNEL_LIBDIR);
if ((old_ld_preload = getenv("LD_PRELOAD"))) {
sprintf(strchr(envbuf, '\0'), " %s", old_ld_preload);
}
setenv("LD_PRELOAD", envbuf, 1);
#endif
}
int main(int argc, char **argv)
{
int ret = 0;
@@ -1683,24 +1719,7 @@ int main(int argc, char **argv)
if (opendev() == -1)
exit(EXIT_FAILURE);
if (disable_sched_yield) {
char sched_yield_lib_path[PATH_MAX];
sprintf(sched_yield_lib_path, "%s/libsched_yield.so.1.0.0",
MCKERNEL_LIBDIR);
__dprintf("%s: %s\n", __FUNCTION__, sched_yield_lib_path);
if (setenv("LD_PRELOAD", sched_yield_lib_path, 1) < 0) {
printf("%s: warning: failed to set LD_PRELOAD for sched_yield\n",
__FUNCTION__);
}
}
/* Set LD_PRELOAD to McKernel specific value */
else if (getenv(ld_preload_envname)) {
if (setenv("LD_PRELOAD", getenv(ld_preload_envname), 1) < 0) {
printf("%s: warning: failed to set LD_PRELOAD environment variable\n",
__FUNCTION__);
}
unsetenv(ld_preload_envname);
}
ld_preload_init();
/* Collect environment variables */
envs_len = flatten_strings(-1, NULL, environ, &envs);
@@ -3416,6 +3435,194 @@ return_execve2:
}
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
break;
case 801: {// swapout
#ifdef ENABLE_QLMPI
int rc;
int spawned;
int rank;
int ql_fd = -1;
int len;
struct sockaddr_un unix_addr;
char msg_buf[QL_BUF_MAX];
char *ql_name;
rc = PMI_Init(&spawned);
if (rc != 0) {
fprintf(stderr, "swapout(): ERROR: failed to init PMI\n");
ret = -1;
goto return_swapout;
}
rc = PMI_Get_rank(&rank);
if (rc != 0) {
fprintf(stderr, "swapout(): ERROR: failed to get Rank\n");
ret = -1;
goto return_swapout;
}
// swap synchronization
rc = PMI_Barrier();
if (rank == 0) {
// tell ql_server what calculation is done.
ql_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (ql_fd < 0) {
fprintf(stderr, "swapout(): ERROR: failed to open socket\n");
ret = -1;
goto return_swapout;
}
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, getenv("QL_SOCKET_FILE"));
len = sizeof(unix_addr.sun_family) + strlen(unix_addr.sun_path) + 1;
rc = connect(ql_fd, (struct sockaddr*)&unix_addr, len);
if (rc < 0) {
fprintf(stderr, "swapout(): ERROR: failed to connect ql_server\n");
ret = -1;
goto return_swapout;
}
ql_name = getenv(QL_NAME);
sprintf(msg_buf, "%c %04x %s",
QL_EXEC_END, (unsigned int)strlen(ql_name), ql_name);
rc = send(ql_fd, msg_buf, strlen(msg_buf) + 1, 0);
if (rc < 0) {
fprintf(stderr, "swapout(): ERROR: failed to send QL_EXEC_END\n");
ret = -1;
goto return_swapout;
}
// wait resume-req from ql_server.
#ifdef QL_DEBUG
fprintf(stdout, "INFO: waiting resume-req ...\n");
#endif
rc = recv(ql_fd, msg_buf, strlen(msg_buf) + 1, 0);
if (rc < 0) {
fprintf(stderr, "swapout(): ERROR: failed to recieve\n");
ret = -1;
goto return_swapout;
}
// parse message
if (msg_buf[0] == QL_RET_RESUME) {
#ifdef QL_DEBUG
fprintf(stdout, "INFO: recieved resume-req\n");
#endif
}
else {
fprintf(stderr, "swapout(): ERROR: recieved unexpected requsest from ql_server\n");
ret = -1;
goto return_swapout;
}
// resume-req synchronization
rc = PMI_Barrier();
}
else {
// resume-req synchronization
rc = PMI_Barrier();
}
ret = 0;
return_swapout:
if (ql_fd >= 0) {
close(ql_fd);
}
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
#else
printf("mcexec has not been compiled with ENABLE_QLMPI\n");
ret = -1;
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
#endif // ENABLE_QLMPI
break;
}
case 802: /* debugging purpose */
printf("linux mlock(%p, %ld)\n",
(void *)w.sr.args[0], w.sr.args[1]);
printf("str(%p)=%s", (void*)w.sr.args[0], (char*)w.sr.args[0]);
ret = mlock((void *)w.sr.args[0], w.sr.args[1]);
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
break;
#ifndef ARG_MAX
#define ARG_MAX 256
#endif
case 811: { // linux_spawn
int rc, i;
pid_t pid;
size_t slen;
char *exec_path = NULL;
char* argv[ARG_MAX];
char** spawn_args = (char**)w.sr.args[1];
if (!w.sr.args[0] || ! spawn_args) {
fprintf(stderr, "linux_spawn(): ERROR: invalid argument \n");
ret = -1;
goto return_linux_spawn;
}
// copy exec_path
slen = strlen((char*)w.sr.args[0]) + 1;
if (slen <= 0 || slen >= PATH_MAX) {
fprintf(stderr, "linux_spawn(): ERROR: invalid exec_path \n");
ret = -1;
goto return_linux_spawn;
}
exec_path = malloc(slen);
if (!exec_path) {
fprintf(stderr, "linux_spawn(): ERROR: failed to allocating exec_path\n");
ret = -1;
goto return_linux_spawn;
}
memset(exec_path, '\0', slen);
rc = do_strncpy_from_user(fd, exec_path, (void *)w.sr.args[0], slen);
if (rc < 0) {
fprintf(stderr, "linux_spawn(): ERROR: failed to strncpy from user\n");
ret = -1;
goto return_linux_spawn;
}
// copy args to argv[]
for (i = 0; spawn_args[i] != NULL; i++) {
slen = strlen(spawn_args[i]) + 1;
argv[i] = malloc(slen);
if (!argv[i]) {
fprintf(stderr, "linux_spawn(): ERROR: failed to allocating argv[%d]\n", i);
ret = -1;
goto return_linux_spawn;
}
memset(argv[i], '\0', slen);
rc = do_strncpy_from_user(fd, argv[i], spawn_args[i], slen);
if (rc < 0) {
fprintf(stderr, "linux_spawn(): ERROR: failed to strncpy from user\n");
ret = -1;
goto return_linux_spawn;
}
}
rc = posix_spawn(&pid, exec_path, NULL, NULL, argv, NULL);
if (rc != 0) {
fprintf(stderr, "linux_spawn(): ERROR: posix_spawn returned %d\n", rc);
ret = -1;
goto return_linux_spawn;
}
ret = 0;
return_linux_spawn:
// free allocated memory
if (exec_path) {
free(exec_path);
}
for (i = 0; argv[i] != NULL; i++) {
free(argv[i]);
}
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
break;
}
default:
ret = do_generic_syscall(&w);

381
executer/user/md5.c Normal file
View File

@@ -0,0 +1,381 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "../include/md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

File diff suppressed because it is too large Load Diff

597
executer/user/ql_server.c Normal file
View File

@@ -0,0 +1,597 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/un.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <alloca.h>
#include <unistd.h>
#include <fcntl.h>
#include "../include/qlmpi.h"
#define NALLOC 10
#define NOLOG
#ifndef NOLOG
#define LOGFILE "ql_server.log"
int log_open(char *f_name);
int log_close();
void log_printf(const char *format, ...);
void log_dump(struct client_fd *fd_list,int fd_size);
FILE * log_fp;
#endif
int listen_fd = -1;
char file_path[1024];
int check_ql_server( char * path,char * file ,char *filep){
struct stat st;
int rc;
sprintf(filep,"%s/%s",path,file);
rc = stat(filep,&st);
if (rc == 0) {
fprintf(stderr,"socket file exests. %s\n",filep);
return rc;
}
else {
rc = stat(path,&st);
if ( rc == 0) {
fprintf(stderr,"dir(file) exests. %s %d\n",path,rc);
return 1;
}
else {
mode_t m = st.st_mode;
if (S_ISDIR(m)) {
fprintf(stderr,"dir exests. %s %d\n",path,rc);
return rc; /* dir exist */
}
else {
if (mkdir(path, (S_IRUSR | S_IWUSR | S_IRWXU |
S_IRGRP | S_IWGRP | S_IRWXG |
S_IROTH | S_IWOTH | S_IRWXO)) == 0) {
fprintf(stderr,"dir create. %s %d\n",path,rc);
return 1;
}
fprintf(stderr,"mkdir error. %s %d\n",path,rc);
return 0; /* mkdir error */
}
}
}
}
void terminate(int rc){
if (listen_fd >= 0) {
shutdown(listen_fd, 2);
close(listen_fd);
unlink(file_path);
}
#ifndef NOLOG
log_close();
#endif
exit(rc);
}
int s_fd_list(char * p_name,int client_type ,
struct client_fd *fd_list,int fd_size){
int i;
for (i = 0; fd_size > i; i++) {
if ((fd_list[i].client == client_type) &&
(!strcmp(fd_list[i].name,p_name)) &&
(fd_list[i].fd != -1)) {
break;
}
}
return i;
}
int main( int argc, char *argv[]){
int i,j, fd, rc = 0, len, maxfd;
int fd_size ;
struct client_fd *fd_list;
fd_set rset, allset;
struct sockaddr_un unix_addr;
char *buf;
int s_indx;
#ifndef NOLOG
int e_no; /*errno copy*/
#endif
char * null_buff = "";
if (argc < 3 ) {
fprintf(stderr," few args \n");
exit(-1);
}
for (i = 0; i < 4096; i++)
close(i);
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
open("/dev/null", O_WRONLY);
if (!check_ql_server(argv[1], argv[2] ,file_path)) {
fprintf(stderr,"ql_server already exists.\n");
exit(-1);
}
signal(SIGINT, terminate);
signal(SIGTERM, terminate);
listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
fprintf(stderr,"listen error.\n");
terminate(rc);
}
#ifndef NOLOG
log_open(argv[1]);
#endif
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, file_path);
#ifndef NOLOG
log_printf("file_path =%s \n",file_path);
#endif
len = sizeof(unix_addr.sun_family) + strlen(unix_addr.sun_path) + 1;
rc = bind(listen_fd, (struct sockaddr *)&unix_addr, len);
if (rc < 0) {
#ifndef NOLOG
log_printf("bind error \n",file_path);
#endif
terminate(rc);
}
// become a daemon
if (fork())
exit(0);
if (fork())
exit(0);
setsid();
rc = listen(listen_fd, 5);
if (rc < 0) {
#ifndef NOLOG
log_printf("listen error \n");
#endif
terminate(rc);
}
FD_ZERO(&allset);
FD_SET(listen_fd, &allset);
maxfd = listen_fd;
fd_size = NALLOC;
fd_list = malloc(sizeof(struct client_fd)*fd_size);
for (i = 0; i < fd_size; i++) {
fd_list[i].fd = -1;
}
#ifndef NOLOG
log_printf("loop_start \n");
#endif
for (;;) {
memcpy(&rset, &allset, sizeof(rset));
rc = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (rc == -1) {
#ifndef NOLOG
e_no = errno;
log_printf("server:select error.\n");
log_printf("select error string by strerror: %s\n",
strerror(e_no));
log_printf("select error code: %d\n", e_no);
#endif
terminate(rc);
}
#ifndef NOLOG
log_printf("server:select.\n");
#endif
if (FD_ISSET(listen_fd, &rset)) {
len = sizeof(unix_addr);
fd = accept(listen_fd, (struct sockaddr *)&unix_addr,
(socklen_t*)&len);
if (fd < 0) {
#ifndef NOLOG
log_printf("server:accept error.\n");
#endif
terminate(fd);
}
#ifndef NOLOG
log_printf("server:accept (%d).\n", fd);
#endif
for (i = 0; fd_size > i; i++) {
if (fd_list[i].fd == -1) {
fd_list[i].fd = fd;
break;
}
}
if (i >= fd_size) {
fd_list = realloc(fd_list,
sizeof(int)*(fd_size+NALLOC));
for (i = fd_size; i < (fd_size + NALLOC); i++) {
fd_list[i].fd = -1;
}
fd_list[fd_size].fd = fd;
fd_size += NALLOC;
}
FD_SET(fd, &allset);
if (fd > maxfd) {
maxfd = fd;
}
}
for (i = 0; i < fd_size; i++) {
if (fd_list[i].fd == -1)
continue;
fd = fd_list[i].fd;
if (!FD_ISSET(fd, &rset))
continue;
rc = ql_recv(fd, &buf);
#ifndef NOLOG
log_printf("ql_recv (%d) index = %d fd = %d \n", rc,i,fd);
#endif
if(rc < 0){
#ifndef NOLOG
log_printf("server:recv (%d) error.\n", fd);
#endif
terminate(rc);
}
if (rc == 0) {
#ifndef NOLOG
log_printf("server:closed (%d).\n", fd);
#endif
fd_list[i].fd = -1;
if (strcmp(fd_list[i].name,null_buff)) {
free(fd_list[i].name);
fd_list[i].name = null_buff;
}
FD_CLR(fd, &allset);
maxfd = -1;
for (j = 0; fd_size > j ; j++) {
if (fd > maxfd) {
maxfd = fd;
}
}
close(fd);
#ifndef NOLOG
log_printf("index = %d\n",i);
log_dump(fd_list,fd_size);
#endif
if (maxfd == -1) {
terminate(rc);
}
continue;
}
if (rc == QL_EXEC_END){ /* swapout from mcexec */
fd_list[i].client = QL_MCEXEC_PRO;
fd_list[i].name = buf;
fd_list[i].status = QL_EXEC_END;
#ifndef NOLOG
log_printf("index = %d\n",i);
log_dump(fd_list,fd_size);
#endif
/* send E command to ql_talker */
if ((s_indx = s_fd_list(fd_list[i].name,
QL_MPEXEC,fd_list,
fd_size)) < fd_size) {
#ifndef NOLOG
log_printf("E command to talker %d \n",s_indx);
#endif
rc = ql_send(fd_list[s_indx].fd,
QL_EXEC_END,NULL);
/* fd close for ql_talker */
FD_CLR(fd_list[s_indx].fd, &allset);
maxfd = -1;
close(fd_list[s_indx].fd);
free(fd_list[s_indx].name);
fd_list[s_indx].fd = -1;
fd_list[s_indx].name = null_buff;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
if (maxfd == -1) terminate(0);
}
else{
/* ql_talker not found */
#ifndef NOLOG
log_printf("ql_talker not found\n",i);
#endif
/* send I command to mcexec and param_file put A command*/
}
#ifndef NOLOG
log_printf("index = %d\n",i);
log_dump(fd_list,fd_size);
#endif
}
else if (rc == QL_RET_RESUME) {
/* recv R command from ql_talker */
fd_list[i].client = QL_MPEXEC;
fd_list[i].name = buf;
fd_list[i].status = QL_RET_RESUME;
#ifndef NOLOG
log_printf("index = %d,fd_size=%d\n",
i,fd_size);
log_dump(fd_list,fd_size);
#endif
/* send R command to mcexec */
if (((s_indx = s_fd_list(fd_list[i].name,
QL_MCEXEC_PRO ,
fd_list,fd_size)) < fd_size) &&
fd_list[s_indx].status == QL_EXEC_END) {
#ifndef NOLOG
log_printf("R command to mcexec %d \n",s_indx);
log_dump(fd_list,fd_size);
#endif
rc = ql_send(fd_list[s_indx].fd,
QL_RET_RESUME,NULL);
fd_list[s_indx].status = QL_RET_RESUME;
FD_CLR(fd_list[s_indx].fd, &allset);
close(fd_list[s_indx].fd);
free(fd_list[s_indx].name);
fd_list[s_indx].fd = -1;
fd_list[s_indx].name = null_buff;
maxfd = -1;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
if (maxfd == -1) terminate(0);
}
else{
/* mcexec not found */
/* send A command to ql_talker */
#ifndef NOLOG
log_printf("send A command index = %d,fd_size=%d\n",
i,fd_size);
log_dump(fd_list,fd_size);
#endif
rc = ql_send(fd_list[i].fd,
QL_AB_END,NULL);
/* fd close for ql_talker */
FD_CLR(fd_list[i].fd, &allset);
close(fd_list[i].fd);
free(fd_list[i].name);
fd_list[i].fd = -1;
// fd_list[i].name = NULL;
fd_list[i].name = null_buff;
maxfd = -1;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
if (maxfd == -1) terminate(0);
}
#ifndef NOLOG
log_printf("index = %d,s_indx=%d\n",
i,s_indx);
log_dump(fd_list,fd_size);
#endif
}
else if (rc == QL_COM_CONN) {
/* connect from ql_mpiexec_* */
fd_list[i].client = QL_MPEXEC;
fd_list[i].name = buf;
fd_list[i].status = QL_COM_CONN;
#ifndef NOLOG
log_printf("N command index = %d,fd_size=%d\n",
i,fd_size);
log_dump(fd_list,fd_size);
#endif
if ((s_indx = s_fd_list(fd_list[i].name,
QL_MCEXEC_PRO,fd_list,
fd_size)) < fd_size) {
rc = ql_send(fd_list[i].fd,
QL_EXEC_END,NULL);
/* fd close for ql_talker */
FD_CLR(fd_list[i].fd, &allset);
maxfd = -1;
close(fd_list[i].fd);
free(fd_list[i].name);
fd_list[i].fd = -1;
fd_list[i].name = null_buff;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
// if (maxfd == -1) terminate(0);
}
#ifndef NOLOG
log_dump(fd_list,fd_size);
#endif
}
else if(rc == QL_RET_FINAL) {
/* F command from Monitor Process */
fd_list[i].client = QL_MONITOR;
fd_list[i].name = buf;
fd_list[i].status = QL_RET_FINAL;
#ifndef NOLOG
log_printf("F command index = %d,fd_size=%d\n",
i,fd_size);
log_dump(fd_list,fd_size);
#endif
/* search ql_mpiexec_start process */
if ((s_indx = s_fd_list(fd_list[i].name,
QL_MPEXEC,fd_list,
fd_size)) < fd_size) {
/* send A command */
rc = ql_send(fd_list[s_indx].fd,
QL_AB_END,NULL);
/* table clear */
FD_CLR(fd_list[s_indx].fd, &allset);
maxfd = -1;
close(fd_list[s_indx].fd);
free(fd_list[s_indx].name);
fd_list[s_indx].fd = -1;
fd_list[s_indx].name = null_buff;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
}
/* search mcexec process */
if ((s_indx = s_fd_list(fd_list[i].name,
QL_MCEXEC_PRO,fd_list,
fd_size)) < fd_size) {
/* table clear */
FD_CLR(fd_list[s_indx].fd, &allset);
maxfd = -1;
close(fd_list[s_indx].fd);
free(fd_list[s_indx].name);
fd_list[s_indx].fd = -1;
fd_list[s_indx].name = null_buff;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
}
FD_CLR(fd_list[i].fd, &allset);
close(fd_list[i].fd);
free(fd_list[i].name);
fd_list[i].fd = -1;
fd_list[i].name = null_buff;
maxfd = -1;
for (j = 0; fd_size > j ; j++) {
if (fd_list[j].fd > maxfd) {
maxfd = fd_list[j].fd;
}
}
#ifndef NOLOG
log_printf("F command end index = %d,fd_size=%d\n",
i,fd_size);
log_dump(fd_list,fd_size);
#endif
if (maxfd == -1)
terminate(0);
}
else {
#ifndef NOLOG
log_printf("server:unknwon commond %d (%d).\n",
rc, fd);
#endif
}
#ifndef NOLOG
log_printf("server:recv (%d) .\n", fd);
#endif
}
}
terminate(0);
}
#ifndef NOLOG
int log_open(char *f_path){
char f_name[1024];
sprintf(f_name,"%s/%s",f_path,LOGFILE);
if ((log_fp = fopen(f_name,"w")) == NULL) {
log_fp = stderr;
}
return 0;
}
int log_close(){
if (log_fp != stdout) {
fclose(log_fp);
}
return 0;
}
void log_printf(const char *format, ...){
va_list arglist;
char log[1024];
va_start(arglist, format);
vsprintf(log, format, arglist);
fprintf(log_fp, "%s\n", log);
va_end(arglist);
fflush(log_fp);
}
void log_dump(struct client_fd *fd_list,int fd_size){
int i;
for (i = 0; fd_size > i; i++) {
if (fd_list[i].fd != -1) {
log_printf("|%4d|%4d|%c|%s|\n",fd_list[i].fd,
fd_list[i].client,(char)fd_list[i].status,
fd_list[i].name);
}
else{
log_printf("|%4d|0000| | |\n",fd_list[i].fd);
}
}
log_printf("-----------------------\n");
}
#endif
int ql_recv(int fd,char ** buf){
char l_buf[QL_BUF_MAX];
char comm;
int size = 0;
int rc;
int ret;
rc = recv(fd, l_buf, QL_BUF_MAX, 0);
#ifndef NOLOG
log_printf("rc = %d,l_buf=%s\n",rc,l_buf);
#endif
if (rc <= 0) {
return rc;
}
sscanf(l_buf, "%c %x", &comm, &size);
ret = (int)(comm);
#ifndef NOLOG
log_printf("COMM=%c size = %x rc= %d\n", ret, size, rc);
#endif
if (size > 0) {
*buf = malloc(size+1);
memcpy(*buf, &l_buf[7], size);
buf[size] = 0x00;
#ifndef NOLOG
log_printf("COMM=%c size = %x *buf= %s\n",ret,size,*buf);
#endif
}
#ifndef NOLOG
log_printf("ret = %d\n", ret);
#endif
return ret;
}
int ql_send(int fd,int command,char *buf){
char *lbuf;
int size;
int rc;
if (buf != NULL) {
size = strlen(buf);
lbuf = alloca(size+7+1);
sprintf(lbuf,"%c %04x %s",command,size,buf);
}
else{
size = 0;
lbuf = alloca(6+1);
sprintf(lbuf,"%c 0000",command);
}
#ifndef NOLOG
log_printf("send lbuf=%s",lbuf);
#endif
rc=send(fd,lbuf,strlen(lbuf),0);
return rc;
}

101
executer/user/ql_talker.c Normal file
View File

@@ -0,0 +1,101 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include "../include/qlmpi.h"
int fd = -1;
#define BUF_MAX 256
void terminate(int rc)
{
if(fd >= 0){
shutdown(fd, 2);
close(fd);
}
exit(rc);
}
int main(int argc, char* argv[])
{
int rc=-1, len;
struct sockaddr_un unix_addr;
char buf[BUF_MAX];
signal(SIGINT, terminate);
signal(SIGTERM, terminate);
if (argc < 5) {
#ifdef QL_DEBUG
printf("too few arguments\n");
#endif
return rc;
}
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
#ifdef QL_DEBUG
printf("client:socket error.\n");
#endif
terminate(rc);
}
#ifdef QL_DEBUG
printf("client:socket.\n");
#endif
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, argv[4]);
#ifdef QL_DEBUG
printf("socket_path %s\n",argv[4]);
#endif
len = sizeof(unix_addr.sun_family)+strlen(unix_addr.sun_path) + 1;
rc = connect(fd, (struct sockaddr*)&unix_addr, len);
if (rc < 0) {
#ifdef QL_DEBUG
printf("client:connect error.\n");
printf("%s %s\n", unix_addr.sun_path, strerror(errno));
#endif
terminate(rc);
}
if (argv[1][0]) {
sprintf(buf,"%s %04x %s",argv[1],
(unsigned int)strlen(argv[3]),argv[3]);
rc = send(fd, buf, strlen(buf) + 1, 0);
if (rc < 0) {
#ifdef QL_DEBUG
printf("send error.\n");
#endif
terminate(rc);
}
}
if (strcmp(argv[2],"-n")) {
#ifdef QL_DEBUG
printf("waiting reply message from ql_server ...\n");
#endif
rc = recv(fd, buf, 256, 0);
#ifdef QL_DEBUG
printf("%s\n",buf);
#endif
if (rc < 0) {
#ifdef QL_DEBUG
printf("recv error\n");
#endif
terminate(rc);
}
if (buf[0] == argv[2][0]){
terminate(0);
}
if (buf[0] == QL_AB_END){
/* abnormal end */
terminate(-2);
}
}
terminate(0);
return rc; /*not reached */
}

320
executer/user/qlmpilib.c Normal file
View File

@@ -0,0 +1,320 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <errno.h>
#include "mpi.h"
#include "../include/qlmpilib.h"
#include "../include/qlmpi.h"
#include "../include/pmi.h"
#define BUF_SIZE (32*1024)
#define NALLOC 10
#define QL_SUCCESS 0
#define QL_NORMAL 2
//#define QL_DEBUG
static char ql_name[33];
static char swap_file[1024];
static char param_file[1024];
static int ql_mode_flg = 0; /* 0 is normal */
static int rank = -1;
static char buffer[BUF_SIZE];
static int ql_initialized;
int mck_ql_argc = NALLOC;
char **mck_ql_argv;
char **mck_ql_env;
static void freev(char **v)
{
char **a;
for (a = v; *a; a++)
free(*a);
free(v);
}
static void esc_get(char *in, char *out)
{
char *p;
char *q;
int c;
for (p = in, q = out; *p; p++) {
if (*p == '%' && p[1] && p[2]) {
int i;
for (i = 0, c = 0; i < 2; i++) {
p++;
c <<= 4;
if (*p >= '0' && *p <= '9')
c += *p - '0';
else if (*p >= 'A' && *p <= 'F')
c += *p - 'A' + 10;
else if (*p >= 'a' && *p <= 'f')
c += *p - 'a' + 10;
}
*(q++) = c;
}
else
*(q++) = *p;
}
*q = '\0';
}
static int swapout(char *fname, void *buf, size_t sz, int flag)
{
int cc;
cc = syscall(801, fname, buf, sz, flag);
return cc;
}
static int ql_get_option() {
char *env_str;
env_str = getenv(QL_NAME);
if (env_str == NULL) {
return 0;
}
else{
strcpy(ql_name,env_str);
return 1;
}
}
int ql_init() {
char tmp_path[1024];
char *env_str;
if (ql_initialized) {
return QL_CONTINUE;
}
ql_mode_flg = ql_get_option();
#ifdef QL_DEBUG
printf("flg = %d \n",ql_mode_flg);
#endif
if (ql_mode_flg) {
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* get param_file path */
env_str = getenv(QL_PARAM_ENV);
if (env_str == NULL) {
sprintf(tmp_path,"%s/",getenv("HOME"));
}
else{
sprintf(tmp_path,"%s/",env_str);
}
sprintf(param_file,"%s%s%s",tmp_path,ql_name,QL_PARAM_EXTE);
#ifdef QL_DEBUG
printf("param_file = %s\n",param_file);
#endif
/* get swap_file path*/
env_str = getenv(QL_SWAP_ENV);
if (env_str == NULL) {
strcpy(tmp_path,QL_SWAP_PATH);
}
else{
strcpy(tmp_path,env_str);
}
sprintf(swap_file,"%s/%s%d",tmp_path,ql_name,rank);
#ifdef QL_DEBUG
printf("swap_file = %s rank=%d\n",swap_file,rank);
#endif
ql_initialized = 1;
return QL_SUCCESS;
}
ql_initialized = 1;
return QL_NORMAL;
}
int ql_client(int *argc,char ***argv)
{
int rc;
int ret = QL_EXIT;
char buf[4096];
FILE *fp;
char **envs;
char **args;
char **a;
char **e;
if (ql_mode_flg == 0) return(QL_EXIT);
syscall(803);
rc = PMI_Barrier();
rc = swapout(swap_file, buffer, BUF_SIZE, 0);
#ifdef QL_DEBUG
printf(" swapout rc=%d\n",rc);
#endif
if (rc == -1) {
/* terminate due to swap error */
syscall(804);
return QL_EXIT;
}
/* param file */
if ((fp = fopen(param_file,"r")) == NULL) {
/* param file open error */
#ifdef QL_DEBUG
printf("param_file open error\n");
#endif
syscall(804);
return QL_EXIT;
}
a = args = NULL;
e = envs = NULL;
while ((fgets(buf, 4096, fp)) != NULL) {
int cmd = buf[0];
char *t;
int n;
// remove return code
buf[strlen(buf) - 1] = '\0';
if (cmd == QL_COMMAND) {
t = strchr(buf, '=');
if (!t ||
(t[1] != QL_RET_RESUME && t[1] != QL_RET_FINAL)) {
fprintf(stderr, "invalid file format\n");
exit(1);
}
t++;
if (*t == QL_RET_RESUME) {
ret = QL_CONTINUE;
#ifdef QL_DEBUG
printf("COM = %c ret = %d\n", *t, ret);
#endif
}
else {
ret = QL_EXIT;
#ifdef QL_DEBUG
printf(" ret = %d",ret);
#endif
}
t = strchr(t, ' ');
if (t) {
n = atoi(t + 1);
args = malloc(sizeof(char *) * (n + 1));
a = args;
t = strchr(t + 1, ' ');
if (t) {
n = atoi(t + 1);
envs = malloc(sizeof(char *) * (n + 1));
e = envs;
}
}
}
else if (cmd == QL_ARG) {
if (!args)
continue;
t = strchr(buf, ' ');
if (!t)
continue;
n = atoi(t + 1);
t = strchr(t + 1, ' ');
if (!t)
continue;
t++;
*a = malloc(n + 1);
esc_get(t, *a);
a++;
}
else if (cmd == QL_ENV) {
if (!envs)
continue;
t = strchr(buf, ' ');
if (!t)
continue;
n = atoi(t + 1);
t = strchr(t + 1, ' ');
if (!t)
continue;
t++;
*e = malloc(n + 1);
esc_get(t, *e);
e++;
}
else {
}
}
fclose(fp);
if (args) {
*a = NULL;
if (mck_ql_argv)
freev(mck_ql_argv);
mck_ql_argv = args;
if (argv)
*argv = args;
for (mck_ql_argc = 0; mck_ql_argv[mck_ql_argc]; mck_ql_argc++);
if (argc)
*argc = mck_ql_argc;
}
if (envs) {
*e = NULL;
if (mck_ql_env)
freev(mck_ql_env);
mck_ql_env = envs;
environ = envs;
}
syscall(804);
#ifdef QL_DEBUG
printf(" return rtn = %d\n",ret);
#endif
return ret;
}
int MPI_Init(int *argc,char ***argv){
int rc = 0;
rc = PMPI_Init(argc,argv);
if (rc == MPI_SUCCESS)
ql_init();
return rc;
}
void
mpi_init_(int *ierr)
{
extern void pmpi_init_(int *ierr) __attribute__ ((__weak__));
if (!pmpi_init_) {
*ierr = MPI_ERR_OTHER;
return;
}
pmpi_init_(ierr);
if (*ierr == MPI_SUCCESS)
ql_init();
return;
}
void ql_client_(int *ierr)
{
int argc;
char **argv;
*ierr = ql_client(&argc, &argv);
}