Example #1
0
    def entry_ops(cls, entries):
        pfx = gauxpfx()
        logging.debug('entries: %s' % repr(entries))
        # regular file

        def entry_pack_reg(gf, bn, mo, uid, gid):
            blen = len(bn)
            return struct.pack(cls._fmt_mknod(blen),
                               uid, gid, gf, mo, bn,
                               stat.S_IMODE(mo), 0, umask())

        def entry_pack_reg_stat(gf, bn, st):
            blen = len(bn)
            mo = st['mode']
            return struct.pack(cls._fmt_mknod(blen),
                               st['uid'], st['gid'],
                               gf, mo, bn,
                               stat.S_IMODE(mo), 0, umask())
        # mkdir

        def entry_pack_mkdir(gf, bn, mo, uid, gid):
            blen = len(bn)
            return struct.pack(cls._fmt_mkdir(blen),
                               uid, gid, gf, mo, bn,
                               stat.S_IMODE(mo), umask())
        # symlink

        def entry_pack_symlink(gf, bn, lnk, st):
            blen = len(bn)
            llen = len(lnk)
            return struct.pack(cls._fmt_symlink(blen, llen),
                               st['uid'], st['gid'],
                               gf, st['mode'], bn, lnk)

        def entry_purge(entry, gfid):
            # This is an extremely racy code and needs to be fixed ASAP.
            # The GFID check here is to be sure that the pargfid/bname
            # to be purged is the GFID gotten from the changelog.
            # (a stat(changelog_gfid) would also be valid here)
            # The race here is between the GFID check and the purge.
            disk_gfid = cls.gfid_mnt(entry)
            if isinstance(disk_gfid, int):
                return
            if not gfid == disk_gfid:
                return
            er = errno_wrap(os.unlink, [entry], [ENOENT, EISDIR])
            if isinstance(er, int):
                if er == EISDIR:
                    er = errno_wrap(os.rmdir, [entry], [ENOENT, ENOTEMPTY])
                    if er == ENOTEMPTY:
                        return er
        for e in entries:
            blob = None
            op = e['op']
            gfid = e['gfid']
            entry = e['entry']
            (pg, bname) = entry2pb(entry)
            if op in ['RMDIR', 'UNLINK']:
                while True:
                    er = entry_purge(entry, gfid)
                    if isinstance(er, int):
                        time.sleep(1)
                    else:
                        break
            elif op in ['CREATE', 'MKNOD']:
                blob = entry_pack_reg(
                    gfid, bname, e['mode'], e['uid'], e['uid'])
            elif op == 'MKDIR':
                blob = entry_pack_mkdir(
                    gfid, bname, e['mode'], e['uid'], e['uid'])
            elif op == 'LINK':
                slink = os.path.join(pfx, gfid)
                st = lstat(slink)
                if isinstance(st, int):
                    (pg, bname) = entry2pb(entry)
                    blob = entry_pack_reg_stat(gfid, bname, e['stat'])
                else:
                    errno_wrap(os.link, [slink, entry], [ENOENT, EEXIST])
            elif op == 'SYMLINK':
                blob = entry_pack_symlink(gfid, bname, e['link'], e['stat'])
            elif op == 'RENAME':
                en = e['entry1']
                st = lstat(entry)
                if isinstance(st, int):
                    (pg, bname) = entry2pb(en)
                    blob = entry_pack_reg_stat(gfid, bname, e['stat'])
                else:
                    errno_wrap(os.rename, [entry, en], [ENOENT, EEXIST])
            if blob:
                errno_wrap(Xattr.lsetxattr_l, [pg, 'glusterfs.gfid.newfile',
                                               blob],
                           [EEXIST], [ENOENT, ESTALE, EINVAL])
