cmogstored.git  about / heads / tags
alternative mogstored implementation for MogileFS
blob 93f39cef935b5467983087155490262e45974e71 2068 bytes (raw)
$ git show HEAD:iostat.c	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
/*
 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 */

/*
 * iostat(1) -> global mountlist -> each mog_dev in each mog_svc
 */
#include "cmogstored.h"

/* called after a stats line for a single device is complete */
void mog_iostat_line_done(struct mog_iostat *iostat)
{
	if (iostat->dev_tip < sizeof(iostat->dev)) {
		iostat->dev[iostat->dev_tip] = 0;
		if (iostat->util_tip < sizeof(iostat->util)) {
			iostat->util[iostat->util_tip] = 0;
		} else {
			iostat->util[0] = '-';
			iostat->util[1] = 0;
		}

		mog_mnt_update_util(iostat);
	} else {
		syslog(LOG_ERR, "device name from iostat too long");
	}
}

/* called every second, after stats for each device line are out */
void mog_iostat_commit(void)
{
	mog_svc_each(mog_svc_devstats_broadcast, NULL);
}

static void iostat_close(struct mog_fd *mfd)
{
	assert(mfd->fd_type == MOG_FD_TYPE_IOSTAT && "bad fd_type");
	mog_fd_put(mfd);
}

static void iostat_reset(struct mog_iostat *iostat)
{
	bool ready = iostat->ready;
	mog_iostat_init(iostat);
	iostat->ready = ready;
}

void mog_iostat_queue_step(struct mog_fd *mfd)
{
	/*
	 * only one thread ever hits this function at once,
	 * no point in ever running multiple iostat(1) processes
	 */
	static char buf[1024];
	ssize_t r;
	struct mog_iostat *iostat = &mfd->as.iostat;

	assert(mfd->fd >= 0 && mfd->fd_type == MOG_FD_TYPE_IOSTAT &&
	       "bad iostat mfd");
retry:
	r = read(mfd->fd, buf, sizeof(buf));
	if (r > 0) {
		switch (mog_iostat_parse(iostat, buf, r)) {
		case MOG_PARSER_ERROR:
			syslog(LOG_ERR, "iostat parser error");
			iostat_close(mfd);
			return;
		case MOG_PARSER_DONE:
			iostat_reset(iostat);
			goto retry;
		case MOG_PARSER_CONTINUE:
			goto retry;
		}
	} else if (r == 0) {
		/* iostat exits every 30s by default */
		iostat_close(mfd);
	} else {
		switch (errno) {
		case_EAGAIN:
			mog_idleq_push(iostat->queue, mfd, MOG_QEV_RD);
			return;
		case EINTR: goto retry;
		}
		syslog(LOG_ERR, "iostat read() failed: %m");
		iostat_close(mfd);
	}
}

git clone https://yhbt.net/cmogstored.git