/**
 * Update <key, oldval> with <key, val>
 */
int zht_update(const char *key, const char *val)
{
	log_msg("cshou debug === zht_update: key = %s, value = %s\n", key, val);

	return zht_insert(key, val);

	char res[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(key, res);
	if (ZHT_LOOKUP_FAIL == stat) {
		int insert_res = zht_insert(key, val);
		if (insert_res) {
			log_msg("DFZ debug: zht_update() _insert() failed code %d. \n\n", insert_res);
			return -1;
		}
		return 0;
	}

	int remove_res = zht_remove(key);
	log_msg("DFZ debug: zht_update() - remove_res = %d. \n\n", remove_res);

	int insert_res = zht_insert(key, val);
	log_msg("DFZ debug: zht_update() - insert_res = %d. \n\n", insert_res);

	char newval[ZHT_MAX_BUFF] = {0};
	int status = zht_lookup(key, newval);

	log_msg("DFZ debug: zht_update() - status = %d. \n\n", status);

	if (ZHT_LOOKUP_FAIL == status)
		log_msg("DFZ debug: zht_update() - key %s not found. \n\n", key);
	else
		log_msg("DFZ debug: zht_update() - key = %s, newval = %s. \n\n", key, newval);

	return 0;
}
/**
 * FUSE document:
 *
 * Create and open a file
 *
 * If the file does not exist, first create it with the specified
 * mode, and then open it.
 *
 * If this method is not implemented or under Linux kernel
 * versions earlier than 2.6.15, the mknod() and open() methods
 * will be called instead.
 *
 * Introduced in version 2.5
 *
 * *****************************************************************
 * DFZ:
 * 	In fusionFS, a file creation always happens in the local node
 */
int fusion_create(const char *path, mode_t mode, struct fuse_file_info *fi)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};
	int fd;

	log_msg("\nfusion_create(path=\"%s\", mode=0%03o, fi=0x%08x)\n", path, mode, fi);
	fusion_fullpath(fpath, path);

	/*if <path> exists in ZHT, we should return at this point*/
	char res[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(path, res);
	if (ZHT_LOOKUP_FAIL == stat) {
		log_msg("\n================DFZ ERROR: file already exists. \n");
		return -1;
	}

	/*create the local file*/
	fd = creat(fpath, mode);
	if (fd < 0)
		retstat = fusion_error("fusion_create creat");
	fi->fh = fd;
	log_fi(fi);

	/*add the filename to its parent path in the ZHT entry*/
	char dirname[PATH_MAX] = {0};
	char *pch = strrchr(path, '/');
	strncpy(dirname, path, pch - path + 1);
	log_msg("\n================DFZ debug: dirname = %s \n", dirname);
	char oldval[ZHT_MAX_BUFF] = {0};
	stat = zht_lookup(dirname, oldval);

	if (ZHT_LOOKUP_FAIL == stat) {
		log_msg("\n================DFZ ERROR: no parent path exists. \n");
		return -1;
	}
	log_msg("\n================DFZ debug: oldval = %s. \n", oldval);
	zht_append(dirname, pch + 1);

	// log_msg("cshou debug ==== dirname=%s, filename=%s\n", dirname, pch + 1);

	/*insert <path, ip_addr> into ZHT */
	char addr[PATH_MAX] = {0};
	net_getmyip(addr);
	log_msg("\n================DFZ debug _create(): addr = %s. \n", addr);
	if (zht_insert(path, addr))
		log_msg("\n================ERROR _create(): failed to insert <%s, %s> to ZHT. \n", path, addr);
		
	
	char myaddr[PATH_MAX] = {0};
	net_getmyip(myaddr);

	spade_create(myaddr, fpath, fuse_get_context()->pid);

	return retstat;
}
Exemplo n.º 3
0
/**
 * Update <key, oldval> with <key, val>
 */
