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

📄 blktapctrl.c

📁 xen 3.2.2 源码
💻 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 <sys/stat.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"#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 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 void make_blktap_dev(char *devname, int major, int minor){	struct stat st;		if (lstat(devname, &st) != 0) {		/*Need to create device*/		if (mkdir(BLKTAP_DEV_DIR, 0755) == 0)			DPRINTF("Created %s directory\n",BLKTAP_DEV_DIR);		if (mknod(devname, S_IFCHR|0600,                	makedev(major, minor)) == 0)			DPRINTF("Created %s device\n",devname);	} else {		DPRINTF("%s device already exists\n",devname);		/* it already exists, but is it the same major number */		if (((st.st_rdev>>8) & 0xff) != major) {			DPRINTF("%s has old major %d\n",				devname,				(unsigned int)((st.st_rdev >> 8) & 0xff));			/* only try again if we succed in deleting it */			if (!unlink(devname))				make_blktap_dev(devname, major, minor);		}	}}static int get_new_dev(int *major, int *minor, blkif_t *blkif){	domid_translate_t tr;	int ret;	char *devname;		tr.domid = blkif->domid;        tr.busid = (unsigned short)blkif->be_id;	ret = ioctl(ctlfd, BLKTAP_IOCTL_NEWINTF, tr );		if ( (ret <= 0)||(ret > MAX_TAP_DEV) ) {		DPRINTF("Incorrect Dev ID [%d]\n",ret);		return -1;	}		*minor = ret;	*major = ioctl(ctlfd, BLKTAP_IOCTL_MAJOR, ret );	if (*major < 0) {		DPRINTF("Incorrect Major ID [%d]\n",*major);		return -1;	}	if (asprintf(&devname,"%s/%s%d",BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, *minor) == -1)		return -1;	make_blktap_dev(devname,*major,*minor);		DPRINTF("Received device id %d and major %d, "		"sent domid %d and be_id %d\n",		*minor, *major, tr.domid, tr.busid);	return 0;}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 = sizeof(dtypes)/sizeof(disk_info_t *);	*type = MAX_DISK_TYPES + 1;        *blkif = NULL;	if ( (ptr = strstr(path, ":"))!=NULL) {		memcpy(handle, path, (ptr - path));		*dev = ptr + 1;		ptr = handle + (ptr - path);		*ptr = '\0';		DPRINTF("Detected handle: [%s]\n",handle);		for (i = 0; i < size; i++) 			if (strncmp(handle, dtypes[i]->handle,                                     (ptr - path)) ==0) {                                found = 1;                                break;                        }                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;

⌨️ 快捷键说明

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