Esempio n. 1
0
/*
 * object db create/destroy/set
 */
static int object_create (
	hdb_handle_t parent_object_handle,
	hdb_handle_t *object_handle,
	const void *object_name,
	size_t object_name_len)
{
	struct object_instance *object_instance;
	struct object_instance *parent_instance;
	unsigned int res;
	int found = 0;
	int i;

	objdb_lock();
	res = hdb_handle_get (&object_instance_database,
		parent_object_handle, (void *)&parent_instance);
	if (res != 0) {
		goto error_exit;
	}

	/*
	 * Do validation check if validation is configured for the parent object
	 */
	if (parent_instance->object_valid_list_entries) {
		for (i = 0; i < parent_instance->object_valid_list_entries; i++) {
			if ((object_name_len ==
					parent_instance->object_valid_list[i].object_len) &&
				(memcmp (object_name,
					 parent_instance->object_valid_list[i].object_name,
					 object_name_len) == 0)) {

				found = 1;
				break;
			}
		}

		/*
		 * Item not found in validation list
		 */
		if (found == 0) {
			goto error_object_put;
		}
	}


	res = hdb_handle_create (&object_instance_database,
		sizeof (struct object_instance), object_handle);
	if (res != 0) {
		goto error_object_put;
	}

	res = hdb_handle_get (&object_instance_database,
		*object_handle, (void *)&object_instance);
	if (res != 0) {
		goto error_destroy;
	}
	list_init (&object_instance->key_head);
	list_init (&object_instance->child_head);
	list_init (&object_instance->child_list);
	list_init (&object_instance->track_head);
	object_instance->object_name = malloc (object_name_len);
	if (object_instance->object_name == 0) {
		goto error_put_destroy;
	}
	memcpy (object_instance->object_name, object_name, object_name_len);

	object_instance->object_name_len = object_name_len;

	list_add_tail (&object_instance->child_list, &parent_instance->child_head);

	object_instance->object_handle = *object_handle;
	object_instance->find_child_list = &object_instance->child_head;
	object_instance->iter_key_list = &object_instance->key_head;
	object_instance->iter_list = &object_instance->child_head;
	object_instance->priv = NULL;
	object_instance->object_valid_list = NULL;
	object_instance->object_valid_list_entries = 0;
	object_instance->parent_handle = parent_object_handle;

	hdb_handle_put (&object_instance_database, *object_handle);

	hdb_handle_put (&object_instance_database, parent_object_handle);
	object_created_notification(
		object_instance->parent_handle,
		object_instance->object_handle,
		object_instance->object_name,
		object_instance->object_name_len);
	objdb_unlock();
	return (0);

error_put_destroy:
	hdb_handle_put (&object_instance_database, *object_handle);

error_destroy:
	hdb_handle_destroy (&object_instance_database, *object_handle);

error_object_put:
	hdb_handle_put (&object_instance_database, parent_object_handle);

error_exit:
	objdb_unlock();
	return (-1);
}
Esempio n. 2
0
cs_error_t cmap_track_add(
	cmap_handle_t handle,
	const char *key_name,
	int32_t track_type,
	cmap_notify_fn_t notify_fn,
	void *user_data,
	cmap_track_handle_t *cmap_track_handle)
{
	cs_error_t error;
	struct iovec iov;
	struct cmap_inst *cmap_inst;
	struct req_lib_cmap_track_add req_lib_cmap_track_add;
	struct res_lib_cmap_track_add res_lib_cmap_track_add;
	struct cmap_track_inst *cmap_track_inst;
	cmap_track_handle_t cmap_track_inst_handle;

	error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
	if (error != CS_OK) {
		return (error);
	}

	error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db,
				sizeof(*cmap_track_inst), &cmap_track_inst_handle));
	if (error != CS_OK) {
		goto error_put;
	}

	error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
				cmap_track_inst_handle, (void *)&cmap_track_inst));
	if (error != CS_OK) {
		goto error_put_destroy;
	}

	cmap_track_inst->user_data = user_data;
	cmap_track_inst->notify_fn = notify_fn;
	cmap_track_inst->c = cmap_inst->c;

	memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add));
	req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add);
	req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD;

	if (key_name) {
		if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
			return (CS_ERR_NAME_TOO_LONG);
		}
		memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name));
		req_lib_cmap_track_add.key_name.length = strlen(key_name);
	}

	req_lib_cmap_track_add.track_type = track_type;
	req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle;

	iov.iov_base = (char *)&req_lib_cmap_track_add;
	iov.iov_len = sizeof(req_lib_cmap_track_add);

	error = qb_to_cs_error(qb_ipcc_sendv_recv(
		cmap_inst->c,
		&iov,
		1,
		&res_lib_cmap_track_add,
		sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS));

	if (error == CS_OK) {
		error = res_lib_cmap_track_add.header.error;
	}

	if (error == CS_OK) {
		*cmap_track_handle = res_lib_cmap_track_add.track_handle;
		cmap_track_inst->track_handle = *cmap_track_handle;
	}

	(void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);

	(void)hdb_handle_put (&cmap_handle_t_db, handle);

	return (error);

