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

📄 blktapctrl.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * blktapctrl.c *  * userspace controller for the blktap disks. * As requests for new block devices arrive, * the controller spawns off a separate process * per-disk. * * * Copyright (c) 2005 Julian Chesterfield and Andrew Warfield. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */#include <stdio.h>#include <stdlib.h>#include <sys/mman.h>#include <err.h>#include <errno.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>#include <fcntl.h>#include <sys/poll.h>#include <sys/ioctl.h>#include <string.h>#include <unistd.h>#include <xs.h>#include <sys/time.h>#include <syslog.h>                                                                     #include "blktaplib.h"#include "blktapctrl.h"#include "tapdisk.h"#include "list.h"#include "xs_api.h" /* for xs_fire_next_watch() */#define PIDFILE "/var/run/blktapctrl.pid"#define NUM_POLL_FDS 2#define MSG_SIZE 4096#define MAX_TIMEOUT 10#define MAX_RAND_VAL 0xFFFF#define MAX_ATTEMPTS 10int run = 1;int max_timeout = MAX_TIMEOUT;int ctlfd = 0;int blktap_major;static int open_ctrl_socket(char *devname);static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);static int read_msg(int fd, int msgtype, void *ptr);static driver_list_entry_t *active_disks[MAX_DISK_TYPES];static unsigned long long tapdisk_get_size(blkif_t *blkif){	image_t *img = (image_t *)blkif->prv;	return img->size;}static unsigned long tapdisk_get_secsize(blkif_t *blkif){	image_t *img = (image_t *)blkif->prv;	return img->secsize;}static unsigned int tapdisk_get_info(blkif_t *blkif){	image_t *img = (image_t *)blkif->prv;	return img->info;}struct blkif_ops tapdisk_ops = {	.get_size = tapdisk_get_size,	.get_secsize = tapdisk_get_secsize,	.get_info = tapdisk_get_info,};static void init_driver_list(void){	int i;	for (i = 0; i < MAX_DISK_TYPES; i++)		active_disks[i] = NULL;	return;}static void init_rng(void){	static uint32_t seed;	struct timeval tv;	gettimeofday(&tv, NULL);	seed = tv.tv_usec;	srand48(seed);	return;}static int get_tapdisk_pid(blkif_t *blkif){	int ret;	if ((ret = write_msg(blkif->fds[WRITE], CTLMSG_PID, blkif, NULL)) 	    <= 0) {		DPRINTF("Write_msg failed - CTLMSG_PID(%d)\n", ret);		return -EINVAL;	}	if ((ret = read_msg(blkif->fds[READ], CTLMSG_PID_RSP, blkif))	     <= 0) {		DPRINTF("Read_msg failure - CTLMSG_PID(%d)\n", ret);		return -EINVAL;	}		return 1;}/* Look up the disk specified by path:  *   if found, dev points to the device string in the path *             type is the tapdisk driver type id *             blkif is the existing interface if this is a shared driver *             and NULL otherwise. *   return 0 on success, -1 on error. */static int test_path(char *path, char **dev, int *type, blkif_t **blkif){	char *ptr, handle[10];	int i, size, found = 0;	size_t handle_len;	size = sizeof(dtypes)/sizeof(disk_info_t *);	*type = MAX_DISK_TYPES + 1;        *blkif = NULL;	if ( (ptr = strstr(path, ":"))!=NULL) {		handle_len = (ptr - path);		memcpy(handle, path, handle_len);		*dev = ptr + 1;		ptr = handle + handle_len;		*ptr = '\0';		DPRINTF("Detected handle: [%s]\n",handle);		for (i = 0; i < size; i++) {			if ((strlen(dtypes[i]->handle) == handle_len) &&					strncmp(handle, dtypes[i]->handle,					handle_len) == 0) {                                found = 1;                        }			if (found) {				*type = dtypes[i]->idnum;                                                if (dtypes[i]->single_handler == 1) {                                /* Check whether tapdisk process                                    already exists */                                if (active_disks[dtypes[i]->idnum] == NULL)                                         *blkif = NULL;                                else                                         *blkif = active_disks[dtypes[i]                                                             ->idnum]->blkif;                        }                        return 0;                }            }        }        /* Fall-through case, we didn't find a disk driver. */        DPRINTF("Unknown blktap disk type [%s]!\n",handle);        *dev = NULL;        return -1;}static void add_disktype(blkif_t *blkif, int type){	driver_list_entry_t *entry, **pprev;	if (type > MAX_DISK_TYPES)		return;	entry = malloc(sizeof(driver_list_entry_t));	entry->blkif = blkif;	entry->next  = NULL;	pprev = &active_disks[type];	while (*pprev != NULL)		pprev = &(*pprev)->next;	*pprev = entry;	entry->pprev = pprev;}static int del_disktype(blkif_t *blkif){	driver_list_entry_t *entry, **pprev;	int type = blkif->drivertype, count = 0, close = 0;	if (type > MAX_DISK_TYPES)		return 1;	pprev = &active_disks[type];	while ((*pprev != NULL) && ((*pprev)->blkif != blkif))		pprev = &(*pprev)->next;	if ((entry = *pprev) == NULL) {		DPRINTF("DEL_DISKTYPE: No match\n");		return 1;	}	*pprev = entry->next;	if (entry->next)		entry->next->pprev = pprev;	DPRINTF("DEL_DISKTYPE: Freeing entry\n");	free(entry);	/* Caller should close() if no single controller, or list is empty. */	return (!dtypes[type]->single_handler || (active_disks[type] == NULL));}static int write_msg(int fd, int msgtype, void *ptr, void *ptr2){	blkif_t *blkif;	blkif_info_t *blk;	msg_hdr_t *msg;	msg_newdev_t *msg_dev;	char *p, *buf, *path;	int msglen, len, ret;	fd_set writefds;	struct timeval timeout;	image_t *image, *img;	uint32_t seed;	blkif = (blkif_t *)ptr;	blk = blkif->info;	image = blkif->prv;	len = 0;	switch (msgtype)	{	case CTLMSG_PARAMS:		path = (char *)ptr2;		DPRINTF("Write_msg called: CTLMSG_PARAMS, sending [%s, %s]\n",			blk->params, path);		msglen = sizeof(msg_hdr_t) + strlen(path) + 1;		buf = malloc(msglen);		/*Assign header fields*/		msg = (msg_hdr_t *)buf;		msg->type = CTLMSG_PARAMS;		msg->len = msglen;		msg->drivertype = blkif->drivertype;		msg->readonly = blkif->readonly;		gettimeofday(&timeout, NULL);		msg->cookie = blkif->cookie;		DPRINTF("Generated cookie, %d\n",blkif->cookie);		/*Copy blk->params to msg*/		p = buf + sizeof(msg_hdr_t);		memcpy(p, path, strlen(path) + 1);		break;	case CTLMSG_NEWDEV:		DPRINTF("Write_msg called: CTLMSG_NEWDEV\n");		msglen = sizeof(msg_hdr_t) + sizeof(msg_newdev_t);		buf = malloc(msglen);				/*Assign header fields*/		msg = (msg_hdr_t *)buf;		msg->type = CTLMSG_NEWDEV;		msg->len = msglen;		msg->drivertype = blkif->drivertype;		msg->cookie = blkif->cookie;				msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));		msg_dev->devnum = blkif->minor;		msg_dev->domid = blkif->domid;		break;	case CTLMSG_CLOSE:		DPRINTF("Write_msg called: CTLMSG_CLOSE\n");		msglen = sizeof(msg_hdr_t);		buf = malloc(msglen);				/*Assign header fields*/		msg = (msg_hdr_t *)buf;		msg->type = CTLMSG_CLOSE;		msg->len = msglen;		msg->drivertype = blkif->drivertype;		msg->cookie = blkif->cookie;				break;	case CTLMSG_PID:		DPRINTF("Write_msg called: CTLMSG_PID\n");		msglen = sizeof(msg_hdr_t);		buf = malloc(msglen);				/*Assign header fields*/		msg = (msg_hdr_t *)buf;		msg->type = CTLMSG_PID;		msg->len = msglen;		msg->drivertype = blkif->drivertype;		msg->cookie = blkif->cookie;				break;			default:		return -1;	}	/*Now send the message*/	ret = 0;	FD_ZERO(&writefds);	FD_SET(fd,&writefds);	timeout.tv_sec = max_timeout; /*Wait for up to max_timeout seconds*/	timeout.tv_usec = 0;	if (select(fd+1, (fd_set *) 0, &writefds, 		  (fd_set *) 0, &timeout) > 0) {		len = write(fd, buf, msglen);		if (len == -1) DPRINTF("Write failed: (%d)\n",errno);	}	free(buf);	return len;}static int read_msg(int fd, int msgtype, void *ptr){	blkif_t *blkif;	blkif_info_t *blk;	msg_hdr_t *msg;	msg_pid_t *msg_pid;	char *p, *buf;	int msglen = MSG_SIZE, len, ret;	fd_set readfds;	struct timeval timeout;	image_t *image, *img;	blkif = (blkif_t *)ptr;	blk = blkif->info;	image = blkif->prv;	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;		}

⌨️ 快捷键说明

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