int zht_update(const char *key, const char *val)
{
//	/*DFZ debug*/
//	char oldval[PATH_MAX] = {0};
//	int status = zht_lookup(key, oldval);
//	log_msg("DFZ debug: zht_update() - status = %d. \n\n", status);
//	if (ZHT_LOOKUP_FAIL == status)
//		log_msg("DFZ debug: zht_update() - key %s not found. \n\n", key);
//	else
//		log_msg("DFZ debug: zht_update() - key = %s, oldval = %s. \n\n", key, oldval);

	/*ZHT supports update semantics now: */
	return zht_insert(key, val);

	char res[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(key, res);
	if (ZHT_LOOKUP_FAIL == stat) {
		int insert_res = zht_insert(key, val);
		if (insert_res) {
			log_msg("DFZ debug: zht_update() _insert() failed code %d. \n\n", insert_res);
			return -1;
		}
		return 0;
	}

	int remove_res = zht_remove(key);
	 log_msg("DFZ debug: zht_update() - remove_res = %d. \n\n", remove_res);

//	/*DFZ debug*/
//	status = zht_lookup(key, oldval);
//	if (ZHT_LOOKUP_FAIL == status)
//		log_msg("DFZ debug: zht_update() - key %s not found. \n\n", key);
//	else
//		log_msg("DFZ debug: zht_update() - key = %s, oldval = %s. \n\n", key, oldval);
//
//	log_msg("DFZ debug: zht_update() - key = %s, val =  %s. \n\n", key, val);

	int insert_res = zht_insert(key, val);
	log_msg("DFZ debug: zht_update() - insert_res = %d. \n\n", insert_res);

	char newval[ZHT_MAX_BUFF] = {0};
	int status = zht_lookup(key, newval);

	log_msg("DFZ debug: zht_update() - status = %d. \n\n", status);

	if (ZHT_LOOKUP_FAIL == status)
		log_msg("DFZ debug: zht_update() - key %s not found. \n\n", key);
	else
		log_msg("DFZ debug: zht_update() - key = %s, newval = %s. \n\n", key, newval);

	return 0;
}
Exemplo n.º 4
0
/**
 * Remove a file
 *
 * DFZ: two ways to unlink remote files:
 * 		1) [Accepted] add a "unlink request" service type in the ffsnetd daemon process
 * 		2) don't touch the remote file when updating the meta data, but do a batch job in each node to
 * 			self-check dangling files
 */
int fusion_unlink(const char *path)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};

	log_msg("fusion_unlink(path=\"%s\")\n", path);
	fusion_fullpath(fpath, path);

	/*remove the file from its parent dir in ZHT*/
	char dirname[PATH_MAX] = {0}, fname[PATH_MAX] = {0};
	char *pch = strrchr(path, '/');
	strncpy(dirname, path, pch - path + 1);
	strcpy(fname, pch + 1);
	zht_delete(dirname, fname);

	/*remove the file entry from ZHT*/
	char oldaddr[PATH_MAX] = {0};
	zht_lookup(path, oldaddr);
	zht_remove(path);

	/*DFZ: Uncomment the following for only metadata benchmark, i.e. don't really remove anything*/
	return 0;

	/*if this file doesn't exist*/
	char val[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(path, val);
	if (ZHT_LOOKUP_FAIL == stat) {
		fusion_error("_unlink() trying to remove a nonexistent file");
		return -1;
	}

	/*
	 * The following is to really remove the file
	 */

	/*if it's a local operation, we are done here*/
	char myip[PATH_MAX] = {0};
	net_getmyip(myip);
	if (!strcmp(myip, oldaddr)) {
		log_msg("\n DFZ debug: _unlink() local unlink.\n\n");
		retstat = unlink(fpath);
		if (retstat < 0)
			retstat = fusion_error("fusion_unlink unlink");
		return retstat;
	}

	log_msg("\n DFZ debug: _unlink() remote rmfile.\n\n");
	/*or we need to remove the remote file*/
	ffs_rmfile_c("udt", oldaddr, "9000", fpath);

	return retstat;
}
/**
 * <key, oldval> -> <key, (oldval - val)>
 */
int zht_delete(const char *key, const char *val)
{
	char newval[ZHT_MAX_BUFF] = {0};
	char search[PATH_MAX] = {0};

	char oldval[ZHT_MAX_BUFF] = {0};
	zht_lookup(key, oldval);

	strcpy(search, " ");
	strcat(search, val);
	strcat(search, " ");

	char *pch = strstr(oldval, search);
	
	/*if for some reason val doesn't exist, we are doen here*/
	if (!pch)
		return 0;	
	
	strncpy(newval, oldval, pch - oldval);
	strcat(newval, " ");
	strcat(newval, pch + strlen(search));

	zht_update(key, newval);

	return 0;
}
/** Open directory
 *
 * This method should check if the open operation is permitted for
 * this  directory
 *
 * Introduced in version 2.3
 */
