diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 436 | 
1 files changed, 436 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c new file mode 100644 index 00000000000..0e3168036cb --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -0,0 +1,436 @@ +/* +  Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.com> +  This file is part of GlusterFS. + +  GlusterFS is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3 of the License, +  or (at your option) any later version. + +  GlusterFS is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU General Public License +  along with this program.  If not, see +  <http://www.gnu.org/licenses/>. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif +#include <inttypes.h> + + +#include "globals.h" +#include "glusterfs.h" +#include "compat.h" +#include "dict.h" +//#include "protocol.h" +//#include "transport.h" +#include "xlator.h" +#include "logging.h" +#include "timer.h" +#include "defaults.h" +#include "compat.h" +#include "compat-errno.h" +#include "statedump.h" +#include "glusterd-mem-types.h" +#include "glusterd.h" +#include "glusterd-sm.h" +#include "glusterd-utils.h" + +#include <sys/resource.h> +#include <inttypes.h> + +static glusterd_lock_t lock; + +static int32_t +glusterd_get_lock_owner (uuid_t *uuid) +{ +        uuid_copy (*uuid, lock.owner) ; +        return 0; +} + +static int32_t +glusterd_set_lock_owner (uuid_t owner) +{ +        uuid_copy (lock.owner, owner); +        //TODO: set timestamp +        return 0; +} + +static int32_t +glusterd_unset_lock_owner (uuid_t owner) +{ +        uuid_clear (lock.owner); +        //TODO: set timestamp +        return 0; +} + +int32_t +glusterd_lock (uuid_t   uuid) +{ + +        uuid_t  owner; +        char    new_owner_str[50]; +        char    owner_str[50]; +        int     ret = -1; + +        GF_ASSERT (uuid); +        uuid_unparse (uuid, new_owner_str); + +        glusterd_get_lock_owner (&owner); + +        if (!uuid_is_null (owner)) { +                uuid_unparse (owner, owner_str); +                gf_log ("glusterd", GF_LOG_ERROR, "Unable to get lock" +                        " for uuid: %s, lock held by: %s", new_owner_str, +                        owner_str); +                goto out; +        } + +        ret = glusterd_set_lock_owner (uuid); + +        if (!ret) { +                gf_log ("glusterd", GF_LOG_NORMAL, "Cluster lock held by" +                         " %s", new_owner_str); +        } + +out: +        return ret; +} + + +int32_t +glusterd_unlock (uuid_t uuid) +{         +        uuid_t  owner; +        char    new_owner_str[50]; +        char    owner_str[50]; +        int32_t ret = -1; + +        GF_ASSERT (uuid); +        uuid_unparse (uuid, new_owner_str); + +        glusterd_get_lock_owner (&owner); + +        if (NULL == owner) { +                gf_log ("glusterd", GF_LOG_ERROR, "Cluster lock not held!"); +                goto out; +        } + +        ret = uuid_compare (uuid, owner); + +        if (ret) { +               uuid_unparse (owner, owner_str); +               gf_log ("glusterd", GF_LOG_ERROR, "Cluster lock held by %s" +                        " ,unlock req from %s!", owner_str, new_owner_str); +               goto out; +        } + +        ret = glusterd_unset_lock_owner (uuid); + +        if (ret) { +                gf_log ("glusterd", GF_LOG_ERROR, "Unable to clear cluster " +                        "lock"); +                goto out; +        } + +        ret = 0; + +out: +        return ret; +} + + +int +glusterd_get_uuid (uuid_t *uuid) +{ +        glusterd_conf_t         *priv = NULL; + +        priv = THIS->private; + +        GF_ASSERT (priv); + +        uuid_copy (*uuid, priv->uuid); + +        return 0; +} + +int +glusterd_submit_request (glusterd_peerinfo_t *peerinfo, void *req, +                         call_frame_t *frame, rpc_clnt_prog_t *prog,  +                         int procnum, struct iobref *iobref,  +                         gd_serialize_t sfunc, xlator_t *this, +                         fop_cbk_fn_t cbkfn) +{ +        int                     ret         = -1; +        struct iobuf            *iobuf      = NULL; +        int                     count      = 0; +        char                    new_iobref = 0, start_ping = 0; +        struct iovec            iov         = {0, }; + +        GF_ASSERT (peerinfo); +        GF_ASSERT (this); + +        iobuf = iobuf_get (this->ctx->iobuf_pool); +        if (!iobuf) { +                goto out; +        }; + +        if (!iobref) { +                iobref = iobref_new (); +                if (!iobref) { +                        goto out; +                } + +                new_iobref = 1; +        } + +        iobref_add (iobref, iobuf); + +        iov.iov_base = iobuf->ptr; +        iov.iov_len  = 128 * GF_UNIT_KB; + +        /* Create the xdr payload */ +        if (req && sfunc) { +                ret = sfunc (iov, req); +                if (ret == -1) { +                        goto out; +                } +                iov.iov_len = ret; +                count = 1; +        } +        /* Send the msg */ +        ret = rpc_clnt_submit (peerinfo->rpc, prog, procnum, cbkfn,  +                               &iov, count,  +                               NULL, 0, iobref, frame); + +        if (ret == 0) { +                pthread_mutex_lock (&peerinfo->rpc->conn.lock); +                { +                        if (!peerinfo->rpc->conn.ping_started) { +                                start_ping = 1; +                        } +                } +                pthread_mutex_unlock (&peerinfo->rpc->conn.lock); +        } + +        if (start_ping) +                //client_start_ping ((void *) this); + +        ret = 0; +out: +        if (new_iobref) { +                iobref_unref (iobref); +        } + +        iobuf_unref (iobuf); + +        return ret; +} + + +struct iobuf * +glusterd_serialize_reply (rpcsvc_request_t *req, void *arg,  +                          gd_serialize_t sfunc, struct iovec *outmsg) +{ +        struct iobuf            *iob = NULL; +        ssize_t                  retlen = -1; + +        /* First, get the io buffer into which the reply in arg will +         * be serialized. +         */ +        iob = iobuf_get (req->conn->svc->ctx->iobuf_pool); +        if (!iob) { +                gf_log ("", GF_LOG_ERROR, "Failed to get iobuf"); +                goto ret; +        } + +        iobuf_to_iovec (iob, outmsg); +        /* Use the given serializer to translate the give C structure in arg +         * to XDR format which will be written into the buffer in outmsg. +         */ +        /* retlen is used to received the error since size_t is unsigned and we +         * need -1 for error notification during encoding. +         */ +        retlen = sfunc (*outmsg, arg); +        if (retlen == -1) { +                gf_log ("", GF_LOG_ERROR, "Failed to encode message"); +                goto ret; +        } + +        outmsg->iov_len = retlen; +ret: +        if (retlen == -1) { +                iobuf_unref (iob); +                iob = NULL; +        } + +        return iob; +} + +int +glusterd_submit_reply (rpcsvc_request_t *req, void *arg, +                       struct iovec *payload, int payloadcount, +                       struct iobref *iobref, gd_serialize_t sfunc) +{ +        struct iobuf           *iob        = NULL; +        int                     ret        = -1; +        struct iovec            rsp        = {0,}; +        char                    new_iobref = 0; + +        if (!req) { +                GF_ASSERT (req); +                goto out; +        } + + +        if (!iobref) { +                iobref = iobref_new (); +                if (!iobref) { +                        gf_log ("", GF_LOG_ERROR, "out of memory"); +                        goto out; +                } + +                new_iobref = 1; +        } + +        iob = glusterd_serialize_reply (req, arg, sfunc, &rsp); +        if (!iob) { +                gf_log ("", GF_LOG_ERROR, "Failed to serialize reply"); +                goto out; +        } + +        iobref_add (iobref, iob); + +        ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount, +                                     iobref); + +        /* Now that we've done our job of handing the message to the RPC layer +         * we can safely unref the iob in the hope that RPC layer must have +         * ref'ed the iob on receiving into the txlist. +         */ +        iobuf_unref (iob); +        if (ret == -1) { +                gf_log ("", GF_LOG_ERROR, "Reply submission failed"); +                goto out; +        } + +        ret = 0; +out: + +        if (new_iobref) { +                iobref_unref (iobref); +        } + +        return ret; +} + +gf_boolean_t +glusterd_check_volume_exists (char *volname) +{ +        char pathname[1024] = {0,}; +        struct stat stbuf = {0,}; +        int32_t ret = -1; + +        snprintf (pathname, 1024, "%s/vols/%s", GLUSTERD_DEFAULT_WORKDIR,  +                  volname); + +        ret = stat (pathname, &stbuf); + +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Volume %s does not exist." +                        "stat failed with errno: %d", volname, errno); +                return _gf_false; +        } + +        return _gf_true; +} + +int32_t +glusterd_volinfo_new (glusterd_volinfo_t **volinfo) +{ +        glusterd_volinfo_t      *new_volinfo = NULL; +        int32_t                 ret = -1; + +        GF_ASSERT (volinfo); + +        new_volinfo = GF_CALLOC (1, sizeof(*new_volinfo), +                                 gf_gld_mt_glusterd_volinfo_t); + +        if (!new_volinfo) +                goto out; + +        INIT_LIST_HEAD (&new_volinfo->vol_list); +        INIT_LIST_HEAD (&new_volinfo->bricks); + +        *volinfo = new_volinfo; + +        ret = 0; +         +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int32_t +glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo) +{ +        glusterd_brickinfo_t      *new_brickinfo = NULL; +        int32_t                   ret = -1; + +        GF_ASSERT (brickinfo); + +        new_brickinfo = GF_CALLOC (1, sizeof(*new_brickinfo), +                                   gf_gld_mt_glusterd_brickinfo_t); + +        if (!new_brickinfo) +                goto out; + +        INIT_LIST_HEAD (&new_brickinfo->brick_list); + +        *brickinfo = new_brickinfo; + +        ret = 0; + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int32_t +glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo) +{ +        int32_t                 ret = -1; +        glusterd_brickinfo_t    *new_brickinfo = NULL; +        char                    *hostname = NULL; +        char                    *path = NULL; + +        GF_ASSERT (brick); +        GF_ASSERT (brickinfo); + +        hostname = strtok (brick, ":"); +        path = strtok (NULL, ":"); + +        GF_ASSERT (hostname); +        GF_ASSERT (path); + +        ret = glusterd_brickinfo_new (&new_brickinfo); + +        if (ret) +                goto out; + +        strncpy (new_brickinfo->hostname, hostname, 1024); +        strncpy (new_brickinfo->path, path, 1024); + +        *brickinfo = new_brickinfo; + +        ret = 0; +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +}  | 
