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

📄 xs_api.c

📁 xen 3.2.2 源码
💻 C
字号:
/* * xs_api.c *  * blocktap interface functions to xenstore * * (c) 2005 Andrew Warfield and Julian Chesterfield * * * 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 <string.h>#include <err.h>#include <stdarg.h>#include <errno.h>#include <xs.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <poll.h>#include "blktaplib.h"#include "list.h"#include "xs_api.h"#if 0#define DPRINTF(_f, _a...) printf ( _f , ## _a )#else#define DPRINTF(_f, _a...) ((void)0)#endifstatic LIST_HEAD(watches);#define BASE_DEV_VAL 2048int xs_gather(struct xs_handle *xs, const char *dir, ...){	va_list ap;	const char *name;	char *path, **e;	int ret = 0, num,i;	unsigned int len;	xs_transaction_t xth;again:	if ( (xth = xs_transaction_start(xs)) == XBT_NULL) {		DPRINTF("unable to start xs trasanction\n");		ret = ENOMEM;		return ret;	}		va_start(ap, dir);	while ( (ret == 0) && (name = va_arg(ap, char *)) != NULL) {		const char *fmt = va_arg(ap, char *);		void *result = va_arg(ap, void *);		char *p;				if (asprintf(&path, "%s/%s", dir, name) == -1)		{			printf("allocation error in xs_gather!\n");			ret = ENOMEM;			break;		}				p = xs_read(xs, xth, path, &len);						free(path);		if (p == NULL) {			ret = ENOENT;			break;		}		if (fmt) {			if (sscanf(p, fmt, result) == 0)				ret = EINVAL;			free(p);		} else			*(char **)result = p;	}	va_end(ap);	if (!xs_transaction_end(xs, xth, ret)) {		if (ret == 0 && errno == EAGAIN)			goto again;		else			ret = errno;	}	return ret;}/* Single printf and write: returns -errno or 0. */int xs_printf(struct xs_handle *h, const char *dir, const char *node, 	      const char *fmt, ...){	char *buf, *path;	va_list ap;	int ret;		va_start(ap, fmt);	ret = vasprintf(&buf, fmt, ap);	va_end(ap);		if (ret == -1)		return ENOMEM;	if (asprintf(&path, "%s/%s", dir, node) == -1) {		free(buf);		return ENOMEM;	}	ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);		free(buf);	free(path);		return ret;}int xs_exists(struct xs_handle *h, const char *path){	char **d;	unsigned int num;	xs_transaction_t xth;		if ( (xth = xs_transaction_start(h)) == XBT_NULL) {		printf("unable to start xs trasanction\n");		return 0;	}			d = xs_directory(h, xth, path, &num);	xs_transaction_end(h, xth, 0);	if (d == NULL)		return 0;	free(d);	return 1;}/** * This assumes that the domain name we are looking for is unique.  * Name parameter Domain-0  */char *get_dom_domid(struct xs_handle *h){	char **e, *val, *domid = NULL;	unsigned int num, len;	int i;	char *path;	xs_transaction_t xth;		if ( (xth = xs_transaction_start(h)) == XBT_NULL) {		warn("unable to start xs trasanction\n");		return NULL;	}		e = xs_directory(h, xth, "/local/domain", &num);	if (e == NULL)		goto done;	for (i = 0; (i < num) && (domid == NULL); i++) {		if (asprintf(&path, "/local/domain/%s/name", e[i]) == -1)			break;		val = xs_read(h, xth, path, &len);		free(path);		if (val == NULL)			continue;				if (strcmp(val, DOMNAME) == 0) {			/* match! */			if (asprintf(&path, "/local/domain/%s/domid", e[i]) == -1) {				free(val);				break;			}			domid = xs_read(h, xth, path, &len);			free(path);		}		free(val);	}done:	xs_transaction_end(h, xth, 0);	if (e)		free(e);	return domid;}int convert_dev_name_to_num(char *name) {	char *p, *ptr;	int majors[10] = {3,22,33,34,56,57,88,89,90,91};	int maj,i,ret = 0;	char *p_sd = "/dev/sd";	char *p_hd = "/dev/hd";	char *p_xvd = "/dev/xvd";	char *p_plx = "plx";	char *alpha = "abcdefghijklmnop";	if (strstr(name, p_sd) != NULL) {		p = name + strlen(p_sd);		for(i = 0, ptr = alpha; i < strlen(alpha); i++) {			if(*ptr == *p)				break;			*ptr++;		}		*p++;		ret = BASE_DEV_VAL + (16*i) + atoi(p);	} else if (strstr(name, p_hd) != NULL) {		p = name + strlen(p_hd);		for (i = 0, ptr = alpha; i < strlen(alpha); i++) {			if(*ptr == *p) break;			*ptr++;		}		*p++;		ret = (majors[i/2]*256) + atoi(p);	} else if (strstr(name, p_xvd) != NULL) {		p = name + strlen(p_xvd);		for(i = 0, ptr = alpha; i < strlen(alpha); i++) {			if(*ptr == *p) break;			*ptr++;		}		*p++;		ret = (202*256) + (16*i) + atoi(p);	} else if (strstr(name, p_plx) != NULL) {		p = name + strlen(p_plx);		ret = atoi(p);	} else {		DPRINTF("Unknown device type, setting to default.\n");		ret = BASE_DEV_VAL;	}	return ret;}/** * A little paranoia: we don't just trust token.  */static struct xenbus_watch *find_watch(const char *token){	struct xenbus_watch *i, *cmp;		cmp = (void *)strtoul(token, NULL, 16);		list_for_each_entry(i, &watches, list)		if (i == cmp)			return i;	return NULL;}/** * Register callback to watch this node.  * like xs_watch, return 0 on failure  */int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch){	/* Pointer in ascii is the token. */	char token[sizeof(watch) * 2 + 1];	snprintf(token, sizeof(token), "%lX", (long)watch);	if (find_watch(token)) {		DPRINTF("watch collision!\n");		return -EINVAL;	}		if (!xs_watch(h, watch->node, token)) {		DPRINTF("unable to set watch!\n");		return -EINVAL;	}	list_add(&watch->list, &watches);	return 0;}int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch){	char token[sizeof(watch) * 2 + 1];		snprintf(token, sizeof(token), "%lX", (long)watch);	if (!find_watch(token)) {		DPRINTF("no such watch!\n");		return -EINVAL;	}	if (!xs_unwatch(h, watch->node, token))		DPRINTF("XENBUS Failed to release watch %s\n",			watch->node);	list_del(&watch->list);		return 0;}/** * Re-register callbacks to all watches.  */void reregister_xenbus_watches(struct xs_handle *h){	struct xenbus_watch *watch;	char token[sizeof(watch) * 2 + 1];		list_for_each_entry(watch, &watches, list) {		snprintf(token, sizeof(token), "%lX", (long)watch);		xs_watch(h, watch->node, token);	}}/** * based on watch_thread()  */int xs_fire_next_watch(struct xs_handle *h){	char **res;	char *token;	char *node = NULL;	struct xenbus_watch *w;	int er;	unsigned int num;		res = xs_read_watch(h, &num);	if (res == NULL) 		return -EAGAIN; /* in O_NONBLOCK, read_watch returns 0... */		node  = res[XS_WATCH_PATH];	token = res[XS_WATCH_TOKEN];	w = find_watch(token);	if (w) 		w->callback(h, w, node);	free(res);	return 1;}

⌨️ 快捷键说明

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