int fusion_opendir(const char *path, struct fuse_file_info *fi)
{
	DIR *dp;
	int retstat = 0;
	char fpath[PATH_MAX] = {0};

	log_msg("\nfusion_opendir(path=\"%s\", fi=0x%08x)\n", path, fi);
	fusion_fullpath(fpath, path);

	/*if path exists in ZHT, create it locally*/
	char res[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(path, res);

	if (ZHT_LOOKUP_FAIL != stat) {
		mkdir(fpath, 0775);
	}
	else {
		/*TODO*/
		fusion_error("_opendir() failed: <fpath> not found in ZHT");
	}

	dp = opendir(fpath);
	if (dp == NULL)
		retstat = fusion_error("fusion_opendir opendir");

	fi->fh = (intptr_t) dp;

	log_fi(fi);

	return retstat;
}
Exemplo n.º 7
0
int Worker::update_nodehistory(uint32_t currnode, string alltasks) {
	int num_vector_count, per_vector_count;
	vector<vector<string> > tokenize_string = tokenize(alltasks, '\"', '\'',
			num_vector_count, per_vector_count);
	uint32_t num_nodes = svrclient.memberList.size();
	//cout << "Worker = " << selfIndex << " num_vector_count = " << num_vector_count << " per_vector_count = " << per_vector_count << endl;
	for (int i = 0; i < num_vector_count; i++) {
		for (int j = 0; j < per_vector_count; j++) {
			try {
				string &taskid = tokenize_string.at(i).at(j);
				string value = zht_lookup(taskid);
				Package recv_pkg;
				recv_pkg.ParseFromString(value);

				int index = myhash(taskid.c_str(), num_nodes);
				if (index != selfIndex) {
					cout
							<< "something wrong..doing remote update_nodehistory index = "
							<< index << " selfIndex = " << selfIndex << endl;
				}

				// update number of moves (increment)
				uint32_t old_nummoves = recv_pkg.nummoves();
				recv_pkg.set_nummoves(old_nummoves + 1);

				// update current location of task
				recv_pkg.set_currnode(currnode);

				// update task migration history
				stringstream nodehistory_ss;
				nodehistory_ss << currnode << "\'";
				string new_nodehistory(nodehistory_ss.str());
				new_nodehistory.append(recv_pkg.nodehistory()); //cout << "update_nodehistory: task " << recv_pkg.virtualpath() << " node history = " << recv_pkg.nodehistory();
				recv_pkg.set_nodehistory(new_nodehistory); //cout << " node history = " << recv_pkg.nodehistory() << endl;

				// insert updated task into ZHT
				int ret = zht_insert(recv_pkg.SerializeAsString());
				if (ret != 0) {
					cout << "update_nodehistory: zht_insert error ret = " << ret
							<< endl;
					exit(1);
				}
			} catch (exception& e) {
				cout << "update_nodehistory: (tokenize_string.at(i).at(0)) "
						<< " " << e.what() << endl;
				exit(1);
			}
		}
	}
	return 0;
}
Exemplo n.º 8
0
int Worker::update_numwait(string alltasks) {
	int num_vector_count, per_vector_count;
	vector<vector<string> > tokenize_string = tokenize(alltasks, '\"', '\'',
			num_vector_count, per_vector_count);
	uint32_t num_nodes = svrclient.memberList.size();
	for (int i = 0; i < num_vector_count; i++) {
		for (int j = 0; j < per_vector_count; j++) {
			try {
				string &taskid = tokenize_string.at(i).at(j);
				string value = zht_lookup(taskid);
				Package recv_pkg;
				recv_pkg.ParseFromString(value);

				int index = myhash(taskid.c_str(), num_nodes);
				if (index != selfIndex) {
					cout
							<< "something wrong..doing remote update_numwait: index = "
							<< index << " selfIndex = " << selfIndex << endl;
				}

				// update number of tasks to wait (decrement)
				uint32_t old_numwait = recv_pkg.numwait();
				recv_pkg.set_numwait(old_numwait - 1);
				notr++;
				if (LOGGING) {
					if (old_numwait - 1 == 0) {
						log_fp << "task = " << taskid << " is ready" << endl;
					}
				}

				// insert updated task into ZHT
				int ret = zht_insert(recv_pkg.SerializeAsString());
				if (ret != 0) {
					cout << "update_numwait: old_numwait = " << old_numwait
							<< endl;
					cout << "update_numwait: zht_insert error ret = " << ret
							<< " key = " << taskid << " index = " << index
							<< " selfindex = " << selfIndex << endl;
					exit(1);
				}
			} catch (exception& e) {
				cout << "update_numwait: (tokenize_string.at(i).at(0)) " << " "
						<< e.what() << endl;
				exit(1);
			}
		}
	}
	log_fp << "notr = " << notr << endl;
	return 0;
}
/**
 * <key, oldval> -> <key, (oldval + val)>
 */
int zht_append(const char *key, const char *val)
{
	char newval[ZHT_MAX_BUFF] = {0};

	char oldval[ZHT_MAX_BUFF] = {0};
	zht_lookup(key, oldval);

	strcpy(newval, oldval);
	strcat(newval, val);
	strcat(newval, " ");

	zht_update(key, newval);

	return 0;
}
Exemplo n.º 10
0
/**
 * Remove a directory
 *
 * 		DFZ: updated for ZHT
 *
 * 		TODO: deleting a non-empty directory will cause some problems
 */
int fusion_rmdir(const char *path)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};

	log_msg("fusion_rmdir(path=\"%s\")\n", path);
	fusion_fullpath(fpath, path);

	/*check ZHT if <path/> is empty */
	char dirname[PATH_MAX] = {0};
	strcpy(dirname, path);
	strcat(dirname, "/");

	char val[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(dirname, val);

	if (ZHT_LOOKUP_FAIL != stat
			&& !strcmp(" ", val)) {
		char rmcmd[PATH_MAX] = {0};
		strcpy(rmcmd, "rm -r ");
		strcat(rmcmd, fpath);
		system(rmcmd);
	}
	else {
		fusion_error("fusion_rmdir() directory not empty or not a directory");
		return -1;
	}
//	retstat = rmdir(fpath);
//	if (retstat < 0)
//		retstat = fusion_error("fusion_rmdir rmdir");

	/* update ZHT */
	char parentpath[PATH_MAX] = {0};
	char curpath[PATH_MAX] = {0};
	char fullpath[PATH_MAX] = {0};
	char *pch = strrchr(path, '/');
	strncpy(parentpath, path, pch - path + 1);
	strcpy(curpath, pch + 1);
	strcat(curpath, "/");
	strcpy(fullpath, path);
	strcat(fullpath, "/");
	log_msg("\n==========DFZ debug: fusion_rmdir() parentpath = %s, curpath = %s \n\n", parentpath, curpath);

	zht_delete(parentpath, curpath);
	zht_remove(fullpath);

	return retstat;
}
Exemplo n.º 11
0
int Worker::check_if_task_is_ready(string key) {
	int index = myhash(key.c_str(), svrclient.memberList.size());
	if (index != selfIndex) {
		Package check_package;
		check_package.set_virtualpath(key);
		check_package.set_operation(23);
		string check_str = check_package.SerializeAsString();
		pthread_mutex_lock(&msg_lock);
		int ret = svrclient.svrtosvr(check_str, check_str.size(), index);
		pthread_mutex_unlock(&msg_lock);
		return ret;
	} else {
		string value = zht_lookup(key);
		Package check_package;
		check_package.ParseFromString(value);
		return check_package.numwait();
	}
}
Exemplo n.º 12
0
/** Release an open file
 *
 * Release is called when there are no more references to an open
 * file: all file descriptors are closed and all memory mappings
 * are unmapped.
 *
 * For every open() call there will be exactly one release() call
 * with the same flags and file descriptor.  It is possible to
 * have a file opened more than once, in which case only the last
 * release will mean, that no more reads/writes will happen on the
 * file.  The return value of release is ignored.
 *
 * Changed in version 2.2
 *
 * *****************************************************************
 * DFZ: this is equivalent to fclose(). Nothing is surprising unless
 * 		it modifies the file. In this case we need to make the node
 * 		who modifies the file as the new location of this file, as
 * 		to update the value in ZHT. We also need to remove the old
 * 		copy in its previous node from where it's copied from.
 */