error_put_destroy:
	(void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
	(void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle);

error_put:
	(void)hdb_handle_put (&cmap_handle_t_db, handle);

	return (error);
}
Esempio n. 3
0
/*
 * External API
 */
cs_error_t
coroipcc_service_connect (
	const char *socket_name,
	unsigned int service,
	size_t request_size,
	size_t response_size,
	size_t dispatch_size,
	hdb_handle_t *handle)

{
	int request_fd;
	struct sockaddr_un address;
	cs_error_t res;
	struct ipc_instance *ipc_instance;
#if _POSIX_THREAD_PROCESS_SHARED < 1
	key_t semkey = 0;
	union semun semun;
#endif
	int sys_res;
	mar_req_setup_t req_setup;
	mar_res_setup_t res_setup;
	char control_map_path[PATH_MAX];
	char request_map_path[PATH_MAX];
	char response_map_path[PATH_MAX];
	char dispatch_map_path[PATH_MAX];

	res = hdb_error_to_cs (hdb_handle_create (&ipc_hdb,
		sizeof (struct ipc_instance), handle));
	if (res != CS_OK) {
		return (res);
	}

	res = hdb_error_to_cs (hdb_handle_get (&ipc_hdb, *handle, (void **)&ipc_instance));
	if (res != CS_OK) {
		return (res);
	}

	res_setup.error = CS_ERR_LIBRARY;

#if defined(COROSYNC_SOLARIS)
	request_fd = socket (PF_UNIX, SOCK_STREAM, 0);
#else
	request_fd = socket (PF_LOCAL, SOCK_STREAM, 0);
#endif
	if (request_fd == -1) {
		return (CS_ERR_LIBRARY);
	}
#ifdef SO_NOSIGPIPE
	socket_nosigpipe (request_fd);
#endif

	memset (&address, 0, sizeof (struct sockaddr_un));
	address.sun_family = AF_UNIX;
#if defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN)
	address.sun_len = SUN_LEN(&address);
#endif

#if defined(COROSYNC_LINUX)
	sprintf (address.sun_path + 1, "%s", socket_name);
#else
	sprintf (address.sun_path, "%s/%s", SOCKETDIR, socket_name);
#endif
	sys_res = connect (request_fd, (struct sockaddr *)&address,
		COROSYNC_SUN_LEN(&address));
	if (sys_res == -1) {
		res = CS_ERR_TRY_AGAIN;
		goto error_connect;
	}

	sys_res = memory_map (
		control_map_path,
		"control_buffer-XXXXXX",
		(void *)&ipc_instance->control_buffer,
		8192);
	if (sys_res == -1) {
		res = CS_ERR_LIBRARY;
		goto error_connect;
	}

	sys_res = memory_map (
		request_map_path,
		"request_buffer-XXXXXX",
		(void *)&ipc_instance->request_buffer,
		request_size);
	if (sys_res == -1) {
		res = CS_ERR_LIBRARY;
		goto error_request_buffer;
	}

	sys_res = memory_map (
		response_map_path,
		"response_buffer-XXXXXX",
		(void *)&ipc_instance->response_buffer,
		response_size);
	if (sys_res == -1) {
		res = CS_ERR_LIBRARY;
		goto error_response_buffer;
	}

	sys_res = circular_memory_map (
		dispatch_map_path,
		"dispatch_buffer-XXXXXX",
		(void *)&ipc_instance->dispatch_buffer,
		dispatch_size);
	if (sys_res == -1) {
		res = CS_ERR_LIBRARY;
		goto error_dispatch_buffer;
	}

#if _POSIX_THREAD_PROCESS_SHARED > 0
	sem_init (&ipc_instance->control_buffer->sem_request_or_flush_or_exit, 1, 0);
	sem_init (&ipc_instance->control_buffer->sem_request, 1, 0);
	sem_init (&ipc_instance->control_buffer->sem_response, 1, 0);
	sem_init (&ipc_instance->control_buffer->sem_dispatch, 1, 0);
#else
{
	int i;

	/*
	 * Allocate a semaphore segment
	 */
	while (1) {
		semkey = random();
		ipc_instance->euid = geteuid ();
		if ((ipc_instance->control_buffer->semid
		     = semget (semkey, 4, IPC_CREAT|IPC_EXCL|0600)) != -1) {
		      break;
		}
		/*
		 * EACCESS can be returned as non root user when opening a different
		 * users semaphore.
		 *
		 * EEXIST can happen when we are a root or nonroot user opening
		 * an existing shared memory segment for which we have access
		 */
		if (errno != EEXIST && errno != EACCES) {
			res = CS_ERR_LIBRARY;
			goto error_exit;
		}
	}

	for (i = 0; i < 4; i++) {
		semun.val = 0;
		sys_res = semctl (ipc_instance->control_buffer->semid, i, SETVAL, semun);
		if (sys_res != 0) {
			res = CS_ERR_LIBRARY;
			goto error_exit;
		}
	}
}
#endif

	/*
	 * Initialize IPC setup message
	 */
	req_setup.service = service;
	strcpy (req_setup.control_file, control_map_path);
	strcpy (req_setup.request_file, request_map_path);
	strcpy (req_setup.response_file, response_map_path);
	strcpy (req_setup.dispatch_file, dispatch_map_path);
	req_setup.control_size = 8192;
	req_setup.request_size = request_size;
	req_setup.response_size = response_size;
	req_setup.dispatch_size = dispatch_size;

#if _POSIX_THREAD_PROCESS_SHARED < 1
	req_setup.semkey = semkey;
#endif

	res = socket_send (request_fd, &req_setup, sizeof (mar_req_setup_t));
	if (res != CS_OK) {
		goto error_exit;
	}
	res = socket_recv (request_fd, &res_setup, sizeof (mar_res_setup_t));
	if (res != CS_OK) {
		goto error_exit;
	}

	ipc_instance->fd = request_fd;

	if (res_setup.error == CS_ERR_TRY_AGAIN) {
		res = res_setup.error;
		goto error_exit;
	}

	ipc_instance->control_size = 8192;
	ipc_instance->request_size = request_size;
	ipc_instance->response_size = response_size;
	ipc_instance->dispatch_size = dispatch_size;

	pthread_mutex_init (&ipc_instance->mutex, NULL);

	hdb_handle_put (&ipc_hdb, *handle);

	return (res_setup.error);

error_exit:
#if _POSIX_THREAD_PROCESS_SHARED < 1
	if (ipc_instance->control_buffer->semid > 0)
		semctl (ipc_instance->control_buffer->semid, 0, IPC_RMID);
#endif
	memory_unmap (ipc_instance->dispatch_buffer, dispatch_size);
error_dispatch_buffer:
	memory_unmap (ipc_instance->response_buffer, response_size);
error_response_buffer:
	memory_unmap (ipc_instance->request_buffer, request_size);
error_request_buffer:
	memory_unmap (ipc_instance->control_buffer, 8192);
error_connect:
	close (request_fd);

	hdb_handle_destroy (&ipc_hdb, *handle);
	hdb_handle_put (&ipc_hdb, *handle);

	return (res);
}
Esempio n. 4
0
cs_error_t quorum_initialize (
	quorum_handle_t *handle,
	quorum_callbacks_t *callbacks,
	uint32_t *quorum_type)
{
	cs_error_t error;
	struct quorum_inst *quorum_inst;
	struct iovec iov;
	struct qb_ipc_request_header req;
	struct res_lib_quorum_gettype res_lib_quorum_gettype;

	error = hdb_error_to_cs(hdb_handle_create (&quorum_handle_t_db, sizeof (struct quorum_inst), handle));
	if (error != CS_OK) {
		goto error_no_destroy;
	}

	error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, *handle, (void *)&quorum_inst));
	if (error != CS_OK) {
		goto error_destroy;
	}

	error = CS_OK;
	quorum_inst->c = qb_ipcc_connect ("quorum", IPC_REQUEST_SIZE);
	if (quorum_inst->c == NULL) {
		error = qb_to_cs_error(-errno);
		goto error_put_destroy;
	}

	req.size = sizeof (req);
	req.id = MESSAGE_REQ_QUORUM_GETTYPE;

	iov.iov_base = (char *)&req;
	iov.iov_len = sizeof (req);

	error = qb_to_cs_error(qb_ipcc_sendv_recv (
		quorum_inst->c,
		&iov,
		1,
		&res_lib_quorum_gettype,
		sizeof (struct res_lib_quorum_gettype), -1));

	if (error != CS_OK) {
		goto error_put_destroy;
	}

	error = res_lib_quorum_gettype.header.error;

	*quorum_type = res_lib_quorum_gettype.quorum_type;

	if (callbacks)
		memcpy(&quorum_inst->callbacks, callbacks, sizeof (*callbacks));
	else
		memset(&quorum_inst->callbacks, 0, sizeof (*callbacks));

	(void)hdb_handle_put (&quorum_handle_t_db, *handle);

	return (CS_OK);

