- storage: add some code

svn path=/trunk/boinc/; revision=25400
This commit is contained in:
David Anderson 2012-03-11 01:51:07 +00:00
parent 8f8caec6e7
commit 67d6ab7cf2
7 changed files with 197 additions and 28 deletions

View File

@ -2526,3 +2526,11 @@ Rom 9 Mar 2012
samples/vboxwrapper/ samples/vboxwrapper/
vbox.cpp vbox.cpp
vboxwrapper.cpp vboxwrapper.cpp
David 10 Mar 2012
- storage: add some code
vda/
vda_lib.cpp,h
ssim.cpp
vdad.cpp

View File

@ -450,6 +450,18 @@ void CHUNK::download_complete() {
sfp->recover(); sfp->recover();
} }
int META_CHUNK::encode() {
return 0;
}
int META_CHUNK::decode() {
return 0;
}
int DATA_UNIT::delete_file() {
return 0;
}
const char* status_str(int status) { const char* status_str(int status) {
switch (status) { switch (status) {
case PRESENT: return "present"; case PRESENT: return "present";

View File

@ -2,7 +2,7 @@
the processing of a dfile by the vdad the processing of a dfile by the vdad
DATA_UNIT DATA_UNIT
int status (PRESENT, RECOVERABLE, UNRECOVERABLE) int status (PRESENT, RECOVERABLE, UNRECOVERABLE)
bool keep_present bool keep_present
unit is currently PRESENT unit is currently PRESENT
keep enough descendant chunks on server so that keep enough descendant chunks on server so that
@ -12,10 +12,10 @@ DATA_UNIT
start enough uploads to make it PRESENT start enough uploads to make it PRESENT
META_CHUNK META_CHUNK
bool need_reconstruct bool need_reconstruct
decode this unit during this pass. decode this unit during this pass.
This is set only if some child is UNREC This is set only if some child is UNREC
bool needed_by_parent bool needed_by_parent
this unit is needed to reconstruct parent. this unit is needed to reconstruct parent.
(don't delete it after reconstructing) (don't delete it after reconstructing)

View File

@ -151,6 +151,7 @@ dir/
data_m040.vda data_m040.vda
0/ 0/
data.vda (symlink to ../Coding/data_k001.vda) data.vda (symlink to ../Coding/data_k001.vda)
these are retained even when the file is deleted
if this is a meta-chunk: if this is a meta-chunk:
Coding/ Coding/

View File

@ -15,6 +15,8 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>. // along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// Code that's shared by the simulator and vdad
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -51,12 +53,14 @@ META_CHUNK::META_CHUNK(
j j
)); ));
} }
bottom_level = false;
} else { } else {
for (int j=0; j<coding.m; j++) { for (int j=0; j<coding.m; j++) {
children.push_back( children.push_back(
new CHUNK(this, size/coding.n, j) new CHUNK(this, size/coding.n, j)
); );
} }
bottom_level = true;
} }
} }
@ -318,15 +322,16 @@ int CHUNK::recovery_action(double now) {
return 0; return 0;
} }
#if 0
void META_CHUNK::decide_reconstruct() { void META_CHUNK::decide_reconstruct() {
unsigned int i;
if (some_child_is_unrecoverable()) { if (some_child_is_unrecoverable()) {
if (status == PRESENT) { if (status == PRESENT) {
need_reconstruct = true; need_reconstruct = true;
} else if (status == RECOVERABLE) { } else if (status == RECOVERABLE) {
need_present = true; need_present = true;
for (i=0; i<children.size(); i++) { for (i=0; i<children.size(); i++) {
DATA_UNIT* c = children[i]; DATA_UNIT& c = *(children[i]);
if (c.in_recovery_set) { if (c.in_recovery_set) {
if (c.status == PRESENT) { if (c.status == PRESENT) {
c.keep_present = true; c.keep_present = true;
@ -340,10 +345,10 @@ void META_CHUNK::decide_reconstruct() {
if (needed_by_parent) { if (needed_by_parent) {
need_reconstruct = true; need_reconstruct = true;
} }
if (need_reconstruct and !bottom_level()) { if (need_reconstruct and !bottom_level) {
int n = 0; int n = 0;
for (i=0; i<children.size(); i++) { for (i=0; i<children.size(); i++) {
DATA_UNIT* c = children[i]; META_CHUNK& c = *(META_CHUNK*)children[i];
if (c.status == PRESENT) { if (c.status == PRESENT) {
c.needed_by_parent = true; c.needed_by_parent = true;
n++; n++;
@ -356,7 +361,7 @@ void META_CHUNK::decide_reconstruct() {
if (keep_present) { if (keep_present) {
int n = 0; int n = 0;
for (i=0; i<children.size(); i++) { for (i=0; i<children.size(); i++) {
DATA_UNIT* c = children[i]; DATA_UNIT& c = *(children[i]);
if (c.status == PRESENT) { if (c.status == PRESENT) {
c.keep_present = true; c.keep_present = true;
n++; n++;
@ -366,12 +371,103 @@ void META_CHUNK::decide_reconstruct() {
} }
} }
} }
if (!bottom_level()) { if (!bottom_level) {
for (i=0; i<children.size(); i++) { for (i=0; i<children.size(); i++) {
META_CHUNK* c = (META_CHUNK*)children[i]; META_CHUNK& c = *(META_CHUNK*)children[i];
c.decide_reconstruct(); c.decide_reconstruct();
} }
} }
} }
#endif int META_CHUNK::reconstruct_and_cleanup() {
unsigned int i;
int retval;
if (!bottom_level) {
for (i=0; i<children.size(); i++) {
META_CHUNK& c = *(META_CHUNK*)children[i];
retval = c.reconstruct_and_cleanup();
if (retval) return retval;
}
}
if (need_reconstruct) {
retval = decode();
if (retval) return retval;
retval = expand();
if (retval) return retval;
if (!needed_by_parent) {
delete_file();
}
}
if (bottom_level) {
int npresent = coding.m;
for (i=0; i<children.size(); i++) {
CHUNK& c = *(CHUNK*)children[i];
if (c.status != UNRECOVERABLE && !c.keep_present) {
if (!keep_present || npresent > coding.n) {
c.delete_file();
npresent--;
c.new_present_on_server = false;
}
}
}
}
return 0;
}
int META_CHUNK::expand() {
unsigned int i;
int retval;
if (bottom_level) {
bool do_encode = false;
for (i=0; i<children.size(); i++) {
CHUNK& c = *(CHUNK*)children[i];
if (c.status != PRESENT && c.need_more_replicas()) {
do_encode = true;
break;
}
}
if (do_encode) {
retval = encode();
if (retval) return retval;
}
for (i=0; i<children.size(); i++) {
CHUNK& c = *(CHUNK*)children[i];
if (c.need_more_replicas() || c.download_in_progress()) {
c.new_present_on_server = true;
} else {
c.new_present_on_server = false;
c.delete_file();
}
}
} else {
bool do_encode = false;
for (i=0; i<children.size(); i++) {
META_CHUNK& c = *(META_CHUNK*)children[i];
if (c.status == UNRECOVERABLE) {
do_encode = true;
break;
}
}
if (do_encode) {
retval = encode();
if (retval) return retval;
for (i=0; i<children.size(); i++) {
META_CHUNK& c = *(META_CHUNK*)children[i];
if (c.status != UNRECOVERABLE) {
c.delete_file();
}
}
for (i=0; i<children.size(); i++) {
META_CHUNK& c = *(META_CHUNK*)children[i];
if (c.status == UNRECOVERABLE) {
retval = c.expand();
if (retval) return retval;
c.delete_file();
}
}
}
}
return 0;
}

View File

@ -86,6 +86,11 @@ struct DATA_UNIT {
int min_failures; int min_failures;
// min # of host failures that would make this unrecoverable // min # of host failures that would make this unrecoverable
char name[64]; char name[64];
char dir[1024];
bool keep_present;
bool need_present;
int delete_file();
}; };
struct META_CHUNK : DATA_UNIT { struct META_CHUNK : DATA_UNIT {
@ -96,6 +101,10 @@ struct META_CHUNK : DATA_UNIT {
VDA_FILE_AUX* dfile; VDA_FILE_AUX* dfile;
bool uploading; bool uploading;
CODING coding; CODING coding;
bool bottom_level;
bool need_reconstruct;
bool needed_by_parent;
double child_size;
// used by ssim // used by ssim
META_CHUNK( META_CHUNK(
@ -110,6 +119,19 @@ struct META_CHUNK : DATA_UNIT {
virtual int recovery_plan(); virtual int recovery_plan();
virtual int recovery_action(double); virtual int recovery_action(double);
void decide_reconstruct();
int reconstruct_and_cleanup();
int expand();
bool some_child_is_unrecoverable() {
for (unsigned int i=0; i<children.size(); i++) {
DATA_UNIT& d = *(children[i]);
if (d.status == UNRECOVERABLE) return true;
}
return false;
}
int decode();
int encode();
}; };
struct CHUNK : DATA_UNIT { struct CHUNK : DATA_UNIT {
@ -117,6 +139,7 @@ struct CHUNK : DATA_UNIT {
META_CHUNK* parent; META_CHUNK* parent;
double size; double size;
bool present_on_server; bool present_on_server;
bool new_present_on_server;
CHUNK(META_CHUNK* mc, double s, int index); CHUNK(META_CHUNK* mc, double s, int index);
@ -128,4 +151,7 @@ struct CHUNK : DATA_UNIT {
int assign(); int assign();
virtual int recovery_plan(); virtual int recovery_plan();
virtual int recovery_action(double); virtual int recovery_action(double);
bool need_more_replicas() {
return ((int)hosts.size() < parent->dfile->policy.replication);
}
}; };

View File

@ -80,25 +80,25 @@ void encoder_filename(
// //
// The size of these chunks is returned in "size" // The size of these chunks is returned in "size"
// //
int encode(const char* dir, CODING& c, double& size) { int META_CHUNK::encode() {
char cmd[1024]; char cmd[1024];
sprintf(cmd, sprintf(cmd,
"cd %s; /mydisks/b/users/boincadm/vda_test/encoder %s %d %d cauchy_good 32 1024 500000", "cd %s; /mydisks/b/users/boincadm/vda_test/encoder %s %d %d cauchy_good 32 1024 500000",
dir, DATA_FILENAME, c.n, c.k dir, DATA_FILENAME, coding.n, coding.k
); );
printf("%s\n", cmd); printf("%s\n", cmd);
int s = system(cmd); int s = system(cmd);
if (WIFEXITED(s)) { if (WIFEXITED(s)) {
int status = WEXITSTATUS(s); int st = WEXITSTATUS(s);
if (status != 32) return -1; // encoder returns 32 for some reason if (st != 32) return -1; // encoder returns 32 for some reason
} }
// make symlinks // make symlinks
// //
for (int i=0; i<c.m; i++) { for (int i=0; i<coding.m; i++) {
char enc_filename[1024], target_path[1024]; char enc_filename[1024], target_path[1024];
char dir_name[1024], link_name[1024]; char dir_name[1024], link_name[1024];
encoder_filename("data", "vda", c, i, enc_filename); encoder_filename("data", "vda", coding, i, enc_filename);
sprintf(target_path, "%s/Coding/%s", dir, enc_filename); sprintf(target_path, "%s/Coding/%s", dir, enc_filename);
sprintf(dir_name, "%s/%d", dir, i); sprintf(dir_name, "%s/%d", dir, i);
int retval = mkdir(dir_name, 0777); int retval = mkdir(dir_name, 0777);
@ -115,12 +115,35 @@ int encode(const char* dir, CODING& c, double& size) {
return retval; return retval;
} }
if (i == 0) { if (i == 0) {
file_size(target_path, size); file_size(target_path, child_size);
} }
} }
return 0; return 0;
} }
int META_CHUNK::decode() {
char cmd[1024];
sprintf(cmd,
"cd %s; /mydisks/b/users/boincadm/vda_test/decoder %s",
dir, DATA_FILENAME
);
printf("%s\n", cmd);
int s = system(cmd);
if (WIFEXITED(s)) {
int st = WEXITSTATUS(s);
if (st != 32) return -1; // encoder returns 32 for some reason
}
return 0;
}
int DATA_UNIT::delete_file() {
char path[1024], buf[1024];
sprintf(path, "%s/data.vda", dir);
size_t n = readlink(path, buf, 1024);
buf[n] = 0;
return unlink(buf);
}
CHUNK::CHUNK(META_CHUNK* mc, double s, int index) { CHUNK::CHUNK(META_CHUNK* mc, double s, int index) {
parent = mc; parent = mc;
present_on_server = true; present_on_server = true;
@ -130,6 +153,7 @@ CHUNK::CHUNK(META_CHUNK* mc, double s, int index) {
} else { } else {
sprintf(name, "%d", index); sprintf(name, "%d", index);
} }
sprintf(dir, "%s/%d", mc->dir, index);
} }
// assign this chunk to a host // assign this chunk to a host
@ -302,17 +326,18 @@ META_CHUNK::META_CHUNK(VDA_FILE_AUX* d, META_CHUNK* p, int index) {
// initialize a meta-chunk: // initialize a meta-chunk:
// encode it, then recursively initialize its meta-chunk children // encode it, then recursively initialize its meta-chunk children
// //
int META_CHUNK::init(const char* dir, POLICY& p, int level) { int META_CHUNK::init(const char* _dir, POLICY& p, int level) {
double size; double size;
char child_dir[1024]; char child_dir[1024];
CODING& c = p.codings[level]; strcpy(dir, _dir);
int retval = encode(dir, c, size); coding = p.codings[level];
int retval = encode();
if (retval) return retval; if (retval) return retval;
p.chunk_sizes[level] = size; p.chunk_sizes[level] = child_size;
if (level+1 < p.coding_levels) { if (level+1 < p.coding_levels) {
for (int i=0; i<c.m; i++) { for (int i=0; i<coding.m; i++) {
sprintf(child_dir, "%s/%d", dir, i); sprintf(child_dir, "%s/%d", dir, i);
META_CHUNK* mc = new META_CHUNK(dfile, parent, i); META_CHUNK* mc = new META_CHUNK(dfile, parent, i);
retval = mc->init(child_dir, p, level+1); retval = mc->init(child_dir, p, level+1);
@ -320,7 +345,7 @@ int META_CHUNK::init(const char* dir, POLICY& p, int level) {
children.push_back(mc); children.push_back(mc);
} }
} else { } else {
for (int i=0; i<c.m; i++) { for (int i=0; i<coding.m; i++) {
CHUNK* cp = new CHUNK(this, p.chunk_sizes[level], i); CHUNK* cp = new CHUNK(this, p.chunk_sizes[level], i);
children.push_back(cp); children.push_back(cp);
@ -375,12 +400,13 @@ int VDA_FILE_AUX::init() {
return 0; return 0;
} }
int META_CHUNK::get_state(const char* dir, POLICY& p, int level) { int META_CHUNK::get_state(const char* _dir, POLICY& p, int level) {
int retval; int retval;
CODING& c = p.codings[level]; strcpy(dir, _dir);
coding = p.codings[level];
if (level+1 < p.coding_levels) { if (level+1 < p.coding_levels) {
for (int i=0; i<c.m; i++) { for (int i=0; i<coding.m; i++) {
char child_dir[1024]; char child_dir[1024];
sprintf(child_dir, "%s/%s.%d", dir, DATA_FILENAME, i); sprintf(child_dir, "%s/%s.%d", dir, DATA_FILENAME, i);
META_CHUNK* mc = new META_CHUNK(dfile, this, i); META_CHUNK* mc = new META_CHUNK(dfile, this, i);
@ -389,7 +415,7 @@ int META_CHUNK::get_state(const char* dir, POLICY& p, int level) {
children.push_back(mc); children.push_back(mc);
} }
} else { } else {
for (int i=0; i<c.m; i++) { for (int i=0; i<coding.m; i++) {
CHUNK* ch = new CHUNK(this, p.chunk_sizes[level], i); CHUNK* ch = new CHUNK(this, p.chunk_sizes[level], i);
children.push_back(ch); children.push_back(ch);
} }