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

📄 daemon.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This source code is a part of coLinux source package. * * Dan Aloni <da-x@colinux.org>, 2003 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. * */ #include <colinux/common/common.h>#include <colinux/common/version.h>#include <colinux/common/libc.h>#include <colinux/os/user/file.h>#include <colinux/os/user/misc.h>#include <colinux/os/user/exec.h>#include <colinux/os/alloc.h>#include <colinux/os/timer.h>#include <colinux/user/macaddress.h>#include <colinux/user/debug.h>#include <memory.h>#include <stdarg.h>#include <stdlib.h>#include "daemon.h"#include "manager.h"#include "monitor.h"#include "config.h"#include "reactor.h"co_rc_t co_load_config_file(co_daemon_t *daemon){	co_rc_t rc;	if (daemon->start_parameters->cmdline_config) {		daemon->config = daemon->start_parameters->config;		return CO_RC(OK);	}	co_terminal_print_color(CO_TERM_COLOR_YELLOW, "XML configuration files are obsolete. Please pass command line\n");	co_terminal_print_color(CO_TERM_COLOR_YELLOW, "options, or use '@' to pass a command-line compatible configuration\n");	co_terminal_print_color(CO_TERM_COLOR_YELLOW, "file (e.g. @config.txt)\n\n");	rc = CO_RC(ERROR);	return rc;}void co_daemon_print_header(void){	static int printed_already = 0;	if (printed_already)		return;	co_terminal_print("Cooperative Linux Daemon, " COLINUX_VERSION "\n");	co_terminal_print("Compiled on " __DATE__ " " __TIME__ "\n");	co_terminal_print("\n");	printed_already = 1;}void co_daemon_syntax(){	co_daemon_print_header();	co_terminal_print("syntax: \n");	co_terminal_print("\n");	co_terminal_print("    colinux-daemon [-d] [-h] [k] [-t name] [-v level] [configuration and boot parameter] @params.txt\n");	co_terminal_print("\n");	co_terminal_print("  -d             Don't launch and attach a coLinux console on startup\n");	co_terminal_print("  -h             Show this help text\n");	co_terminal_print("  -k             Suppress kernel messages\n");	co_terminal_print("  -p pidfile     Write pid to file.\n");	co_terminal_print("  -t name        When spawning a console, this is the type of console\n");	co_terminal_print("                 (e.g, nt, fltk, etc...)\n");	co_terminal_print("  -v level       Verbose messages, level 1 prints booting details, 2 or\n");	co_terminal_print("                 more checks configs, 3 prints errors, default is 0 (off)\n");	co_terminal_print("  @params.txt    Take more command line params from the given text file\n");	co_terminal_print("                 (can be multi-line)\n");	co_terminal_print("\n");	co_terminal_print("Configuration and boot parameters:\n");	co_terminal_print("\n");	co_terminal_print("Params should start with kernel=vmlinux (is the kernel image file\n");	co_terminal_print("the '@' option is not needed. Instead, you pass all configuration\n");	co_terminal_print("via the command line, for example:\n");	co_terminal_print("\n");	co_terminal_print("  colinux-daemon kernel=vmlinux cobd0=root_fs hda1=:cobd0 root=/dev/cobd0 eth0=slirp\n");	co_terminal_print(" \n");	co_terminal_print("\n");	co_terminal_print("Use of new aliases automatically allocates cobd(s), for example:\n");	co_terminal_print("\n");	co_terminal_print("  colinux-daemon mem=32 kernel=vmlinux hda1=root_fs root=/dev/hda1 \\\n");	co_terminal_print("  eth0=pcap-bridge,\"Local Area Connection\"\n");	co_terminal_print("\n");	co_terminal_print("Unhandled parameters are forwarded to the kernel's boot parameters string.\n");	co_terminal_print("See README.txt for more details about command-line usage.\n");	co_terminal_print("See colinux-daemon's documentation for more options.\n");	co_terminal_print("\n");}co_rc_t co_daemon_parse_args(co_command_line_params_t cmdline, co_start_parameters_t *start_parameters){	co_rc_t rc;	bool_t dont_launch_console = PFALSE;	bool_t verbose_specified = PFALSE;	int verbose_level = 0;	co_snprintf(start_parameters->console, sizeof(start_parameters->console), "fltk");	rc = co_cmdline_params_one_arugment_parameter(cmdline, "-c", 						      &start_parameters->config_specified,						      start_parameters->config_path,						      sizeof(start_parameters->config_path));	if (!CO_OK(rc)) 		return rc;	rc = co_cmdline_params_one_arugment_parameter(cmdline, "-p",						      &start_parameters->pidfile_specified,						      start_parameters->pidfile,						      sizeof(start_parameters->pidfile));	if (!CO_OK(rc))		return rc;	rc = co_cmdline_params_one_arugment_parameter(cmdline, "-t", 						      NULL,						      start_parameters->console,						      sizeof(start_parameters->console));	if (!CO_OK(rc)) 		return rc;	rc = co_cmdline_params_argumentless_parameter(cmdline, "-d", &dont_launch_console);	if (!CO_OK(rc)) 		return rc;	rc = co_cmdline_params_argumentless_parameter(cmdline, "-k", &start_parameters->suppress_printk);	if (!CO_OK(rc)) 		return rc;	rc = co_cmdline_params_one_arugment_int_parameter(cmdline, "-v",							  &verbose_specified, &verbose_level);	if (co_global_debug_levels.misc_level < verbose_level)		co_global_debug_levels.misc_level = verbose_level;	rc = co_cmdline_params_argumentless_parameter(cmdline, "-h", &start_parameters->show_help);	if (!CO_OK(rc)) 		return rc;	start_parameters->launch_console = !dont_launch_console;	rc = co_parse_config_args(cmdline, start_parameters);	if (!CO_OK(rc)) {		co_terminal_print("daemon: error parsing configuration parameters and boot params\n");		return rc;	}		return CO_RC(OK);}static void init_srand(void){	co_timestamp_t t;	co_os_get_timestamp(&t);	srand(t.low ^ t.high);}co_rc_t co_daemon_create(co_start_parameters_t *start_parameters, co_daemon_t **co_daemon_out){	co_rc_t rc;	co_daemon_t *daemon;	init_srand();	daemon = co_os_malloc(sizeof(co_daemon_t));	if (daemon == NULL) {		rc = CO_RC(OUT_OF_MEMORY);		goto out;	}	memset(daemon, 0, sizeof(*daemon));	daemon->start_parameters = start_parameters;	memcpy(daemon->config.config_path, start_parameters->config_path, 	       sizeof(start_parameters->config_path));	rc = co_load_config_file(daemon);	if (!CO_OK(rc)) {		co_debug_error("error loading configuration");		goto out_free;	}	*co_daemon_out = daemon;	return rc;out_free:	co_os_free(daemon);out:	return rc;}void co_daemon_destroy(co_daemon_t *daemon){	co_debug("daemon cleanup");	co_os_free(daemon);}/* Remember: Strip tool scans only this file for needed symbols */staticco_rc_t co_daemon_load_symbol_and_data(co_daemon_t *daemon, 				       const char *symbol_name, 				       unsigned long *address_out,				       void *buffer,				       unsigned long buffer_size){	co_rc_t rc = CO_RC_OK;	co_elf_symbol_t *sym;	void *data;	sym = co_get_symbol_by_name(daemon->elf_data, symbol_name);	if (sym) 		*address_out = co_elf_get_symbol_value(sym);	else {		co_debug_error("symbol %s not found", symbol_name);		return CO_RC(ERROR);			}		data = co_elf_get_symbol_data(daemon->elf_data, sym);	if (data == NULL) {		co_debug_error("data of symbol %s not found", symbol_name);		return CO_RC(ERROR);	}		memcpy(buffer, data, buffer_size);	return rc;}/* Remember: Strip tool scans only this file for needed symbols */staticco_rc_t co_daemon_load_symbol(co_daemon_t *daemon, 			      const char *symbol_name, 			      unsigned long *address_out){	co_rc_t rc = CO_RC_OK;	co_elf_symbol_t *sym;	sym = co_get_symbol_by_name(daemon->elf_data, symbol_name);	if (sym) 		*address_out = co_elf_get_symbol_value(sym);	else {		co_debug_error("symbol %s not found", symbol_name);		rc = CO_RC(ERROR);	}	return rc;}void co_daemon_prepare_net_macs(co_daemon_t *daemon){	int i;	for (i=0; i < CO_MODULE_MAX_CONET; i++) { 		co_netdev_desc_t *net_dev;		net_dev = &daemon->config.net_devs[i];		if (net_dev->enabled == PFALSE)			continue;					if (net_dev->manual_mac_address == PFALSE) {			unsigned long rand_mac = rand();			int i;			for (i=0; i < 10; i++)				rand_mac *= rand() + 1234;			net_dev->mac_address[0] = 0;			net_dev->mac_address[1] = 0xFF;			net_dev->mac_address[2] = rand_mac >> 030;			net_dev->mac_address[3] = rand_mac >> 020;			net_dev->mac_address[4] = rand_mac >> 010;			net_dev->mac_address[5] = rand_mac >> 000;		}	}}co_rc_t co_load_initrd(co_daemon_t *daemon){	co_rc_t rc;	char *initrd;	unsigned long initrd_size; 	if (!daemon->config.initrd_enabled)		return CO_RC(OK);	co_debug("reading initrd from (%s)", daemon->config.initrd_path);	rc = co_os_file_load(daemon->config.initrd_path, &initrd, &initrd_size, 0);	if (!CO_OK(rc)) {		co_terminal_print("error loading initrd file\n");		return rc;	}	co_debug("initrd size: %ld bytes", initrd_size);	rc = co_user_monitor_load_initrd(daemon->monitor, initrd, initrd_size);	co_os_free(initrd);	return rc;}static void memory_usage_limit_resached(co_manager_ioctl_create_t *create_params){	co_manager_ioctl_info_t info = {0, };	co_manager_handle_t handle;	co_rc_t rc;	co_terminal_print("colinux: memory size configuration for this VM: %ld MB\n",			  create_params->actual_memsize_used / 0x100000);	co_terminal_print("colinux: memory usage limit reached\n");	co_terminal_print("colinux: try to decrease memory size configuration\n");	handle = co_os_manager_open();	if (!handle) {		co_terminal_print("colinux: error opening manager\n");		return;	}	rc = co_manager_info(handle, &info);	if (!CO_OK(rc)) {		co_terminal_print("colinux: erroneous manager info\n");		co_os_manager_close(handle);		return;	}	co_os_manager_close(handle);	co_terminal_print("colinux: memory usage limit: %ld MB\n",			  info.hostmem_usage_limit / 0x100000);	co_terminal_print("colinux: current memory used by running VMs: %ld MB\n",			  info.hostmem_used / 0x100000);}co_rc_t co_daemon_monitor_create(co_daemon_t *daemon){	co_manager_ioctl_create_t create_params = {0, };	co_symbols_import_t *import;	co_rc_t rc;	import = &create_params.import;		rc = co_daemon_load_symbol(daemon, "_kernel_start", &import->kernel_start);	if (!CO_OK(rc)) 		goto out;	rc = co_daemon_load_symbol(daemon, "_end", &import->kernel_end);	if (!CO_OK(rc)) 		goto out;	rc = co_daemon_load_symbol(daemon, "init_thread_union", &import->kernel_init_task_union);	if (!CO_OK(rc)) {		goto out;	}	rc = co_daemon_load_symbol(daemon, "co_start", &import->kernel_colinux_start);	if (!CO_OK(rc)) 		goto out;	rc = co_daemon_load_symbol(daemon, "swapper_pg_dir", &import->kernel_swapper_pg_dir);	if (!CO_OK(rc)) 		goto out;	rc = co_daemon_load_symbol(daemon, "idt_table", &import->kernel_idt_table);	if (!CO_OK(rc)) 		goto out;	if (co_get_symbol_by_name(daemon->elf_data, "per_cpu__gdt_page"))		// >= 2.6.22		rc = co_daemon_load_symbol(daemon, "per_cpu__gdt_page", &import->kernel_gdt_table);	else		// <= 2.6.17		rc = co_daemon_load_symbol(daemon, "cpu_gdt_table", &import->kernel_gdt_table);	if (!CO_OK(rc))		goto out;	rc = co_daemon_load_symbol_and_data(daemon, "co_info", &import->kernel_co_info,					    &create_params.info, sizeof(create_params.info));	if (!CO_OK(rc)) {		goto out;	}	rc = co_daemon_load_symbol_and_data(daemon, "co_arch_info", &import->kernel_co_arch_info,					    &create_params.arch_info, sizeof(create_params.arch_info));	if (!CO_OK(rc)) {		goto out;	}	if (create_params.info.api_version != CO_LINUX_API_VERSION) {		co_terminal_print("colinux: error, expected kernel API version %d, got %ld\n",				  CO_LINUX_API_VERSION, create_params.info.api_version);		rc = CO_RC(VERSION_MISMATCHED);		goto out;	}	if (create_params.info.compiler_abi != __GXX_ABI_VERSION) {		co_terminal_print("colinux: error, expected gcc abi version %d, got %ld\n",				  __GXX_ABI_VERSION, create_params.info.compiler_abi);		co_terminal_print("colinux: Daemons gcc version %d.%d.x, "				  "incompatible to kernel gcc version %ld.%ld.x\n",				  __GNUC__, __GNUC_MINOR__,				  create_params.info.compiler_major,				  create_params.info.compiler_minor);		rc = CO_RC(COMPILER_MISMATCHED);		goto out;	}	co_daemon_prepare_net_macs(daemon);	create_params.config = daemon->config;	rc = co_user_monitor_create(&daemon->monitor, &create_params);	if (!CO_OK(rc)) {		if (CO_RC_GET_CODE(rc) == CO_RC_HOSTMEM_USE_LIMIT_REACHED) { 			memory_usage_limit_resached(&create_params);		}		goto out;	}	daemon->shared = (co_monitor_user_kernel_shared_t *)create_params.shared_user_address;	if (!daemon->shared)		return CO_RC(ERROR); 	daemon->shared->userspace_msgwait_count = 0;	daemon->id = create_params.id;	rc = co_load_initrd(daemon);

⌨️ 快捷键说明

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