示例#1
0
/**
 * Iterate on each item of the map, applying callback.
 */
void
map_foreach(const map_t *m, keyval_fn_t cb, void *u)
{
	map_check(m);
	g_assert(cb);

	switch (m->type) {
	case MAP_HASH:
		htable_foreach(m->u.ht, (ckeyval_fn_t) cb, u);
		break;
	case MAP_ORDERED_HASH:
		ohash_table_foreach(m->u.ot, cb, u);
		break;
	case MAP_PATRICIA:
		{
			struct pat_foreach ctx;

			ctx.cb = cb;
			ctx.u = u;

			patricia_foreach(m->u.pt, pat_foreach_wrapper, &ctx);
		}
		break;
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
}
示例#2
0
static int 
mcast_hostlist(const char *vm_name, const char *vm_uuid,
	       int state, void *priv)
{
	struct mcast_hostlist_arg *arg = (struct mcast_hostlist_arg *)priv;
	host_state_t hinfo;
	struct timeval tv;
	int ret;

	if (map_check(arg->map, arg->src, vm_uuid) == 0) {
		/* if we don't have access to fence this VM,
		 * we should not see it in a hostlist either */
		return 0;
	}

	strncpy((char *)hinfo.domain, vm_name, sizeof(hinfo.domain));
	strncpy((char *)hinfo.uuid, vm_uuid, sizeof(hinfo.uuid));
	hinfo.state = state;

	tv.tv_sec = 1;
	tv.tv_usec = 0;
	ret = _write_retry(arg->fd, &hinfo, sizeof(hinfo), &tv);
	if (ret == sizeof(hinfo))
		return 0;
	return 1;
}
示例#3
0
/**
 * Iterate over the map, applying callback on each item and removing it if
 * the callback returns TRUE.
 *
 * @return the amount of items deleted.
 */
size_t
map_foreach_remove(const map_t *m, keyval_rm_fn_t cb, void *u)
{
	map_check(m);
	g_assert(cb);

	switch (m->type) {
	case MAP_HASH:
		return htable_foreach_remove(m->u.ht, (ckeyval_rm_fn_t) cb, u);
	case MAP_ORDERED_HASH:
		return ohash_table_foreach_remove(m->u.ot, cb, u);
	case MAP_PATRICIA:
		{
			struct pat_foreach_remove ctx;

			ctx.cb = cb;
			ctx.u = u;

			return patricia_foreach_remove(
				m->u.pt, pat_foreach_remove_wrapper, &ctx);
		}
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
	return 0;
}
示例#4
0
/**
 * Switch the implementation of an existing map to a PATRICIA tree.
 * Returns the previous implementation.
 */
void *
map_switch_to_patricia(map_t *m, patricia_t *pt)
{
	void *implementation;

	map_check(m);
	g_assert(pt);

	implementation = map_implementation(m);
	m->type = MAP_PATRICIA;
	m->u.pt = pt;

	return implementation;
}
示例#5
0
/**
 * Switch the implementation of an existing map to an ordered hash table.
 * Returns the previous implementation.
 */
void *
map_switch_to_ordered_hash(map_t *m, ohash_table_t *ot)
{
	void *implementation;

	map_check(m);
	g_assert(ot);

	implementation = map_implementation(m);
	m->type = MAP_ORDERED_HASH;
	m->u.ot = ot;

	return implementation;
}
示例#6
0
/**
 * Switch the implementation of an existing map to a hash table.
 * Returns the previous implementation.
 */
void *
map_switch_to_hash(map_t *m, htable_t *ht)
{
	void *implementation;

	map_check(m);
	g_assert(ht);

	implementation = map_implementation(m);
	m->type = MAP_HASH;
	m->u.ht = ht;

	return implementation;
}
示例#7
0
ATF_TC_BODY(mmap_prot_1, tc)
{
	void *map;
	int fd;

	/*
	 * Open a file write-only and try to
	 * map it read-only. This should fail.
	 */
	fd = open(path, O_WRONLY | O_CREAT, 0700);

	if (fd < 0)
		return;

	ATF_REQUIRE(write(fd, "XXX", 3) == 3);

	map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
	map_check(map, 1);

	map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
	map_check(map, 0);

	ATF_REQUIRE(close(fd) == 0);
}
示例#8
0
/**
 * Release the map encapsulation, returning the underlying implementation
 * object (will need to be cast back to the proper type for perusal).
 */
void *
map_release(map_t *m)
{
	void *implementation;

	map_check(m);

	implementation = map_implementation(m);

	m->type = MAP_MAXTYPE;
	m->magic = 0;
	WFREE(m);

	return implementation;
}
示例#9
0
ATF_TC_BODY(mmap_va0, tc)
{
	int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE;
	size_t len = sizeof(int);
	void *map;
	int val;

	/*
	 * Make an anonymous fixed mapping at zero address. If the address
	 * is restricted as noted in security(7), the syscall should fail.
	 */
#ifdef __FreeBSD__
	if (sysctlbyname("security.bsd.map_at_zero", &val, &len, NULL, 0) != 0)
		atf_tc_fail("failed to read security.bsd.map_at_zero");
	val = !val; /* 1 == enable  map at zero */
#endif
#ifdef __NetBSD__
	if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0)
		atf_tc_fail("failed to read vm.user_va0_disable");
#endif

	map = mmap(NULL, page, PROT_EXEC, flags, -1, 0);
	map_check(map, val);

	map = mmap(NULL, page, PROT_READ, flags, -1, 0);
	map_check(map, val);

	map = mmap(NULL, page, PROT_WRITE, flags, -1, 0);
	map_check(map, val);

	map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0);
	map_check(map, val);

	map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0);
	map_check(map, val);
}
示例#10
0
/**
 * Extended lookup of a key in the map, returning both key/value pointers.
 */
