2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
28 #include <sys/types.h>
30 #elif defined(WIN32) && !defined(__CYGWIN__)
37 #define DEFAULT_LOG_FILE "./status.log"
38 #define DEFAULT_CONF_FILE "v3_nbd.ini"
41 #define DEFAULT_PORT 9500
42 #define MAX_STRING_SIZE 1024
45 #define LOGFILE_TAG "logfile"
46 #define IP_ADDR_TAG "address"
47 #define PORT_TAG "port"
48 #define DISKS_TAG "disks"
52 //using namespace __gnu_cxx;
55 typedef enum {ISO, RAW} disk_type_t;
63 // eqstr from vtl (config.h)
64 typedef map<const string, struct disk_info, eqstr> disk_list_t;
67 unsigned long server_addr;
75 static const int enable_debug = 1;
76 static struct nbd_config g_nbd_conf;
79 int config_nbd(string conf_file_name);
80 int serv_loop(int serv_sock);
81 void setup_disk(string disk_tag);
84 int __main (int argc, char ** argv);
88 int main(int argc, char ** argv) {
89 return __main(argc, argv);
100 int __main (int argc, char ** argv) {
109 config_file = string(argv[1]);
111 config_file = DEFAULT_CONF_FILE;
115 if (config_nbd(config_file) == -1) {
116 cerr << "Configuration Error" << endl;
120 // setup network sockets
122 vtl_debug("Starting Server Loop\n");
123 serv_loop(serv_sock);
130 int serv_loop(int serv_sock) {
131 fd_set all_set, read_set;
133 RawEthernetPacket pkt;
136 FD_SET(serv_sock, &all_set);
143 nready = select(max_fd + 1, &read_set, NULL, NULL, NULL);
147 if (errno == EINTR) {
150 perror("Select returned error: ");
156 if (FD_ISSET(serv_sock, &read_set)) {
167 int serv_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
169 RawEthernetPacket pkt;
170 WSANETWORKEVENTS net_events;
174 events[VNET_EVENT] = WSACreateEvent();
176 WSAEventSelect(vnet_sock, events[VNET_EVENT], FD_READ | FD_CLOSE);
177 events[IF_EVENT] = if_get_event(iface);
180 event_i = WSAWaitForMultipleEvents(2, events, false, WSA_INFINITE, false);
181 cout << "Wait returned" << endl;
183 if (event_i == WAIT_FAILED) {
184 cout << "ERROR: " << GetLastError() << endl;
187 event_i -= WAIT_OBJECT_0;
189 if (event_i == VNET_EVENT) {
191 if (WSAEnumNetworkEvents(vnet_sock, events[event_i], &net_events) == SOCKET_ERROR) {
192 cout << "EnumEventsError: " << WSAGetLastError() << endl;
195 if (net_events.lNetworkEvents & FD_READ) {
197 JRLDBG("Receied VNET Packet\n");
200 if (vnet_info->link_type == TCP_LINK) {
201 pkt.Unserialize(vnet_sock);
202 } else if (vnet_info->link_type == UDP_LINK) {
203 pkt.UdpUnserialize(vnet_sock);
206 process_outbound_pkt(&pkt);
208 if_write_pkt(iface, &pkt);
210 } else if (net_events.lNetworkEvents & FD_CLOSE) {
224 int config_nbd(string conf_file_name) {
227 if (read_config(conf_file_name, &config_map) != 0) {
228 cerr << "Could not read config file..." << endl;
232 if (config_map.count(IP_ADDR_TAG) > 0) {
233 g_nbd_conf.server_addr = ToIPAddress(config_map[IP_ADDR_TAG].c_str());
236 if (config_map.count(PORT_TAG) > 0) {
237 g_nbd_conf.server_port = atoi(config_map[PORT_TAG].c_str());
239 g_nbd_conf.server_port = DEFAULT_PORT;
242 if (config_map.count(DISKS_TAG) > 0) {
243 istringstream disk_stream(config_map[DISKS_TAG], istringstream::in);
247 while (disk_stream >> disk_tag) {
249 if (i >= MAX_DISKS) {
250 cerr << "You specified too many disks, truncating..." << endl;
254 setup_disk(disk_tag);
259 g_nbd_conf.num_disks = i;
261 cerr << "Must specify a set of disks" << endl;
266 if (config_map.count(LOGFILE_TAG) == 0) {
267 config_map[LOGFILE_TAG] = DEFAULT_LOG_FILE;
271 vtl_debug_init(config_map[LOGFILE_TAG], enable_debug);
277 void setup_disk(string disk_tag) {
278 printf("Setting up %s\n", disk_tag.c_str());
284 cout << "Usage: v3_nbd [config_file]" << endl;