glusterfs
135 строк · 3.4 Кб
1/*
2Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
3This file is part of GlusterFS.
4
5This file is licensed to you under your choice of the GNU Lesser
6General Public License, version 3 or any later version (LGPLv3 or
7later), or the GNU General Public License, version 2 (GPLv2), in all
8cases as published by the Free Software Foundation.
9*/
10
11#include <sys/types.h>12#include <sys/socket.h>13#include <sys/un.h>14#include <stdio.h>15#include <unistd.h>16#include <time.h>17#include <stdarg.h>18#include <string.h>19#include <netinet/in.h>20#include <netdb.h>21
22#include "glusterfs/syscall.h"23#include "glusterfs/mem-pool.h"24#include "glusterfs/globals.h"25#include "glusterfs/events.h"26
27#define EVENT_HOST "127.0.0.1"28#define EVENT_PORT 5555529
30int
31_gf_event(eventtypes_t event, const char *fmt, ...)32{
33int ret = 0;34int sock = -1;35char *eventstr = NULL;36va_list arguments;37char *msg = NULL;38glusterfs_ctx_t *ctx = NULL;39char *host = NULL;40struct addrinfo hints;41struct addrinfo *result = NULL;42struct addrinfo *iter_result_ptr = NULL;43xlator_t *this = THIS;44char *volfile_server_transport = NULL;45
46/* Global context */47ctx = this->ctx;48
49if (event < 0 || event >= EVENT_LAST) {50ret = EVENT_ERROR_INVALID_INPUTS;51goto out;52}53
54if (ctx) {55volfile_server_transport = ctx->cmd_args.volfile_server_transport;56}57if (!volfile_server_transport) {58volfile_server_transport = "tcp";59}60
61/* host = NULL returns localhost */62if (ctx && ctx->cmd_args.volfile_server &&63(strcmp(volfile_server_transport, "unix"))) {64/* If it is client code then volfile_server is set65use that information to push the events. */
66host = ctx->cmd_args.volfile_server;67}68
69memset(&hints, 0, sizeof(hints));70hints.ai_family = AF_UNSPEC;71hints.ai_socktype = SOCK_DGRAM;72hints.ai_flags = AI_ADDRCONFIG;73
74if ((getaddrinfo(host, TOSTRING(EVENT_PORT), &hints, &result)) != 0) {75ret = EVENT_ERROR_RESOLVE;76goto out;77}78
79// iterate over the result and break when socket creation is success.80for (iter_result_ptr = result; iter_result_ptr != NULL;81iter_result_ptr = iter_result_ptr->ai_next) {82sock = socket(iter_result_ptr->ai_family, iter_result_ptr->ai_socktype,83iter_result_ptr->ai_protocol);84if (sock != -1) {85break;86}87}88/*89* If none of the addrinfo structures lead to a successful socket
90* creation, socket creation has failed.
91*/
92if (sock < 0) {93ret = EVENT_ERROR_SOCKET;94goto out;95}96
97va_start(arguments, fmt);98ret = gf_vasprintf(&msg, fmt, arguments);99va_end(arguments);100
101if (ret < 0) {102ret = EVENT_ERROR_INVALID_INPUTS;103goto out;104}105
106ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)gf_time(), event, msg);107GF_FREE(msg);108if (ret <= 0) {109ret = EVENT_ERROR_MSG_FORMAT;110goto out;111}112
113/* Send Message */114if (sendto(sock, eventstr, strlen(eventstr), 0, result->ai_addr,115result->ai_addrlen) <= 0) {116ret = EVENT_ERROR_SEND;117goto out;118}119
120ret = EVENT_SEND_OK;121
122out:123if (sock >= 0) {124sys_close(sock);125}126
127/* Allocated by gf_asprintf */128if (eventstr)129GF_FREE(eventstr);130
131if (result)132freeaddrinfo(result);133
134return ret;135}
136