bool
map_lookup_extended(const map_t *m, const void *key, void **okey, void **oval)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		return htable_lookup_extended(m->u.ht, key, (const void **) okey, oval);
	case MAP_ORDERED_HASH:
		return ohash_table_lookup_extended(m->u.ot, key, okey, oval);
	case MAP_PATRICIA:
		return patricia_lookup_extended(m->u.pt, key, okey, oval);
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
	return FALSE;
}
示例#11
0
/**
 * @return amount of items held in map.
 */
size_t
map_count(const map_t *m)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		return htable_count(m->u.ht);
	case MAP_ORDERED_HASH:
		return ohash_table_count(m->u.ot);
	case MAP_PATRICIA:
		return patricia_count(m->u.pt);
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
	return 0;
}
示例#12
0
/**
 * Lookup a key in the map.
 */
void *
map_lookup(const map_t *m, const void *key)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		return htable_lookup(m->u.ht, key);
	case MAP_ORDERED_HASH:
		return ohash_table_lookup(m->u.ot, key);
	case MAP_PATRICIA:
		return patricia_lookup(m->u.pt, key);
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
	return NULL;
}
示例#13
0
/**
 * Check whether map contains the key.
 */
bool
map_contains(const map_t *m, const void *key)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		return htable_contains(m->u.ht, key);
	case MAP_ORDERED_HASH:
		return ohash_table_contains(m->u.ot, key);
	case MAP_PATRICIA:
		return patricia_contains(m->u.pt, key);
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
	return FALSE;
}
示例#14
0
/**
 * Returns the underlying map implementation.
 */
void *
map_implementation(const map_t *m)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		return m->u.ht;
	case MAP_ORDERED_HASH:
		return m->u.ot;
	case MAP_PATRICIA:
		return m->u.pt;
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}

	return NULL;
}
示例#15
0
/**
 * Replace a key/value pair in the map.
 */
void
map_replace(const map_t *m, const void *key, const void *value)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		htable_insert_const(m->u.ht, key, value);
		break;
	case MAP_ORDERED_HASH:
		ohash_table_replace(m->u.ot, key, value);
		break;
	case MAP_PATRICIA:
		patricia_insert(m->u.pt, key, value);		/* Does replace */
		break;
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}
}
示例#16
0
/**
 * Mark map as thread-safe.
 *
 * If the underlying implementation does not implement thread-safety, this
 * causes a fatal error.
 */
void
map_thread_safe(const map_t *m)
{
	const char *type = NULL;

	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		htable_thread_safe(m->u.ht);
		return;
	case MAP_ORDERED_HASH:
		type = "ordered hash";
		break;
	case MAP_PATRICIA:
		type = "PATRICIA";
		break;
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}

	s_error("%s(): %s implementation is not thread-safe yet", G_STRFUNC, type);
}
示例#17
0
/**
 * Destroy a map.
 */
