int main(int argc, char **argv)
{
	GMainLoop *loop;
	GIOChannel *libtcmu_gio;
	struct tcmulib_context *ctx;

	while (1) {
		int c;
		int option_index = 0;

		c = getopt_long(argc, argv, "dhV",
				long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'd':
			tcmu_set_log_level(TCMU_CONF_LOG_DEBUG);
			break;
		case 'V':
			printf("tcmu-synthesizer %s\n", TCMUR_VERSION);
			exit(1);
		default:
		case 'h':
			usage();
			exit(1);
		}
	}

	if (tcmu_setup_log()) {
		fprintf(stderr, "Could not setup tcmu logger.\n");
		exit(1);
	}

	ctx = tcmulib_initialize(&syn_handler, 1);
	if (!ctx) {
		tcmu_err("tcmulib_initialize failed\n");
		tcmu_destroy_log();
		exit(1);
	}

	tcmulib_register(ctx);
	/* Set up event for libtcmu */
	libtcmu_gio = g_io_channel_unix_new(tcmulib_get_master_fd(ctx));
	g_io_add_watch(libtcmu_gio, G_IO_IN, tcmulib_callback, ctx);
	loop = g_main_loop_new(NULL, FALSE);
	g_main_loop_run(loop);
	g_main_loop_unref(loop);
	tcmu_destroy_log();
	return 0;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
	struct tcmulib_context *tcmulib_ctx;
	struct pollfd pollfds[16];
	int i;
	int ret;

	if (tcmu_setup_log()) {
		fprintf(stderr, "Could not setup tcmu logger.\n");
		exit(1);
	}

	/* If any TCMU devices that exist that match subtype,
	   handler->added() will now be called from within
	   tcmulib_initialize(). */
	tcmulib_ctx = tcmulib_initialize(&foo_handler, 1);
	if (tcmulib_ctx <= 0) {
		tcmu_err("tcmulib_initialize failed with %p\n", tcmulib_ctx);
		exit(1);
	}

	while (1) {
		pollfds[0].fd = tcmulib_get_master_fd(tcmulib_ctx);
		pollfds[0].events = POLLIN;
		pollfds[0].revents = 0;

		for (i = 0; i < dev_array_len; i++) {
			pollfds[i+1].fd = tcmu_get_dev_fd(tcmu_dev_array[i]);
			pollfds[i+1].events = POLLIN;
			pollfds[i+1].revents = 0;
		}

		/* Use ppoll instead poll to avoid poll call reschedules during signal
		 * handling. If we were removing a device, then the uio device's memory
		 * could be freed, but the poll would be rescheduled and end up accessing
		 * the released device. */
		ret = ppoll(pollfds, dev_array_len+1, NULL, NULL);
		if (ret == -1) {
			tcmu_err("ppoll() returned %d, exiting\n", ret);
			exit(EXIT_FAILURE);
		}

		if (pollfds[0].revents) {
			/* If any tcmu devices have been added or removed, the
			   added() and removed() handler callbacks will be called
			   from within this. */
			tcmulib_master_fd_ready(tcmulib_ctx);

			/* Since devices (may) have changed, re-poll() instead of
			   processing per-device fds. */
			continue;
		}

		for (i = 0; i < dev_array_len; i++) {
			if (pollfds[i+1].revents) {
				struct tcmulib_cmd *cmd;
				struct tcmu_device *dev = tcmu_dev_array[i];

				tcmulib_processing_start(dev);

				while ((cmd = tcmulib_get_next_command(dev)) != NULL) {
					ret = foo_handle_cmd(dev,
							     cmd->cdb,
							     cmd->iovec,
							     cmd->iov_cnt,
							     cmd->sense_buf);
					tcmulib_command_complete(dev, cmd, ret);
				}

				tcmulib_processing_complete(dev);
			}
		}
	}

	return 0;
}
Esempio n. 3
0
int main(int argc, char **argv)
{
	struct tcmulib_context *tcmulib_cxt;
	struct pollfd pollfds[16];
	int i;
	int ret;

	/* If any TCMU devices that exist that match subtype,
	   handler->added() will now be called from within
	   tcmulib_initialize(). */
	tcmulib_cxt = tcmulib_initialize(&foo_handler, 1, errp);
	if (tcmulib_cxt <= 0) {
		errp("tcmulib_initialize failed with %p\n", tcmulib_cxt);
		exit(1);
	}

	while (1) {
		pollfds[0].fd = tcmulib_get_master_fd(tcmulib_cxt);
		pollfds[0].events = POLLIN;
		pollfds[0].revents = 0;

		for (i = 0; i < dev_array_len; i++) {
			pollfds[i+1].fd = tcmu_get_dev_fd(tcmu_dev_array[i]);
			pollfds[i+1].events = POLLIN;
			pollfds[i+1].revents = 0;
		}

		ret = poll(pollfds, dev_array_len+1, -1);

		if (ret <= 0) {
			errp("poll() returned %d, exiting\n", ret);
			exit(1);
		}

		if (pollfds[0].revents) {
			/* If any tcmu devices have been added or removed, the
			   added() and removed() handler callbacks will be called
			   from within this. */
			tcmulib_master_fd_ready(tcmulib_cxt);

			/* Since devices (may) have changed, re-poll() instead of
			   processing per-device fds. */
			continue;
		}

		for (i = 0; i < dev_array_len; i++) {
			if (pollfds[i+1].revents) {
				struct tcmulib_cmd *cmd;
				struct tcmu_device *dev = tcmu_dev_array[i];

				while ((cmd = tcmulib_get_next_command(dev)) != NULL) {
					ret = foo_handle_cmd(dev,
							     cmd->cdb,
							     cmd->iovec,
							     cmd->iov_cnt,
							     cmd->sense_buf);
					tcmulib_command_complete(dev, cmd, ret);
				}

				tcmulib_processing_complete(dev);
			}
		}
	}

	return 0;
}