int fusion_release(const char *path, struct fuse_file_info *fi)
{
	pid_t pid = fuse_get_context()->pid;
	log_msg("=====cshou debug fusion_release: can we get pid here ? %d\n", pid);

	int retstat = 0;
	char fpath[PATH_MAX] = {0};
	fusion_fullpath(fpath, path);

	log_msg("\nfusion_release(path=\"%s\", fi=0x%08x)\n", path, fi);
	log_fi(fi);

	/*is this file written?*/
	int iswritten = 0;
	int flags = fcntl(fi->fh, F_GETFL);
	if (-1 == flags) {
		/*I don't know what to do... failed to get the old flags */
		fusion_error("_release(): fd lost. ");
	}
	/*
	O_ACCMODE<0003>????д?ļ?????ʱ??????ȡ??flag?ĵ?2λ
	O_RDONLY<00>??ֻ??????
	O_WRONLY<01>??ֻд????
	O_RDWR<02>????д????
	 */
	else if (O_ACCMODE & flags) {
		iswritten = 1;
	}

	/*if this is just a local IO, we are all set*/
	char myip[PATH_MAX] = {0};
	net_getmyip(myip);

	// if (iswritten) {
	// 	spade_write(myip, fpath, pid, 0, 0);
	// }
	// else {
	// 	spade_read(myip, fpath, pid, 0, 0);
	// }


	// We need to close the file.  Had we allocated any resources
	// (buffers etc) we'd need to free them here as well.
	retstat = close(fi->fh);


	/*dealing with the remote copy*/
	if (iswritten) { /*so it's a write mode*/
		char oldip[PATH_MAX] = {0};
		int stat = zht_lookup(path, oldip);
		/*if path doesn't exist in ZHT, try to remove it locally */
		if (ZHT_LOOKUP_FAIL == stat) {
			unlink(fpath);
			return 0;
		}

		/*DFZ: test GPU erasure */

		/*update m to be the number of (redundant) parities*/
		int ida_on = 1, m = 3, n = 8 - m; /*assuming we use all 8 available Cosmos nodes*/
		if (ida_on)
		{
			log_msg("start testing GPU erasure.\n");
			gib_context gc;
			long bs = 1024 * 1024; /* block size */

			/*read the file into buffer*/
			FILE *f = fopen(fpath, "r");
			fseek(f, 0, SEEK_END);
			long fsize = ftell(f);
			fseek(f, 0, SEEK_SET);
			char *string = malloc(fsize + 1);
			fread(string, fsize, 1, f);
			fclose(f);
			string[fsize] = 0;

			log_msg("before git_init(). \n");
			if (n >= 2 && (n + m) <= 8) /*Gibraltar lib requires both n and m larger than 2; Cosmos has 8 GPU nodes available*/
			{
				int rc = gib_init(m, n, &gc);
				log_msg("after git_init(). \n");
				if (rc)
				{
					log_msg("error in gib_init().\n");
				}
				void *data;
				gib_alloc(&data, bs, &bs, gc);
				memcpy(data, string, fsize);
				gib_generate(data, bs, gc);

				/*send data chunks to n+m-1 nodes*/
				int i = 0;
				for (i = 0; i < n + m; i++)
				{
					char suffix[16] = {0};
					sprintf(suffix, "%d", i);
					char new_filename[256] = {0};
					strcpy(new_filename, fpath);
					strcat(new_filename, suffix); 

					FILE *fh = fopen(new_filename, "w");
					fwrite(i * bs + data, 1, bs, fh);
					fclose(fh);

					/*send out all new_filename to n+m-1 nodes*/
					if (!i) continue; /* don't worry about the first chunk */

					char member[16] = {0};
					member[0] = 'p';
					char idx[2] = {0};
					sprintf(idx, "%d", i + 3); /*Cosmos node starts from p3*/
					strcat(member, idx);
					ffs_sendfile_c("udt", member, "9000", new_filename, new_filename);
				}

				/*DFZ: test only. To recover the failed parity
				char buff_id[256] = {'1'};
				gib_recover(data, bs, buff_id, m, gc);
				*/
				gib_free(data, gc);
				gib_destroy(gc);
				log_msg("GPU erasure successful. \n");

			}
		}
		/*traditinal data replication*/
		else
		{
			int i = 0;
			for (i = 0; i < m; i++)
			{
				char member[16] = {0};
				member[0] = 'p';
				char idx[2] = {0};
				sprintf(idx, "%d", i + 4); /*primary copy on p3, replicas on p4-p10*/
				strcat(member, idx);
				ffs_sendfile_c("udt", member, "9000", fpath, fpath);
			}
		}
		/*DFZ: end of GPU erasure test*/

		char nodeaddr[PATH_MAX] = {0};
		zht_lookup(path, nodeaddr);

		if (!strcmp(myip, nodeaddr)) {
			return retstat;
		}

		/*update this file's node value in ZHT*/
		char myip[PATH_MAX] = {0};
		net_getmyip(myip);
		zht_update(path, myip);
		/*TODO: potentially, need to update the parent directory in ZHT
		 * because the physical directory is also created in the new node*/

		/*remove the file from its old node*/
		/******************************************************************************
		 * DFZ: I want a more conservative way to clean dirty copies, so the following
		 * remote removal is deferred for now.
		 *
		 * In other words just like the redundant directories, dirty files will be
		 * removed when its parent directory is removed from ZHT
		 * *******************************************************************************/
//		ffs_rmfile_c("udt", oldip, "9000", fpath);

		 // invoke spade
		 // spade_write(myip, fpath, fuse_get_context()->pid, 0, 0);
	}
	else { /*read-only file*/
		/* we don't want o keep a redundant copy in local node to
		 * prevent from the issue on removing multiple files
		 * across different nodes. So, we remove the local file
		 */
		unlink(fpath);
		log_msg("\n=========DFZ debug _release(): %s unlinked from local node. \n\n", fpath);

		// invoke spade
		// spade_read(myip, fpath, fuse_get_context()->pid, 0, 0);
	}

	return retstat;
}
Exemplo n.º 13
0
/** Get file attributes.
 *
 * Similar to stat().  The 'st_dev' and 'st_blksize' fields are
 * ignored.  The 'st_ino' field is ignored except if the 'use_ino'
 * mount option is given.
 *
 * DFZ: This is the first function to be called whenever the user tries to
 * 		get access to any file, even if only to its meta data. Two cases:
 * 			1) if the file exists, i.e. it's stored in ZHT, then this file is
 * 				transfered to the local node first and 'lstat' the local copy
 * 			2) if the file doesn't exist, FUSE will pass the control to
 * 				_create()
 */
int fusion_getattr(const char *path, struct stat *statbuf)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};

	log_msg("\nfusion_getattr(path=\"%s\", statbuf=0x%08x)\n", path, statbuf);
	fusion_fullpath(fpath, path);

	char res[ZHT_MAX_BUFF] = {0};
	int status = zht_lookup(path, res);

	char myaddr[PATH_MAX] = {0};
	net_getmyip(myaddr);

	bool is_transfer = false;

	log_msg("\n ===========CSHOU debug: _getattr() the local IP got: %s \n\n", myaddr);

	if (ZHT_LOOKUP_FAIL == status) { /* if not found in ZHT */
		log_msg("\n ===========DFZ debug: _getattr() %s does not exist \n\n", path);

		/*if path is an existing directory*/
		char dirname[PATH_MAX] = {0};
		strcpy(dirname, path);
		strcat(dirname, "/");

		log_msg("\n ===========DFZ debug: _getattr() dirname = %s. \n\n", dirname);

		char res[ZHT_MAX_BUFF] = {0};
		int stat = zht_lookup(dirname, res);

		if (ZHT_LOOKUP_FAIL != stat) {
			log_msg("\n ===========DFZ debug: _getattr() res = %s. \n\n", res);

			mkdir(fpath, 0755);
			char cmd_mkdir[PATH_MAX] = {0};
			strcpy(cmd_mkdir, "mkdir -p ");
			strcat(cmd_mkdir, fpath);
			system(cmd_mkdir);

			log_msg("\n ===========DFZ debug: _getattr() new directory %s/ created \n\n", fpath);
		}

	}
	else { /* if file exists in ZHT */
		log_msg("\n ===========DFZ debug: _getattr() zht_lookup() = %s. \n\n", res);

		if (access(fpath, F_OK)) { /*if it isn't on this node, copy it over*/

			ffs_recvfile_c("udt", res, "9000", fpath, fpath);

			// ADDED BY CSHOU
			//if (strcmp(res, myaddr) != 0 && strcmp(res, "") != 0)
			//if (strcmp(res, myaddr) != 0 && res && strlen(res) != 0)
				//is_transfer = true;
				//spade_receivefile(fpath, res, fpath, statbuf->st_size, statbuf->st_mtime);

			log_msg("\n ===========DFZ debug: _getattr() %s transferred from %s. \n\n",
					fpath, res);
		}
		else if (strcmp("/", path) /*even it's in local node, it could be outdated.*/
				&& strcmp(res, myaddr)) {
			ffs_recvfile_c("udt", res, "9000", fpath, fpath);

			// ADDED BY CSHOU
			//if (strcmp(res, myaddr) != 0 && res && strlen(res) != 0)
				//is_transfer = true;
				//spade_receivefile(fpath, res, fpath, statbuf->st_size, statbuf->st_mtime);

			log_msg("\n ===========DFZ debug: _getattr() %s transferred from %s because local copy might be outdated. \n\n",
					fpath, res);
		}
		else {
			/* let it be */
			log_msg("\n ===========DFZ debug: _getattr() %s exists in local. \n\n", fpath);
		}
	}

	retstat = lstat(fpath, statbuf);

	if (retstat != 0)
		retstat = fusion_error("fusion_getattr lstat");

	log_stat(statbuf);

	/*
	if (is_transfer) {
			char s_size[20];
			sprintf(s_size, "%zd", statbuf->st_size);
			spade_receivefile(fpath, res, fpath, s_size, ctime(&statbuf->st_mtime));
		}*/
	

	return retstat;
}
Exemplo n.º 14
0
/** Read directory
 *
 * This supersedes the old getdir() interface.  New applications
 * should use this.
 *
 * The filesystem may choose between two modes of operation:
 *
 * 1) The readdir implementation ignores the offset parameter, and
 * passes zero to the filler function's offset.  The filler
 * function will not return '1' (unless an error happens), so the
 * whole directory is read in a single readdir operation.  This
 * works just like the old getdir() method.
 *
 * 2) The readdir implementation keeps track of the offsets of the
 * directory entries.  It uses the offset parameter and always
 * passes non-zero offset to the filler function.  When the buffer
 * is full (or an error happens) the filler function will return
 * '1'.
 *
 * Introduced in version 2.3
 */
int fusion_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
		off_t offset, struct fuse_file_info *fi)
{
	log_msg(
			"\nfusion_readdir(path=\"%s\", buf=0x%08x, filler=0x%08x, offset=%lld, fi=0x%08x)\n",
			path, buf, filler, offset, fi);

	int retstat = 0;
	char fpath[PATH_MAX] = {0};
	fusion_fullpath(fpath, path);

	/* append a '/' if it's not the root directory */
	char dirname[PATH_MAX] = {0};
	strcpy(dirname, path);
	if (strcmp("/", dirname)) {
		strcat(dirname, "/");
	}

	char filelist[ZHT_MAX_BUFF] = {0};
	int stat = zht_lookup(dirname, filelist);

	if (ZHT_LOOKUP_FAIL == stat)
		log_msg("\n ===========DFZ debug: fusion_readdir() filelist not found in ZHT \n\n");
	else
		log_msg("\n ===========DFZ debug: fusion_readdir() filelist = %s. \n\n", filelist);

	/*If <path/> has no files, clean up the local physical path*/
	if (!strcmp(" ", filelist)) {
		char rmallcmd[PATH_MAX] = {0};
		strcpy(rmallcmd, "rm -r ");
		strcat(rmallcmd, fpath);
		strcat(rmallcmd, "*");
		system(rmallcmd);
	}

	char *pch = strtok((char*)filelist, " ");
	while (pch) {

		log_msg("calling filler with name %s\n", pch);
		if (filler(buf, pch, NULL, 0) != 0) {
			log_msg("    ERROR fusion_readdir filler:  buffer full");
			return -ENOMEM;
		}

		/*create some dummy dirs for listing*/
		if ('/' == *(pch + strlen(pch) - 1)) {
			char newdir[PATH_MAX] = {0};
			strcpy(newdir, fpath);
			strcat(newdir, "/");
			strcat(newdir, pch);
			mkdir(newdir, 0775);
		}

		pch = strtok(NULL, " ");
	}


//
//	DIR *dp;
//	struct dirent *de;
//
//
//	// once again, no need for fullpath -- but note that I need to cast fi->fh
//	dp = (DIR *) (uintptr_t) fi->fh;
//
//	// Every directory contains at least two entries: . and ..  If my
//	// first call to the system readdir() returns NULL I've got an
//	// error; near as I can tell, that's the only condition under
//	// which I can get an error from readdir()
//	de = readdir(dp);
//	if (de == 0) {
//		retstat = fusion_error("fusion_readdir readdir");
//		return retstat;
//	}
//
//	// This will copy the entire directory into the buffer.  The loop exits
//	// when either the system readdir() returns NULL, or filler()
//	// returns something non-zero.  The first case just means I've
//	// read the whole directory; the second means the buffer is full.
//	do {
//		log_msg("calling filler with name %s\n", de->d_name);
//		if (filler(buf, de->d_name, NULL, 0) != 0) {
//			log_msg("    ERROR fusion_readdir filler:  buffer full");
//			return -ENOMEM;
//		}
//	} while ((de = readdir(dp)) != NULL);
//
////	filler(buf, ep->data, NULL, 0);

	log_fi(fi);

	return retstat;
}
Exemplo n.º 15
0
/** Release an open file
 *
 * Release is called when there are no more references to an open
 * file: all file descriptors are closed and all memory mappings
 * are unmapped.
 *
 * For every open() call there will be exactly one release() call
 * with the same flags and file descriptor.  It is possible to
 * have a file opened more than once, in which case only the last
 * release will mean, that no more reads/writes will happen on the
 * file.  The return value of release is ignored.
 *
 * Changed in version 2.2
 *
 * *****************************************************************
 * DFZ: this is equivalent to fclose(). Nothing is surprising unless
 * 		it modifies the file. In this case we need to make the node
 * 		who modifies the file as the new location of this file, as
 * 		to update the value in ZHT. We also need to remove the old
 * 		copy in its previous node from where it's copied from.
 */
