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

📄 blktapctrl.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
	} 		free(buf);		return ret;}static int launch_tapdisk_provider(char **argv){	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(argv[0], argv);		DPRINTF("execvp failed: %d (%s)\n", errno, strerror(errno));		DPRINTF("PATH = %s\n", getenv("PATH"));		_exit(1);	} else {		pid_t got;		do {			got = waitpid(child, NULL, 0);		} while (got != child);	}	return child;}static int launch_tapdisk(char *wrctldev, char *rdctldev){	char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL };	if (launch_tapdisk_provider(argv) < 0)		return -1;	return 0;}static int launch_tapdisk_ioemu(void){	char *argv[] = { "tapdisk-ioemu", NULL };	return launch_tapdisk_provider(argv);}/*  * Connect to an ioemu based disk provider (qemu-dm or tapdisk-ioemu) * * If the domain has a device model, connect to qemu-dm through the * domain specific pipe. Otherwise use a single tapdisk-ioemu instance * which is represented by domid 0 and provides access for Dom0 and * all DomUs without device model. */static int connect_qemu(blkif_t *blkif, int domid){	char *rdctldev, *wrctldev;	static int tapdisk_ioemu_pid = 0;	static int dom0_readfd = 0;	static int dom0_writefd = 0;		if (asprintf(&rdctldev, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) < 0)		return -1;	if (asprintf(&wrctldev, BLKTAP_CTRL_DIR "/qemu-write-%d", domid) < 0) {		free(rdctldev);		return -1;	}	DPRINTF("Using qemu blktap pipe: %s\n", rdctldev);		if (domid == 0) {		/*		 * tapdisk-ioemu exits as soon as the last image is 		 * disconnected. Check if it is still running.		 */		if (tapdisk_ioemu_pid == 0 || kill(tapdisk_ioemu_pid, 0)) {			/* No device model and tapdisk-ioemu doesn't run yet */			DPRINTF("Launching tapdisk-ioemu\n");			tapdisk_ioemu_pid = launch_tapdisk_ioemu();						dom0_readfd = open_ctrl_socket(wrctldev);			dom0_writefd = open_ctrl_socket(rdctldev);		}		DPRINTF("Using tapdisk-ioemu connection\n");		blkif->fds[READ] = dom0_readfd;		blkif->fds[WRITE] = dom0_writefd;	} else if (access(rdctldev, R_OK | W_OK) == 0) {		/* Use existing pipe to the device model */		DPRINTF("Using qemu-dm connection\n");		blkif->fds[READ] = open_ctrl_socket(wrctldev);		blkif->fds[WRITE] = open_ctrl_socket(rdctldev);	} else {		/* No device model => try with tapdisk-ioemu */		DPRINTF("No device model\n");		connect_qemu(blkif, 0);	}		free(rdctldev);	free(wrctldev);		if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1)		return -1;	DPRINTF("Attached to qemu blktap pipes\n");	return 0;}/* Launch tapdisk instance */static int connect_tapdisk(blkif_t *blkif, int minor){	char *rdctldev = NULL, *wrctldev = NULL;	int ret = -1;	DPRINTF("tapdisk 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)		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;	}	ret = 0;	fail:	if (rdctldev)		free(rdctldev);	if (wrctldev)		free(wrctldev);	return ret;}static 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 (blktap_interface_create(ctlfd, &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) {			if (type == DISK_TYPE_IOEMU) {				if (connect_qemu(blkif, blkif->domid))					goto fail;			} else {				if (connect_tapdisk(blkif, minor))					goto fail;			}		} 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;}static 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;}static 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);	ctlfd = blktap_interface_open();	if (ctlfd < 0) {		DPRINTF("couldn't open blktap interface\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 + -