Esempio n. 1
0
static struct chirp_file *chirp_multi_create(const char *volume, const char *path, INT64_T flags, INT64_T mode, time_t stoptime)
{
	struct chirp_server *server;
	struct file_info info;

	if(!chirp_multi_lpath(volume, path, info.lpath, stoptime))
		return 0;

	while(1) {
		server = chirp_volume_server_choose(current_volume);
		if(!server) {
			errno = ENOSPC;
			return 0;
		}

		if(!server->prepared) {
			debug(D_MULTI, "preparing server %s", server->name);
			char keypath[CHIRP_PATH_MAX];
			sprintf(keypath, "/%s", current_volume->key);
			int result = chirp_reli_mkdir_recursive(server->name, keypath, 0777, stoptime);
			if(result < 0 && errno != EEXIST) {
				server->priority += 10;
				continue;
			}
			server->prepared = 1;
		}

		char cookie[17];
		strcpy(info.rhost, server->name);
		string_cookie(cookie, 16);
		sprintf(info.rpath, "%s/%s", current_volume->key, cookie);

		debug(D_MULTI, "create: /multi/%s%s at /chirp/%s/%s", volume, path, info.rhost, info.rpath);
		if(chirp_multi_update(volume, path, &info, stoptime) < 0)
			return 0;

		/* O_EXCL is needed to make sure that we don't accidentally choose the same local name twice. */
		struct chirp_file *file = chirp_reli_open(info.rhost, info.rpath, flags | O_EXCL, mode, stoptime);
		if(file) {
			server->priority += 1;
			return file;
		} else {
			debug(D_MULTI, "create failed, trying another server...");
			server->priority += 10;
		}
	}


}
Esempio n. 2
0
struct chirp_matrix *chirp_matrix_create(const char *host, const char *path, int width, int height, int element_size, int nhosts, time_t stoptime)
{
	char host_file[CHIRP_LINE_MAX];
	int result;
	unsigned int i;
	char **hosts;

	int nfiles = nhosts;
	while(1) {
		INT64_T n_row_per_file = height / nfiles;
		if(height % nfiles)
			n_row_per_file++;
		INT64_T file_size = n_row_per_file * width * element_size;
		if(file_size > GIGABYTE) {
			nfiles *= 2;
			continue;
		} else {
			break;
		}
	}

	char line[CHIRP_LINE_MAX * nfiles];

	FILE *file = NULL;
	if(getenv("CHIRP_HOSTS")) {
		sprintf(host_file, "%s", getenv("CHIRP_HOSTS"));
		file = fopen(host_file, "r");
	}

	if(!file) {
		if(getenv("HOME")) {
			sprintf(host_file, "%s/.chirp/hosts", getenv("HOME"));
			file = fopen(host_file, "r");
		}
	}

	if(!file) {
		sprintf(host_file, "./chirp_hosts");
		file = fopen(host_file, "r");
		if(!file) {
			file = fopen(host_file, "w");
			char hostname[CHIRP_LINE_MAX];
			gethostname(hostname, CHIRP_LINE_MAX - 1);	// get hostname, this may not have domain name, though!
			fprintf(file, "%s\n", hostname);
			fclose(file);
			file = fopen(host_file, "r");
		}
	}


	if(!file) {
		debug(D_NOTICE | D_CHIRP, "matrix: could not open host list in %s: %s\n", host_file, strerror(errno));
		errno = EINVAL;
		return 0;
	}

	hosts = malloc(sizeof(*hosts) * nhosts);

	for(i = 0; (int) i < nhosts; i++) {
		if(!fgets(line, sizeof(line), file)) {
			rewind(file);
			fgets(line, sizeof(line), file);
		}
		hosts[i] = strdup(line);
		int len = strlen(hosts[i]);
		hosts[i][len - 1] = '\0';
	}

	fclose(file);

	sprintf(line, "%d\n%d\n%d\n%d\n%d\n", width, height, element_size, nhosts, nfiles);

	char datapath1[CHIRP_LINE_MAX];
	char datapath2[CHIRP_LINE_MAX];
	char datapath3[CHIRP_LINE_MAX];
	char username[USERNAME_MAX];

	char cookie[16];

	username_get(username);
	string_cookie(cookie, sizeof(cookie));

	sprintf(datapath1, "/%s", username);
	sprintf(datapath2, "/%s/matrixdata", username);
	sprintf(datapath3, "/%s/matrixdata/%s", username, cookie);

	for(i = 0; (int) i < nfiles; i++) {
		const char *datahost = hosts[i % nhosts];
		result = chirp_reli_mkdir(datahost, datapath1, 0700, stoptime);
		result = chirp_reli_mkdir(datahost, datapath2, 0700, stoptime);
		result = chirp_reli_mkdir(datahost, datapath3, 0700, stoptime);

		sprintf(&line[strlen(line)], "%s %s/data.%d\n", datahost, datapath3, i);
	}

	for(i = 0; (int) i < nhosts; i++) {
		free(hosts[i]);
	}
	free(hosts);

	char metapath[CHIRP_LINE_MAX];
	strcpy(metapath, path);
	result = chirp_reli_putfile_buffer(host, path, line, 0700, strlen(line), stoptime);
	if(result < 0) {
		for(i = 1; i < strlen(metapath); i++)
			if(metapath[i] == '/') {
				metapath[i] = '\0';
				result = chirp_reli_mkdir(host, metapath, 0700, stoptime);
				if(result < 0 && errno != EEXIST) {
					debug(D_CHIRP, "matrix: could not build directory /chirp/%s/%s to create metadata file: %s\n", host, metapath, strerror(errno));
					return 0;
				}
				metapath[i] = '/';
			}
		result = chirp_reli_putfile_buffer(host, path, line, 0700, strlen(line), stoptime);
		if(result < 0) {
			debug(D_CHIRP, "matrix: could not create metadata file /chirp/%s/%s: %s\n", host, path, strerror(errno));
			return 0;
		}
	}
	debug(D_CHIRP, "matrix: created matrix %s/%s -- now opening\n", host, path);
	return chirp_matrix_open(host, path, stoptime);
}