int fusion_release(const char *path, struct fuse_file_info *fi)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};
	fusion_fullpath(fpath, path);

	log_msg("\nfusion_release(path=\"%s\", fi=0x%08x)\n", path, fi);
	log_fi(fi);

	/*is this file written?*/
	int iswritten = 0;
	int flags = fcntl(fi->fh, F_GETFL);
	if (-1 == flags) {
		/*I don't know what to do... failed to get the old flags */
		fusion_error("_release(): fd lost. ");
	}
	/*
	O_ACCMODE<0003>:读写文件操作时,用于取出flag的低2位
	O_RDONLY<00>:只读打开
	O_WRONLY<01>:只写打开
	O_RDWR<02>:读写打开
	 */
	else if (O_ACCMODE & flags) {
		iswritten = 1;
	}


	// We need to close the file.  Had we allocated any resources
	// (buffers etc) we'd need to free them here as well.
	retstat = close(fi->fh);

	/*DFZ: uncomment this for metadata benchmark*/
	return 0;

	/*if this is just a local IO, we are all set*/
	char myip[PATH_MAX] = {0};
	net_getmyip(myip);

	char nodeaddr[PATH_MAX] = {0};
	zht_lookup(path, nodeaddr);

	if (!strcmp(myip, nodeaddr)) {
		return retstat;
	}

	/*dealing with the remote copy*/
	if (iswritten) { /*so it's a write mode*/
		char oldip[PATH_MAX] = {0};
		int stat = zht_lookup(path, oldip);
		/*if path doesn't exist in ZHT, try to remove it locally */
		if (ZHT_LOOKUP_FAIL == stat) {
			unlink(fpath);
			return 0;
		}

		/*update this file's node value in ZHT*/
		char myip[PATH_MAX] = {0};
		net_getmyip(myip);
		zht_update(path, myip);
		/*TODO: potentially, need to update the parent directory in ZHT
		 * because the physical directory is also created in the new node*/

		/*remove the file from its old node*/
		/******************************************************************************
		 * DFZ: I want a more conservative way to clean dirty copies, so the following
		 * remote removal is deferred for now.
		 *
		 * In other words just like the redundant directories, dirty files will be
		 * removed when its parent directory is removed from ZHT
		 * *******************************************************************************/
//		ffs_rmfile_c("udt", oldip, "9000", fpath);
	}
	else { /*read-only file*/
		/* we don't want o keep a redundant copy in local node to
		 * prevent from the issue on removing multiple files
		 * across different nodes. So, we remove the local file
		 */
		unlink(fpath);
		log_msg("\n=========DFZ debug _release(): %s unlinked from local node. \n\n", fpath);
	}

	return retstat;
}
Exemplo n.º 16
0
/** Get file attributes.
 *
 * Similar to stat().  The 'st_dev' and 'st_blksize' fields are
 * ignored.  The 'st_ino' field is ignored except if the 'use_ino'
 * mount option is given.
 *
 * DFZ: This is the first function to be called whenever the user tries to
 * 		get access to any file, even if only to its meta data. Two cases:
 * 			1) if the file exists, i.e. it's stored in ZHT, then this file is
 * 				transfered to the local node first and 'lstat' the local copy
 * 			2) if the file doesn't exist, FUSE will pass the control to
 * 				_create()
 */
