示例#1
0
文件: boot.c 项目: johnhihi/petitboot
static int kexec_reboot(struct boot_task *task)
{
	int result;

	/* First try running shutdown.  Init scripts should run 'exec -e' */
	result = process_run_simple(task, pb_system_apps.shutdown, "-r",
			"now", NULL);

	/* On error, force a kexec with the -e option */
	if (result) {
		result = process_run_simple(task, pb_system_apps.kexec,
						"-e", NULL);
	}

	if (result)
		pb_log("%s: failed: (%d)\n", __func__, result);

	/* okay, kexec -e -f */
	if (result) {
		result = process_run_simple(task, pb_system_apps.kexec,
						"-e", "-f", NULL);
	}

	if (result)
		pb_log("%s: failed: (%d)\n", __func__, result);


	return result;
}
示例#2
0
static void *pcore_thread_recv_send(void *arg)
{
	pb_core_t *core = NULL;

	prctl(PR_SET_NAME, "pbyte_rs_switcher", 0, 0, 0);

	if (!arg)
		goto err;

	core = (pb_core_t *)arg;

	pcore_thread_init (core);

	pb_log (core, PBYTE_INFO, "Recv/Send switcher thread: Inited");

	while (core->active)
	{
		pcore_check_send (core);
		pcore_check_recv (core);
	}

	pb_log (core, PBYTE_INFO, "Recv/Send switcher thread: Normal exit");

	return NULL;

err:
	pb_log (core, PBYTE_ERR, "Recv/Send switcher thread: Force exit");

	return NULL;
}
示例#3
0
int platform_init(void *ctx)
{
	extern struct platform *__start_platforms,  *__stop_platforms;
	struct platform **p;

	platform_ctx = talloc_new(ctx);

	for (p = &__start_platforms; p < &__stop_platforms; p++) {
		pb_debug("%s: Try platform %s\n", __func__, (*p)->name);
		if (!(*p)->probe(*p, platform_ctx))
			continue;
		platform = *p;
		break;
	}

	config = talloc(platform_ctx, struct config);
	config_set_defaults(config);

	if (platform) {
		pb_log("Detected platform type: %s\n", platform->name);
		if (platform->load_config)
			platform->load_config(platform, config);
	} else {
		pb_log("No platform type detected, some platform-specific "
				"functionality will be disabled\n");
	}

	dump_config(config);

	return 0;
}
示例#4
0
文件: boot.c 项目: johnhihi/petitboot
static void run_boot_hooks(struct boot_task *task)
{
	struct dirent **hooks;
	int i, n;

	n = scandir(boot_hook_dir, &hooks, hook_filter, hook_cmp);
	if (n < 1)
		return;

	update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO,
			_("running boot hooks"));

	boot_hook_setenv(task);

	for (i = 0; i < n; i++) {
		const char *argv[2] = { NULL, NULL };
		struct process *process;
		char *path;
		int rc;

		path = join_paths(task, boot_hook_dir, hooks[i]->d_name);

		if (access(path, X_OK)) {
			talloc_free(path);
			continue;
		}

		process = process_create(task);

		argv[0] = path;
		process->path = path;
		process->argv = argv;
		process->keep_stdout = true;

		pb_log("running boot hook %s\n", hooks[i]->d_name);

		rc = process_run_sync(process);
		if (rc) {
			pb_log("boot hook exec failed!\n");

		} else if (WIFEXITED(process->exit_status) &&
			   WEXITSTATUS(process->exit_status)
				== BOOT_HOOK_EXIT_UPDATE) {
			/* if the hook returned with BOOT_HOOK_EXIT_UPDATE,
			 * then we process stdout to look for updated params
			 */
			boot_hook_update(task, hooks[i]->d_name,
					process->stdout_buf);
			boot_hook_setenv(task);
		}

		process_release(process);
		talloc_free(path);
	}

	free(hooks);
}
示例#5
0
static void *pcore_thread_worker(void *arg)
{
	pb_core_t *core = NULL;
	pb_msg_t *pb_msg = NULL;

	prctl(PR_SET_NAME, "pbyte_worker", 0, 0, 0);

	if (!arg)
		return NULL;

	core = (pb_core_t *)arg;

	pcore_thread_init (core);

	pb_log (core, PBYTE_INFO, "Worker thread: Inited");

	while (core->active)
	{
		pb_msg = (pb_msg_t *)mqueue_timedget_msec(&core->queue_in, MSG_TIMEOUT);
		if (pb_msg != NULL)
		{

#ifdef QUEUE_DEBUG
		int qelems = mqueue_get_count(&core->queue_in);

		pb_log (core, (qelems > 1)? PBYTE_INFO:PBYTE_CUT,
		        "GET message from INPUT queue. "
		        "Message in INPUT queue: %d",
		        qelems);
#endif

			pb_msg_print(&core->logger, PBYTE_INFO,
			            "input", pb_msg);

#ifdef TIME_DEBUG
			pb_print_msg_time(&core->logger, "Input queue -> RServer", pb_msg);
#endif

			if (core->message_handler)
				core->message_handler(core->application, pb_msg);

			pb_msg_unpack_free (&pb_msg);
		}
	}

	pb_log (core, PBYTE_INFO, "Worker thread: Normal exit");

	return NULL;
}
示例#6
0
文件: ipmi.c 项目: johnhihi/petitboot
static int ipmi_recv(struct ipmi *ipmi, uint8_t *netfn, uint8_t *cmd,
		long *seq, uint8_t *buf, uint16_t *len)
{
	struct ipmi_recv recv;
	struct ipmi_addr addr;
	int rc;

	recv.addr = (unsigned char *)&addr;
	recv.addr_len = sizeof(addr);
	recv.msg.data = buf;
	recv.msg.data_len = *len;

	rc = ioctl(ipmi->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
	if (rc < 0 && errno != EMSGSIZE) {
		pb_log("IPMI: recv (%d bytes) failed: %m\n", *len);
		return -1;
	} else if (rc < 0 && errno == EMSGSIZE) {
		pb_debug("IPMI: truncated message (netfn %d, cmd %d, "
				"size %d), continuing anyway\n",
				recv.msg.netfn, recv.msg.cmd, *len);
	}

	*netfn = recv.msg.netfn;
	*cmd = recv.msg.cmd;
	*seq = recv.msgid;
	*len = recv.msg.data_len;

	return 0;
}
示例#7
0
文件: ipmi.c 项目: johnhihi/petitboot
static int ipmi_send(struct ipmi *ipmi, uint8_t netfn, uint8_t cmd,
		uint8_t *buf, uint16_t len)
{
	struct ipmi_system_interface_addr addr;
	struct ipmi_req req;
	int rc;

	memset(&addr, 0, sizeof(addr));
	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;

	memset(&req, 0, sizeof(req));
	req.addr = (unsigned char *)&addr;
	req.addr_len = sizeof(addr);

	req.msgid = ipmi->seq++;

	req.msg.data = buf;
	req.msg.data_len = len;
	req.msg.netfn = netfn;
	req.msg.cmd = cmd;

	rc = ioctl(ipmi->fd, IPMICTL_SEND_COMMAND, &req);
	if (rc < 0) {
		pb_log("IPMI: send (netfn %d, cmd %d, %d bytes) failed: %m\n",
				netfn, cmd, len);
		return -1;
	}

	return 0;
}
示例#8
0
文件: boot.c 项目: johnhihi/petitboot
static void boot_hook_update(struct boot_task *task, const char *hookname,
		char *buf)
{
	char *line, *name, *val, *sep;
	char *saveptr = NULL;

	for (;; buf = NULL) {

		line = strtok_r(buf, "\n", &saveptr);
		if (!line)
			break;

		sep = strchr(line, '=');
		if (!sep)
			continue;

		*sep = '\0';
		name = line;
		val = sep + 1;

		boot_hook_update_param(task, task, name, val);

		pb_log("boot hook %s specified %s=%s\n",
				hookname, name, val);
	}
}
示例#9
0
void ui_timer_init(struct waitset *waitset, struct ui_timer *timer,
		unsigned int seconds)
{
	pb_log("%s: %u\n", __func__, seconds);
	timer->timeout = seconds;
	timer->waitset = waitset;
}
示例#10
0
struct pjs *pjs_init(void *ctx, int (*map)(const struct js_event *))
{
	static const char dev_name[] = "/dev/input/js0";
	struct pjs *pjs;

	pjs = talloc_zero(ctx, struct pjs);

	if (!pjs)
		return NULL;

	pjs->map = map;
	pjs->fd = open(dev_name, O_RDONLY | O_NONBLOCK);

	if (pjs->fd < 0) {
		pb_log("%s: open %s failed: %s\n", __func__, dev_name,
			strerror(errno));
		goto out_err;
	}

	talloc_set_destructor(pjs, pjs_destructor);

	pb_debug("%s: using %s\n", __func__, dev_name);

	return pjs;

out_err:
	close(pjs->fd);
	pjs->fd = 0;
	talloc_free(pjs);
	return NULL;
}
示例#11
0
static int pcore_recv_identity (pb_core_t *core, pb_identity_t *identity)
{
	zmq_msg_t msg;
	int rc, more;

	zmq_msg_init (&msg);

	rc = zmq_recvmsg (core->sock, &msg, 0);
	if (rc < 0)
	{
		pb_log (core, PBYTE_WARN,
		        "Recieve identity failed: %s",
		        zmq_strerror(zmq_errno()));
		zmq_msg_close(&msg);
		return -1;
	}

	more = zmq_msg_more (&msg);
	if (more != 1)
	{
		pb_log (core, PBYTE_WARN,
		        "No more data after identity");
		zmq_msg_close(&msg);
		return -2;
	}

	if (zmq_msg_size (&msg) >= PBYTE_IDENTITY_LEN)
	{
		pb_log (core, PBYTE_WARN,
		        "Recieve message failed. "
		        "Large identity");
		zmq_msg_close(&msg);
		return -3;
	}

	// pb_print_buff (&core->logger, PBYTE_INFO,
	//                "incomming identity",
	//                zmq_msg_data(msg),
	//                zmq_msg_size(msg));

	memcpy (identity->identity, zmq_msg_data (&msg), zmq_msg_size (&msg));
	identity->identity_len = zmq_msg_size (&msg);

	zmq_msg_close(&msg);

	return 0;
}
示例#12
0
文件: log.c 项目: sammj/petitboot
void _pb_log_fn(const char *func, const char *fmt, ...)
{
	va_list ap;
	pb_log("%s: ", func);
	va_start(ap, fmt);
	__log(fmt, ap);
	va_end(ap);
}
示例#13
0
文件: timer.c 项目: sammj/petitboot
void ui_timer_disable(struct ui_timer *timer)
{
	if (!timer->waiter)
		return;

	pb_log("%s\n", __func__);
	waiter_remove(timer->waiter);
	timer->waiter = NULL;
}
示例#14
0
int pcore_stop(void *core_ptr)
{
	int rc = 0, i;
	pb_core_t *core = NULL;

	if (!core_ptr)
		return 0;

	core = (pb_core_t *)core_ptr;

	pb_log (core, PBYTE_WARN, "Stop detected");

	if (!core->active)
		return 0;

	core->active = 0;

	rc = pthread_join (core->thread_recv_send, NULL);

	for (i = 0; i < core->worker_count; i++)
	{
		rc |= pthread_join (core->thread_worker[i], NULL);
	}

	if (rc == 0)
	{
		sleep (1);
		zmq_unbind (core->sock, core->URL);
		zmq_close (core->sock);
		zmq_ctx_destroy (core->ctx);

		mqueue_close (&core->queue_in);
		mqueue_close (&core->queue_out);

		pcore_init (core);
	}

	pb_log (core, PBYTE_INFO, "Stop success [%d]", rc);

	free (core);

	return rc;
}
示例#15
0
文件: log.c 项目: sammj/petitboot
void _pb_debug_fn(const char *func, const char *fmt, ...)
{
	va_list ap;
	if (!debug)
		return;
	pb_log("%s: ", func);
	va_start(ap, fmt);
	__log(fmt, ap);
	va_end(ap);
}
示例#16
0
文件: log.c 项目: sammj/petitboot
void _pb_debug_fl(const char *func, int line, const char *fmt, ...)
{
	va_list ap;
	if (!debug)
		return;
	pb_log("%s:%d: ", func, line);
	va_start(ap, fmt);
	__log(fmt, ap);
	va_end(ap);
}
示例#17
0
static int cdrom_open(const char *devpath, const char *loc)
{
	int fd;

	fd = open(devpath, O_RDONLY | O_NONBLOCK);
	if (fd < 0)
		pb_log("%s: can't open %s: %s\n", loc, devpath,
				strerror(errno));

	return fd;
}
示例#18
0
void cdrom_eject(const char *devpath)
{
	int fd, rc;

	fd = cdrom_open(devpath, __func__);
	if (fd < 0)
		return;

	/* unlock cdrom device */
	rc = ioctl(fd, CDROM_LOCKDOOR, 0);
	if (rc < 0)
		pb_log("%s: CDROM_LOCKDOOR(unlock) failed: %s\n",
				__func__, strerror(errno));

	rc = ioctl(fd, CDROMEJECT, 0);
	if (rc < 0)
		pb_log("%s: CDROM_EJECT failed: %s\n",
				__func__, strerror(errno));
	close(fd);
}
示例#19
0
int config_set(struct config *newconfig)
{
	int rc;

	if (!platform || !platform->save_config)
		return -1;

	if (newconfig == config)
		return 0;

	pb_log("new configuration data received\n");
	dump_config(newconfig);

	rc = platform->save_config(platform, newconfig);

	if (!rc)
		config = talloc_steal(platform_ctx, newconfig);
	else
		pb_log("error saving new configuration; changes lost\n");

	return rc;
}
示例#20
0
int pcore_msg_send (void *core_ptr, pb_msg_t *pb_msg)
{
	int rc;
	pb_core_t *core = NULL;

	if (!core_ptr || !pb_msg)
		goto err;

	core = (pb_core_t *)core_ptr;

	rc = mqueue_put (&core->queue_out, (void *)pb_msg, 0);
	if (rc < 0)
	{
		pb_log (core, PBYTE_ERR,
		        "Send failed. "
		        "Failed to put message in queue [%d]", rc);
		goto err;
	}

#ifdef QUEUE_DEBUG
		int qelems = mqueue_get_count(&core->queue_in);

		pb_log (core, (qelems > 1)? PBYTE_INFO:PBYTE_CUT,
		        "PUT message to OUTPUT queue. "
		        "Message in OUTPUT queue: %d",
		        qelems);
#endif

	return 0;

err:
	pcore_proc_error (core, pb_msg);

	if (pb_msg)
		pb_msg_unpack_free (&pb_msg);

	return -1;
}
示例#21
0
int pjs_process_event(const struct pjs *pjs)
{
	int result;
	struct js_event e;

	assert(pjs->fd);

	result = read(pjs->fd, &e, sizeof(e));

	if (result != sizeof(e)) {
		pb_log("%s: read failed: %s\n", __func__, strerror(errno));
		return 0;
	}

	return pjs->map(&e);
}
示例#22
0
文件: boot.c 项目: johnhihi/petitboot
/**
 * kexec_load - kexec load helper.
 */
static int kexec_load(struct boot_task *boot_task)
{
	int result;
	const char *argv[7];
	const char **p;
	char *s_initrd = NULL;
	char *s_dtb = NULL;
	char *s_args = NULL;

	p = argv;
	*p++ = pb_system_apps.kexec;	/* 1 */
	*p++ = "-l";			/* 2 */

	if (boot_task->local_initrd) {
		s_initrd = talloc_asprintf(boot_task, "--initrd=%s",
				boot_task->local_initrd);
		assert(s_initrd);
		*p++ = s_initrd;	 /* 3 */
	}

	if (boot_task->local_dtb) {
		s_dtb = talloc_asprintf(boot_task, "--dtb=%s",
						boot_task->local_dtb);
		assert(s_dtb);
		*p++ = s_dtb;		 /* 4 */
	}

	if (boot_task->args) {
		s_args = talloc_asprintf(boot_task, "--append=%s",
						boot_task->args);
		assert(s_args);
		*p++ = s_args;		/* 5 */
	}

	*p++ = boot_task->local_image;	/* 6 */
	*p++ = NULL;			/* 7 */

	result = process_run_simple_argv(boot_task, argv);

	if (result)
		pb_log("%s: failed: (%d)\n", __func__, result);

	return result;
}
示例#23
0
文件: ipmi.c 项目: johnhihi/petitboot
struct ipmi *ipmi_open(void *ctx)
{
	struct ipmi *ipmi;
	int fd;

	fd = open(ipmi_devnode, O_RDWR);
	if (fd < 0) {
		pb_log("IPMI: can't open IPMI device %s: %m\n", ipmi_devnode);
		return NULL;
	}

	ipmi = talloc(ctx, struct ipmi);
	ipmi->fd = fd;
	ipmi->seq = 0;

	talloc_set_destructor(ipmi, ipmi_destroy);

	return ipmi;
}
示例#24
0
int cui_run_cmd(struct pmenu_item *item)
{
	int result;
	struct cui *cui = cui_from_item(item);
	const char **cmd_argv = item->data;

	nc_scr_status_printf(cui->current, _("Running %s..."), cmd_argv[0]);

	def_prog_mode();

	result = process_run_simple_argv(item, cmd_argv);

	reset_prog_mode();
	redrawwin(cui->current->main_ncw);

	if (result) {
		pb_log("%s: failed: '%s'\n", __func__, cmd_argv[0]);
		nc_scr_status_printf(cui->current, _("Failed: %s"),
				cmd_argv[0]);
	}

	return result;
}
示例#25
0
static int pcore_check_send (pb_core_t *core)
{
	int rc = -1, size = 0, budget;
	char *data = NULL, *output_data = NULL;
	pb_msg_t *pb_msg = NULL;
	char identity_str[256] = {0};

	if (!core)
		return -1;

	budget = BUDGET;

	while (--budget > 0)
	{
		data = mqueue_timedget_msec (&core->queue_out, MSG_TIMEOUT);
		if (!data)
			break;

#ifdef QUEUE_DEBUG
		int qelems = mqueue_get_count(&core->queue_out);

		pb_log (core, (qelems > 1)? PBYTE_INFO:PBYTE_CUT,
		        "GET message from OUTPUT queue. "
		        "Message in OUTPUT queue: %d",
		        qelems);
#endif

		pb_msg = (pb_msg_t *)data;

		pb_pb_identity_to_str (&pb_msg->identity, 1, identity_str, sizeof (identity_str));

		pb_log (core, PBYTE_INFO,
		        "%s: Send '%s'",
		        identity_str,
		        pb_pb_msg_type_to_str (pb_msg->message_params.msg_type));

		pb_msg_print (&core->logger, PBYTE_INFO, "output", pb_msg);

		rc = pb_msg_pack (pb_msg, &output_data, &size);
		if (rc < 0 || size <= 0 || !output_data)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to pack message. "
			        "Skip message");
			goto skip_message;
		}

		// pb_print_buff (&core->logger, PBYTE_INFO,
		//                "output message",
		//                output_data, size);

		if (core->mode == ePBYTE_SERVER)
		{
#ifdef TIME_DEBUG
			pb_print_msg_time(&core->logger, "Output queue -> send", pb_msg);
#endif
			/* send identity first for ZMQ-routing */
			rc = zmq_send (core->sock, pb_msg->identity.identity,
			               pb_msg->identity.identity_len, ZMQ_SNDMORE);
			if (rc != pb_msg->identity.identity_len)
			{
				pb_log (core, PBYTE_WARN,
				        "Send identity failed: %s",
				        zmq_strerror(zmq_errno()));
				goto skip_message;
			}
		}

		rc = zmq_send (core->sock, output_data, size, 0);
		if (rc != size)
		{
			pb_log (core, PBYTE_WARN,
			        "Send message failed: %s",
			        zmq_strerror(zmq_errno()));
			goto skip_message;
		}

		pb_log (core, PBYTE_INFO,
		        "%s: '%s': Message was sent",
		        identity_str,
		        pb_pb_msg_type_to_str(pb_msg->message_params.msg_type));

		pb_msg_pack_free (&output_data);
		pb_msg_unpack_free (&pb_msg);
	}

	return 0;

