コード例 #1
0
ファイル: stats.c プロジェクト: HoraceWeebler/connman
static int stats_file_setup(struct stats_file *file)
{
	struct stats_file_header *hdr;
	struct stat st;
	size_t size = 0;
	int err;

	DBG("file %p fd %d name %s", file, file->fd, file->name);

	err = fstat(file->fd, &st);
	if (err < 0) {
		connman_error("fstat error %s for %s\n",
			strerror(errno), file->name);

		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return -errno;
	}

	size = (size_t)st.st_size;
	file->max_len = STATS_MAX_FILE_SIZE;

	if (size < (size_t)sysconf(_SC_PAGESIZE))
		size = sysconf(_SC_PAGESIZE);

	err = stats_file_remap(file, size);
	if (err < 0) {
		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return err;
	}

	hdr = get_hdr(file);

	if (hdr->magic != MAGIC ||
			hdr->begin < sizeof(struct stats_file_header) ||
			hdr->end < sizeof(struct stats_file_header) ||
			hdr->home < sizeof(struct stats_file_header) ||
			hdr->roaming < sizeof(struct stats_file_header) ||
			hdr->begin > file->len ||
			hdr->end > file->len) {
		hdr->magic = MAGIC;
		hdr->begin = sizeof(struct stats_file_header);
		hdr->end = sizeof(struct stats_file_header);
		hdr->home = UINT_MAX;
		hdr->roaming = UINT_MAX;

		stats_file_update_cache(file);
	}

	return 0;
}
コード例 #2
0
ファイル: stats-tool.c プロジェクト: HoraceWeebler/connman
static int append_record(struct stats_file *file,
				struct stats_record *rec)
{
	struct stats_record *cur, *next;
	int err;

	if (file->last == get_end(file)) {
		err = stats_file_remap(file, file->len +
					sysconf(_SC_PAGESIZE));
		if (err < 0)
			return err;

		stats_file_update_cache(file);
	}

	cur = get_end(file);
	next = get_next(file, cur);

	memcpy(next, rec, sizeof(struct stats_record));

	set_end(file, next);

	return 0;
}
コード例 #3
0
ファイル: stats-tool.c プロジェクト: HoraceWeebler/connman
static int stats_create(struct stats_file *file, unsigned int nr,
			unsigned int interval, time_t start_ts,
			struct stats_record *start)
{
	unsigned int i;
	int err;
	struct stats_record *cur, *next;
	struct stats_file_header *hdr;
	unsigned int pkt;
	unsigned int step_ts;
	unsigned int roaming = FALSE;

	hdr = get_hdr(file);

	hdr->magic = MAGIC;
	hdr->begin = sizeof(struct stats_file_header);
	hdr->end = sizeof(struct stats_file_header);
	hdr->home = UINT_MAX;
	hdr->roaming = UINT_MAX;

	stats_file_update_cache(file);

	if (start) {
		struct stats_record *rec;

		rec = get_end(file);
		memcpy(rec, start, sizeof(struct stats_record));
	} else {
		get_end(file)->ts = start_ts;
	}

	for (i = 0; i < nr; i++) {
		if (file->last == get_end(file)) {
			err = stats_file_remap(file, file->len +
						sysconf(_SC_PAGESIZE));
			if (err < 0)
				return err;

			stats_file_update_cache(file);
		}
		cur = get_end(file);
		next = get_next(file, cur);

		step_ts = (rand() % interval);
		if (step_ts == 0)
			step_ts = 1;

		next->ts = cur->ts + step_ts;
		next->roaming = roaming;
		next->data.time = cur->data.time + step_ts;

		next->data.rx_packets = cur->data.rx_packets;
		next->data.rx_bytes = cur->data.rx_bytes;

		if (rand() % 3 == 0) {
			pkt = rand() % 5;
			next->data.rx_packets += pkt;
			next->data.rx_bytes += pkt * (rand() % 1500);
		}

		next->data.tx_packets = cur->data.tx_packets;
		next->data.tx_bytes = cur->data.tx_bytes;

		if (rand() % 3 == 0) {
			pkt = rand() % 5;
			next->data.tx_packets += pkt;
			next->data.tx_bytes += pkt * (rand() % 1500);
		}

		set_end(file, next);

		if ((rand() % 50) == 0)
			roaming = roaming ? FALSE : TRUE;

	}