error_put_destroy:
	(void)hdb_handle_put (&quorum_handle_t_db, *handle);
error_destroy:
	(void)hdb_handle_destroy (&quorum_handle_t_db, *handle);
error_no_destroy:
	return (error);
}
Esempio n. 5
0
/*
 * object db reading
 */
static int object_find_create (
	hdb_handle_t object_handle,
	const void *object_name,
	size_t object_len,
	hdb_handle_t *object_find_handle)
{
	int res;
	struct object_instance *iter_obj_inst;
	struct object_instance *object_instance;
	struct object_find_instance *object_find_instance;
	struct list_head *list;
	hdb_handle_t *handles_array, *handles_array_realloc;
	size_t ha_len;
	size_t ha_used;

	res = hdb_handle_get (&object_instance_database,
		object_handle, (void *)&object_instance);
	if (res != 0) {
		goto error_exit;
	}

	res = hdb_handle_create (&object_find_instance_database,
		sizeof (struct object_find_instance), object_find_handle);
	if (res != 0) {
		goto error_put;
	}
	res = hdb_handle_get (&object_find_instance_database,
		*object_find_handle, (void *)&object_find_instance);
	if (res != 0) {
		goto error_destroy;
	}

	object_find_instance->object_name = (char *)object_name;
	object_find_instance->object_len = object_len;

	ha_len = ha_used = 0;
	handles_array = NULL;

	for (list = object_instance->child_head.next;
		list != &object_instance->child_head; list = list->next) {

		iter_obj_inst = list_entry (list, struct object_instance,
			child_list);

		if (object_find_instance->object_len == 0 ||
			((iter_obj_inst->object_name_len ==
			  object_find_instance->object_len) &&

			 (memcmp (iter_obj_inst->object_name,
				  object_find_instance->object_name,
				  object_find_instance->object_len) == 0))) {

			/*
			 * Add handle to list
			 */
			if (ha_used + 1 > ha_len) {
				ha_len = ha_len * 2 + 1;
				if ((handles_array_realloc =
				    realloc (handles_array, ha_len * sizeof (hdb_handle_t))) ==
				    NULL) {
					goto error_ha_free;
				}
				handles_array = handles_array_realloc;
			}

			handles_array[ha_used] =
			    iter_obj_inst->object_handle;

			ha_used++;
		}
	}

	object_find_instance->handles_array_size = ha_used;
	object_find_instance->handles_array_pos = 0;
	object_find_instance->handles_array = handles_array;

	hdb_handle_put (&object_instance_database, object_handle);
	hdb_handle_put (&object_find_instance_database, *object_find_handle);

	return (0);

error_ha_free:
	free(handles_array);

error_destroy:
	hdb_handle_destroy (&object_instance_database, *object_find_handle);

error_put:
	hdb_handle_put (&object_instance_database, object_handle);

error_exit:
	return (-1);
}