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

📄 blktapctrl.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	buf = malloc(MSG_SIZE);	ret = 0;	FD_ZERO(&readfds);	FD_SET(fd,&readfds);	timeout.tv_sec = max_timeout; /*Wait for up to max_timeout seconds*/ 	timeout.tv_usec = 0;	if (select(fd+1, &readfds,  (fd_set *) 0,		  (fd_set *) 0, &timeout) > 0) {		ret = read(fd, buf, msglen);	}				if (ret > 0) {		msg = (msg_hdr_t *)buf;		switch (msg->type)		{		case CTLMSG_IMG:			img = (image_t *)(buf + sizeof(msg_hdr_t));			image->size = img->size;			image->secsize = img->secsize;			image->info = img->info;			DPRINTF("Received CTLMSG_IMG: %llu, %lu, %u\n",				image->size, image->secsize, image->info);			if(msgtype != CTLMSG_IMG) ret = 0;			break;					case CTLMSG_IMG_FAIL:			DPRINTF("Received CTLMSG_IMG_FAIL, "				"unable to open image\n");			ret = 0;			break;						case CTLMSG_NEWDEV_RSP:			DPRINTF("Received CTLMSG_NEWDEV_RSP\n");			if(msgtype != CTLMSG_NEWDEV_RSP) ret = 0;			break;					case CTLMSG_NEWDEV_FAIL:			DPRINTF("Received CTLMSG_NEWDEV_FAIL\n");			ret = 0;			break;					case CTLMSG_CLOSE_RSP:			DPRINTF("Received CTLMSG_CLOSE_RSP\n");			if (msgtype != CTLMSG_CLOSE_RSP) ret = 0;			break;		case CTLMSG_PID_RSP:			DPRINTF("Received CTLMSG_PID_RSP\n");			if (msgtype != CTLMSG_PID_RSP) ret = 0;			else {				msg_pid = (msg_pid_t *)					(buf + sizeof(msg_hdr_t));				blkif->tappid = msg_pid->pid;				DPRINTF("\tPID: [%d]\n",blkif->tappid);			}			break;		default:			DPRINTF("UNKNOWN MESSAGE TYPE RECEIVED\n");			ret = 0;			break;		}	} 		free(buf);		return ret;}int launch_tapdisk(char *wrctldev, char *rdctldev){	char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL };	pid_t child;		if ((child = fork()) < 0)		return -1;	if (!child) {		int i;		for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++)			if (i != STDIN_FILENO &&			    i != STDOUT_FILENO &&			    i != STDERR_FILENO)				close(i);		execvp("tapdisk", argv);		_exit(1);	} else {		pid_t got;		do {			got = waitpid(child, NULL, 0);		} while (got != child);	}	return 0;}int blktapctrl_new_blkif(blkif_t *blkif){	blkif_info_t *blk;	int major, minor, fd_read, fd_write, type, new;	char *rdctldev, *wrctldev, *ptr;	image_t *image;	blkif_t *exist = NULL;	static uint16_t next_cookie = 0;	DPRINTF("Received a poll for a new vbd\n");	if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) {		if (get_new_dev(&major, &minor, blkif)<0)			return -1;		if (test_path(blk->params, &ptr, &type, &exist) != 0) {                        DPRINTF("Error in blktap device string(%s).\n",                                blk->params);                        goto fail;                }		blkif->drivertype = type;		blkif->cookie = next_cookie++;		if (!exist) {			DPRINTF("Process does not exist:\n");			if (asprintf(&rdctldev,				     "%s/tapctrlread%d", BLKTAP_CTRL_DIR, minor) == -1)				goto fail;			if (asprintf(&wrctldev,				     "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor) == -1) {				free(rdctldev);				goto fail;			}			blkif->fds[READ] = open_ctrl_socket(rdctldev);			blkif->fds[WRITE] = open_ctrl_socket(wrctldev);						if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) 				goto fail;			/*launch the new process*/ 			DPRINTF("Launching process, CMDLINE [tapdisk %s %s]\n",wrctldev, rdctldev); 			if (launch_tapdisk(wrctldev, rdctldev) == -1) { 				DPRINTF("Unable to fork, cmdline: [tapdisk %s %s]\n",wrctldev, rdctldev);				goto fail;			}			free(rdctldev);			free(wrctldev);		} else {			DPRINTF("Process exists!\n");			blkif->fds[READ] = exist->fds[READ];			blkif->fds[WRITE] = exist->fds[WRITE];		}		add_disktype(blkif, type);		blkif->major = major;		blkif->minor = minor;		image = (image_t *)malloc(sizeof(image_t));		blkif->prv = (void *)image;		blkif->ops = &tapdisk_ops;		/*Retrieve the PID of the new process*/		if (get_tapdisk_pid(blkif) <= 0) {			DPRINTF("Unable to contact disk process\n");			goto fail;		}		/* Both of the following read and write calls will block up to 		 * max_timeout val*/		if (write_msg(blkif->fds[WRITE], CTLMSG_PARAMS, blkif, ptr) 		    <= 0) {			DPRINTF("Write_msg failed - CTLMSG_PARAMS\n");			goto fail;		}		if (read_msg(blkif->fds[READ], CTLMSG_IMG, blkif) <= 0) {			DPRINTF("Read_msg failure - CTLMSG_IMG\n");			goto fail;		}	} else return -1;	return 0;fail:	ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor);	return -EINVAL;}int map_new_blktapctrl(blkif_t *blkif){	DPRINTF("Received a poll for a new devmap\n");	if (write_msg(blkif->fds[WRITE], CTLMSG_NEWDEV, blkif, NULL) <= 0) {		DPRINTF("Write_msg failed - CTLMSG_NEWDEV\n");		return -EINVAL;	}	if (read_msg(blkif->fds[READ], CTLMSG_NEWDEV_RSP, blkif) <= 0) {		DPRINTF("Read_msg failed - CTLMSG_NEWDEV_RSP\n");		return -EINVAL;	}	DPRINTF("Exiting map_new_blktapctrl\n");	return blkif->minor - 1;}int unmap_blktapctrl(blkif_t *blkif){	DPRINTF("Unmapping vbd\n");	if (write_msg(blkif->fds[WRITE], CTLMSG_CLOSE, blkif, NULL) <= 0) {		DPRINTF("Write_msg failed - CTLMSG_CLOSE\n");		return -EINVAL;	}	if (del_disktype(blkif)) {		close(blkif->fds[WRITE]);		close(blkif->fds[READ]);	}	return 0;}int open_ctrl_socket(char *devname){	int ret;	int ipc_fd;	fd_set socks;	struct timeval timeout;	if (mkdir(BLKTAP_CTRL_DIR, 0755) == 0)		DPRINTF("Created %s directory\n", BLKTAP_CTRL_DIR);	ret = mkfifo(devname,S_IRWXU|S_IRWXG|S_IRWXO);	if ( (ret != 0) && (errno != EEXIST) ) {		DPRINTF("ERROR: pipe failed (%d)\n", errno);		exit(0);	}	ipc_fd = open(devname,O_RDWR|O_NONBLOCK);	if (ipc_fd < 0) {		DPRINTF("FD open failed\n");		return -1;	}	return ipc_fd;}static void print_drivers(void){	int i, size;	size = sizeof(dtypes)/sizeof(disk_info_t *);	DPRINTF("blktapctrl: v1.0.0\n");	for (i = 0; i < size; i++)		DPRINTF("Found driver: [%s]\n",dtypes[i]->name);} static void write_pidfile(long pid){	char buf[100];	int len;	int fd;	int flags;	fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);	if (fd == -1) {		DPRINTF("Opening pid file failed (%d)\n", errno);		exit(1);	}	/* We exit silently if daemon already running. */	if (lockf(fd, F_TLOCK, 0) == -1)		exit(0);	/* Set FD_CLOEXEC, so that tapdisk doesn't get this file	   descriptor. */	if ((flags = fcntl(fd, F_GETFD)) == -1) {		DPRINTF("F_GETFD failed (%d)\n", errno);		exit(1);	}	flags |= FD_CLOEXEC;	if (fcntl(fd, F_SETFD, flags) == -1) {		DPRINTF("F_SETFD failed (%d)\n", errno);		exit(1);	}	len = snprintf(buf, sizeof(buf), "%ld\n", pid);	if (write(fd, buf, len) != len) {		DPRINTF("Writing pid file failed (%d)\n", errno);		exit(1);	}}int main(int argc, char *argv[]){	char *devname;	tapdev_info_t *ctlinfo;	int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0;	struct xs_handle *h;	struct pollfd  pfd[NUM_POLL_FDS];	pid_t process;	char buf[128];	__init_blkif();	snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());	openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);	if (daemon(0,0)) {		DPRINTF("daemon failed (%d)\n", errno);		goto open_failed;	}	print_drivers();	init_driver_list();	init_rng();	register_new_blkif_hook(blktapctrl_new_blkif);	register_new_devmap_hook(map_new_blktapctrl);	register_new_unmap_hook(unmap_blktapctrl);	/* Attach to blktap0 */	if (asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME) == -1)                goto open_failed;	if ((ret = xc_find_device_number("blktap0")) < 0) {		DPRINTF("couldn't find device number for 'blktap0'\n");		goto open_failed;	}	blktap_major = major(ret);	make_blktap_dev(devname,blktap_major,0);	ctlfd = open(devname, O_RDWR);	if (ctlfd == -1) {		DPRINTF("blktap0 open failed\n");		goto open_failed;	} retry:	/* Set up store connection and watch. */	h = xs_daemon_open();	if (h == NULL) {		DPRINTF("xs_daemon_open failed -- "			"is xenstore running?\n");                if (count < MAX_ATTEMPTS) {                        count++;                        sleep(2);                        goto retry;                } else goto open_failed;	}		ret = setup_probe_watch(h);	if (ret != 0) {		DPRINTF("Failed adding device probewatch\n");		xs_daemon_close(h);		goto open_failed;	}	ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );	process = getpid();	write_pidfile(process);	ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );	/*Static pollhooks*/	pfd_count = 0;	tap_pfd = pfd_count++;	pfd[tap_pfd].fd = ctlfd;	pfd[tap_pfd].events = POLLIN;		store_pfd = pfd_count++;	pfd[store_pfd].fd = xs_fileno(h);	pfd[store_pfd].events = POLLIN;	while (run) {		timeout = 1000; /*Milliseconds*/                ret = poll(pfd, pfd_count, timeout);		if (ret > 0) {			if (pfd[store_pfd].revents) {				ret = xs_fire_next_watch(h);			}		}	}	xs_daemon_close(h);	ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH );	close(ctlfd);	closelog();	return 0;	 open_failed:	DPRINTF("Unable to start blktapctrl\n");	closelog();	return -1;}/* * Local variables: *  c-file-style: "linux" *  indent-tabs-mode: t *  c-indent-level: 8 *  c-basic-offset: 8 *  tab-width: 8 * End: */

⌨️ 快捷键说明

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