void
map_destroy(map_t *m)
{
	map_check(m);

	switch (m->type) {
	case MAP_HASH:
		htable_free_null(&m->u.ht);
		break;
	case MAP_ORDERED_HASH:
		ohash_table_destroy_null(&m->u.ot);
		break;
	case MAP_PATRICIA:
		patricia_destroy(m->u.pt);
		break;
	case MAP_MAXTYPE:
		g_assert_not_reached();
	}

	m->type = MAP_MAXTYPE;
	m->magic = 0;
	WFREE(m);
}
示例#18
0
static int 
vsock_hostlist(const char *vm_name, const char *vm_uuid,
	       int state, void *priv)
{
	struct vsock_hostlist_arg *arg = (struct vsock_hostlist_arg *) priv;
	host_state_t hinfo;
	struct timeval tv;
	int ret;
	uint32_t peer_cid = 0;
	char peer_cid_str[24];

	ret = get_peer_cid(arg->fd, &peer_cid);
	if (ret < 0) {
		printf("Unable to get peer CID: %s\n", strerror(errno));
		peer_cid_str[0] = '\0';
	} else
		snprintf(peer_cid_str, sizeof(peer_cid_str), "%u", peer_cid);

	/* Noops if auth == AUTH_NONE */

	if (map_check(arg->map, peer_cid_str, vm_uuid) == 0) {
		/* if we don't have access to fence this VM,
		 * we should not see it in a hostlist either */
		return 0;
	}

	strncpy((char *)hinfo.domain, vm_name, sizeof(hinfo.domain));
	strncpy((char *)hinfo.uuid, vm_uuid, sizeof(hinfo.uuid));
	hinfo.state = state;

	tv.tv_sec = 1;
	tv.tv_usec = 0;
	ret = _write_retry(arg->fd, &hinfo, sizeof(hinfo), &tv);
	if (ret == sizeof(hinfo))
		return 0;
	return 1;
}
示例#19
0
文件: memory.c 项目: marssaxman/fleet
void _memory_init(struct multiboot_info *info) {
	// Use whatever information the bootloader gave us to figure out what
	// lives where in our address space and which parts of it we can use.
	if (info->flags & 1<<6) {
		// We have a BIOS memory map.
		struct memory_map *mmap = (struct memory_map*)info->memory_map_addr;
		map_check(mmap, info->memory_map_length);
	} else if (info->flags & 1<<0) {
		// We know how large the upper and lower memory banks are.
		simple_check(info->mem_lower * 1024, info->mem_upper * 1024);
	}
	if (IMAGE_BASE < memory_end && IMAGE_END > memory_base) {
		// The beginning of our memory region is already home to our
		// executable image and bootstrap stack. Move the allocation pointer
		// past it so we don't accidentally reuse it.
		memory_break = IMAGE_END;
	} else {
		memory_break = memory_base;
	}
	if (IMAGE_BASE > memory_base && IMAGE_BASE < memory_end) {
		// Truncate the memory region so it no longer overlaps the executable.
		memory_end = IMAGE_BASE;
	}
}
示例#20
0
static int
do_fence_request_tcp(int fd, fence_req_t *req, tcp_info *info)
{
	char ip_addr_src[1024];
	char response = 1;
	struct tcp_hostlist_arg arg;

	/* Noops if auth == AUTH_NONE */
	if (tcp_response(fd, info->args.auth, info->key, info->key_len, 10) <= 0) {
		printf("Failed to respond to challenge\n");
		close(fd);
		return -1;
	}

	if (tcp_challenge(fd, info->args.auth, info->key, info->key_len, 10) <= 0) {
		printf("Remote failed challenge\n");
		close(fd);
		return -1;
	}

	dbg_printf(2, "Request %d seqno %d target %s\n", 
		   req->request, req->seqno, req->domain);

	switch(req->request) {
	case FENCE_NULL:
		response = info->cb->null((char *)req->domain, info->priv);
		break;
	case FENCE_ON:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->on((char *)req->domain, ip_addr_src,
					req->seqno, info->priv);
		break;
	case FENCE_OFF:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->off((char *)req->domain, ip_addr_src,
					 req->seqno, info->priv);
		break;
	case FENCE_REBOOT:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->reboot((char *)req->domain, ip_addr_src,
					    req->seqno, info->priv);
		break;
	case FENCE_STATUS:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->status((char *)req->domain, info->priv);
		break;
	case FENCE_DEVSTATUS:
		response = info->cb->devstatus(info->priv);
		break;
	case FENCE_HOSTLIST:
		arg.map = info->map;
		arg.src = ip_addr_src;
		arg.fd = fd;

		tcp_hostlist_begin(arg.fd);
		response = info->cb->hostlist(tcp_hostlist, &arg,
					      info->priv);
		tcp_hostlist_end(arg.fd);
		break;
	}

	dbg_printf(3, "Sending response to caller...\n");
	if (write(fd, &response, 1) < 0) {
		perror("write");
	}

	history_record(info->history, req);

	if (fd != -1)
		close(fd);

	return 1;
}
示例#21
0
static int
do_fence_request_tcp(fence_req_t *req, mcast_info *info)
{
	char ip_addr_src[1024];
	int fd = -1;
	char response = 1;
	struct mcast_hostlist_arg arg;

	fd = connect_tcp(req, info->args.auth, info->key, info->key_len);
	if (fd < 0) {
		dbg_printf(2, "Could not send reply to fence request: %s\n",
			strerror(errno));
		goto out;
	}

	inet_ntop(req->family, req->address,
		  ip_addr_src, sizeof(ip_addr_src));

	dbg_printf(2, "Request %d seqno %d src %s target %s\n", 
		   req->request, req->seqno, ip_addr_src, req->domain);

	switch(req->request) {
	case FENCE_NULL:
		response = info->cb->null((char *)req->domain, info->priv);
		break;
	case FENCE_ON:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->on((char *)req->domain, ip_addr_src,
					req->seqno, info->priv);
		break;
	case FENCE_OFF:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->off((char *)req->domain, ip_addr_src,
					 req->seqno, info->priv);
		break;
	case FENCE_REBOOT:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->reboot((char *)req->domain, ip_addr_src,
					    req->seqno, info->priv);
		break;
	case FENCE_STATUS:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->status((char *)req->domain, info->priv);
		break;
	case FENCE_DEVSTATUS:
		response = info->cb->devstatus(info->priv);
		break;
	case FENCE_HOSTLIST:
		arg.map = info->map;
		arg.src = ip_addr_src;
		arg.fd = fd;

		mcast_hostlist_begin(arg.fd);
		response = info->cb->hostlist(mcast_hostlist, &arg,
					      info->priv);
		mcast_hostlist_end(arg.fd);
		break;
	}

	dbg_printf(3, "Sending response to caller...\n");
	if (write(fd, &response, 1) < 0) {
		perror("write");
	}

	/* XVM shotguns multicast packets, so we want to avoid 
	 * acting on the same request multiple times if the first
	 * attempt was successful.
	 */
	history_record(info->history, req);
out:
	if (fd != -1)
		close(fd);

	return 1;
}
示例#22
0
static int
do_fence_request_vsock(int fd, fence_req_t *req, vsock_info *info)
{
	char response = 1;
	struct vsock_hostlist_arg arg;
	uint32_t peer_cid = 0;
	char peer_cid_str[24];
	int ret;

	ret = get_peer_cid(fd, &peer_cid);
	if (ret < 0) {
		printf("Unable to get peer CID: %s\n", strerror(errno));
		return -1;
	}

	snprintf(peer_cid_str, sizeof(peer_cid_str), "%u", peer_cid);

	/* Noops if auth == AUTH_NONE */
	if (sock_response(fd, info->args.auth, info->key, info->key_len, 10) <= 0) {
		printf("CID %u Failed to respond to challenge\n", peer_cid);
		close(fd);
		return -1;
	}

	ret = sock_challenge(fd, info->args.auth, info->key, info->key_len, 10);
	if (ret <= 0) {
		printf("Remote CID %u failed challenge\n", peer_cid);
		close(fd);
		return -1;
	}

	dbg_printf(2, "Request %d seqno %d target %s from CID %u\n", 
		   req->request, req->seqno, req->domain, peer_cid);

	switch(req->request) {
	case FENCE_NULL:
		response = info->cb->null((char *)req->domain, info->priv);
		break;
	case FENCE_ON:
		if (map_check(info->map, peer_cid_str,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->on((char *)req->domain, peer_cid_str,
					req->seqno, info->priv);
		break;
	case FENCE_OFF:
		if (map_check(info->map, peer_cid_str,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->off((char *)req->domain, peer_cid_str,
					 req->seqno, info->priv);
		break;
	case FENCE_REBOOT:
		if (map_check(info->map, peer_cid_str,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->reboot((char *)req->domain, peer_cid_str,
					    req->seqno, info->priv);
		break;
	case FENCE_STATUS:
		if (map_check(info->map, peer_cid_str,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->status((char *)req->domain, info->priv);
		break;
	case FENCE_DEVSTATUS:
		response = info->cb->devstatus(info->priv);
		break;
	case FENCE_HOSTLIST:
		arg.map = info->map;
		arg.fd = fd;

		vsock_hostlist_begin(arg.fd);
		response = info->cb->hostlist(vsock_hostlist, &arg, info->priv);
		vsock_hostlist_end(arg.fd);
		break;
	}

	dbg_printf(3, "Sending response to caller CID %u...\n", peer_cid);
	if (_write_retry(fd, &response, 1, NULL) < 0)
		perror("write");

	history_record(info->history, req);

	if (fd != -1)
		close(fd);

	return 1;
}