Hi,
I am working on a process migration project under linux. I want to create
an environment for dynamic load balancing.
In the beginning phase I have some important problems. The first is
saving/restoring the BSS segment - unitialized data segment + heap , and
Stack Segment of the process. I try to obtain the start of the data
segment from the output of the "size -A executablefile" . This command
gives the start address of bss segment and its size. The end of the bss
segment, as far as I know is the end of heap area, obtained by sbrk(0)
macro. In the program, (I may send my code to those interested) to save
the data heap and stack segments I do the following :
////////////////////////////////////////////////////
#define STACKSIZE 8192
struct MIGENV {
long FSF ; //address of first stack frame
long *TMP_STACK ; //pointer to temporary stack
jmp_buf orig_env, new_env ;
} ;
struct MIGENV migenv ;
//////////////////////////////
main() {
signal(SIGUSR1,checkpoint) ;
signal(SIGUSR2,resume) ;
setjmp(migenv.orig_env) ;
migenv.FSF=*(long)*(long *)migenv.orig_env[0].__bp ;
mymain() ;
}
//////////////////////////////
void checkpoint() {
long BP, SP, PC ;
long BSS, BSS_size, HEAP_size ;
char s[10] ;
int k ;
FILE *fd ;
if (setjmp(migenv.orig_env)==0) {
SP=(long)migenv.orig_env[0].__sp ;
fd=fopen("checkpt.dat","w+") ;
fwrite(&migenv.orig_env,1,sizeof(jmp_buf),fd) ;
fwrite(&migenv.FSF,1,sizeof(migenv.FSF),fd) ;
fwrite((long *)SP,sizeof(long),migenv.FSF-SP+8,fd) ;
fclose(fd) ;
//get BSS start address and BSS size
system("size -A | grep ^.bss > sections.dat") ;
fd=fopen("sections.dat","r+") ;
fscanf(fd,"%s %lu %lu \n",&s,&BSS_size,&BSS) ;
//compute heap size
HEAP_size=(long)sbrk(0)-(BSS+BSS_size) ;
fprintf(fd,"%lu",HEAP_size) ;
fclose(fd) ;
//write uninitialized data and heap to data.dat file
fd=fopen("data.dat","w+") ;
k=fwrite((void *)BSS,1,BSS_size,fd) ;
printf("%d bytes of %d checkpointed \n",k,BSS_size) ;
k=fwrite((void *)(BSS+BSS_size),1,HEAP_size,fd) ;
printf("%d bytes of %d checkpointed \n",k,HEAP_size) ;
fclose(fd) ;
} else {
//when state is restored by longjmp , program continues
//from here.
resumeOK() ;
}
};
////////////////////////
void resume() {
//Restore Data
puts("Restoring Data Section") ;
restore_data() ;
//Now Restore Stack
puts("Restoring Stack Section") ;
migenv.TMP_STACK=(long *)malloc(STACKSIZE) ;
if (setjmp(migenv.new_env)==0) {
migenv.TMP_STACK[STACKSIZE-1]=(long)migenv.new_env[0].__bp
;
migenv.new_env[0].__bp=migenv.TMP_STACK+(STACKSIZE-2) ;
migenv.new_env[0].__sp=migenv.TMP_STACK+(STACKSIZE-3) ;
longjmp(migenv.new_env,1) ;
} else {
//Now Running on temporary stack
puts("Running On Temporary Stack") ;
restore_stack() ;
}
};
/////////////////////////////
void restore_data() {
char s[10] ;
FILE *fd ;
long BSS,BSS_size,HEAP_size,h ;
int j,k ;
fd=fopen("sections.dat","r") ;
fscanf(fd,"%s %lu %lu \n",&s,&BSS_size,&BSS) ;
fscanf(fd,"%lu",&HEAP_size) ;
fclose(fd) ;
//Now allocate space from heap and restore heap
//Then restore uninitialized data segment
h=(long)sbrk(HEAP_size-((long)sbrk(0)-BSS-BSS_size)) ;
fd=fopen("data.dat","r")
//restore data
BSS_size=fread((void *)BSS,1,BSS_size,fd) ;
//restore heap
h=fread((void *)(BSS+BSS_size),1,HEAP_size,fd) ;
fclose(fd) ;
puts("BSS Section Restored") ;
} ;
//////////////////////////////////////////////////
void restore_stack() {
FILE *fd ;
long BP,SP,PC ;
fopen("checkpt.dat","r") ;
fread(&migenv.orig_env,1,sizeof(migenv.orig_env),fd) ; //restore
origin$
fread(&migenv.FSF,1,sizeof(migenv.FSF),fd) ;
fread((long *)SP, sizeof(long), migenv.FSF-SP+8,fd) ;//restore
stack
fclose(fd) ;
longjmp(migenv.orig_env,0) ;
};
///////////////////////////////////////////
The above code doesn't work, I always get a segmentation fault. Does any
one have an idea about saving and restoring the memory sections of a linux
process.
Thanks.
__________________
Cagri Koksal
Network Engineer
Finansbank/Turkey