- FILE *fh;
- char buffer[1024];
-
- char *fields[32];
- int numfields;
- int fieldshift = 0;
-
- int minor = 0;
-
- derive_t read_sectors = 0;
- derive_t write_sectors = 0;
-
- derive_t read_ops = 0;
- derive_t read_merged = 0;
- derive_t read_time = 0;
- derive_t write_ops = 0;
- derive_t write_merged = 0;
- derive_t write_time = 0;
- int is_disk = 0;
-
- diskstats_t *ds, *pre_ds;
-
- if ((fh = fopen ("/proc/diskstats", "r")) == NULL)
- {
- fh = fopen ("/proc/partitions", "r");
- if (fh == NULL)
- {
- ERROR ("disk plugin: fopen (/proc/{diskstats,partitions}) failed.");
- return (-1);
- }
-
- /* Kernel is 2.4.* */
- fieldshift = 1;
- }
-
- while (fgets (buffer, sizeof (buffer), fh) != NULL)
- {
- char *disk_name;
-
- numfields = strsplit (buffer, fields, 32);
-
- if ((numfields != (14 + fieldshift)) && (numfields != 7))
- continue;
-
- minor = atoll (fields[1]);
-
- disk_name = fields[2 + fieldshift];
-
- for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next)
- if (strcmp (disk_name, ds->name) == 0)
- break;
-
- if (ds == NULL)
- {
- if ((ds = (diskstats_t *) calloc (1, sizeof (diskstats_t))) == NULL)
- continue;
-
- if ((ds->name = strdup (disk_name)) == NULL)
- {
- free (ds);
- continue;
- }
-
- if (pre_ds == NULL)
- disklist = ds;
- else
- pre_ds->next = ds;
- }
-
- is_disk = 0;
- if (numfields == 7)
- {
- /* Kernel 2.6, Partition */
- read_ops = atoll (fields[3]);
- read_sectors = atoll (fields[4]);
- write_ops = atoll (fields[5]);
- write_sectors = atoll (fields[6]);
- }
- else if (numfields == (14 + fieldshift))
- {
- read_ops = atoll (fields[3 + fieldshift]);
- write_ops = atoll (fields[7 + fieldshift]);
-
- read_sectors = atoll (fields[5 + fieldshift]);
- write_sectors = atoll (fields[9 + fieldshift]);
-
- if ((fieldshift == 0) || (minor == 0))
- {
- is_disk = 1;
- read_merged = atoll (fields[4 + fieldshift]);
- read_time = atoll (fields[6 + fieldshift]);
- write_merged = atoll (fields[8 + fieldshift]);
- write_time = atoll (fields[10+ fieldshift]);
- }
- }
- else
- {
- DEBUG ("numfields = %i; => unknown file format.", numfields);
- continue;
- }
-
- {
- derive_t diff_read_sectors;
- derive_t diff_write_sectors;
-
- /* If the counter wraps around, it's only 32 bits.. */
- if (read_sectors < ds->read_sectors)
- diff_read_sectors = 1 + read_sectors
- + (UINT_MAX - ds->read_sectors);
- else
- diff_read_sectors = read_sectors - ds->read_sectors;
- if (write_sectors < ds->write_sectors)
- diff_write_sectors = 1 + write_sectors
- + (UINT_MAX - ds->write_sectors);
- else
- diff_write_sectors = write_sectors - ds->write_sectors;
-
- ds->read_bytes += 512 * diff_read_sectors;
- ds->write_bytes += 512 * diff_write_sectors;
- ds->read_sectors = read_sectors;
- ds->write_sectors = write_sectors;
- }
-
- /* Calculate the average time an io-op needs to complete */
- if (is_disk)
- {
- derive_t diff_read_ops;
- derive_t diff_write_ops;
- derive_t diff_read_time;
- derive_t diff_write_time;
-
- if (read_ops < ds->read_ops)
- diff_read_ops = 1 + read_ops
- + (UINT_MAX - ds->read_ops);
- else
- diff_read_ops = read_ops - ds->read_ops;
- DEBUG ("disk plugin: disk_name = %s; read_ops = %"PRIi64"; "
- "ds->read_ops = %"PRIi64"; diff_read_ops = %"PRIi64";",
- disk_name,
- read_ops, ds->read_ops, diff_read_ops);
-
- if (write_ops < ds->write_ops)
- diff_write_ops = 1 + write_ops
- + (UINT_MAX - ds->write_ops);
- else
- diff_write_ops = write_ops - ds->write_ops;
-
- if (read_time < ds->read_time)
- diff_read_time = 1 + read_time
- + (UINT_MAX - ds->read_time);
- else
- diff_read_time = read_time - ds->read_time;
-
- if (write_time < ds->write_time)
- diff_write_time = 1 + write_time
- + (UINT_MAX - ds->write_time);
- else
- diff_write_time = write_time - ds->write_time;
-
- if (diff_read_ops != 0)
- ds->avg_read_time += disk_calc_time_incr (
- diff_read_time, diff_read_ops);
- if (diff_write_ops != 0)
- ds->avg_write_time += disk_calc_time_incr (
- diff_write_time, diff_write_ops);
-
- ds->read_ops = read_ops;
- ds->read_time = read_time;
- ds->write_ops = write_ops;
- ds->write_time = write_time;
- } /* if (is_disk) */
-
- /* Don't write to the RRDs if we've just started.. */
- ds->poll_count++;
- if (ds->poll_count <= 2)
- {
- DEBUG ("disk plugin: (ds->poll_count = %i) <= "
- "(min_poll_count = 2); => Not writing.",
- ds->poll_count);
- continue;
- }
-
- if ((read_ops == 0) && (write_ops == 0))
- {
- DEBUG ("disk plugin: ((read_ops == 0) && "
- "(write_ops == 0)); => Not writing.");
- continue;
- }
-
- if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
- disk_submit (disk_name, "disk_octets",
- ds->read_bytes, ds->write_bytes);
-
- if ((ds->read_ops != 0) || (ds->write_ops != 0))
- disk_submit (disk_name, "disk_ops",
- read_ops, write_ops);
-
- if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0))
- disk_submit (disk_name, "disk_time",
- ds->avg_read_time, ds->avg_write_time);
-
- if (is_disk)
- {
- disk_submit (disk_name, "disk_merged",
- read_merged, write_merged);
- } /* if (is_disk) */
- } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
-
- fclose (fh);
+ FILE *fh;
+ char buffer[1024];
+
+ char *fields[32];
+ int numfields;
+ int fieldshift = 0;
+
+ int minor = 0;
+
+ derive_t read_sectors = 0;
+ derive_t write_sectors = 0;
+
+ derive_t read_ops = 0;
+ derive_t read_merged = 0;
+ derive_t read_time = 0;
+ derive_t write_ops = 0;
+ derive_t write_merged = 0;
+ derive_t write_time = 0;
+ gauge_t in_progress = NAN;
+ derive_t io_time = 0;
+ derive_t weighted_time = 0;
+ int is_disk = 0;
+
+ diskstats_t *ds, *pre_ds;
+
+ if ((fh = fopen("/proc/diskstats", "r")) == NULL) {
+ fh = fopen("/proc/partitions", "r");
+ if (fh == NULL) {
+ ERROR("disk plugin: fopen (/proc/{diskstats,partitions}) failed.");
+ return (-1);
+ }
+
+ /* Kernel is 2.4.* */
+ fieldshift = 1;
+ }
+
+ while (fgets(buffer, sizeof(buffer), fh) != NULL) {
+ char *disk_name;
+ char *output_name;
+
+ numfields = strsplit(buffer, fields, 32);
+
+ if ((numfields != (14 + fieldshift)) && (numfields != 7))
+ continue;
+
+ minor = atoll(fields[1]);
+
+ disk_name = fields[2 + fieldshift];
+
+ for (ds = disklist, pre_ds = disklist; ds != NULL;
+ pre_ds = ds, ds = ds->next)
+ if (strcmp(disk_name, ds->name) == 0)
+ break;
+
+ if (ds == NULL) {
+ if ((ds = (diskstats_t *)calloc(1, sizeof(diskstats_t))) == NULL)
+ continue;
+
+ if ((ds->name = strdup(disk_name)) == NULL) {
+ free(ds);
+ continue;
+ }
+
+ if (pre_ds == NULL)
+ disklist = ds;
+ else
+ pre_ds->next = ds;
+ }
+
+ is_disk = 0;
+ if (numfields == 7) {
+ /* Kernel 2.6, Partition */
+ read_ops = atoll(fields[3]);
+ read_sectors = atoll(fields[4]);
+ write_ops = atoll(fields[5]);
+ write_sectors = atoll(fields[6]);
+ } else if (numfields == (14 + fieldshift)) {
+ read_ops = atoll(fields[3 + fieldshift]);
+ write_ops = atoll(fields[7 + fieldshift]);
+
+ read_sectors = atoll(fields[5 + fieldshift]);
+ write_sectors = atoll(fields[9 + fieldshift]);
+
+ if ((fieldshift == 0) || (minor == 0)) {
+ is_disk = 1;
+ read_merged = atoll(fields[4 + fieldshift]);
+ read_time = atoll(fields[6 + fieldshift]);
+ write_merged = atoll(fields[8 + fieldshift]);
+ write_time = atoll(fields[10 + fieldshift]);
+
+ in_progress = atof(fields[11 + fieldshift]);
+
+ io_time = atof(fields[12 + fieldshift]);
+ weighted_time = atof(fields[13 + fieldshift]);
+ }
+ } else {
+ DEBUG("numfields = %i; => unknown file format.", numfields);
+ continue;
+ }
+
+ {
+ derive_t diff_read_sectors;
+ derive_t diff_write_sectors;
+
+ /* If the counter wraps around, it's only 32 bits.. */
+ if (read_sectors < ds->read_sectors)
+ diff_read_sectors = 1 + read_sectors + (UINT_MAX - ds->read_sectors);
+ else
+ diff_read_sectors = read_sectors - ds->read_sectors;
+ if (write_sectors < ds->write_sectors)
+ diff_write_sectors = 1 + write_sectors + (UINT_MAX - ds->write_sectors);
+ else
+ diff_write_sectors = write_sectors - ds->write_sectors;
+
+ ds->read_bytes += 512 * diff_read_sectors;
+ ds->write_bytes += 512 * diff_write_sectors;
+ ds->read_sectors = read_sectors;
+ ds->write_sectors = write_sectors;
+ }
+
+ /* Calculate the average time an io-op needs to complete */
+ if (is_disk) {
+ derive_t diff_read_ops;
+ derive_t diff_write_ops;
+ derive_t diff_read_time;
+ derive_t diff_write_time;
+
+ if (read_ops < ds->read_ops)
+ diff_read_ops = 1 + read_ops + (UINT_MAX - ds->read_ops);
+ else
+ diff_read_ops = read_ops - ds->read_ops;
+ DEBUG("disk plugin: disk_name = %s; read_ops = %" PRIi64 "; "
+ "ds->read_ops = %" PRIi64 "; diff_read_ops = %" PRIi64 ";",
+ disk_name, read_ops, ds->read_ops, diff_read_ops);
+
+ if (write_ops < ds->write_ops)
+ diff_write_ops = 1 + write_ops + (UINT_MAX - ds->write_ops);
+ else
+ diff_write_ops = write_ops - ds->write_ops;
+
+ if (read_time < ds->read_time)
+ diff_read_time = 1 + read_time + (UINT_MAX - ds->read_time);
+ else
+ diff_read_time = read_time - ds->read_time;
+
+ if (write_time < ds->write_time)
+ diff_write_time = 1 + write_time + (UINT_MAX - ds->write_time);
+ else
+ diff_write_time = write_time - ds->write_time;
+
+ if (diff_read_ops != 0)
+ ds->avg_read_time += disk_calc_time_incr(diff_read_time, diff_read_ops);
+ if (diff_write_ops != 0)
+ ds->avg_write_time +=
+ disk_calc_time_incr(diff_write_time, diff_write_ops);
+
+ ds->read_ops = read_ops;
+ ds->read_time = read_time;
+ ds->write_ops = write_ops;
+ ds->write_time = write_time;
+
+ if (read_merged || write_merged)
+ ds->has_merged = 1;
+
+ if (in_progress)
+ ds->has_in_progress = 1;
+
+ if (io_time)
+ ds->has_io_time = 1;
+
+ } /* if (is_disk) */
+
+ /* Don't write to the RRDs if we've just started.. */
+ ds->poll_count++;
+ if (ds->poll_count <= 2) {
+ DEBUG("disk plugin: (ds->poll_count = %i) <= "
+ "(min_poll_count = 2); => Not writing.",
+ ds->poll_count);
+ continue;
+ }
+
+ if ((read_ops == 0) && (write_ops == 0)) {
+ DEBUG("disk plugin: ((read_ops == 0) && "
+ "(write_ops == 0)); => Not writing.");
+ continue;
+ }
+
+ output_name = disk_name;
+
+#if HAVE_LIBUDEV
+ char *alt_name = NULL;
+ if (conf_udev_name_attr != NULL) {
+ alt_name =
+ disk_udev_attr_name(handle_udev, disk_name, conf_udev_name_attr);
+ if (alt_name != NULL)
+ output_name = alt_name;
+ }
+#endif
+
+ if (ignorelist_match(ignorelist, output_name) != 0) {
+#if HAVE_LIBUDEV
+ /* release udev-based alternate name, if allocated */
+ sfree(alt_name);
+#endif
+ continue;
+ }
+
+ if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
+ disk_submit(output_name, "disk_octets", ds->read_bytes, ds->write_bytes);
+
+ if ((ds->read_ops != 0) || (ds->write_ops != 0))
+ disk_submit(output_name, "disk_ops", read_ops, write_ops);
+
+ if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0))
+ disk_submit(output_name, "disk_time", ds->avg_read_time,
+ ds->avg_write_time);
+
+ if (is_disk) {
+ if (ds->has_merged)
+ disk_submit(output_name, "disk_merged", read_merged, write_merged);
+ if (ds->has_in_progress)
+ submit_in_progress(output_name, in_progress);
+ if (ds->has_io_time)
+ submit_io_time(output_name, io_time, weighted_time);
+ } /* if (is_disk) */
+
+#if HAVE_LIBUDEV
+ /* release udev-based alternate name, if allocated */
+ sfree(alt_name);
+#endif
+ } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
+
+ fclose(fh);