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


Reply via email to