?? daemon.c
字號:
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, ¶ms); 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, ¶ms); 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 + -