drbd plugin: replace atoi with strtol
[collectd.git] / src / drbd.c
1 /**
2  * collectd - src/drbd.c
3  * Copyright (C) 2014  Tim Laszlo
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; only version 2 of the License is applicable.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  * Authors:
19  *   Tim Laszlo <tim.laszlo at gmail.com>
20  **/
21
22 /*
23  See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
24
25  version: 8.3.11 (api:88/proto:86-96)
26  srcversion: 71955441799F513ACA6DA60 
27   0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
28          ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
29                                                 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
30  */
31
32 #include "collectd.h"
33 #include "common.h"
34 #include "plugin.h"
35
36 static const char *drbd_stats = "/proc/drbd";
37 static const char *drbd_names[] =
38 {
39         "network_send",  /* ns (network send) */
40         "network_recv",  /* nr (network receive) */
41         "disk_write",      /* dw (disk write) */
42         "disk_read",            /* dr (disk read) */
43         "activity_log",  /* al (activity log) */
44         "bitmap",                  /* bm (bit map) */
45         "local_count",    /* lo (local count) */
46         "pending",                /* pe (pending) */
47         "unacknowledged",   /* ua (unacknowledged) */
48         "app pending",    /* ap (application pending) */
49         "epochs",                  /* ep (epochs) */
50         NULL,                      /* wo (write order) */
51         "oos"                      /* oos (out of sync) */
52 };
53 static size_t drbd_names_num = STATIC_ARRAY_SIZE (drbd_names);
54
55 static int drbd_init (void)
56 {
57         return (0);
58 }
59
60
61 static int drbd_submit_fields (long int resource,
62                 char **fields, size_t fields_num)
63 {
64         char plugin_instance[DATA_MAX_NAME_LEN];
65         value_t values[fields_num];
66         value_list_t vl = VALUE_LIST_INIT;
67         size_t i;
68
69         if (resource < 0)
70         {
71                 WARNING ("drbd plugin: Unable to parse resource");
72                 return (EINVAL);
73         }
74
75         if (fields_num != drbd_names_num)
76         {
77                 WARNING ("drbd plugin: Wrong number of fields for "
78                                  "r%ld statistics. Expected %zu, got %zu.",
79                                  resource, drbd_names_num, fields_num);
80                 return (EINVAL);
81         }
82
83         ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
84                         resource);
85
86         for (i = 0; i < drbd_names_num; i++)
87         {
88                 char *data;
89                 /* skip non numeric wo */
90                 if (strncmp(fields[i], "wo", 2) == 0)
91                         continue;
92                 data = strchr(fields[i], ':');
93                 if (data == NULL)
94                         return (EINVAL);
95                 (void) parse_value (++data, &values[i], DS_TYPE_DERIVE);
96         }
97
98         vl.values_len = 1;
99         sstrncpy (vl.host, hostname_g, sizeof (vl.host));
100         sstrncpy (vl.plugin, "drbd", sizeof (vl.plugin));
101         sstrncpy (vl.plugin_instance, plugin_instance,
102                         sizeof (vl.plugin_instance));
103         sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
104
105         for (i = 0; i < fields_num; i++)
106         {
107                 if (drbd_names[i] == NULL)
108                         continue;
109                 vl.values = values + i;
110                 sstrncpy (vl.type_instance, drbd_names[i],
111                                 sizeof (vl.type_instance));
112                 plugin_dispatch_values (&vl);
113         }
114
115         return (0);
116 } /* drbd_submit_fields */
117
118 static int drbd_read (void)
119 {
120         FILE *fh;
121         char buffer[256];
122
123         long int resource = -1;
124         char *fields[16];
125         int fields_num = 0;
126
127         fh = fopen (drbd_stats, "r");
128         if (fh == NULL)
129         {
130                 WARNING ("Unable to open%s", drbd_stats);
131                 return (EINVAL);
132         }
133
134         while (fgets (buffer, sizeof (buffer), fh) != NULL)
135         {
136                 fields_num = strsplit (buffer,
137                                 fields, STATIC_ARRAY_SIZE (fields));
138
139                 /* ignore headers */
140                 if (fields_num < 4)
141                         continue;
142
143                 if (isdigit(fields[0][0]))
144                 {
145                         /* parse the resource line */
146                         resource = strtol(fields[0], NULL, 10);
147                 }
148                 else
149                 {
150                         /* handle stats data */
151                         drbd_submit_fields(resource, fields, fields_num);
152                 }
153         } /* while (fgets) */
154
155         fclose (fh);
156         return (0);
157 } /* void drbd_read */
158
159 void module_register (void)
160 {
161         plugin_register_init ("drbd", drbd_init);
162         plugin_register_read ("drbd", drbd_read);
163 } /* void module_register */