Пример #1
0
int ghostfs_sync(struct ghostfs *gfs)
{
	struct cluster *c;
	int ret, i;

	ret = cluster_get(gfs, 0, &c);
	if (ret < 0)
		return ret;

	ret = write_header(gfs, c);
	if (ret < 0)
		return ret;

	if (!gfs->clusters) // nothing more to sync
		return 0;

	for (i = 1; i < gfs->hdr.cluster_count; i++) {
		c = gfs->clusters[i];

		if (!c || !cluster_dirty(c))
			continue;

		ret = write_cluster(gfs, c, i);
		if (ret < 0)
			return ret;
	}

	return 0;
}
Пример #2
0
static int cluster_get_next(struct ghostfs *gfs, struct cluster **pcluster)
{
	if ((*pcluster)->hdr.next == 0) {
		warnx("fs: cluster missing, bad filesystem");
		return -EIO;
	}

	return cluster_get(gfs, (*pcluster)->hdr.next, pcluster);
}
int	check_vcenter_hv_discovery(AGENT_REQUEST *request, const char *username, const char *password,
		AGENT_RESULT *result)
{
	struct zbx_json		json_data;
	int			i, ret = SYSINFO_RET_FAIL;
	char			*url, *name;
	zbx_vmware_service_t	*service;

	if (1 != request->nparam)
		return SYSINFO_RET_FAIL;

	url = get_rparam(request, 0);

	zbx_vmware_lock();

	if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
		goto unlock;

	zbx_json_init(&json_data, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addarray(&json_data, ZBX_PROTO_TAG_DATA);

	for (i = 0; i < service->data->hvs.values_num; i++)
	{
		zbx_vmware_cluster_t	*cluster = NULL;
		zbx_vmware_hv_t	*hv = (zbx_vmware_hv_t *)service->data->hvs.values[i];

		if (NULL == (name = zbx_xml_read_value(hv->details, ZBX_XPATH_LN2("config", "name"))))
			continue;

		if (NULL != hv->clusterid)
			cluster = cluster_get(&service->data->clusters, hv->clusterid);

		zbx_json_addobject(&json_data, NULL);
		zbx_json_addstring(&json_data, "{#HV.UUID}", hv->uuid, ZBX_JSON_TYPE_STRING);
		zbx_json_addstring(&json_data, "{#HV.ID}", hv->id, ZBX_JSON_TYPE_STRING);
		zbx_json_addstring(&json_data, "{#HV.NAME}", name, ZBX_JSON_TYPE_STRING);
		zbx_json_addstring(&json_data, "{#CLUSTER.NAME}",
				(NULL != cluster ? cluster->name : ""), ZBX_JSON_TYPE_STRING);
		zbx_json_close(&json_data);

		zbx_free(name);
	}

	zbx_json_close(&json_data);

	SET_STR_RESULT(result, zbx_strdup(NULL, json_data.buffer));

	zbx_json_free(&json_data);

	ret = SYSINFO_RET_OK;
unlock:
	zbx_vmware_unlock();

	return ret;
}
Пример #4
0
static int dir_iter_init(struct ghostfs *gfs, struct dir_iter *it, int cluster_nr)
{
	int ret;

	ret = cluster_get(gfs, cluster_nr, &it->cluster);
	if (ret < 0)
		return ret;

	it->gfs = gfs;
	it->entry = (struct dir_entry *)it->cluster->data;
	it->entry_nr = 0;
	return 0;
}
Пример #5
0
int ghostfs_mount(struct ghostfs **pgfs, struct stegger *stegger)
{
	struct ghostfs *gfs;
	int i, ret;

	gfs = calloc(1, sizeof(*gfs));
	if (!gfs)
		return -ENOMEM;

	gfs->stegger = stegger;
	gfs->root_entry.size = 0x80000000;

	ret = ghostfs_check(gfs);
	if (ret < 0) {
		ghostfs_free(gfs);
		return ret;
	}

	gfs->clusters = calloc(1, sizeof(struct cluster *) * gfs->hdr.cluster_count);
	if (!gfs->clusters) {
		ghostfs_free(gfs);
		return -ENOMEM;
	}

	gfs->uid = getuid();
	gfs->gid = getgid();
	time(&gfs->mount_time);

	// check free clusters
	for (i = 1; i < gfs->hdr.cluster_count; i++) {
		struct cluster *c;

		ret = cluster_get(gfs, i, &c);
		if (ret < 0) {
			ghostfs_free(gfs);
			return ret;
		}

		if (!c->hdr.used)
			gfs->free_clusters++;
	}

	*pgfs = gfs;

	return 0;
}
int	check_vcenter_vm_cluster_name(AGENT_REQUEST *request, const char *username, const char *password,
		AGENT_RESULT *result)
{
	int			i, ret = SYSINFO_RET_FAIL;
	char			*url, *uuid;
	zbx_vmware_service_t	*service;
	zbx_vmware_cluster_t	*cluster = NULL;

	if (2 != request->nparam)
		return SYSINFO_RET_FAIL;

	url = get_rparam(request, 0);
	uuid = get_rparam(request, 1);

	if ('\0' == *uuid)
		return SYSINFO_RET_FAIL;

	zbx_vmware_lock();

	if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
		goto unlock;

	for (i = 0; i < service->data->hvs.values_num; i++)
	{
		zbx_vmware_hv_t	*hv = service->data->hvs.values[i];
		zbx_vmware_vm_t		*vm;

		if (NULL != (vm = vm_get(&hv->vms, uuid)))
		{
			if (NULL != hv->clusterid)
				cluster = cluster_get(&service->data->clusters, hv->clusterid);

			break;
		}
	}

	SET_STR_RESULT(result, zbx_strdup(NULL, NULL != cluster ? cluster->name : ""));

	ret = SYSINFO_RET_OK;
unlock:
	zbx_vmware_unlock();

	return ret;
}
Пример #7
0
// cluster_at returns the cluster at the given index starting from cluster nr
static int cluster_at(struct ghostfs *gfs, int nr, int index, struct cluster **pcluster)
{
	struct cluster *c = NULL;
	int ret, i;

	for (i = 0; i <= index; i++) {
		if (!nr) {
			warnx("fs: cluster missing, bad filesystem");
			return -EIO;
		}

		ret = cluster_get(gfs, nr, &c);
		if (ret < 0)
			return ret;

		nr = c->hdr.next;
	}

	*pcluster = c;

	return 0;
}
Пример #8
0
static int free_clusters(struct ghostfs *gfs, struct cluster *c)
{
	int ret;

	for (;;) {
		c->hdr.used = 0;
		cluster_set_dirty(c, true);
		gfs->free_clusters++;

		if (!c->hdr.next)
			break;

		ret = cluster_get(gfs, c->hdr.next, &c);
		if (ret < 0) {
			errno = -ret;
			warn("failed to free cluster");
			return ret;
		}
	}

	return 0;
}
int	check_vcenter_hv_cluster_name(AGENT_REQUEST *request, const char *username, const char *password,
		AGENT_RESULT *result)
{
	char			*url, *uuid;
	zbx_vmware_hv_t		*hv;
	zbx_vmware_service_t	*service;
	int			ret = SYSINFO_RET_FAIL;
	zbx_vmware_cluster_t	*cluster = NULL;

	if (2 != request->nparam)
		return SYSINFO_RET_FAIL;

	url = get_rparam(request, 0);
	uuid = get_rparam(request, 1);

	if ('\0' == *uuid)
		return SYSINFO_RET_FAIL;

	zbx_vmware_lock();

	if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
		goto unlock;

	if (NULL == (hv = hv_get(&service->data->hvs, uuid)))
		goto unlock;

	if (NULL != hv->clusterid)
		cluster = cluster_get(&service->data->clusters, hv->clusterid);

	SET_STR_RESULT(result, zbx_strdup(NULL, NULL != cluster ? cluster->name : ""));

	ret = SYSINFO_RET_OK;
unlock:
	zbx_vmware_unlock();

	return ret;
}
Пример #10
0
static int do_truncate(struct ghostfs *gfs, struct dir_iter *it, off_t new_size)
{
	int ret;
	int count;
	int next;
	struct cluster *c = NULL;

	if (new_size < 0)
		return -EINVAL;

	if (new_size > FILESIZE_MAX)
		return -EFBIG;

	if (dir_entry_is_directory(it->entry))
		return -EISDIR;

	next = it->entry->cluster;
	count = size_to_clusters(min(it->entry->size, new_size));

	if (count) {
		ret = cluster_at(gfs, next, count - 1, &c);
		if (ret < 0)
			return ret;

		next = c->hdr.next;
	}

	if (new_size > it->entry->size) {
		int alloc;
		long used = it->entry->size % CLUSTER_DATA;

		// zero remaining cluster space
		if (used) {
			memset(c->data + used, 0, CLUSTER_DATA - used);
			cluster_set_dirty(c, true);
		}

		alloc = size_to_clusters(new_size) - count;
		if (alloc) {
			ret = alloc_clusters(gfs, alloc, NULL, true);
			if (ret < 0)
				return ret;

			if (c) {
				c->hdr.next = ret;
				cluster_set_dirty(c, true);
			} else {
				it->entry->cluster = ret;
			}
		}
	} else if (new_size < it->entry->size) {
		if (next) {
			if (c) {
				c->hdr.next = 0;
				cluster_set_dirty(c, true);
			}

			ret = cluster_get(gfs, next, &c);
			if (ret < 0)
				return ret;

			free_clusters(gfs, c);
		}
	}

	dir_entry_set_size(it->entry, new_size, false);
	cluster_set_dirty(it->cluster, true);

	return 0;
}
Пример #11
0
// allocates a list of clusters
static int alloc_clusters(struct ghostfs *gfs, int count, struct cluster **pfirst, bool zero)
{
	struct cluster *prev = NULL;
	struct cluster *c;
	int first = 0;
	int pos = 1;
	int alloc = 0;
	int ret;

	while (alloc < count) {
		for (;;) {
			if (pos >= gfs->hdr.cluster_count) {
				ret = -ENOSPC;
				goto undo;
			}

			ret = cluster_get(gfs, pos, &c);
			if (ret < 0)
				goto undo;

			if (!c->hdr.used) {
				if (zero)
					memset(c->data, 0, sizeof(c->data));

				c->hdr.used = 1;
				cluster_set_dirty(c, true);
				gfs->free_clusters--;

				if (!first) {
					first = pos;
					if (pfirst)
						*pfirst = c;
				} else {
					prev->hdr.next = pos;
				}
				prev = c;
				pos++;
				break;
			}
			pos++;
		}
		alloc++;
	}

	prev->hdr.next = 0;

	return first;
undo:
	pos = first;

	while (alloc > 0) {
		int r = cluster_get(gfs, pos, &c);
		if (r < 0)
			return r;

		c->hdr.used = 0;
		cluster_set_dirty(c, true);
		gfs->free_clusters++;

		pos = c->hdr.next;
		alloc--;
	}

	return ret;
}