Example #2
0
    def entry_ops(cls, entries):
        pfx = gauxpfx()
        logging.debug("entries: %s" % repr(entries))
        # regular file

        def entry_pack_reg(gf, bn, mo, uid, gid):
            blen = len(bn)
            return struct.pack(cls._fmt_mknod(blen), uid, gid, gf, mo, bn, stat.S_IMODE(mo), 0, umask())

        def entry_pack_reg_stat(gf, bn, st):
            blen = len(bn)
            mo = st["mode"]
            return struct.pack(cls._fmt_mknod(blen), st["uid"], st["gid"], gf, mo, bn, stat.S_IMODE(mo), 0, umask())

        # mkdir

        def entry_pack_mkdir(gf, bn, mo, uid, gid):
            blen = len(bn)
            return struct.pack(cls._fmt_mkdir(blen), uid, gid, gf, mo, bn, stat.S_IMODE(mo), umask())

        # symlink

        def entry_pack_symlink(gf, bn, lnk, st):
            blen = len(bn)
            llen = len(lnk)
            return struct.pack(cls._fmt_symlink(blen, llen), st["uid"], st["gid"], gf, st["mode"], bn, lnk)

        def entry_purge(entry, gfid):
            # This is an extremely racy code and needs to be fixed ASAP.
            # The GFID check here is to be sure that the pargfid/bname
            # to be purged is the GFID gotten from the changelog.
            # (a stat(changelog_gfid) would also be valid here)
            # The race here is between the GFID check and the purge.
            disk_gfid = cls.gfid_mnt(entry)
            if isinstance(disk_gfid, int):
                return
            if not gfid == disk_gfid:
                return
            er = errno_wrap(os.unlink, [entry], [ENOENT, EISDIR])
            if isinstance(er, int):
                if er == EISDIR:
                    er = errno_wrap(os.rmdir, [entry], [ENOENT, ENOTEMPTY])
                    if er == ENOTEMPTY:
                        return er

        for e in entries:
            blob = None
            op = e["op"]
            gfid = e["gfid"]
            entry = e["entry"]
            (pg, bname) = entry2pb(entry)
            if op in ["RMDIR", "UNLINK"]:
                while True:
                    er = entry_purge(entry, gfid)
                    if isinstance(er, int):
                        if er == ENOTEMPTY and op == "RMDIR":
                            er1 = errno_wrap(shutil.rmtree, [os.path.join(pg, bname)], [ENOENT])
                            if not isinstance(er1, int):
                                logging.info("Removed %s/%s recursively" % (pg, bname))
                                break

                        logging.warn("Failed to remove %s => %s/%s. %s" % (gfid, pg, bname, os.strerror(er)))
                        time.sleep(1)
                    else:
                        break
            elif op in ["CREATE", "MKNOD"]:
                blob = entry_pack_reg(gfid, bname, e["mode"], e["uid"], e["gid"])
            elif op == "MKDIR":
                blob = entry_pack_mkdir(gfid, bname, e["mode"], e["uid"], e["gid"])
            elif op == "LINK":
                slink = os.path.join(pfx, gfid)
                st = lstat(slink)
                if isinstance(st, int):
                    (pg, bname) = entry2pb(entry)
                    blob = entry_pack_reg_stat(gfid, bname, e["stat"])
                else:
                    errno_wrap(os.link, [slink, entry], [ENOENT, EEXIST])
            elif op == "SYMLINK":
                blob = entry_pack_symlink(gfid, bname, e["link"], e["stat"])
            elif op == "RENAME":
                en = e["entry1"]
                st = lstat(entry)
                if isinstance(st, int):
                    if e["stat"] and not stat.S_ISDIR(e["stat"]["mode"]):
                        (pg, bname) = entry2pb(en)
                        blob = entry_pack_reg_stat(gfid, bname, e["stat"])
                else:
                    errno_wrap(os.rename, [entry, en], [ENOENT, EEXIST])
            if blob:
                errno_wrap(Xattr.lsetxattr, [pg, "glusterfs.gfid.newfile", blob], [EEXIST], [ENOENT, ESTALE, EINVAL])
