From: Jack Lange <jarusl@cs.northwestern.edu>
Date: Wed, 8 Jul 2009 22:24:45 +0000 (-0500)
Subject: added disk support to the nbd server
X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=2fc55bdc014038e625b3628fdaf0b60d7ebede77;p=palacios.git

added disk support to the nbd server
---

diff --git a/misc/network_servers/v3_nbd/iso.cc b/misc/network_servers/v3_nbd/iso.cc
index 31faa85..b3542a6 100644
--- a/misc/network_servers/v3_nbd/iso.cc
+++ b/misc/network_servers/v3_nbd/iso.cc
@@ -51,7 +51,7 @@ unsigned int iso_image::read(unsigned char * buf, off_t offset, int length) {
     fseeko(this->f, offset, SEEK_SET);
 
     while (bytes_read < total_bytes) {
-	int tmp_bytes = fread(buf, 1, length, this->f);
+	int tmp_bytes = fread(buf, 1, length - bytes_read, this->f);
 	
 	if (tmp_bytes == 0) {
 	    break;
@@ -65,7 +65,6 @@ unsigned int iso_image::read(unsigned char * buf, off_t offset, int length) {
 
 
 unsigned int iso_image::write(unsigned char * buf, off_t offset, int length) {
-    
     return 0;
 }
 
diff --git a/misc/network_servers/v3_nbd/nbd.ini b/misc/network_servers/v3_nbd/nbd.ini
index 0eec74c..fe84ef9 100644
--- a/misc/network_servers/v3_nbd/nbd.ini
+++ b/misc/network_servers/v3_nbd/nbd.ini
@@ -2,7 +2,16 @@ logfile: ./nbd.log
 
 port : 9502
 
-disks : puppy-hd puppy-iso
+disks : puppy-hdd puppy-iso ubuntu-hdd ubuntu-cd
 
 puppy-iso.file : /opt/vmm-tools/isos/puppy.iso
 puppy-iso.type : ISO
+
+puppy-hdd.file : /home/jarusl/guests/puppy-test1.hdd
+puppy-hdd.type : RAW
+
+ubuntu-hdd.file : /home/jarusl/guests/ubuntu.hdd
+ubuntu-hdd.type : RAW
+
+ubuntu-cd.file : /opt/vmm-tools/isos/ubuntu-7.10-desktop-i386.iso
+ubuntu-cd.type : ISO
diff --git a/misc/network_servers/v3_nbd/raw.cc b/misc/network_servers/v3_nbd/raw.cc
index 668850f..04228ae 100644
--- a/misc/network_servers/v3_nbd/raw.cc
+++ b/misc/network_servers/v3_nbd/raw.cc
@@ -27,22 +27,49 @@ raw_disk::raw_disk(string & filename) : v3_disk(filename){
 
 
 off_t raw_disk::get_capacity() {
-    
-    return 0;
-}
+        struct stat f_stats;
+
+    stat(this->filename.c_str(), &f_stats);
 
+    return f_stats.st_size;
+}
 
 
 unsigned int raw_disk::read(unsigned char * buf, off_t offset, int length) {
-
-    return 0;
+    int total_bytes = length;
+    int bytes_read = 0;
+    
+    fseeko(this->f, offset, SEEK_SET);
+
+    while (bytes_read < total_bytes) {
+	int tmp_bytes = fread(buf, 1, length - bytes_read, this->f);
+	
+	if (tmp_bytes == 0) {
+	    break;
+	}
+	bytes_read += tmp_bytes;
+    }
+
+    return bytes_read;
 }
 
 
-
 unsigned int raw_disk::write(unsigned char * buf, off_t offset, int length) {
-    
-    return 0;
+    int total_bytes = length;
+    int bytes_written = 0;
+
+    fseeko(this->f, offset, SEEK_SET);
+
+    while (bytes_written < total_bytes) {
+	int tmp_bytes = fwrite(buf, 1, length - bytes_written, this->f);
+
+	if (tmp_bytes == 0) {
+	    break;
+	}
+	bytes_written += tmp_bytes;
+    }
+
+    return bytes_written;
 }
 
 
diff --git a/misc/network_servers/v3_nbd/v3_nbd.cc b/misc/network_servers/v3_nbd/v3_nbd.cc
index c74c4c1..b3eb805 100644
--- a/misc/network_servers/v3_nbd/v3_nbd.cc
+++ b/misc/network_servers/v3_nbd/v3_nbd.cc
@@ -486,7 +486,56 @@ int handle_read_request(SOCK conn, v3_disk * disk) {
 // send : 
 //    1 bytes : status
 int handle_write_request(SOCK conn, v3_disk * disk) {
-    return -1;
+    off_t offset = 0;
+    unsigned int length = 0;
+    unsigned char * buf = NULL;
+    unsigned int ret_len = 0;
+    unsigned char status = NBD_STATUS_OK;
+
+    vtl_debug("Write Request\n");
+    
+    if (Receive(conn, (char *)&offset, 8, true) <= 0) {
+	vtl_debug("Error receiving write offset\n");
+	return -1;
+    }
+
+    vtl_debug("Write Offset %d\n", offset);
+
+    if (Receive(conn, (char *)&length, 4, true) <= 0) {
+	vtl_debug("Error receiving write length\n");
+	return -1;
+    }
+
+    vtl_debug("Write length: %d\n", length);
+
+    buf = new unsigned char[length];
+    
+    vtl_debug("Receiving Data\n");
+
+    if (Receive(conn, (char *)buf, length, true)  <= 0) {
+	vtl_debug("Error receiving Write Data\n");
+	return -1;
+    }
+
+    vtl_debug("Wrote %d bytes to source disk\n", ret_len);
+
+    if (disk->write(buf, offset, length) != length) {
+	vtl_debug("Write Error\n");
+	status = NBD_STATUS_ERR;
+    }
+
+    vtl_debug("Sending Status byte (%d)\n", status);
+
+    if (Send(conn, (char *)&status, 1, true) <= 0) {
+	vtl_debug("Error Sending Wrte Status\n");
+	return -1;
+    }
+
+    vtl_debug("Write Complete\n");
+
+    delete buf;
+
+    return 0;
 }