1 /**
2 * collectd - src/drbd.c
3 * Copyright (C) 2014 Tim Laszlo
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Tim Laszlo <tim.laszlo at gmail.com>
25 **/
27 /*
28 See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
30 version: 8.3.11 (api:88/proto:86-96)
31 srcversion: 71955441799F513ACA6DA60
32 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
33 ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
34 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
35 */
37 #include "collectd.h"
38 #include "common.h"
39 #include "plugin.h"
41 static const char *drbd_stats = "/proc/drbd";
42 static const char *drbd_names[] =
43 {
44 "network_send", /* ns (network send) */
45 "network_recv", /* nr (network receive) */
46 "disk_write", /* dw (disk write) */
47 "disk_read", /* dr (disk read) */
48 "activity_log", /* al (activity log) */
49 "bitmap", /* bm (bit map) */
50 "local_count", /* lo (local count) */
51 "pending", /* pe (pending) */
52 "unacknowledged", /* ua (unacknowledged) */
53 "app pending", /* ap (application pending) */
54 "epochs", /* ep (epochs) */
55 NULL, /* wo (write order) */
56 "oos" /* oos (out of sync) */
57 };
58 static size_t drbd_names_num = STATIC_ARRAY_SIZE (drbd_names);
60 static int drbd_init (void)
61 {
62 return (0);
63 }
66 static int drbd_submit_fields (long int resource,
67 char **fields, size_t fields_num)
68 {
69 char plugin_instance[DATA_MAX_NAME_LEN];
70 value_t values[fields_num];
71 value_list_t vl = VALUE_LIST_INIT;
72 size_t i;
74 if (resource < 0)
75 {
76 WARNING ("drbd plugin: Unable to parse resource");
77 return (EINVAL);
78 }
80 if (fields_num != drbd_names_num)
81 {
82 WARNING ("drbd plugin: Wrong number of fields for "
83 "r%ld statistics. Expected %zu, got %zu.",
84 resource, drbd_names_num, fields_num);
85 return (EINVAL);
86 }
88 ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
89 resource);
91 for (i = 0; i < drbd_names_num; i++)
92 {
93 char *data;
94 /* skip non numeric wo */
95 if (strncmp(fields[i], "wo", 2) == 0)
96 continue;
97 data = strchr(fields[i], ':');
98 if (data == NULL)
99 return (EINVAL);
100 (void) parse_value (++data, &values[i], DS_TYPE_DERIVE);
101 }
103 vl.values_len = 1;
104 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
105 sstrncpy (vl.plugin, "drbd", sizeof (vl.plugin));
106 sstrncpy (vl.plugin_instance, plugin_instance,
107 sizeof (vl.plugin_instance));
108 sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
110 for (i = 0; i < fields_num; i++)
111 {
112 if (drbd_names[i] == NULL)
113 continue;
114 vl.values = values + i;
115 sstrncpy (vl.type_instance, drbd_names[i],
116 sizeof (vl.type_instance));
117 plugin_dispatch_values (&vl);
118 }
120 return (0);
121 } /* drbd_submit_fields */
123 static int drbd_read (void)
124 {
125 FILE *fh;
126 char buffer[256];
128 long int resource = -1;
129 char *fields[16];
130 int fields_num = 0;
132 fh = fopen (drbd_stats, "r");
133 if (fh == NULL)
134 {
135 WARNING ("drbd plugin: Unable to open %s", drbd_stats);
136 return (EINVAL);
137 }
139 while (fgets (buffer, sizeof (buffer), fh) != NULL)
140 {
141 fields_num = strsplit (buffer,
142 fields, STATIC_ARRAY_SIZE (fields));
144 /* ignore headers (first two iterations) */
145 if ((strcmp(fields[0], "version:") == 0) ||
146 (strcmp(fields[0], "srcversion:") == 0) ||
147 (strcmp(fields[0], "GIT-hash:") == 0))
148 {
149 continue;
150 }
152 if (isdigit(fields[0][0]))
153 {
154 /* parse the resource line, next loop iteration
155 will submit values for this resource */
156 resource = strtol(fields[0], NULL, 10);
157 }
158 else
159 {
160 /* handle stats data for the resource defined in the
161 previous iteration */
162 drbd_submit_fields(resource, fields, fields_num);
163 }
164 } /* while (fgets) */
166 fclose (fh);
167 return (0);
168 } /* void drbd_read */
170 void module_register (void)
171 {
172 plugin_register_init ("drbd", drbd_init);
173 plugin_register_read ("drbd", drbd_read);
174 } /* void module_register */