skip_message:
	pcore_proc_error (core, pb_msg);

	if (output_data)
		pb_msg_pack_free (&output_data);

	if (pb_msg)
		pb_msg_unpack_free (&pb_msg);

	return rc;
}
示例#26
0
static int pcore_check_recv (pb_core_t *core)
{
	int rc, count, budget;
	zmq_msg_t msg;
	pb_msg_t *pb_msg = NULL;
	pb_identity_t identity = {0};

	budget = BUDGET;

	while (--budget > 0)
	{
		count = zmq_poll (&core->pollitem, 1, MSG_TIMEOUT);
		if (!count)
			break;

		zmq_msg_init (&msg);

		if (count < 0) {
			pb_log (core, PBYTE_WARN, "Poll: %s", zmq_strerror(zmq_errno()));
			goto skip_message;
		}

		if (core->mode == ePBYTE_SERVER)
		{
			/* identity comes first */
			if (pcore_recv_identity (core, &identity) != 0)
				goto skip_message;
		}

		/* then the first part of the message body */
		rc = zmq_recvmsg (core->sock, &msg, 0);
		if (rc <= 0)
		{
			pb_log (core, PBYTE_WARN,
			        "Recieve message failed: %s",
			        zmq_strerror(zmq_errno()));
			goto skip_message;
		}

		// pb_print_buff (&core->logger, PBYTE_INFO,
		//                "incomming message",
		//                zmq_msg_data(msg),
		//                zmq_msg_size(msg));

		rc = pb_msg_unpack (&pb_msg, (char *)zmq_msg_data(&msg), zmq_msg_size(&msg));
		if (rc != 0)
		{
			pb_log (core, PBYTE_WARN,
			        "Recieve message failed. "
			        "Failed to unpack message");
			goto skip_message;
		}

		pb_msg_set_identity (pb_msg, &identity);

#ifdef TIME_DEBUG
		pb_clockgettime(&pb_msg->start);
#endif

		rc = mqueue_put(&core->queue_in, (void *)pb_msg, 0);
		if (rc < 0)
		{
			pb_log (core, PBYTE_WARN,
			        "Recieve message failed. "
			        "Failed to put message in queue");
			goto skip_message;
		}

#ifdef QUEUE_DEBUG
		int qelems = mqueue_get_count(&core->queue_in);

		pb_log (core, (qelems > 1)? PBYTE_INFO:PBYTE_CUT,
		        "PUT message to INPUT queue. "
		        "Messages in INPUT queue: %d",
		        qelems);
#endif

		pb_msg = NULL;
		zmq_msg_close(&msg);
	}

	return 0;

skip_message:
	if (pb_msg)
		pb_msg_unpack_free (&pb_msg);

	zmq_msg_close(&msg);

	return -1;
}
示例#27
0
int pcore_start (void **core_ptr,
                 pcore_params_t *pcore_params,
                 void *application)
{
	int rc = 0, i;
	pb_core_t *core = NULL;

	if (!pcore_params || !application)
	{
		rc = -1;
		goto err;
	}

	*core_ptr = (pb_core_t *)calloc(1, sizeof (pb_core_t));
	if (!*core_ptr)
	{
		rc = -1;
		goto err;
	}

	core = *core_ptr;

	pcore_init(core);

	if (pcore_params->mode != ePBYTE_SERVER &&
	    pcore_params->mode != ePBYTE_CLIENT)
	{
		rc = -2;
		goto err;
	}

	core->mode = pcore_params->mode;
	core->application = application;

	if (pcore_params->message_handler)
		core->message_handler = pcore_params->message_handler;

	if (pcore_params->error_handler)
		core->error_handler = pcore_params->error_handler;

	if (pcore_params->logger)
	{
		sprintf (core->logger.prefix, "PCORE_%s:",
		         (pcore_params->mode == ePBYTE_SERVER)? "S":"C");

		pb_log_set_logger (&core->logger, pcore_params->logger);
		pb_log_set_prio (&core->logger, pcore_params->logger_prio);
	}

	if (pcore_params->thread_init)
	{
		core->thread_init = pcore_params->thread_init;
	} else {
		pb_log (core, PBYTE_ERR,
		        "Failed to start. "
		        "Thread init callback not set");

		rc = -2;
		goto err;
	}

	if (!pcore_params->addr ||
	    (pcore_params->port <= 0 || 65535 <= pcore_params->port) ||
	    (pcore_params->io_threads <= 0))
	{
		pb_log (core, PBYTE_ERR,
		        "Failed to start. "
		        "Invalid params");

		rc = -3;
		goto err;
	}

	if (pcore_params->worker_count <= 0 ||
	    pcore_params->worker_count >= MAX_WORKER_COUNT)
	{
		core->worker_count = DEF_WORKER_COUNT;
	} else {
		core->worker_count = pcore_params->worker_count;
	}

	sprintf(core->URL, "tcp://%s:%d", pcore_params->addr, pcore_params->port);

	core->ctx = zmq_init (pcore_params->io_threads);
	if (!core->ctx)
	{
		pb_log (core, PBYTE_ERR,
		        "Failed to start. "
		        "Can't init context: %s",
		        zmq_strerror(zmq_errno()));

		rc = -4;
		goto err;
	}

	if (pcore_params->mode == ePBYTE_SERVER)
	{
		core->sock = zmq_socket (core->ctx, ZMQ_ROUTER);
		if (!core->sock)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to start. "
			        "Can't init socket: %s",
			        zmq_strerror(zmq_errno()));

			rc = -5;
			goto err;
		}

		pb_log (core, PBYTE_INFO, "Try bind in '%s'", core->URL);

		rc = zmq_bind (core->sock, core->URL);
		if (rc != 0)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to start. "
			        "Bind failed: %s",
			        zmq_strerror(zmq_errno()));

			rc = -6;
			goto err;
		}
	} else {
		core->sock = zmq_socket (core->ctx, ZMQ_DEALER);
		if (!core->sock)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to start. "
			        "Can't init socket: %s",
			        zmq_strerror(zmq_errno()));

			rc = -5;
			goto err;
		}

		rc = zmq_setsockopt (core->sock,
		                     ZMQ_IDENTITY,
		                     pcore_params->identity.identity,
		                     strlen(pcore_params->identity.identity));
		if (rc != 0)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to set identity: %s",
			        zmq_strerror(zmq_errno()));

			rc = -6;
			goto err;
		}

		pb_log (core, PBYTE_INFO,
		        "Try connect to '%s'",
		        core->URL);

		rc = zmq_connect (core->sock, core->URL);
		if (rc != 0)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to start. "
			        "Connect failed: %s",
			        zmq_strerror(zmq_errno()));

			rc = -6;
			goto err;
		}
	}

	mqueue_init (&core->queue_in, MQUEUESIZE);
	mqueue_init (&core->queue_out, MQUEUESIZE);

	core->pollitem.socket  = core->sock;
	core->pollitem.fd      = 0;
	core->pollitem.events  = ZMQ_POLLIN;
	core->pollitem.revents = 0;

	core->active = 1;

	rc = pthread_create(&core->thread_recv_send,
	                    NULL,
	                    &pcore_thread_recv_send,
	                    (void *)core);
	if(rc < 0)
	{
		pb_log (core, PBYTE_ERR,
		        "Failed to start. "
		        "Can't create recv/send switcher thread: %s",
		        strerror(errno));

		rc = -7;
		goto err;
	}

	for (i = 0; i < core->worker_count; i++)
	{
		rc = pthread_create (&core->thread_worker[i],
		                     NULL,
		                     &pcore_thread_worker,
		                     (void *)core);
		if(rc < 0)
		{
			pb_log (core, PBYTE_ERR,
			        "Failed to start. "
			        "Can't create primary worker%d thread: %s",
			        i, strerror(errno));

			rc = -8 - i;
			goto err;
		}
	}

	pb_log (core, PBYTE_INFO,
	        "Start success. Worker count: %d",
	        core->worker_count);

	return 0;

