v5upgrade target: Don't use "memcpy" to copy static strings.
[collectd.git] / src / target_v5upgrade.c
1 /**
2  * collectd - src/target_set.c
3  * Copyright (C) 2008-2010  Florian Forster
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; only version 2.1 of the License is
8  * applicable.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors:
20  *   Florian Forster <octo at verplant.org>
21  **/
22
23 #include "collectd.h"
24 #include "plugin.h"
25 #include "common.h"
26 #include "filter_chain.h"
27
28 static void v5_swap_instances (value_list_t *vl) /* {{{ */
29 {
30   char tmp[DATA_MAX_NAME_LEN];
31
32   assert (sizeof (tmp) == sizeof (vl->plugin_instance));
33   assert (sizeof (tmp) == sizeof (vl->type_instance));
34
35   memcpy (tmp, vl->plugin_instance, sizeof (tmp));
36   memcpy (vl->plugin_instance, vl->type_instance, sizeof (tmp));
37   memcpy (vl->type_instance, tmp, sizeof (tmp));
38 } /* }}} void v5_swap_instances */
39
40 /*
41  * Df type
42  *
43  * By default, the "df" plugin of version 4.* uses the "df" type and puts the
44  * mount point in the type instance. Detect this behavior and convert the type
45  * to "df_complex". This can be selected in versions 4.9 and 4.10 by setting
46  * the "ReportReserved" option of the "df" plugin.
47  */
48 static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */
49 {
50   value_list_t new_vl;
51   value_t new_value;
52
53   /* Can't upgrade if both instances have been set. */
54   if ((vl->plugin_instance[0] != 0)
55       && (vl->type_instance[0] != 0))
56     return (FC_TARGET_CONTINUE);
57
58   /* Copy everything: Time, interval, host, ... */
59   memcpy (&new_vl, vl, sizeof (new_vl));
60
61   /* Reset data we can't simply copy */
62   new_vl.values = &new_value;
63   new_vl.values_len = 1;
64   new_vl.meta = NULL;
65
66   /* Move the mount point name to the plugin instance */
67   if (new_vl.plugin_instance[0] == 0)
68     v5_swap_instances (&new_vl);
69
70   /* Change the type to "df_complex" */
71   sstrncpy (new_vl.type, "df_complex", sizeof (new_vl.type));
72
73   /* Dispatch two new value lists instead of this one */
74   new_vl.values[0].gauge = vl->values[0].gauge;
75   sstrncpy (new_vl.type_instance, "used", sizeof (new_vl.type_instance));
76   plugin_dispatch_values (&new_vl);
77
78   new_vl.values[0].gauge = vl->values[1].gauge;
79   sstrncpy (new_vl.type_instance, "free", sizeof (new_vl.type_instance));
80   plugin_dispatch_values (&new_vl);
81
82   /* Abort processing */
83   return (FC_TARGET_STOP);
84 } /* }}} int v5_df */
85
86 /*
87  * Interface plugin
88  *
89  * 4.* stores the interface in the type instance and leaves the plugin
90  * instance empty. If this is the case, put the interface name into the plugin
91  * instance and clear the type instance.
92  */
93 static int v5_interface (const data_set_t *ds, value_list_t *vl) /* {{{ */
94 {
95   if ((vl->plugin_instance[0] != 0) || (vl->type_instance[0] == 0))
96     return (FC_TARGET_CONTINUE);
97
98   v5_swap_instances (vl);
99   return (FC_TARGET_CONTINUE);
100 } /* }}} int v5_interface */
101
102 static int v5_destroy (void **user_data) /* {{{ */
103 {
104   return (0);
105 } /* }}} int v5_destroy */
106
107 static int v5_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
108 {
109   *user_data = NULL;
110   return (0);
111 } /* }}} int v5_create */
112
113 static int v5_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
114     notification_meta_t __attribute__((unused)) **meta,
115     void __attribute__((unused)) **user_data)
116 {
117   if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
118     return (-EINVAL);
119
120   if (strcmp ("df", vl->type) == 0)
121     return (v5_df (ds, vl));
122   else if (strcmp ("interface", vl->plugin) == 0)
123     return (v5_interface (ds, vl));
124
125   return (FC_TARGET_CONTINUE);
126 } /* }}} int v5_invoke */
127
128 void module_register (void)
129 {
130         target_proc_t tproc;
131
132         memset (&tproc, 0, sizeof (tproc));
133         tproc.create  = v5_create;
134         tproc.destroy = v5_destroy;
135         tproc.invoke  = v5_invoke;
136         fc_register_target ("v5upgrade", tproc);
137 } /* module_register */
138
139 /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
140