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

📄 daemon.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 2 页
字号:
out:	return rc;}void co_daemon_monitor_destroy(co_daemon_t *daemon){	co_user_monitor_close(daemon->monitor);	daemon->monitor = NULL;}co_rc_t co_daemon_start_monitor(co_daemon_t *daemon){	co_rc_t rc;	unsigned long size;	co_manager_ioctl_status_t status;	rc = co_os_file_load(daemon->config.vmlinux_path, &daemon->buf, &size, 0);	if (!CO_OK(rc)) {		co_terminal_print("error loading vmlinux file\n");		goto out;	}	rc = co_elf_image_read(&daemon->elf_data, daemon->buf, size);	if (!CO_OK(rc)) {		co_terminal_print("error reading image (%ld bytes)\n", size);		goto out_free_vmlinux; 	}	co_debug("creating monitor");	rc = co_daemon_monitor_create(daemon);	if (!CO_OK(rc)) {		co_debug_error("error initializing");		goto out_free_vmlinux;	}	// Don't start, if API_VERSION mismatch	rc = co_manager_status(daemon->monitor->handle, &status);	if (!CO_OK(rc))		goto out_destroy;	rc = co_elf_image_load(daemon);	if (!CO_OK(rc)) {		co_terminal_print("error loading image\n");		goto out_destroy;	}	return rc;out_destroy:	co_daemon_monitor_destroy(daemon);out_free_vmlinux:	co_os_file_free(daemon->buf);out:	return rc;}void co_daemon_send_shutdown(co_daemon_t *daemon){	struct {		co_message_t message;		co_linux_message_t linux_msg;		co_linux_message_power_t data;	} message;	daemon->next_reboot_will_shutdown = PTRUE;	co_terminal_print_color(CO_TERM_COLOR_YELLOW, "colinux: Linux VM goes shutdown, please wait!\n");	message.message.from = CO_MODULE_DAEMON;	message.message.to = CO_MODULE_LINUX;	message.message.priority = CO_PRIORITY_IMPORTANT;	message.message.type = CO_MESSAGE_TYPE_OTHER;	message.message.size = sizeof(message.linux_msg) + sizeof(message.data);	message.linux_msg.device = CO_DEVICE_POWER;	message.linux_msg.unit = 0;	message.linux_msg.size = sizeof(message.data);	message.data.type = CO_LINUX_MESSAGE_POWER_SHUTDOWN;	co_user_monitor_message_send(daemon->message_monitor, &message.message);}co_rc_t co_daemon_handle_printk(co_daemon_t *daemon, co_message_t *message){	if (message->type == CO_MESSAGE_TYPE_STRING) {		char *string_start = (char *)message->data;               		if (string_start[0] == '<'  &&  		    string_start[1] >= '0'  &&  string_start[1] <= '9'  &&		    string_start[2] == '>')		{			string_start += 3;		}		if (!daemon->start_parameters->suppress_printk) {			co_terminal_print_color(CO_TERM_COLOR_WHITE, 						"%s", string_start);		}		if (co_strstr(string_start, "VFS: Unable to mount root fs on")) {			co_terminal_print_color(CO_TERM_COLOR_YELLOW, 						"colinux: kernel panic suggests that either you forget to supply a\n");			co_terminal_print_color(CO_TERM_COLOR_YELLOW, 						"root= kernel boot paramter or the file / device mapped to the root\n");			co_terminal_print_color(CO_TERM_COLOR_YELLOW, 						"file system is not found or inaccessible.\n");			co_terminal_print_color(CO_TERM_COLOR_YELLOW, 						"Please Check your coLinux configuration and use option \"-v 3\".\n");		}	}	return CO_RC(OK);}static co_rc_t message_receive(co_reactor_user_t user, unsigned char *buffer, unsigned long size){	co_message_t *message;	unsigned long message_size;	long size_left = size;	long position = 0;	co_daemon_t *daemon = (typeof(daemon))(user->private_data);	while (size_left > 0) {		message = (typeof(message))(&buffer[position]);		message_size = message->size + sizeof(*message);		size_left -= message_size;		if (size_left >= 0) {			switch(message->to) {			case CO_MODULE_PRINTK:				co_daemon_handle_printk(daemon, message);			default:				break;			}		}		position += message_size;	}	return CO_RC(OK);}co_rc_t co_daemon_launch_net_daemons(co_daemon_t *daemon){	int i;	co_rc_t rc;	for (i=0; i < CO_MODULE_MAX_CONET; i++) { 		co_netdev_desc_t *net_dev;		char interface_name[CO_NETDEV_DESC_STR_SIZE + 0x10] = {0, };		net_dev = &daemon->config.net_devs[i];		if (net_dev->enabled == PFALSE)			continue;		co_debug("launching daemon for conet%d", i);		if (*net_dev->desc != 0)			co_snprintf(interface_name, sizeof(interface_name), "-n \"%s\"", net_dev->desc);		switch (net_dev->type) 		{		case CO_NETDEV_TYPE_BRIDGED_PCAP: {			char mac_address[18];			co_build_mac_address(mac_address, sizeof(mac_address), net_dev->mac_address);			rc = co_launch_process(NULL, "colinux-bridged-net-daemon -i %d -u %d %s -mac %s -p %d",					daemon->id, i, interface_name, mac_address, net_dev->promisc_mode);			break;		}		case CO_NETDEV_TYPE_TAP: {			rc = co_launch_process(NULL, "colinux-net-daemon -i %d -u %d %s", daemon->id, i, interface_name);			break;		}		case CO_NETDEV_TYPE_SLIRP: {			rc = co_launch_process(NULL, "colinux-slirp-net-daemon -i %d -u %d%s%s",				daemon->id, i, (*net_dev->redir)?" -r ":"", net_dev->redir);			break;		}		default:			rc = CO_RC(ERROR);			break;		}		if (!CO_OK(rc))			co_terminal_print("WARNING: error launching network daemon!\n");	}	return CO_RC(OK);}static co_rc_t co_daemon_launch_serial_daemons(co_daemon_t *daemon){	int i;	co_rc_t rc;	co_serialdev_desc_t *serial;	for (i = 0, serial = daemon->config.serial_devs; i < CO_MODULE_MAX_SERIAL; i++, serial++) {		char mode_param[CO_SERIAL_MODE_STR_SIZE + 10] = {0, };		if (serial->enabled == PFALSE)			continue;		co_debug("launching daemon for ttys%d", i);		if (serial->mode)			co_snprintf(mode_param, sizeof(mode_param), " -m \"%s\"", serial->mode);		rc = co_launch_process(NULL, "colinux-serial-daemon -i %d -u %d -f %s%s",			    daemon->id, i,			    serial->desc,	/* -f COM1 */			    mode_param);	/* -m 9600,n,8,2 */		if (!CO_OK(rc))			co_terminal_print("WARNING: error launching serial daemon!\n");	}	return CO_RC(OK);}static co_rc_t co_daemon_launch_executes(co_daemon_t *daemon){	int i;	co_rc_t rc;	co_execute_desc_t *execute;	for (i = 0, execute = daemon->config.executes; i < CO_MODULE_MAX_EXECUTE; i++, execute++) {		if (execute->enabled == PFALSE)			continue;		co_debug("launching exec%d", i);		rc = co_launch_process(&execute->pid,				(execute->args) ? "%s %s" : "%s",				execute->prog, execute->args);		if (!CO_OK(rc))			co_terminal_print("WARNING: error launching exec%d '%s'!\n", i, execute->prog);	}	return CO_RC(OK);}static co_rc_t co_daemon_kill_executes(co_daemon_t *daemon){	int i;	co_rc_t rc;	co_execute_desc_t *execute;	for (i = 0, execute = daemon->config.executes; i < CO_MODULE_MAX_EXECUTE; i++, execute++) {		if (execute->enabled == PFALSE || execute->pid == 0)			continue;		co_debug("killing exec%d", i);		rc = co_kill_process(execute->pid);		if (!CO_OK(rc))			co_terminal_print("WARNING: error killing '%s'!\n", execute->prog);		execute->pid = 0;	}	return CO_RC(OK);}static co_rc_t co_daemon_restart(co_daemon_t *daemon){	co_rc_t rc = co_user_monitor_reset(daemon->monitor);	if (!CO_OK(rc)) {		co_terminal_print("colinux: reset unsuccessful\n");		return rc;	}	rc = co_elf_image_load(daemon);	if (!CO_OK(rc)) {		co_terminal_print("colinux: error reloading vmlinux\n");		return rc;	}	rc = co_load_initrd(daemon);	if (!CO_OK(rc)) {		co_terminal_print("colinux: error reloading initrd\n");		return rc;	}	return rc;}co_rc_t co_daemon_run(co_daemon_t *daemon){	co_rc_t rc;	co_reactor_t reactor;	co_module_t modules[] = {CO_MODULE_PRINTK, };	bool_t restarting = PFALSE;	co_start_parameters_t *start_parameters = daemon->start_parameters;	rc = co_reactor_create(&reactor);	if (!CO_OK(rc))		return rc;	co_terminal_print("PID: %d\n", (int)daemon->id);	rc = co_user_monitor_open(reactor, message_receive,				  daemon->id, modules, sizeof(modules)/sizeof(co_module_t),				  &daemon->message_monitor);	if (!CO_OK(rc))		goto out;	daemon->message_monitor->reactor_user->private_data = (void *)daemon;	if (start_parameters->pidfile_specified) {		char buf[32];		int size;		size = co_snprintf(buf, sizeof(buf), "%d\n", (int)daemon->id);		rc = co_os_file_write(start_parameters->pidfile, buf, size);		if (!CO_OK(rc)) {			co_terminal_print("colinux: error creating PID file '%s'\n", start_parameters->pidfile);			return rc;		}	}	if (start_parameters->launch_console) {		co_debug_info("colinux: launching console");		rc = co_launch_process(NULL, "colinux-console-%s -a %d", start_parameters->console, daemon->id);		if (!CO_OK(rc)) {			co_terminal_print("error launching console\n");			goto out;		}	}	rc = co_daemon_launch_net_daemons(daemon);	if (!CO_OK(rc)) {		co_terminal_print("error launching network daemons\n");		goto out;	}	rc = co_daemon_launch_serial_daemons(daemon);	if (!CO_OK(rc))		goto out;	rc = co_daemon_launch_executes(daemon);	if (!CO_OK(rc))		goto out;	co_terminal_print("colinux: booting\n");	daemon->next_reboot_will_shutdown = PFALSE;	do {		restarting = PFALSE;		rc = co_user_monitor_start(daemon->monitor);		if (!CO_OK(rc))			goto out;				daemon->running = PTRUE;		while (daemon->running) {			co_monitor_ioctl_run_t params;			rc = co_user_monitor_run(daemon->monitor, &params);			if (!CO_OK(rc))				break;			co_reactor_select(reactor, 0);		}		if (CO_RC_GET_CODE(rc) == CO_RC_INSTANCE_TERMINATED) {			co_monitor_ioctl_get_state_t params;			co_termination_reason_t reason;			co_terminal_print("colinux: Linux VM terminated\n");			rc = co_user_monitor_get_state(daemon->monitor, &params);			if (!CO_OK(rc)) {				co_terminal_print("colinux: unable to get reason for termination (bug?), aborting\n");				break;			}			reason = params.termination_reason;			switch (reason) {			case CO_TERMINATE_REBOOT:				if (daemon->next_reboot_will_shutdown) {					co_terminal_print("colinux: shutting down after reboot.\n");					break;				}				co_terminal_print("colinux: rebooted.\n");				rc = co_daemon_restart(daemon);				if (CO_OK(rc))					restarting = PTRUE;				break;			case CO_TERMINATE_POWEROFF:				co_terminal_print("colinux: powered off, exiting.\n");				break;			case CO_TERMINATE_HALT:				co_terminal_print("colinux: halted, exiting.\n");				break;			case CO_TERMINATE_BUG:				co_terminal_print("colinux: BUG at %s:%ld\n", params.bug_info.file, params.bug_info.line);				break;			default:				co_terminal_print("colinux: terminated with code %d - abnormal exit, aborting\n", reason);				break;			}		}	} while (restarting);	co_daemon_kill_executes(daemon);	co_user_monitor_close(daemon->message_monitor);out:	if (start_parameters->pidfile_specified) {		co_rc_t rc1;		rc1 = co_os_file_unlink(start_parameters->pidfile);		if (!CO_OK(rc1))			co_debug("error removing PID file '%s'", start_parameters->pidfile);	}	co_reactor_destroy(reactor);	return rc;}void co_daemon_end_monitor(co_daemon_t *daemon){	co_debug("shutting down");	co_daemon_monitor_destroy(daemon);	co_os_file_free(daemon->buf);}

⌨️ 快捷键说明

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