err:
	switch(rc)
	{
		case -7:
			if (core && core->sock)
				zmq_unbind (core->sock, core->URL);
		case -6:
			if (core && core->sock)
				zmq_close (core->sock);
		case -5:
			if (core && core->ctx)
				zmq_ctx_destroy (core->ctx);
		case -4:
		case -3:
		case -2:
			free (core);
		case -1: break;

		default:
			pcore_stop (core);
			break;
	}

	return rc;

}
示例#28
0
文件: ipmi.c 项目: johnhihi/petitboot
/* Reads and applies an IPMI interface config override, which closely follows
 * the format of an interface config struct as described in lib/types */
void parse_ipmi_interface_override(struct config *config, uint8_t *buf,
				uint16_t len)
{
	struct interface_config *ifconf;
	char *ipstr, *gatewaystr;
	uint8_t hwsize, ipsize;
	int addr_type, i = 0;
	socklen_t addr_len;

	/* Get 1-byte hardware address size and ip address size */
	memcpy(&hwsize, &buf[i], sizeof(hwsize));
	i += sizeof(hwsize);
	memcpy(&ipsize, &buf[i], sizeof(ipsize));
	i += sizeof(ipsize);

	if (!hwsize || !ipsize) {
		pb_log("%s: Empty response\n", __func__);
		return;
	}

	/* At the moment only support 6-byte MAC addresses */
	if (hwsize != sizeof(ifconf->hwaddr)) {
		pb_log("Unsupported HW address size in network override: %u\n",
		       hwsize);
		return;
	}

	/* Sanity check the IP address size */
	if (ipsize == 4) {
		addr_type = AF_INET;
		addr_len = INET_ADDRSTRLEN;
	} else if (ipsize == 16) {
		addr_type = AF_INET6;
		addr_len = INET6_ADDRSTRLEN;
	} else {
		pb_log("Unsupported IP address size: %u\n", ipsize);
		return;
	}

	/* Everything past here is the interface config */
	ifconf = talloc_zero(config, struct interface_config);
	if (!ifconf) {
		pb_log("Failed to allocate network override\n");
		return;
	}

	/* Hardware Address */
	memcpy(ifconf->hwaddr, &buf[i], hwsize);
	i += hwsize;

	/* Check 1-byte ignore and method flags */
	ifconf->ignore = !!buf[i++];
	ifconf->method = !!buf[i++];

	if (ifconf->method == CONFIG_METHOD_STATIC) {
		if (ipsize + ipsize  + 1 > len - i) {
			pb_log("Expected data greater than buffer size\n");
			talloc_free(ifconf);
			return;
		}

		/* IP address */
		ipstr = talloc_array(ifconf, char, addr_len);
		if (!inet_ntop(addr_type, &buf[i], ipstr, addr_len)) {
			pb_log("Failed to convert ipaddr: %m\n");
			talloc_free(ifconf);
			return;
		}
		i += ipsize;

		/* IP address subnet */
		ifconf->static_config.address = talloc_asprintf(ifconf,
						"%s/%u", ipstr, buf[i]);
		i++;

		/* Gateway address */
		gatewaystr = talloc_array(ifconf, char, addr_len);
		if (!inet_ntop(addr_type, &buf[i], gatewaystr, addr_len)) {
			pb_log("Failed to convert gateway: %m\n");
			talloc_free(ifconf);
			return;
		}
		ifconf->static_config.gateway = gatewaystr;
		i += ipsize;
	}

	pb_log("Applying IPMI network config\n");

	/* Replace any existing interface config */
	talloc_free(config->network.interfaces);
	config->network.n_interfaces = 1;
	config->network.interfaces = talloc(config, struct interface_config *);
	config->network.interfaces[0] = ifconf;
}
示例#29
0
void cui_abort(struct cui *cui)
{
	pb_log("%s: exiting\n", __func__);
	cui->abort = 1;
}
示例#30
0
文件: boot.c 项目: johnhihi/petitboot
struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
		struct boot_command *cmd, int dry_run,
		boot_status_fn status_fn, void *status_arg)
{
	struct pb_url *image = NULL, *initrd = NULL, *dtb = NULL;
	struct boot_task *boot_task;
	const char *boot_desc;
	int rc;

	if (opt && opt->option->name)
		boot_desc = opt->option->name;
	else if (cmd && cmd->boot_image_file)
		boot_desc = cmd->boot_image_file;
	else
		boot_desc = _("(unknown)");

	update_status(status_fn, status_arg, BOOT_STATUS_INFO,
			_("Booting %s."), boot_desc);

	if (cmd && cmd->boot_image_file) {
		image = pb_url_parse(opt, cmd->boot_image_file);
	} else if (opt && opt->boot_image) {
		image = opt->boot_image->url;
	} else {
		pb_log("%s: no image specified\n", __func__);
		update_status(status_fn, status_arg, BOOT_STATUS_INFO,
				_("Boot failed: no image specified"));
		return NULL;
	}

	if (cmd && cmd->initrd_file) {
		initrd = pb_url_parse(opt, cmd->initrd_file);
	} else if (opt && opt->initrd) {
		initrd = opt->initrd->url;
	}

	if (cmd && cmd->dtb_file) {
		dtb = pb_url_parse(opt, cmd->dtb_file);
	} else if (opt && opt->dtb) {
		dtb = opt->dtb->url;
	}

	boot_task = talloc_zero(ctx, struct boot_task);
	boot_task->dry_run = dry_run;
	boot_task->status_fn = status_fn;
	boot_task->status_arg = status_arg;

	if (cmd && cmd->boot_args) {
		boot_task->args = talloc_strdup(boot_task, cmd->boot_args);
	} else if (opt && opt->option->boot_args) {
		boot_task->args = talloc_strdup(boot_task,
						opt->option->boot_args);
	} else {
		boot_task->args = NULL;
	}

	/* start async loads for boot resources */
	rc = start_url_load(boot_task, "kernel image", image, &boot_task->image)
	  || start_url_load(boot_task, "initrd", initrd, &boot_task->initrd)
	  || start_url_load(boot_task, "dtb", dtb, &boot_task->dtb);

	/* If all URLs are local, we may be done. */
	if (rc) {
		talloc_free(boot_task);
		return NULL;
	}

	boot_process(NULL, boot_task);

	return boot_task;
}