	return 0;
}
コード例 #4
0
ファイル: stats-tool.c プロジェクト: HoraceWeebler/connman
static int stats_open(struct stats_file *file, const char *name)
{
	struct stats_file_header *hdr;
	struct stat tm;
	int err;
	size_t size = 0;

	bzero(file, sizeof(struct stats_file));

	if (name) {
		file->name = g_strdup(name);

		file->fd = TFR(open(file->name,
					O_RDWR | O_CREAT | O_CLOEXEC, 0644));
		if (file->fd == -1) {
			fprintf(stderr, "open error %s for %s\n",
				strerror(errno), file->name);
			return -errno;
		}

		err = fstat(file->fd, &tm);
		if (err < 0) {
			fprintf(stderr, "fstat error %s for %s\n",
				strerror(errno), file->name);
			return err;
		}

		size = (size_t)tm.st_size;
	} else {
		file->name = g_strdup("stats.XXXXXX.tmp");
		file->fd = g_mkstemp_full(file->name, O_RDWR | O_CREAT, 0644);
		if (file->fd == -1) {
			fprintf(stderr, "creating tmp failed\n");
			return -1;
		}
	}

	if (size == 0)
		size = sysconf(_SC_PAGESIZE);

	err = stats_file_remap(file, size);
	if (err < 0) {
		fprintf(stderr, "remap failed\n");
		return err;
	}

	/* Initialize new file */
	hdr = get_hdr(file);
	if (hdr->magic != MAGIC ||
			hdr->begin < sizeof(struct stats_file_header) ||
			hdr->end < sizeof(struct stats_file_header) ||
			hdr->home < sizeof(struct stats_file_header) ||
			hdr->roaming < sizeof(struct stats_file_header) ||
			hdr->begin > file->len ||
			hdr->end > file->len) {
		hdr->magic = MAGIC;
		hdr->begin = sizeof(struct stats_file_header);
		hdr->end = sizeof(struct stats_file_header);
		hdr->home = UINT_MAX;
		hdr->roaming = UINT_MAX;

	}
	stats_file_update_cache(file);

	return 0;
}
コード例 #5
0
ファイル: stats.c プロジェクト: saukko/connman
static void stats_convert(struct stats_file *file)
{
	struct stats_file temp_file;
	int err;

	DBG("converting data file %s", file->name);

	stats_file_update_cache32(file);

	bzero(&temp_file, sizeof(struct stats_file));

	err = stats_open_temp(&temp_file);
	if (err < 0) {
		connman_error("failed to open temporary file during data conversion");
		return;
	}
	stats_file_setup(&temp_file);

	struct stats_iter32 data_iter;
	struct stats_record32 *record;

	data_iter.file = file;
	data_iter.begin = get_iterator_begin32(data_iter.file);
	data_iter.end = get_iterator_end32(data_iter.file);
	data_iter.it = data_iter.begin;

	record = get_next_record32(&data_iter);
	while (record) {
		struct stats_record *next;

		if (temp_file.last == get_end(&temp_file)) {
			err = stats_file_remap(&temp_file, temp_file.len + sysconf(_SC_PAGESIZE));
			if (err < 0) {
				connman_error("failed to extend file %s", temp_file.name);
				unlink(temp_file.name);
				stats_file_unmap(&temp_file);
				TFR(close(temp_file.fd));
				stats_file_cleanup(&temp_file);
				return;
			}

			stats_file_update_cache(&temp_file);
		}

		next = get_next(&temp_file, get_end(&temp_file));
		if (next == get_begin(&temp_file)) {
			connman_error("ring buffer is full");
			unlink(temp_file.name);
            stats_file_unmap(&temp_file);
			TFR(close(temp_file.fd));
			stats_file_cleanup(&temp_file);
			return;
		}

		next->ts = record->ts;
		next->roaming = record->roaming;
		next->data.rx_packets = record->data.rx_packets;
		next->data.tx_packets = record->data.tx_packets;
		next->data.rx_bytes = record->data.rx_bytes;
		next->data.tx_bytes = record->data.tx_bytes;
		next->data.rx_errors = record->data.rx_errors;
		next->data.tx_errors = record->data.tx_errors;
		next->data.rx_dropped = record->data.rx_dropped;
		next->data.tx_dropped = record->data.tx_dropped;
		next->data.time = record->data.time;

		if (next->roaming)
			set_roaming(&temp_file, next);
		else
			set_home(&temp_file, next);

		set_end(&temp_file, next);

		record = get_next_record32(&data_iter);
	}

	// close and swap
	stats_file_unmap(file);
	TFR(close(file->fd));
	err = rename(temp_file.name, file->name);
	if (err < 0)
		connman_error("failed to rename converted data file %s to %s", temp_file.name, file->name);

	g_free(temp_file.name);
	temp_file.name = file->name;

	memcpy(file, &temp_file, sizeof(struct stats_file));
}
コード例 #6
0
ファイル: stats.c プロジェクト: saukko/connman
static int stats_file_setup(struct stats_file *file)
{
	struct stats_file_header *hdr;
	struct stat st;
	size_t size = 0;
	int err;

	DBG("file %p fd %d name %s", file, file->fd, file->name);

	err = fstat(file->fd, &st);
	if (err < 0) {
		connman_error("fstat error %s for %s\n",
			strerror(errno), file->name);

		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return -errno;
	}

	size = (size_t)st.st_size;
	file->max_len = STATS_MAX_FILE_SIZE;

	if (size < (size_t)sysconf(_SC_PAGESIZE))
		size = sysconf(_SC_PAGESIZE);

	err = stats_file_remap(file, size);
	if (err < 0) {
		TFR(close(file->fd));
		g_free(file->name);
		file->name = NULL;

		return err;
	}

	hdr = get_hdr(file);

	/* Check if data file is in old format and convert */
	if (hdr->magic == MAGIC32 &&
			hdr->begin >= sizeof(struct stats_file_header) &&
			hdr->end >= sizeof(struct stats_file_header) &&
			hdr->home >= sizeof(struct stats_file_header) &&
			hdr->roaming >= sizeof(struct stats_file_header) &&
			hdr->begin <= file->len &&
			hdr->end <= file->len) {
			stats_convert(file);
			/* conversion changes the mapped address */
			hdr = get_hdr(file);
	}

	if (hdr->magic != MAGIC64 ||
			hdr->begin < sizeof(struct stats_file_header) ||
			hdr->end < sizeof(struct stats_file_header) ||
			hdr->home < sizeof(struct stats_file_header) ||
			hdr->roaming < sizeof(struct stats_file_header) ||
			hdr->begin > file->len ||
			hdr->end > file->len) {
		hdr->magic = MAGIC64;
		hdr->begin = sizeof(struct stats_file_header);
		hdr->end = sizeof(struct stats_file_header);
		hdr->home = UINT_MAX;
		hdr->roaming = UINT_MAX;

		stats_file_update_cache(file);
	}

	return 0;
}