Example #3
0
    def entry_ops(cls, entries):
        pfx = gauxpfx()
        logging.debug('entries: %s' % repr(entries))

        # regular file
        def entry_pack_reg(gf, bn, st):
            blen = len(bn)
            mo = st['mode']
            return struct.pack(cls._fmt_mknod(blen), st['uid'], st['gid'], gf,
                               mo, bn, stat.S_IMODE(mo), 0, umask())

        # mkdir
        def entry_pack_mkdir(gf, bn, st):
            blen = len(bn)
            mo = st['mode']
            return struct.pack(cls._fmt_mkdir(blen), st['uid'], st['gid'], gf,
                               mo, bn, stat.S_IMODE(mo), umask())

        #symlink
        def entry_pack_symlink(gf, bn, lnk, st):
            blen = len(bn)
            llen = len(lnk)
            return struct.pack(cls._fmt_symlink(blen, llen), st['uid'],
                               st['gid'], gf, st['mode'], bn, lnk)

        def entry_purge(entry, gfid):
            # This is an extremely racy code and needs to be fixed ASAP.
            # The GFID check here is to be sure that the pargfid/bname
            # to be purged is the GFID gotten from the changelog.
            # (a stat(changelog_gfid) would also be valid here)
            # The race here is between the GFID check and the purge.
            disk_gfid = cls.gfid(entry)
            if isinstance(disk_gfid, int):
                return
            if not gfid == disk_gfid:
                return
            er = errno_wrap(os.unlink, [entry], [ENOENT, EISDIR])
            if isinstance(er, int):
                if er == EISDIR:
                    er = errno_wrap(os.rmdir, [entry], [ENOENT, ENOTEMPTY])
                    if er == ENOTEMPTY:
                        return er

        for e in entries:
            blob = None
            op = e['op']
            gfid = e['gfid']
            entry = e['entry']
            (pg, bname) = entry2pb(entry)
            if op in ['RMDIR', 'UNLINK']:
                while True:
                    er = entry_purge(entry, gfid)
                    if isinstance(er, int):
                        time.sleep(1)
                    else:
                        break
            elif op == 'CREATE':
                blob = entry_pack_reg(gfid, bname, e['stat'])
            elif op == 'MKDIR':
                blob = entry_pack_mkdir(gfid, bname, e['stat'])
            elif op == 'LINK':
                errno_wrap(os.link, [os.path.join(pfx, gfid), entry],
                           [ENOENT, EEXIST])
            elif op == 'SYMLINK':
                blob = entry_pack_symlink(gfid, bname, e['link'], e['stat'])
            elif op == 'RENAME':
                en = e['entry1']
                errno_wrap(os.rename, [entry, en], [ENOENT, EEXIST])
            if blob:
                errno_wrap(Xattr.lsetxattr_l,
                           [pg, 'glusterfs.gfid.newfile', blob],
                           [ENOENT, EEXIST])
Example #4
0
    def entry_ops(cls, entries):
        pfx = gauxpfx()
        logging.debug("entries: %s" % repr(entries))
        # regular file
        def entry_pack_reg(gf, bn, st):
            blen = len(bn)
            mo = st["mode"]
            return struct.pack(cls._fmt_mknod(blen), st["uid"], st["gid"], gf, mo, bn, stat.S_IMODE(mo), 0, umask())

        # mkdir
        def entry_pack_mkdir(gf, bn, st):
            blen = len(bn)
            mo = st["mode"]
            return struct.pack(cls._fmt_mkdir(blen), st["uid"], st["gid"], gf, mo, bn, stat.S_IMODE(mo), umask())

        # symlink
        def entry_pack_symlink(gf, bn, lnk, st):
            blen = len(bn)
            llen = len(lnk)
            return struct.pack(cls._fmt_symlink(blen, llen), st["uid"], st["gid"], gf, st["mode"], bn, lnk)

        def entry_purge(entry, gfid):
            # This is an extremely racy code and needs to be fixed ASAP.
            # The GFID check here is to be sure that the pargfid/bname
            # to be purged is the GFID gotten from the changelog.
            # (a stat(changelog_gfid) would also be valid here)
            # The race here is between the GFID check and the purge.
            disk_gfid = cls.gfid(entry)
            if isinstance(disk_gfid, int):
                return
            if not gfid == disk_gfid:
                return
            er = errno_wrap(os.unlink, [entry], [ENOENT, EISDIR])
            if isinstance(er, int):
                if er == EISDIR:
                    er = errno_wrap(os.rmdir, [entry], [ENOENT, ENOTEMPTY])
                    if er == ENOTEMPTY:
                        return er

        for e in entries:
            blob = None
            op = e["op"]
            gfid = e["gfid"]
            entry = e["entry"]
            (pg, bname) = entry2pb(entry)
            if op in ["RMDIR", "UNLINK"]:
                while True:
                    er = entry_purge(entry, gfid)
                    if isinstance(er, int):
                        time.sleep(1)
                    else:
                        break
            elif op == "CREATE":
                blob = entry_pack_reg(gfid, bname, e["stat"])
            elif op == "MKDIR":
                blob = entry_pack_mkdir(gfid, bname, e["stat"])
            elif op == "LINK":
                errno_wrap(os.link, [os.path.join(pfx, gfid), entry], [ENOENT, EEXIST])
            elif op == "SYMLINK":
                blob = entry_pack_symlink(gfid, bname, e["link"], e["stat"])
            elif op == "RENAME":
                en = e["entry1"]
                errno_wrap(os.rename, [entry, en], [ENOENT, EEXIST])
            if blob:
                errno_wrap(Xattr.lsetxattr_l, [pg, "glusterfs.gfid.newfile", blob], [ENOENT, EEXIST])