summaryrefslogtreecommitdiffstats
path: root/plugins/xenserver/networking
Commit message (Expand)AuthorAgeFilesLines
* Update OpenStack LLC to FoundationKurt Taylor2013-02-266-6/+6
* fix new N402 errorsSean Dague2013-01-101-2/+2
* Backslash continuation removal (Nova folsom-2)Zhongyue Luo2012-05-313-12/+11
* HACKING fixes, all but sqlalchemy.Yuriy Taraday2012-03-073-27/+27
* Remove a whole bunch of unused importsVishvananda Ishaya2012-01-131-1/+0
* Updates OVS rules applied to IPv4 VIFsKevin L. Mitchell2011-12-131-11/+65
* Bug #888719: openvswitch-nova runs after firstboot scriptsEwan Mellor2011-11-111-1/+1
* Allow tenant networks to be shared with domain 0.Ewan Mellor2011-09-243-13/+40
* Use ovs-vsctl iface-to-br to look up the bridge associated with the given VIF.Ewan Mellor2011-09-241-1/+2
* Remove the unnecessary insertion of whitespace. This happens to be enoughEwan Mellor2011-06-201-5/+1
* pep8 fixesCory Wright2011-05-312-6/+7
* move udev file so it follows the xen-backend.rulesCory Wright2011-05-262-1/+1
* move init start position to 96 to allow openvswitch time to fully startCory Wright2011-05-201-1/+1
* fix typo in udev ruleCory Wright2011-05-181-2/+2
* fix sys.argv requirementCory Wright2011-05-131-1/+1
* add udev rules and modified ovs_configure_vif_flows.py to work with udev rulesCory Wright2011-05-132-12/+19
* Add init script and sysconfig file for openvswitch-novaCory Wright2011-05-133-16/+116
* removed unused imports and renamed template variablesCory Wright2011-04-223-56/+53
* change action= to actions=Cory Wright2011-04-212-28/+28
* bugfix signatureCory Wright2011-04-201-2/+2
* refactor the way flows are deleted/resetCory Wright2011-04-201-73/+70
* only apply ipv6 if the data exists in xenstoreCory Wright2011-04-191-2/+2
* strip output, str() link localCory Wright2011-04-192-2/+2
* calc link localCory Wright2011-04-181-2/+3
* set the bridge on each OvsFlowCory Wright2011-04-141-15/+15
* use novalib for vif_rules.py, fix OvsFlow classCory Wright2011-04-012-18/+9
* extract execute methods to a library for reuseCory Wright2011-04-013-35/+57
* change bridgeCory Wright2011-04-011-1/+2
* lots of updates to ovs scriptsCory Wright2011-04-013-87/+80
* minor fix and commentCory Wright2011-03-281-1/+2
* * committing ovs scriptsCory Wright2011-03-183-4/+267
* cast execute commands to strEric Windisch2011-03-111-0/+1
* execvp: fix paramsEric Windisch2011-03-101-17/+16
* execvp: cleanup.Eric Windisch2011-03-091-11/+11
* execvpEric Windisch2011-03-081-33/+58
* Moving README to doc/networking.rst per recommendation from Jay PipesCory Wright2010-12-271-144/+0
* merge antonymesserli's changes, fixed some formatting, and added copyright no...Cory Wright2010-12-222-0/+159
|\
| * Added networking protections readmeAntony Messerli2010-12-221-0/+126
|/
* Close devnull filehandleCory Wright2010-12-201-2/+3
* Rewrite of vif_rules.py to meet coding standards and be more pythonic in Cory Wright2010-12-203-92/+146
* initial commit of xenserver host protectionsAntony Messerli2010-12-203-0/+177
/td>
/*
   Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
   This file is part of GlusterFS.

   This file is licensed to you under your choice of the GNU Lesser
   General Public License, version 3 or any later version (LGPLv3 or
   later), or the GNU General Public License, version 2 (GPLv2), in all
   cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include "locking.h"
#include "marker-quota.h"
#include "marker-common.h"
#include "marker-quota-helper.h"
#include "marker-mem-types.h"

int
mq_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
{
        int ret = -1;

        GF_VALIDATE_OR_GOTO ("marker", loc, out);
        GF_VALIDATE_OR_GOTO ("marker", inode, out);
        GF_VALIDATE_OR_GOTO ("marker", path, out);
        /* Not checking for parent because while filling
         * loc of root, parent will be NULL
         */

        if (inode) {
                loc->inode = inode_ref (inode);
        }

        if (parent)
                loc->parent = inode_ref (parent);

        if (!gf_uuid_is_null (inode->gfid))
                gf_uuid_copy (loc->gfid, inode->gfid);

        loc->path = gf_strdup (path);
        if (!loc->path) {
                gf_log ("loc fill", GF_LOG_ERROR, "strdup failed");
                goto out;
        }

        loc->name = strrchr (loc->path, '/');
        if (loc->name)
                loc->name++;
        else
                goto out;

        ret = 0;

out:
        if (ret < 0)
                loc_wipe (loc);

        return ret;
}


int32_t
mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)
{
        char            *resolvedpath = NULL;
        inode_t         *parent       = NULL;
        int              ret          = -1;

        if ((!inode) || (!loc))
                return ret;

        if ((inode) && __is_root_gfid (inode->gfid)) {
                loc->parent = NULL;
                goto ignore_parent;
        }

        if (parent_gfid == NULL)
                parent = inode_parent (inode, 0, NULL);
        else
                parent = inode_find (inode->table,
                                     (unsigned char *) parent_gfid);

        if (parent == NULL) {
                gf_log ("marker", GF_LOG_ERROR, "parent is NULL for %s",
                        uuid_utoa(inode->gfid));
                goto err;
        }

ignore_parent:
        ret = inode_path (inode, NULL, &resolvedpath);
        if (ret < 0) {
                gf_log ("marker", GF_LOG_ERROR, "failed to resolve path for %s",
                        uuid_utoa(inode->gfid));
                goto err;
        }

        ret = mq_loc_fill (loc, inode, parent, resolvedpath);
        if (ret < 0)
                goto err;

err:
        if (parent)
                inode_unref (parent);

        GF_FREE (resolvedpath);

        return ret;
}


quota_inode_ctx_t *
mq_alloc_inode_ctx ()
{
        int32_t                  ret    = -1;
        quota_inode_ctx_t       *ctx    = NULL;

        QUOTA_ALLOC (ctx, quota_inode_ctx_t, ret);
        if (ret == -1)
                goto out;

        ctx->size = 0;
        ctx->dirty = 0;
        ctx->updation_status = _gf_false;
        LOCK_INIT (&ctx->lock);
        INIT_LIST_HEAD (&ctx->contribution_head);
out:
        return ctx;
}

void
mq_contri_fini (void *data)
{
        inode_contribution_t *contri = data;

        LOCK_DESTROY (&contri->lock);
        GF_FREE (contri);
}

inode_contribution_t*
mq_contri_init (inode_t *inode)
{
        inode_contribution_t *contri   = NULL;
        int32_t               ret      = 0;

        QUOTA_ALLOC (contri, inode_contribution_t, ret);
        if (ret == -1)
                goto out;

        GF_REF_INIT (contri, mq_contri_fini);

        contri->contribution = 0;
        contri->file_count = 0;
        contri->dir_count = 0;
        gf_uuid_copy (contri->gfid, inode->gfid);

        LOCK_INIT (&contri->lock);
        INIT_LIST_HEAD (&contri->contri_list);

out:
        return contri;
}

inode_contribution_t *
mq_get_contribution_node (inode_t *inode, quota_inode_ctx_t *ctx)
{
        inode_contribution_t    *contri = NULL;
        inode_contribution_t    *temp   = NULL;

        if (!inode || !ctx)
                goto out;

        LOCK (&ctx->lock);
        {
                if (list_empty (&ctx->contribution_head))
                        goto unlock;

                list_for_each_entry (temp, &ctx->contribution_head,
                                     contri_list) {
                        if (gf_uuid_compare (temp->gfid, inode->gfid) == 0) {
                                contri = temp;
                                GF_REF_GET (contri);
                                break;
                        }
                }
        }
unlock:
        UNLOCK (&ctx->lock);

out:
        return contri;
}

inode_contribution_t *
__mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx,
                                loc_t *loc)
{
        inode_contribution_t *contribution = NULL;

        if (!loc->parent) {
                if (!gf_uuid_is_null (loc->pargfid))
                        loc->parent = inode_find (loc->inode->table,
                                                  loc->pargfid);

                if (!loc->parent)
                        loc->parent = inode_parent (loc->inode, loc->pargfid,
                                                    loc->name);
                if (!loc->parent)
                        goto out;
        }

        list_for_each_entry (contribution, &ctx->contribution_head,
                             contri_list) {
                if (loc->parent &&
                    gf_uuid_compare (contribution->gfid, loc->parent->gfid) == 0) {
                        goto out;
                }
        }

        contribution = mq_contri_init (loc->parent);
        if (contribution == NULL)
                goto out;

        list_add_tail (&contribution->contri_list, &ctx->contribution_head);

out:
        return contribution;
}


inode_contribution_t *
mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx,
                              loc_t *loc)
{
        inode_contribution_t *contribution = NULL;

        if ((ctx == NULL) || (loc == NULL))
                return NULL;

        if (((loc->path) && (strcmp (loc->path, "/") == 0))
            || (!loc->path && gf_uuid_is_null (loc->pargfid)))
                return NULL;

        LOCK (&ctx->lock);
        {
                contribution = __mq_add_new_contribution_node (this, ctx, loc);
                if (contribution)
                        GF_REF_GET (contribution);
        }
        UNLOCK (&ctx->lock);

        return contribution;
}


int32_t
mq_dict_set_contribution (xlator_t *this, dict_t *dict, loc_t *loc,
                          uuid_t gfid, char *contri_key)
{
        int32_t ret                  = -1;
        char    key[CONTRI_KEY_MAX]  = {0, };

        GF_VALIDATE_OR_GOTO ("marker", this, out);
        GF_VALIDATE_OR_GOTO ("marker", dict, out);
        GF_VALIDATE_OR_GOTO ("marker", loc, out);

        if (gfid && !gf_uuid_is_null(gfid)) {
                GET_CONTRI_KEY (key, gfid, ret);
        } else if (loc->parent) {
                GET_CONTRI_KEY (key, loc->parent->gfid, ret);
        } else {
                /* nameless lookup, fetch contributions to all parents */
                GET_CONTRI_KEY (key, NULL, ret);
        }

        if (ret < 0)
                goto out;

        ret = dict_set_int64 (dict, key, 0);
        if (ret < 0)
                goto out;

        if (contri_key)
                strncpy (contri_key, key, CONTRI_KEY_MAX);

out:
        if (ret < 0)
                gf_log_callingfn (this->name, GF_LOG_ERROR, "dict set failed");

        return ret;
}


int32_t
mq_inode_ctx_get (inode_t *inode, xlator_t *this,
                  quota_inode_ctx_t **ctx)
{
        int32_t             ret      = -1;
        uint64_t            ctx_int  = 0;
        marker_inode_ctx_t *mark_ctx = NULL;

        GF_VALIDATE_OR_GOTO ("marker", inode, out);
        GF_VALIDATE_OR_GOTO ("marker", this, out);
        GF_VALIDATE_OR_GOTO ("marker", ctx, out);

        ret = inode_ctx_get (inode, this, &ctx_int);
        if (ret < 0) {
                ret = -1;
                *ctx = NULL;
                goto out;
        }

        mark_ctx = (marker_inode_ctx_t *) (unsigned long)ctx_int;
        if (mark_ctx->quota_ctx == NULL) {
                ret = -1;
                goto out;
        }

        *ctx = mark_ctx->quota_ctx;

        ret = 0;

out:
        return ret;
}


quota_inode_ctx_t *
__mq_inode_ctx_new (inode_t *inode, xlator_t *this)
{
        int32_t               ret        = -1;
        quota_inode_ctx_t    *quota_ctx  = NULL;
        marker_inode_ctx_t   *mark_ctx   = NULL;

        ret = marker_force_inode_ctx_get (inode, this, &mark_ctx);
        if (ret < 0) {
                gf_log (this->name, GF_LOG_ERROR,
                        "marker_force_inode_ctx_get() failed");
                goto out;
        }

        LOCK (&inode->lock);
        {
                if (mark_ctx->quota_ctx == NULL) {
                        quota_ctx = mq_alloc_inode_ctx ();
                        if (quota_ctx == NULL) {
                                ret = -1;
                                goto unlock;
                        }
                        mark_ctx->quota_ctx = quota_ctx;
                } else {
                        quota_ctx = mark_ctx->quota_ctx;
                }

                ret = 0;
        }
unlock:
        UNLOCK (&inode->lock);
out:
        return quota_ctx;
}


quota_inode_ctx_t *
mq_inode_ctx_new (inode_t * inode, xlator_t *this)
{
        return __mq_inode_ctx_new (inode, this);
}

quota_local_t *
mq_local_new ()
{
        quota_local_t  *local   = NULL;

        local = mem_get0 (THIS->local_pool);
        if (!local)
                goto out;

        local->ref = 1;
        LOCK_INIT (&local->lock);

        local->ctx = NULL;
        local->contri = NULL;

out:
        return local;
}

quota_local_t *
mq_local_ref (quota_local_t *local)
{
        LOCK (&local->lock);
        {
                local->ref ++;
        }
        UNLOCK (&local->lock);

        return local;
}


int32_t
mq_local_unref (xlator_t *this, quota_local_t *local)
{
        int32_t ref = 0;
        if (local == NULL)
                goto out;

        QUOTA_SAFE_DECREMENT (&local->lock, local->ref, ref);

        if (ref != 0)
                goto out;

        if (local->fd != NULL)
                fd_unref (local->fd);

        if (local->contri)
                GF_REF_PUT (local->contri);

        if (local->xdata)
                dict_unref (local->xdata);

        loc_wipe (&local->loc);

        loc_wipe (&local->parent_loc);

        LOCK_DESTROY (&local->lock);

        mem_put (local);
out:
        return 0;
}


inode_contribution_t *
mq_get_contribution_from_loc (xlator_t *this, loc_t *loc)
{
        int32_t               ret          = 0;
        quota_inode_ctx_t    *ctx          = NULL;
        inode_contribution_t *contribution = NULL;

        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
        if (ret < 0) {
                gf_log_callingfn (this->name, GF_LOG_WARNING,
                                  "cannot get marker-quota context from inode "
                                  "(gfid:%s, path:%s)",
                                  uuid_utoa (loc->inode->gfid), loc->path);
                goto err;
        }

        contribution = mq_get_contribution_node (loc->parent, ctx);
        if (contribution == NULL) {
                gf_log_callingfn (this->name, GF_LOG_WARNING,
                                  "inode (gfid:%s, path:%s) has "
                                  "no contribution towards parent (gfid:%s)",
                                  uuid_utoa (loc->inode->gfid),
                                  loc->path, uuid_utoa (loc->parent->gfid));
                goto err;
        }

err:
        return contribution;
}