⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minimig.c

📁 系统迁移的源代码: http://www.diku.dk/hjemmesider/ansatte/jacobg/
💻 C
字号:
#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <sys/mman.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <sched.h>#define PAGE_SIZE 4096#define O_DIRECT      040000#define n_pages 16extern void sha1_digest(unsigned char* out, unsigned char* data, size_t len);unsigned char* page_digests;#define SHA1_DIGEST_SIZE 20void hex(char* out, unsigned char* in){	int i;	char* o = out;	char digits[] = "0123456789abcdef";	for(i=0; i<SHA1_DIGEST_SIZE; i++)	{		char c = *in++;		*o++= digits[(c & 0xf0)>>4];		*o++= digits[ c & 0xf];	}	*o = '\0';}int main(int argc,char** argv){	size_t loader_size;	unsigned long loader_pages;	unsigned long offset = 0;	int dryrun=0;	char* page;	char* loader = mmap(0, 8*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0,0);	int f;	//int i;	int o=-1;	unsigned long num_mfns;	struct sched_param p;	struct page_info {		unsigned long pfn;		char page[PAGE_SIZE];	} ;	struct page_info data[n_pages];	memset(loader,0,8*PAGE_SIZE);	memset(&p, 0, sizeof(p));	p.sched_priority = -20;	sched_setscheduler(getpid(),SCHED_FIFO,&p);	if(argc>1) 	{		if(!strcmp("-n",argv[1])) 		{			dryrun = 1;			puts("dry run.");		}				else offset = atoi(argv[1+dryrun]) * 4200 * PAGE_SIZE;	}	/* to work with O_DIRECT, we need to correctly align the loader. 512 bytes should be	 * enough, but let's do PAGE_SIZE for now	 */	f = open("loader", O_RDONLY);	if(f>=0)	{		size_t* a;		loader_size = read(f,loader+4, 8*PAGE_SIZE);		close(f);		loader_pages = (loader_size + 3*sizeof(size_t) + (PAGE_SIZE-1)) / PAGE_SIZE;		printf("loader pages %d\n", (int)loader_pages);		a = (size_t*) loader;		/* first long has length of loader minus arguments */		*a = loader_pages*PAGE_SIZE - 12;		a = (size_t*) ( loader+loader_pages * PAGE_SIZE - 8);		*a++ = sizeof(size_t);  /* four bytes of args */		*a++ = num_mfns;          /* argument: number of pages in checkpoint */		/* so loader and arguments ended up page-aligned after all */	}	else	{		puts("no file: 'loader'");		exit(-1);	}	page = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0,0);	if(!dryrun)	{		o = open("/dev/hda1",O_WRONLY|O_TRUNC|O_DIRECT);		if(o<0)		{			printf("could not open output fd for write %d\n",o);			exit(-1);		}#if 0		printf("wiping /dev/hda1, fd %d\n",o);		memset(page,0,PAGE_SIZE);		for(i=0; i<0x1003; i++)		{			int r;			lseek(o, offset + i * PAGE_SIZE, SEEK_SET);			r = write(o, page, PAGE_SIZE);			if(r<0)			{				printf("r %d\n",r);				exit(-1);			}		}#endif		/* write the loader and its args */		lseek(o, offset + 0, SEEK_SET);		write(o, loader, loader_pages * PAGE_SIZE);	}	f = open("/dev/checkpoint",O_RDONLY);	if(f<0) switch(errno)	{		case ENOENT:			puts("no /dev/checkpoint!");			puts("please create with:\n\tmknod /dev/checkpoint c 1 12\n\tchmod 400 /dev/checkpoint");			exit(-1);		default:			puts("unable to open /dev/checkpoint");			exit(-1);	}	read(f, &num_mfns, sizeof(num_mfns));	printf("%08lx page frames\n", num_mfns);	page_digests = malloc(SHA1_DIGEST_SIZE*num_mfns);	if(num_mfns<=0) exit(-1);	int last_pfn = -10000;	for(;;)	{		int len = read(f, &data,sizeof(data));		int r;		if(len<0) 		{ 			printf("we have arrived.\n");			if(!dryrun) close(o);			close(f);						/* if run as init we cannot exit */			//if(getpid()==1) while(1) sleep(100); else 			exit(0);		}		if(!dryrun)		{			int i;			int left;			for(i=0,left=len; left>0; left-= sizeof(struct page_info))			{				struct page_info* p = &data[i++];				size_t l = left-4;				if(p->pfn != last_pfn+1)				{					lseek(o, offset + (loader_pages + p->pfn) * PAGE_SIZE, SEEK_SET);				}				last_pfn = p->pfn;				if(l < PAGE_SIZE) memset(page+PAGE_SIZE-l,0,PAGE_SIZE-l);				memcpy(page,p->page,l < PAGE_SIZE ? l : PAGE_SIZE);				r = write(o, page, PAGE_SIZE);				if(p->pfn == num_mfns) break; 				else sha1_digest(page_digests + SHA1_DIGEST_SIZE*p->pfn,p->page,PAGE_SIZE);			}		}		if(!dryrun) fsync(o); /* necessary? */		if(len!=sizeof(data)){						printf("exiting with %d bytes read\n",len);			break;		}	}	if(!dryrun) close(o);	unsigned char final_digest[SHA1_DIGEST_SIZE];	char dout[2*SHA1_DIGEST_SIZE+1];	sha1_digest(final_digest,page_digests,SHA1_DIGEST_SIZE*num_mfns);	hex(dout,final_digest);	printf("checkpoint chksum is %s\n",dout);	puts("done");	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -