Code

Add write_mongodb.patch to make the plugin compatible with Debian.
[pkg-collectd.git] / debian / patches / write_mongodb.patch
1 Description: Update mongodb write code to use latest API and other fixes.
2  This makes the plugin compile with libmongoc in Debian and includes all fixes
3  to the write_mongodb plugin since 5.7.2 (plus related changes to other
4  files):
5  .
6  % git log --oneline collectd-5.7.2.. -- src/write_mongodb.c
7  7f38ca96 Merge branch 'ssnprintf-cleanup'
8  bea5daae write_mongodb: fix a couple of build warnings
9  f81a5a84 write_mongodb: fix build warning
10  be126043 Treewide: replace ssnprintf with snprintf
11  a93cc681 write_mongodb: use ssnprintf_alloc to create dsn
12  2c597543 write_mongodb: fix potential NULL dereference
13  7f9c8e70 write_mongodb.c: clang-format
14  ca1ed50e Use bson_destroy instead of bson_free, and fix memleak issue.
15  307c875e Remove parentheses around return arguments
16  4d3d0c97 Tree-wide: remove last remnants of sizeof(char)
17  1811b98c Update mongodb write code to use latest API (Fixes: #492) (#2236)
18  c7c89cc9 Treewide: remove vim modelines from C code files
19  865f2eb3 More autoconf work
20  eec0cd9c Merge pull request #2041 from mfournier/contrib-docker
21 diff a/configure.ac b/configure.ac
22 --- a/configure.ac
23 +++ b/configure.ac
24 @@ -3319,66 +3319,71 @@
25  # }}}
26  
27  # --with-libmongoc {{{
28 -AC_ARG_WITH(libmongoc, [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
29 -[
30 - if test "x$withval" = "xyes"
31 - then
32 -        with_libmongoc="yes"
33 - else if test "x$withval" = "xno"
34 - then
35 -        with_libmongoc="no"
36 - else
37 -        with_libmongoc="yes"
38 -        LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS -I$withval/include"
39 -        LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS -L$withval/lib"
40 - fi; fi
41 -],
42 -[with_libmongoc="yes"])
43 -
44 -SAVE_CPPFLAGS="$CPPFLAGS"
45 -SAVE_LDFLAGS="$LDFLAGS"
46 -
47 -CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS"
48 -LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
49 -
50 -if test "x$with_libmongoc" = "xyes"
51 -then
52 -       if test "x$LIBMONGOC_CPPFLAGS" != "x"
53 -       then
54 -               AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
55 -       fi
56 -       AC_CHECK_HEADERS(mongo.h,
57 -       [with_libmongoc="yes"],
58 -       [with_libmongoc="no ('mongo.h' not found)"],
59 -[#if HAVE_STDINT_H
60 -# define MONGO_HAVE_STDINT 1
61 -#else
62 -# define MONGO_USE_LONG_LONG_INT 1
63 -#endif
64 -])
65 +AC_ARG_WITH([libmongoc],
66 +  [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
67 +  [
68 +    if test "x$withval" = "xyes"; then
69 +      with_libmongoc="yes"
70 +    else if test "x$withval" = "xno"; then
71 +      with_libmongoc="no"
72 +    else
73 +      with_libmongoc="no"
74 +    fi; fi
75 +  ],
76 +  [with_libmongoc="yes"]
77 +)
78 +
79 +if test "x$with_libmongoc" = "xyes"; then
80 +  PKG_CHECK_MODULES([LIBMONGOC], [libmongoc-1.0],
81 +    [with_libmongoc="yes"],
82 +    [with_libmongoc="no (pkg-config could not find libmongoc)"]
83 +  )
84  fi
85 -if test "x$with_libmongoc" = "xyes"
86 -then
87 -       if test "x$LIBMONGOC_LDFLAGS" != "x"
88 -       then
89 -               AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
90 -       fi
91 -       AC_CHECK_LIB(mongoc, mongo_run_command,
92 -       [with_libmongoc="yes"],
93 -       [with_libmongoc="no (symbol 'mongo_run_command' not found)"])
94 +
95 +if test "x$with_libmongoc" = "xyes"; then
96 +  SAVE_CPPFLAGS="$CPPFLAGS"
97 +
98 +  CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS"
99 +
100 +  if test "x$CPPFLAGS" != "x"; then
101 +    AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CFLAGS])
102 +  fi
104 +  AC_CHECK_HEADERS([mongoc.h],
105 +    [with_libmongoc="yes"],
106 +    [with_libmongoc="no ('mongoc.h' not found)"]
107 +  )
109 +  CPPFLAGS="$SAVE_CPPFLAGS"
110  fi
111  
112 -CPPFLAGS="$SAVE_CPPFLAGS"
113 -LDFLAGS="$SAVE_LDFLAGS"
114 +if test "x$with_libmongoc" = "xyes"; then
115 +  SAVE_CPPFLAGS="$CPPFLAGS"
116 +  SAVE_LDFLAGS="$LDFLAGS"
118 +  CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS"
119 +  LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
121 +  if test "x$LIBMONGOC_LDFLAGS" != "x"; then
122 +    AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
123 +  fi
125 +  AC_CHECK_LIB([mongoc-1.0], [mongoc_init],
126 +    [with_libmongoc="yes"],
127 +    [with_libmongoc="no (symbol 'mongoc_init' not found)"]
128 +  )
130 +  CPPFLAGS="$SAVE_CPPFLAGS"
131 +  LDFLAGS="$SAVE_LDFLAGS"
132 +fi
133  
134 -if test "x$with_libmongoc" = "xyes"
135 -then
136 -       BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
137 -       BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
138 -       AC_SUBST(BUILD_WITH_LIBMONGOC_CPPFLAGS)
139 -       AC_SUBST(BUILD_WITH_LIBMONGOC_LDFLAGS)
140 +if test "x$with_libmongoc" = "xyes"; then
141 +  BUILD_WITH_LIBMONGOC_CFLAGS="$LIBMONGOC_CFLAGS"
142 +  BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
143  fi
144 -AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
146 +AC_SUBST([BUILD_WITH_LIBMONGOC_CFLAGS])
147 +AC_SUBST([BUILD_WITH_LIBMONGOC_LDFLAGS])
148  # }}}
149  
150  # --with-libmosquitto {{{
151 --- a/src/Makefile.am
152 +++ b/src/Makefile.am
153 @@ -1329,9 +1329,8 @@
154  if BUILD_PLUGIN_WRITE_MONGODB
155  pkglib_LTLIBRARIES += write_mongodb.la
156  write_mongodb_la_SOURCES = write_mongodb.c
157 -write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
158 +write_mongodb_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMONGOC_CFLAGS)
159  write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
160 -write_mongodb_la_LIBADD = -lmongoc
161  endif
162  
163  if BUILD_PLUGIN_WRITE_PROMETHEUS
164 --- a/src/write_mongodb.c
165 +++ b/src/write_mongodb.c
166 @@ -3,6 +3,7 @@
167   * Copyright (C) 2010-2013  Florian Forster
168   * Copyright (C) 2010       Akkarit Sangpetch
169   * Copyright (C) 2012       Chris Lundquist
170 + * Copyright (C) 2017       Saikrishna Arcot
171   *
172   * Permission is hereby granted, free of charge, to any person obtaining a
173   * copy of this software and associated documentation files (the "Software"),
174 @@ -26,6 +27,7 @@
175   *   Florian Forster <octo at collectd.org>
176   *   Akkarit Sangpetch <asangpet at andrew.cmu.edu>
177   *   Chris Lundquist <clundquist at bluebox.net>
178 + *   Saikrishna Arcot <saiarcot895 at gmail.com>
179   **/
180  
181  #include "collectd.h"
182 @@ -34,17 +36,7 @@
183  #include "plugin.h"
184  #include "utils_cache.h"
185  
186 -#if HAVE_STDINT_H
187 -#define MONGO_HAVE_STDINT 1
188 -#else
189 -#define MONGO_USE_LONG_LONG_INT 1
190 -#endif
191 -#include <mongo.h>
193 -#if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8)
194 -#define bson_alloc() bson_create()
195 -#define bson_dealloc(b) bson_dispose(b)
196 -#endif
197 +#include <mongoc.h>
198  
199  struct wm_node_s {
200    char name[DATA_MAX_NAME_LEN];
201 @@ -59,8 +51,10 @@
202    char *passwd;
203  
204    _Bool store_rates;
205 +  _Bool connected;
206  
207 -  mongo conn[1];
208 +  mongoc_client_t *client;
209 +  mongoc_database_t *database;
210    pthread_mutex_t lock;
211  };
212  typedef struct wm_node_s wm_node_t;
213 @@ -68,170 +62,222 @@
214  /*
215   * Functions
216   */
217 -static bson *wm_create_bson(const data_set_t *ds, /* {{{ */
218 -                            const value_list_t *vl, _Bool store_rates) {
219 -  bson *ret;
220 +static bson_t *wm_create_bson(const data_set_t *ds, /* {{{ */
221 +                              const value_list_t *vl, _Bool store_rates) {
222 +  bson_t *ret;
223 +  bson_t subarray;
224    gauge_t *rates;
225  
226 -  ret = bson_alloc(); /* matched by bson_dealloc() */
227 -  if (ret == NULL) {
228 -    ERROR("write_mongodb plugin: bson_create failed.");
229 -    return (NULL);
230 +  ret = bson_new();
231 +  if (!ret) {
232 +    ERROR("write_mongodb plugin: bson_new failed.");
233 +    return NULL;
234    }
235  
236    if (store_rates) {
237      rates = uc_get_rate(ds, vl);
238      if (rates == NULL) {
239        ERROR("write_mongodb plugin: uc_get_rate() failed.");
240 -      return (NULL);
241 +      bson_destroy(ret);
242 +      return NULL;
243      }
244    } else {
245      rates = NULL;
246    }
247  
248 -  bson_init(ret); /* matched by bson_destroy() */
249 -  bson_append_date(ret, "time", (bson_date_t)CDTIME_T_TO_MS(vl->time));
250 -  bson_append_string(ret, "host", vl->host);
251 -  bson_append_string(ret, "plugin", vl->plugin);
252 -  bson_append_string(ret, "plugin_instance", vl->plugin_instance);
253 -  bson_append_string(ret, "type", vl->type);
254 -  bson_append_string(ret, "type_instance", vl->type_instance);
255 +  BSON_APPEND_DATE_TIME(ret, "timestamp", CDTIME_T_TO_MS(vl->time));
256 +  BSON_APPEND_UTF8(ret, "host", vl->host);
257 +  BSON_APPEND_UTF8(ret, "plugin", vl->plugin);
258 +  BSON_APPEND_UTF8(ret, "plugin_instance", vl->plugin_instance);
259 +  BSON_APPEND_UTF8(ret, "type", vl->type);
260 +  BSON_APPEND_UTF8(ret, "type_instance", vl->type_instance);
261  
262 -  bson_append_start_array(ret, "values"); /* {{{ */
263 -  for (int i = 0; i < ds->ds_num; i++) {
264 +  BSON_APPEND_ARRAY_BEGIN(ret, "values", &subarray); /* {{{ */
265 +  for (size_t i = 0; i < ds->ds_num; i++) {
266      char key[16];
267  
268 -    ssnprintf(key, sizeof(key), "%i", i);
269 +    snprintf(key, sizeof(key), "%zu", i);
270  
271      if (ds->ds[i].type == DS_TYPE_GAUGE)
272 -      bson_append_double(ret, key, vl->values[i].gauge);
273 +      BSON_APPEND_DOUBLE(&subarray, key, vl->values[i].gauge);
274      else if (store_rates)
275 -      bson_append_double(ret, key, (double)rates[i]);
276 +      BSON_APPEND_DOUBLE(&subarray, key, (double)rates[i]);
277      else if (ds->ds[i].type == DS_TYPE_COUNTER)
278 -      bson_append_long(ret, key, vl->values[i].counter);
279 +      BSON_APPEND_INT64(&subarray, key, vl->values[i].counter);
280      else if (ds->ds[i].type == DS_TYPE_DERIVE)
281 -      bson_append_long(ret, key, vl->values[i].derive);
282 +      BSON_APPEND_INT64(&subarray, key, vl->values[i].derive);
283      else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
284 -      bson_append_long(ret, key, vl->values[i].absolute);
285 -    else
286 -      assert(23 == 42);
287 +      BSON_APPEND_INT64(&subarray, key, vl->values[i].absolute);
288 +    else {
289 +      ERROR("write_mongodb plugin: Unknown ds_type %d for index %zu",
290 +            ds->ds[i].type, i);
291 +      bson_destroy(ret);
292 +      return NULL;
293 +    }
294    }
295 -  bson_append_finish_array(ret); /* }}} values */
296 +  bson_append_array_end(ret, &subarray); /* }}} values */
297  
298 -  bson_append_start_array(ret, "dstypes"); /* {{{ */
299 -  for (int i = 0; i < ds->ds_num; i++) {
300 +  BSON_APPEND_ARRAY_BEGIN(ret, "dstypes", &subarray); /* {{{ */
301 +  for (size_t i = 0; i < ds->ds_num; i++) {
302      char key[16];
303  
304 -    ssnprintf(key, sizeof(key), "%i", i);
305 +    snprintf(key, sizeof(key), "%zu", i);
306  
307      if (store_rates)
308 -      bson_append_string(ret, key, "gauge");
309 +      BSON_APPEND_UTF8(&subarray, key, "gauge");
310      else
311 -      bson_append_string(ret, key, DS_TYPE_TO_STRING(ds->ds[i].type));
312 +      BSON_APPEND_UTF8(&subarray, key, DS_TYPE_TO_STRING(ds->ds[i].type));
313    }
314 -  bson_append_finish_array(ret); /* }}} dstypes */
315 +  bson_append_array_end(ret, &subarray); /* }}} dstypes */
316  
317 -  bson_append_start_array(ret, "dsnames"); /* {{{ */
318 -  for (int i = 0; i < ds->ds_num; i++) {
319 +  BSON_APPEND_ARRAY_BEGIN(ret, "dsnames", &subarray); /* {{{ */
320 +  for (size_t i = 0; i < ds->ds_num; i++) {
321      char key[16];
322  
323 -    ssnprintf(key, sizeof(key), "%i", i);
324 -    bson_append_string(ret, key, ds->ds[i].name);
325 +    snprintf(key, sizeof(key), "%zu", i);
326 +    BSON_APPEND_UTF8(&subarray, key, ds->ds[i].name);
327    }
328 -  bson_append_finish_array(ret); /* }}} dsnames */
330 -  bson_finish(ret);
331 +  bson_append_array_end(ret, &subarray); /* }}} dsnames */
332  
333    sfree(rates);
334 -  return (ret);
335 -} /* }}} bson *wm_create_bson */
336  
337 -static int wm_write(const data_set_t *ds, /* {{{ */
338 -                    const value_list_t *vl, user_data_t *ud) {
339 -  wm_node_t *node = ud->data;
340 -  char collection_name[512];
341 -  bson *bson_record;
342 -  int status;
343 +  size_t error_location;
344 +  if (!bson_validate(ret, BSON_VALIDATE_UTF8, &error_location)) {
345 +    ERROR("write_mongodb plugin: Error in generated BSON document "
346 +          "at byte %zu",
347 +          error_location);
348 +    bson_destroy(ret);
349 +    return NULL;
350 +  }
351  
352 -  ssnprintf(collection_name, sizeof(collection_name), "collectd.%s",
353 -            vl->plugin);
354 +  return ret;
355 +} /* }}} bson *wm_create_bson */
356  
357 -  bson_record = wm_create_bson(ds, vl, node->store_rates);
358 -  if (bson_record == NULL)
359 -    return (ENOMEM);
360 +static int wm_initialize(wm_node_t *node) /* {{{ */
361 +{
362 +  char *uri;
363  
364 -  pthread_mutex_lock(&node->lock);
365 +  if (node->connected)
366 +    return 0;
368 +  INFO("write_mongodb plugin: Connecting to [%s]:%d", node->host, node->port);
369  
370 -  if (!mongo_is_connected(node->conn)) {
371 -    INFO("write_mongodb plugin: Connecting to [%s]:%i",
372 -         (node->host != NULL) ? node->host : "localhost",
373 -         (node->port != 0) ? node->port : MONGO_DEFAULT_PORT);
374 -    status = mongo_connect(node->conn, node->host, node->port);
375 -    if (status != MONGO_OK) {
376 -      ERROR("write_mongodb plugin: Connecting to [%s]:%i failed.",
377 -            (node->host != NULL) ? node->host : "localhost",
378 -            (node->port != 0) ? node->port : MONGO_DEFAULT_PORT);
379 -      mongo_destroy(node->conn);
380 -      pthread_mutex_unlock(&node->lock);
381 -      return (-1);
382 +  if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) {
383 +    uri = ssnprintf_alloc("mongodb://%s:%s@%s:%d/?authSource=%s", node->user,
384 +                          node->passwd, node->host, node->port, node->db);
385 +    if (uri == NULL) {
386 +      ERROR("write_mongodb plugin: Not enough memory to assemble "
387 +            "authentication string.");
388 +      mongoc_client_destroy(node->client);
389 +      node->client = NULL;
390 +      node->connected = 0;
391 +      return -1;
392      }
393  
394 -    if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) {
395 -      status = mongo_cmd_authenticate(node->conn, node->db, node->user,
396 -                                      node->passwd);
397 -      if (status != MONGO_OK) {
398 -        ERROR("write_mongodb plugin: Authenticating to [%s]%i for database "
399 -              "\"%s\" as user \"%s\" failed.",
400 -              (node->host != NULL) ? node->host : "localhost",
401 -              (node->port != 0) ? node->port : MONGO_DEFAULT_PORT, node->db,
402 -              node->user);
403 -        mongo_destroy(node->conn);
404 -        pthread_mutex_unlock(&node->lock);
405 -        return (-1);
406 -      }
407 +    node->client = mongoc_client_new(uri);
408 +    if (!node->client) {
409 +      ERROR("write_mongodb plugin: Authenticating to [%s]:%d for database "
410 +            "\"%s\" as user \"%s\" failed.",
411 +            node->host, node->port, node->db, node->user);
412 +      node->connected = 0;
413 +      sfree(uri);
414 +      return -1;
415 +    }
416 +  } else {
417 +    uri = ssnprintf_alloc("mongodb://%s:%d", node->host, node->port);
418 +    if (uri == NULL) {
419 +      ERROR("write_mongodb plugin: Not enough memory to assemble "
420 +            "authentication string.");
421 +      mongoc_client_destroy(node->client);
422 +      node->client = NULL;
423 +      node->connected = 0;
424 +      return -1;
425      }
426  
427 -    if (node->timeout > 0) {
428 -      status = mongo_set_op_timeout(node->conn, node->timeout);
429 -      if (status != MONGO_OK) {
430 -        WARNING("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s",
431 -                node->timeout, node->conn->errstr);
432 -      }
433 +    node->client = mongoc_client_new(uri);
434 +    if (!node->client) {
435 +      ERROR("write_mongodb plugin: Connecting to [%s]:%d failed.", node->host,
436 +            node->port);
437 +      node->connected = 0;
438 +      sfree(uri);
439 +      return -1;
440      }
441 +    sfree(uri);
442    }
443  
444 -  /* Assert if the connection has been established */
445 -  assert(mongo_is_connected(node->conn));
446 +  node->database = mongoc_client_get_database(node->client, "collectd");
447 +  if (!node->database) {
448 +    ERROR("write_mongodb plugin: error creating/getting database");
449 +    mongoc_client_destroy(node->client);
450 +    node->client = NULL;
451 +    node->connected = 0;
452 +    return -1;
453 +  }
454  
455 -#if MONGO_MINOR >= 6
456 -  /* There was an API change in 0.6.0 as linked below */
457 -  /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */
458 -  status = mongo_insert(node->conn, collection_name, bson_record, NULL);
459 -#else
460 -  status = mongo_insert(node->conn, collection_name, bson_record);
461 -#endif
463 -  if (status != MONGO_OK) {
464 -    ERROR("write_mongodb plugin: error inserting record: %d", node->conn->err);
465 -    if (node->conn->err != MONGO_BSON_INVALID)
466 -      ERROR("write_mongodb plugin: %s", node->conn->errstr);
467 -    else
468 -      ERROR("write_mongodb plugin: Invalid BSON structure, error = %#x",
469 -            (unsigned int)bson_record->err);
470 +  node->connected = 1;
471 +  return 0;
472 +} /* }}} int wm_initialize */
473  
474 -    /* Disconnect except on data errors. */
475 -    if ((node->conn->err != MONGO_BSON_INVALID) &&
476 -        (node->conn->err != MONGO_BSON_NOT_FINISHED))
477 -      mongo_destroy(node->conn);
478 +static int wm_write(const data_set_t *ds, /* {{{ */
479 +                    const value_list_t *vl, user_data_t *ud) {
480 +  wm_node_t *node = ud->data;
481 +  mongoc_collection_t *collection = NULL;
482 +  bson_t *bson_record;
483 +  bson_error_t error;
484 +  int status;
486 +  bson_record = wm_create_bson(ds, vl, node->store_rates);
487 +  if (!bson_record) {
488 +    ERROR("write_mongodb plugin: error making insert bson");
489 +    return -1;
490    }
491  
492 -  pthread_mutex_unlock(&node->lock);
493 +  pthread_mutex_lock(&node->lock);
494 +  if (wm_initialize(node) < 0) {
495 +    ERROR("write_mongodb plugin: error making connection to server");
496 +    pthread_mutex_unlock(&node->lock);
497 +    bson_destroy(bson_record);
498 +    return -1;
499 +  }
501 +  collection =
502 +      mongoc_client_get_collection(node->client, "collectd", vl->plugin);
503 +  if (!collection) {
504 +    ERROR("write_mongodb plugin: error creating/getting collection");
505 +    mongoc_database_destroy(node->database);
506 +    mongoc_client_destroy(node->client);
507 +    node->database = NULL;
508 +    node->client = NULL;
509 +    node->connected = 0;
510 +    pthread_mutex_unlock(&node->lock);
511 +    bson_destroy(bson_record);
512 +    return -1;
513 +  }
515 +  status = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, bson_record,
516 +                                    NULL, &error);
518 +  if (!status) {
519 +    ERROR("write_mongodb plugin: error inserting record: %s", error.message);
520 +    mongoc_database_destroy(node->database);
521 +    mongoc_client_destroy(node->client);
522 +    node->database = NULL;
523 +    node->client = NULL;
524 +    node->connected = 0;
525 +    pthread_mutex_unlock(&node->lock);
526 +    bson_destroy(bson_record);
527 +    mongoc_collection_destroy(collection);
528 +    return -1;
529 +  }
530  
531    /* free our resource as not to leak memory */
532 -  bson_destroy(bson_record); /* matches bson_init() */
533 -  bson_dealloc(bson_record); /* matches bson_alloc() */
534 +  mongoc_collection_destroy(collection);
536 +  pthread_mutex_unlock(&node->lock);
537  
538 -  return (0);
539 +  bson_destroy(bson_record);
541 +  return 0;
542  } /* }}} int wm_write */
543  
544  static void wm_config_free(void *ptr) /* {{{ */
545 @@ -241,8 +287,11 @@
546    if (node == NULL)
547      return;
548  
549 -  if (mongo_is_connected(node->conn))
550 -    mongo_destroy(node->conn);
551 +  mongoc_database_destroy(node->database);
552 +  mongoc_client_destroy(node->client);
553 +  node->database = NULL;
554 +  node->client = NULL;
555 +  node->connected = 0;
556  
557    sfree(node->host);
558    sfree(node);
559 @@ -255,17 +304,23 @@
560  
561    node = calloc(1, sizeof(*node));
562    if (node == NULL)
563 -    return (ENOMEM);
564 -  mongo_init(node->conn);
565 -  node->host = NULL;
566 +    return ENOMEM;
567 +  mongoc_init();
568 +  node->host = strdup("localhost");
569 +  if (node->host == NULL) {
570 +    sfree(node);
571 +    return ENOMEM;
572 +  }
573 +  node->port = MONGOC_DEFAULT_PORT;
574    node->store_rates = 1;
575    pthread_mutex_init(&node->lock, /* attr = */ NULL);
576  
577    status = cf_util_get_string_buffer(ci, node->name, sizeof(node->name));
578  
579    if (status != 0) {
580 +    sfree(node->host);
581      sfree(node);
582 -    return (status);
583 +    return status;
584    }
585  
586    for (int i = 0; i < ci->children_num; i++) {
587 @@ -311,14 +366,15 @@
588    }
589  
590    if (status == 0) {
591 -    char cb_name[DATA_MAX_NAME_LEN];
592 +    char cb_name[sizeof("write_mongodb/") + DATA_MAX_NAME_LEN];
593  
594 -    ssnprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name);
595 +    snprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name);
596  
597 -    status = plugin_register_write(
598 -        cb_name, wm_write, &(user_data_t){
599 -                               .data = node, .free_func = wm_config_free,
600 -                           });
601 +    status =
602 +        plugin_register_write(cb_name, wm_write,
603 +                              &(user_data_t){
604 +                                  .data = node, .free_func = wm_config_free,
605 +                              });
606      INFO("write_mongodb plugin: registered write plugin %s %d", cb_name,
607           status);
608    }
609 @@ -326,7 +382,7 @@
610    if (status != 0)
611      wm_config_free(node);
612  
613 -  return (status);
614 +  return status;
615  } /* }}} int wm_config_node */
616  
617  static int wm_config(oconfig_item_t *ci) /* {{{ */
618 @@ -342,11 +398,9 @@
619                child->key);
620    }
621  
622 -  return (0);
623 +  return 0;
624  } /* }}} int wm_config */
625  
626  void module_register(void) {
627    plugin_register_complex_config("write_mongodb", wm_config);
628  }
630 -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */