示例#1
0
END_TEST

START_TEST(test_abandonBlock)
{
	bool s;
	struct hdfs_object *e = NULL, *lb, *bl;
	const char *tf = "/HADOOFUS_TEST_ABANDONBLOCK",
	      *client = "HADOOFUS_CLIENT";

	// Create the file first
	hdfs_create(h, tf, 0644, client, true/*overwrite*/,
	    false/*createparent*/, 1/*replication*/, 64*1024*1024, &e);
	if (e)
		ck_abort_msg("exception: %s", hdfs_exception_get_message(e));

	mark_point();

	// XXX this must be updated to cover v2.0+ (last_block/fileid)
	lb = hdfs_addBlock(h, tf, client, NULL, NULL, 0, &e);
	if (e)
		ck_abort_msg("exception: %s", hdfs_exception_get_message(e));
	ck_assert(!hdfs_object_is_null(lb));

	mark_point();

	bl = hdfs_block_from_located_block(lb);
	hdfs_object_free(lb);

	mark_point();

	hdfs_abandonBlock(h, bl, tf, client, &e);
	if (e)
		ck_abort_msg("exception: %s", hdfs_exception_get_message(e));

	hdfs_object_free(bl);
	mark_point();

	// Cleanup
	s = hdfs_delete(h, tf, false/*recurse*/, &e);
	if (e)
		ck_abort_msg("exception: %s", hdfs_exception_get_message(e));
	ck_assert_msg(s, "delete returned false");
}
示例#2
0
文件: hdfs.c 项目: 13141516/hadoofus
// Flushes internal buffer to disk. If passed buf is non-NULL, flushes that
// instead. Returns 0 on succ, -1 on err.
static int
_flush(struct hdfs_namenode *fs, struct hdfsFile_internal *f, const void *buf, size_t len)
{
	struct hdfs_object *lb = NULL, *ex = NULL, *excl = NULL, *block = NULL;
	struct hdfs_datanode *dn = NULL;
	int res = 0, tries = 3;
	const char *err = NULL, *msg_fmt;

	const char *wbuf = f->fi_wbuf;
	size_t wbuf_len = f->fi_wbuf_used;

	// Skip the extra copy if the user is feeding us full-sized blocks
	if (buf) {
		wbuf = buf;
		wbuf_len = len;
	}

	if (!wbuf_len)
		goto out;

	// For appends, we need to finish the last block
	if (f->fi_lastblock) {
		lb = f->fi_lastblock;
		f->fi_lastblock = NULL;
	}

	for (; tries > 0; tries--) {
		if (!lb) {
			lb = hdfs_addBlock(fs, f->fi_path, f->fi_client, excl, &ex);
			if (ex) {
				ERR(EIO, "addBlock failed: %s", hdfs_exception_get_message(ex));
				res = -1;
				goto out;
			}
			if (lb->ob_type == H_NULL) {
				ERR(EIO, "addBlock returned bogus null");
				res = -1;
				goto out;
			}
		}

		msg_fmt = "connect to datanode failed";
		dn = hdfs_datanode_new(lb, f->fi_client, HDFS_DATANODE_AP_1_0, &err);
		if (!dn)
			goto dn_failed;

		msg_fmt = "write failed";
		err = hdfs_datanode_write(dn, wbuf, wbuf_len, true/*crcs*/);
		hdfs_datanode_delete(dn);
		if (!err)
			break;

dn_failed:
		// On failure, either warn and try again, or give up
		if (tries == 1) {
			ERR(ECONNREFUSED, "%s: %s%s", msg_fmt, err, "");
			res = -1;
			goto out;
		}

		WARN("%s: %s%s", msg_fmt, err, ", retrying");

		block = hdfs_block_from_located_block(lb);
		hdfs_abandonBlock(fs, block, f->fi_path, f->fi_client, &ex);
		if (ex) {
			ERR(EIO, "abandonBlock failed: %s", hdfs_exception_get_message(ex));
			res = -1;
			goto out;
		}

		hdfs_object_free(block);
		block = NULL;

		// Add physical location of bad block's datanode to excluded
		// list
		if (lb->ob_val._located_block._num_locs > 0) {
			if (!excl)
				excl = hdfs_array_datanode_info_new();

			hdfs_array_datanode_info_append_datanode_info(
			    excl,
			    hdfs_datanode_info_copy(
				lb->ob_val._located_block._locs[0]
				)
			    );
		}

		hdfs_object_free(lb);
		lb = NULL;
	}

	// If we weren't given a user block directly, the internal buf has been
	// flushed:
	if (!buf)
		f->fi_wbuf_used = 0;

out:
	if (ex)
		hdfs_object_free(ex);
	if (lb)
		hdfs_object_free(lb);
	if (block)
		hdfs_object_free(block);
	if (excl)
		hdfs_object_free(excl);
	return res;
}