int fusion_getattr(const char *path, struct stat *statbuf)
{
	int retstat = 0;
	char fpath[PATH_MAX] = {0};

	log_msg("\nfusion_getattr(path=\"%s\", statbuf=0x%08x)\n", path, statbuf);
	fusion_fullpath(fpath, path);

	char res[ZHT_MAX_BUFF] = {0};
	log_msg("\n =====DFZ debug: file %s line %d \n\n", __FILE__, __LINE__);
	int status = zht_lookup(path, res);
	log_msg("\n =====DFZ debug: file %s line %d \n\n", __FILE__, __LINE__);

	char myaddr[PATH_MAX] = {0};
	net_getmyip(myaddr);
	log_msg("\n =====DFZ debug: file %s line %d \n\n", __FILE__, __LINE__);



	if (ZHT_LOOKUP_FAIL == status) { /* if not found in ZHT */
		log_msg("\n ===========DFZ debug: _getattr() %s does not exist \n\n", path);

		/*DFZ: uncomment this for metadata benchmark*/
		return -1;

		/*if path is an existing directory*/
		char dirname[PATH_MAX] = {0};
		strcpy(dirname, path);
		strcat(dirname, "/");

		log_msg("\n ===========DFZ debug: _getattr() dirname = %s. \n\n", dirname);

		char res[ZHT_MAX_BUFF] = {0};
		int stat = zht_lookup(dirname, res);

		if (ZHT_LOOKUP_FAIL != stat) {
			log_msg("\n ===========DFZ debug: _getattr() res = %s. \n\n", res);

			mkdir(fpath, 0755);
			char cmd_mkdir[PATH_MAX] = {0};
			strcpy(cmd_mkdir, "mkdir -p ");
			strcat(cmd_mkdir, fpath);
			system(cmd_mkdir);

			log_msg("\n ===========DFZ debug: _getattr() new directory %s/ created \n\n", fpath);
		}

	}
	else { /* if file exists in ZHT */
		log_msg("\n ===========DFZ debug: _getattr() zht_lookup() = %s. \n\n", res);

		/*DFZ: uncomment this for metadata benchmark*/
		return 0;

		if (access(fpath, F_OK)) { /*if it isn't on this node, copy it over*/

			ffs_recvfile_c("udt", res, "9000", fpath, fpath);

			log_msg("\n ===========DFZ debug: _getattr() %s transferred from %s. \n\n",
					fpath, res);
		}
		else if (strcmp("/", path) /*even it's in local node, it could be outdated.*/
				&& strcmp(res, myaddr)) {
			ffs_recvfile_c("udt", res, "9000", fpath, fpath);

			log_msg("\n ===========DFZ debug: _getattr() %s transferred from %s because local copy might be outdated. \n\n",
					fpath, res);
		}
		else {
			/* let it be */
			log_msg("\n ===========DFZ debug: _getattr() %s exists in local. \n\n", fpath);
		}
	}

	retstat = lstat(fpath, statbuf);

	if (retstat != 0)
		retstat = fusion_error("fusion_getattr lstat");

	log_stat(statbuf);

	return retstat;
}