Re: Upgrade to 4.1.2 geo-replication does not work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sunny,

I did the mentioned changes given in patch and restart the session for geo-replication. But again same errors in the logs. 

I have attaching the config files and logs here.


[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep stop
Stopping geo-replication session between glusterep & gluster-poc-sj::glusterep has been successful
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep delete
Deleting geo-replication session between glusterep & gluster-poc-sj::glusterep has been successful
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep create push-pem force
Creating geo-replication session between glusterep & gluster-poc-sj::glusterep has been successful
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep start
geo-replication start failed for glusterep gluster-poc-sj::glusterep
geo-replication command failed
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep start
geo-replication start failed for glusterep gluster-poc-sj::glusterep
geo-replication command failed
[root@gluster-poc-noida ~]# vim /usr/libexec/glusterfs/python/syncdaemon/repce.py
[root@gluster-poc-noida ~]# systemctl restart glusterd
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep start
Starting geo-replication session between glusterep & gluster-poc-sj::glusterep has been successful
[root@gluster-poc-noida ~]# gluster volume geo-replication glusterep gluster-poc-sj::glusterep status

MASTER NODE          MASTER VOL    MASTER BRICK         SLAVE USER    SLAVE                        SLAVE NODE    STATUS    CRAWL STATUS    LAST_SYNCED
-----------------------------------------------------------------------------------------------------------------------------------------------------
gluster-poc-noida    glusterep     /data/gluster/gv0    root          gluster-poc-sj::glusterep    N/A           Faulty    N/A             N/A
noi-poc-gluster      glusterep     /data/gluster/gv0    root          gluster-poc-sj::glusterep    N/A           Faulty    N/A             N/A
[root@gluster-poc-noida ~]#


/Krishna.

-----Original Message-----
From: Sunny Kumar <sunkumar@xxxxxxxxxx> 
Sent: Tuesday, August 28, 2018 3:17 PM
To: Krishna Verma <kverma@xxxxxxxxxxx>
Cc: gluster-users@xxxxxxxxxxx
Subject: Re: [Gluster-users] Upgrade to 4.1.2 geo-replication does not work

EXTERNAL MAIL


With same log message ?

Can you please verify that
https://urldefense.proofpoint.com/v2/url?u=https-3A__review.gluster.org_-23_c_glusterfs_-2B_20207_&d=DwIBaQ&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=0E5nRoxLsT2ZXgCpJM_6ZItAWQ2jH8rVLG6tiXhoLFE&m=F0ExtFUfa_YCktOGvy82x3IAxvi2GrbPR72jZ8beuYk&s=fGtkmezHJj5YoLN3dUeVUCcYFnREHyOSk36mRjbTTEQ&e= patch is present if not can you please apply that.
and try with symlinking ln -s /usr/lib64/libgfchangelog.so.0 /usr/lib64/libgfchangelog.so.

Please share the log also.

Regards,
Sunny
On Tue, Aug 28, 2018 at 3:02 PM Krishna Verma <kverma@xxxxxxxxxxx> wrote:
>
> Hi Sunny,
>
> Thanks for your response, I tried both, but still I am getting the same error.
>
>
> [root@noi-poc-gluster ~]# ldconfig /usr/lib [root@noi-poc-gluster ~]#
>
> [root@noi-poc-gluster ~]# ln -s /usr/lib64/libgfchangelog.so.1 
> /usr/lib64/libgfchangelog.so [root@noi-poc-gluster ~]# ls -l 
> /usr/lib64/libgfchangelog.so lrwxrwxrwx. 1 root root 30 Aug 28 14:59 
> /usr/lib64/libgfchangelog.so -> /usr/lib64/libgfchangelog.so.1
>
> /Krishna
>
> -----Original Message-----
> From: Sunny Kumar <sunkumar@xxxxxxxxxx>
> Sent: Tuesday, August 28, 2018 2:55 PM
> To: Krishna Verma <kverma@xxxxxxxxxxx>
> Cc: gluster-users@xxxxxxxxxxx
> Subject: Re: [Gluster-users] Upgrade to 4.1.2 geo-replication does not 
> work
>
> EXTERNAL MAIL
>
>
> Hi Krish,
>
> You can run -
> #ldconfig /usr/lib
>
> If that still does not solves your problem you can do manual symlink 
> like - ln -s /usr/lib64/libgfchangelog.so.1 
> /usr/lib64/libgfchangelog.so
>
> Thanks,
> Sunny Kumar
> On Tue, Aug 28, 2018 at 1:47 PM Krishna Verma <kverma@xxxxxxxxxxx> wrote:
> >
> > Hi
> >
> >
> >
> > I am getting below error in gsyncd.log
> >
> >
> >
> > OSError: libgfchangelog.so: cannot open shared object file: No such 
> > file or directory
> >
> > [2018-08-28 07:19:41.446785] E [repce(worker /data/gluster/gv0):197:__call__] RepceClient: call failed       call=26469:139794524604224:1535440781.44        method=init     error=OSError
> >
> > [2018-08-28 07:19:41.447041] E [syncdutils(worker /data/gluster/gv0):330:log_raise_exception] <top>: FAIL:
> >
> > Traceback (most recent call last):
> >
> >   File "/usr/libexec/glusterfs/python/syncdaemon/gsyncd.py", line 
> > 311, in main
> >
> >     func(args)
> >
> >   File "/usr/libexec/glusterfs/python/syncdaemon/subcmds.py", line 
> > 72, in subcmd_worker
> >
> >     local.service_loop(remote)
> >
> >   File "/usr/libexec/glusterfs/python/syncdaemon/resource.py", line 
> > 1236, in service_loop
> >
> >     changelog_agent.init()
> >
> >   File "/usr/libexec/glusterfs/python/syncdaemon/repce.py", line 
> > 216, in __call__
> >
> >     return self.ins(self.meth, *a)
> >
> >   File "/usr/libexec/glusterfs/python/syncdaemon/repce.py", line 
> > 198, in __call__
> >
> >     raise res
> >
> > OSError: libgfchangelog.so: cannot open shared object file: No such 
> > file or directory
> >
> > [2018-08-28 07:19:41.457555] I [repce(agent /data/gluster/gv0):80:service_loop] RepceServer: terminating on reaching EOF.
> >
> > [2018-08-28 07:19:42.440184] I [monitor(monitor):272:monitor] Monitor:
> > worker died in startup phase  brick=/data/gluster/gv0
> >
> >
> >
> > Below is my file location:
> >
> >
> >
> > /usr/lib64/libgfchangelog.so.0
> >
> > /usr/lib64/libgfchangelog.so.0.0.1
> >
> >
> >
> > What I can do to fix it ?
> >
> >
> >
> > /Krish
> >
> > _______________________________________________
> > Gluster-users mailing list
> > Gluster-users@xxxxxxxxxxx
> > https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gluster.o
> > rg 
> > _mailman_listinfo_gluster-2Dusers&d=DwIBaQ&c=aUq983L2pue2FqKFoP6PGHM
> > JQ
> > yoJ7kl3s3GZ-_haXqY&r=0E5nRoxLsT2ZXgCpJM_6ZItAWQ2jH8rVLG6tiXhoLFE&m=_
> > u6
> > vGRjlVsype7Z8hXDgCONilqVe4sIWkXNqqz2n3IQ&s=i0EUwtUHurhJHyw9UPpepCdLB
> > 70
> > 1mkxoNZWYvU7XXug&e=
#
# Copyright (c) 2011-2014 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.
#

import os
import sys
import time
import logging
from threading import Condition
import thread as thread
from Queue import Queue
import cPickle as pickle

from syncdutils import Thread, select, lf

pickle_proto = -1
repce_version = 1.0


def ioparse(i, o):
    if isinstance(i, int):
        i = os.fdopen(i)
    # rely on duck typing for recognizing
    # streams as that works uniformly
    # in py2 and py3
    if hasattr(o, 'fileno'):
        o = o.fileno()
    return (i, o)


def send(out, *args):
    """pickle args and write out wholly in one syscall

    ie. not use the ability of pickle to dump directly to
    a stream, as that would potentially mess up messages
    by interleaving them
    """
    os.write(out, pickle.dumps(args, pickle_proto))


def recv(inf):
    """load an object from input stream"""
    return pickle.load(inf)


class RepceServer(object):

    """RePCe is Hungarian for canola, http://hu.wikipedia.org/wiki/Repce

    ... also our homebrewed RPC backend where the transport layer is
    reduced to a pair of filehandles.

    This is the server component.
    """

    def __init__(self, obj, i, o, wnum=6):
        """register a backend object .obj to which incoming messages
           are dispatched, also incoming/outcoming streams
        """
        self.obj = obj
        self.inf, self.out = ioparse(i, o)
        self.wnum = wnum
        self.q = Queue()

    def service_loop(self):
        """fire up worker threads, get messages and dispatch among them"""
        for i in range(self.wnum):
            t = Thread(target=self.worker)
            t.start()
        try:
            while True:
                self.q.put(recv(self.inf))
        except EOFError:
            logging.info("terminating on reaching EOF.")

    def worker(self):
        """life of a worker

        Get message, extract its id, method name and arguments
        (kwargs not supported), call method on .obj.
        Send back message id + return value.
        If method call throws an exception, rescue it, and send
        back the exception as result (with flag marking it as
        exception).
        """
        while True:
            in_data = self.q.get(True)
            rid = in_data[0]
            rmeth = in_data[1]
            exc = False
            if rmeth == '__repce_version__':
                res = repce_version
            else:
                try:
                    res = getattr(self.obj, rmeth)(*in_data[2:])
                except:
                    res = sys.exc_info()[1]
                    exc = True
                    logging.exception("call failed: ")
            send(self.out, rid, exc, res)


class RepceJob(object):

    """class representing message status we can use
    for waiting on reply"""

    def __init__(self, cbk):
        """
        - .rid: (process-wise) unique id
        - .cbk: what we do upon receiving reply
        """
        self.rid = (os.getpid(), thread.get_ident(), time.time())
        self.cbk = cbk
        self.lever = Condition()
        self.done = False

    def __repr__(self):
        return ':'.join([str(x) for x in self.rid])

    def wait(self):
        self.lever.acquire()
        if not self.done:
            self.lever.wait()
        self.lever.release()
        return self.result

    def wakeup(self, data):
        self.result = data
        self.lever.acquire()
        self.done = True
        self.lever.notify()
        self.lever.release()


class RepceClient(object):

    """RePCe is Hungarian for canola, http://hu.wikipedia.org/wiki/Repce

    ... also our homebrewed RPC backend where the transport layer is
    reduced to a pair of filehandles.

    This is the client component.
    """

    def __init__(self, i, o):
        self.inf, self.out = ioparse(i, o)
        self.jtab = {}
        t = Thread(target=self.listen)
        t.start()

    def listen(self):
        while True:
            select((self.inf,), (), ())
            rid, exc, res = recv(self.inf)
            rjob = self.jtab.pop(rid)
            if rjob.cbk:
                rjob.cbk(rjob, [exc, res])

    def push(self, meth, *args, **kw):
        """wrap arguments in a RepceJob, send them to server
           and return the RepceJob

           @cbk to pass on RepceJob can be given as kwarg.
        """
        cbk = kw.get('cbk')
        if not cbk:
            def cbk(rj, res):
                if res[0]:
                    raise res[1]
        rjob = RepceJob(cbk)
        self.jtab[rjob.rid] = rjob
        logging.debug("call %s %s%s ..." % (repr(rjob), meth, repr(args)))
        send(self.out, rjob.rid, meth, *args)
        return rjob

    def __call__(self, meth, *args):
        """RePCe client is callabe, calling it implements a synchronous
        remote call.

        We do a .push with a cbk which does a wakeup upon receiving anwser,
        then wait on the RepceJob.
        """
        rjob = self.push(
            meth, *args, **{'cbk': lambda rj, res: rj.wakeup(res)})
        exc, res = rjob.wait()
        if exc:
            logging.error(lf('call failed',
                             call=repr(rjob),
                             method=meth,
                             error=str(type(res).__name__)))
            raise res
        logging.debug("call %s %s -> %s" % (repr(rjob), meth, repr(res)))
        return res

    class mprx(object):

        """method proxy, standard trick to implement rubyesque
        method_missing in Python

        A class is a closure factory, you know what I mean, or go read
        some SICP.
        """

        def __init__(self, ins, meth):
            self.ins = ins
            self.meth = meth

        def __call__(self, *a):
            return self.ins(self.meth, *a)

    def __getattr__(self, meth):
        """this implements transparent method dispatch to remote object,
           so that you don't need to call the RepceClient instance like

             rclient('how_old_are_you_if_born_in', 1979)

           but you can make it into an ordinary method call like

             rclient.how_old_are_you_if_born_in(1979)
        """
        return self.mprx(self, meth)

    def __version__(self):
        """used in handshake to verify compatibility"""
        d = {'proto': self('__repce_version__')}
        try:
            d['object'] = self('version')
        except AttributeError:
            pass
        return d
from ConfigParser import ConfigParser as ConfigParser, NoSectionError
import os
from string import Template
from datetime import datetime


# Global object which can be used in other modules
# once load_config is called
_gconf = {}


class GconfNotConfigurable(Exception):
    pass


class GconfInvalidValue(Exception):
    pass


class Gconf(object):
    def __init__(self, default_conf_file, custom_conf_file=None,
                 args={}, extra_tmpl_args={}, override_from_args=False):
        self.default_conf_file = default_conf_file
        self.custom_conf_file = custom_conf_file
        self.tmp_conf_file = None
        self.gconf = {}
        self.gconfdata = {}
        self.gconf_typecast = {}
        self.template_conf = []
        self.non_configurable_configs = []
        self.prev_mtime = 0
        if custom_conf_file is not None:
            self.tmp_conf_file = custom_conf_file + ".tmp"

        self.session_conf_items = []
        self.args = args
        self.extra_tmpl_args = extra_tmpl_args
        self.override_from_args = override_from_args
        # Store default values only if overwriten, Only for JSON/CLI output
        self.default_values = {}
        self._load()

    def _tmpl_substitute(self):
        tmpl_values = {}
        for k, v in self.gconf.items():
            tmpl_values[k.replace("-", "_")] = v

        # override the config file values with the one user passed
        for k, v in self.args.items():
            # override the existing value only if set by user
            if v is not None:
                tmpl_values[k] = v

        for k, v in self.extra_tmpl_args.items():
            tmpl_values[k] = v

        for k, v in self.gconf.items():
            if k in self.template_conf and \
               (isinstance(v, str) or isinstance(v, unicode)):
                self.gconf[k] = Template(v).safe_substitute(tmpl_values)

    def _do_typecast(self):
        for k, v in self.gconf.items():
            cast_func = globals().get(
                "to_" + self.gconf_typecast.get(k, "string"), None)
            if cast_func is not None:
                self.gconf[k] = cast_func(v)
                if self.default_values.get(k, None) is not None:
                    self.default_values[k] = cast_func(v)

    def reset(self, name):
        # If custom conf file is not set then it is only read only configs
        if self.custom_conf_file is None:
            raise GconfNotConfigurable()

        # If a config can not be modified
        if name != "all" and not self._is_configurable(name):
            raise GconfNotConfigurable()

        cnf = ConfigParser()
        with open(self.custom_conf_file) as f:
            cnf.readfp(f)

            # Nothing to Reset, Not configured
            if name != "all":
                if not cnf.has_option("vars", name):
                    return True

                # Remove option from custom conf file
                cnf.remove_option("vars", name)
            else:
                # Remove and add empty section, do not disturb if config file
                # already has any other section
                try:
                    cnf.remove_section("vars")
                except NoSectionError:
                    pass

                cnf.add_section("vars")

        with open(self.tmp_conf_file, "w") as fw:
            cnf.write(fw)

        os.rename(self.tmp_conf_file, self.custom_conf_file)

        self.reload()

        return True

    def set(self, name, value):
        if self.custom_conf_file is None:
            raise GconfNotConfigurable()

        if not self._is_configurable(name):
            raise GconfNotConfigurable()

        if not self._is_valid_value(name, value):
            raise GconfInvalidValue()

        curr_val = self.gconf.get(name, None)
        if curr_val == value:
            return True

        cnf = ConfigParser()
        with open(self.custom_conf_file) as f:
            cnf.readfp(f)

        if not cnf.has_section("vars"):
            cnf.add_section("vars")

        cnf.set("vars", name, value)
        with open(self.tmp_conf_file, "w") as fw:
            cnf.write(fw)

        os.rename(self.tmp_conf_file, self.custom_conf_file)

        self.reload()

        return True

    def check(self, name, value=None, with_conffile=True):
        if with_conffile and self.custom_conf_file is None:
            raise GconfNotConfigurable()

        if not self._is_configurable(name):
            raise GconfNotConfigurable()

        if value is not None and not self._is_valid_value(name, value):
            raise GconfInvalidValue()

    def _load(self):
        self.gconf = {}
        self.template_conf = []
        self.gconf_typecast = {}
        self.non_configurable_configs = []
        self.session_conf_items = []
        self.default_values = {}

        conf = ConfigParser()
        # Default Template config file
        with open(self.default_conf_file) as f:
            conf.readfp(f)

        # Custom Config file
        if self.custom_conf_file is not None:
            with open(self.custom_conf_file) as f:
                conf.readfp(f)

        # Get version from default conf file
        self.version = conf.get("__meta__", "version")

        # Populate default values
        for sect in conf.sections():
            if sect in ["__meta__", "vars"]:
                continue

            # Collect list of available options with help details
            self.gconfdata[sect] = {}
            for k, v in conf.items(sect):
                self.gconfdata[sect][k] = v.strip()

            # Collect the Type cast information
            if conf.has_option(sect, "type"):
                self.gconf_typecast[sect] = conf.get(sect, "type")

            # Prepare list of configurable conf
            if conf.has_option(sect, "configurable"):
                if conf.get(sect, "configurable").lower() == "false":
                    self.non_configurable_configs.append(sect)

            # if it is a template conf value which needs to be substituted
            if conf.has_option(sect, "template"):
                if conf.get(sect, "template").lower().strip() == "true":
                    self.template_conf.append(sect)

            # Set default values
            if conf.has_option(sect, "value"):
                self.gconf[sect] = conf.get(sect, "value").strip()

        # Load the custom conf elements and overwrite
        if conf.has_section("vars"):
            for k, v in conf.items("vars"):
                self.session_conf_items.append(k)
                self.default_values[k] = self.gconf.get(k, "")
                self.gconf[k] = v.strip()

        # Overwrite the Slave configurations which are sent as
        # arguments to gsyncd slave
        if self.override_from_args:
            for k, v in self.args.items():
                k = k.replace("_", "-")
                if k.startswith("slave-") and k in self.gconf:
                    self.gconf[k] = v

        self._tmpl_substitute()
        self._do_typecast()

    def reload(self):
        if self._is_config_changed():
            self._load()

    def get(self, name, default_value=None):
        return self.gconf.get(name, default_value)

    def getall(self, show_defaults=False, show_non_configurable=False):
        cnf = {}
        if not show_defaults:
            for k in self.session_conf_items:
                if k not in self.non_configurable_configs:
                    dv = self.default_values.get(k, "")
                    cnf[k] = {
                        "value": self.get(k),
                        "default": dv,
                        "configurable": True,
                        "modified": False if dv == "" else True
                    }
            return cnf

        # Show all configs including defaults
        for k, v in self.gconf.items():
            configurable = False if k in self.non_configurable_configs \
                           else True
            dv = self.default_values.get(k, "")
            modified = False if dv == "" else True
            if show_non_configurable:
                cnf[k] = {
                    "value": v,
                    "default": dv,
                    "configurable": configurable,
                    "modified": modified
                }
            else:
                if k not in self.non_configurable_configs:
                    cnf[k] = {
                        "value": v,
                        "default": dv,
                        "configurable": configurable,
                        "modified": modified
                    }

        return cnf

    def getr(self, name, default_value=None):
        self.reload()
        return self.get(name, default_value)

    def get_help(self, name=None):
        pass

    def _is_configurable(self, name):
        item = self.gconfdata.get(name, None)
        if item is None:
            return False

        return item.get("configurable", True)

    def _is_valid_value(self, name, value):
        item = self.gconfdata.get(name, None)
        if item is None:
            return False

        # If validation func not defined
        if item.get("validation", None) is None:
            return True

        # minmax validation
        if item["validation"] == "minmax":
            return validate_minmax(value, item["min"], item["max"])

        if item["validation"] == "choice":
            return validate_choice(value, item["allowed_values"])

        if item["validation"] == "bool":
            return validate_bool(value)

        if item["validation"] == "execpath":
            return validate_execpath(value)

        if item["validation"] == "unixtime":
            return validate_unixtime(value)

        return False

    def _is_config_changed(self):
        if self.custom_conf_file is not None and \
           os.path.exists(self.custom_conf_file):
                st = os.lstat(self.custom_conf_file)
                if st.st_mtime > self.prev_mtime:
                    self.prev_mtime = st.st_mtime
                    return True

        return False


def validate_unixtime(value):
    try:
        y = datetime.fromtimestamp(int(value)).strftime("%Y")
        if y == "1970":
            return False

        return True
    except ValueError:
        return False


def validate_minmax(value, minval, maxval):
    value = int(value)
    minval = int(minval)
    maxval = int(maxval)

    return value >= minval and value <= maxval


def validate_choice(value, allowed_values):
    allowed_values = allowed_values.split(",")
    allowed_values = [v.strip() for v in allowed_values]

    return value in allowed_values


def validate_bool(value):
    return value in ["true", "false"]


def validate_execpath(value):
    return os.path.isfile(value) and os.access(value, os.X_OK)


def validate_filepath(value):
    return os.path.isfile(value)


def validate_path(value):
    return os.path.exists(value)


def to_int(value):
    return int(value)


def to_float(value):
    return float(value)


def to_bool(value):
    if isinstance(value, bool):
        return value
    return True if value in ["true", "True"] else False


def get(name, default_value=None):
    return _gconf.get(name, default_value)


def getall(show_defaults=False, show_non_configurable=False):
    return _gconf.getall(show_defaults=show_defaults,
                         show_non_configurable=show_non_configurable)


def getr(name, default_value=None):
    return _gconf.getr(name, default_value)


def load(default_conf, custom_conf=None, args={}, extra_tmpl_args={},
         override_from_args=False):
    global _gconf
    _gconf = Gconf(default_conf, custom_conf, args, extra_tmpl_args,
                   override_from_args)


def setconfig(name, value):
    global _gconf
    _gconf.set(name, value)


def resetconfig(name):
    global _gconf
    _gconf.reset(name)


def check(name, value=None, with_conffile=True):
    global _gconf
    _gconf.check(name, value=value, with_conffile=with_conffile)

Attachment: gsyncd.log
Description: gsyncd.log

_______________________________________________
Gluster-users mailing list
Gluster-users@xxxxxxxxxxx
https://lists.gluster.org/mailman/listinfo/gluster-users

[Index of Archives]     [Gluster Development]     [Linux Filesytems Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux