Beispiel #1
0
 def __search_checkpoints(self, n, x):
     for p in glob(
             os.path.join(kutil.fsget(x.dev), ".inodes", str(x.ino)) + "*"):
         dbg.info("found inodes: %s" % p)
         info = p.split(".")
         tic = (int(info[-2]) * 10**9 + int(info[-1]), 0)
         n.checkpoints.add(fsmgr.FileCheckpoint(tic, tic, x.dev, x.ino, p))
Beispiel #2
0
    def get_file_dev_ino(self):
        """Get the (dev, ino) that this directory entry currently points
    to.

    Should be the same (dev, ino) pair that os.stat() would return
    when called on the pathname of this file."""

        dev_pn = kutil.fsget(self.dev)
        dir_pn = kutil.iget(dev_pn, self.ino)

        cur_ino = self._get_inode(dir_pn, self.name_in_dir)
        return (self.dev, cur_ino)
Beispiel #3
0
    def __init__(self, tic, tac, dev, ino):
        fs = kutil.fsget(dev)
        src = kutil.iget(fs, ino)
        dst = os.path.join(fs, ".inodes", str(ino) + "-" + str(tic[0]))

        shutil.copy(src, dst)

        self.name = ('File', dev, ino, dst)
        self.dev = dev
        self.ino = ino
        self.snap = dst

        super(FileContentCheckpoint, self).__init__(tic, tac)
Beispiel #4
0
    def rollback(self, c):
        assert (isinstance(c, FileCheckpoint))

        # XXX. hack to ignore /proc and /dev entries
        if any(c.d_pn.startswith(d) for d in ["/proc", "/dev"]):
            return None

        cpn = c.pn()

        try:
            dev_pn = kutil.fsget(self.dev)
            ino_pn = kutil.iget(dev_pn, self.ino)
        except kutil.MissingInode:
            if cpn is None:
                return

        dbg.infom("!", "#R<rollback#> %s(%s) -> %s" % (self.ino, ino_pn, cpn))
        dbg.infom("readers %s" % str(self.readers))
        dbg.infom("writers %s" % str(self.writers))

        if runopts.dryrun:
            return

        cstat = os.lstat(cpn) if cpn else None
        istat = os.lstat(ino_pn)

        if (cstat
                and stat.S_IFMT(istat.st_mode) != stat.S_IFMT(cstat.st_mode)):
            raise Exception('inode changed types', cpn, ino_pn, cstat, istat)

        if stat.S_ISREG(istat.st_mode):
            if cpn:
                with open(cpn, 'r') as f1:
                    f1data = f1.read()
            else:
                f1data = ''
            with open(ino_pn, 'r') as f2:
                f2data = f2.read()
            if f1data != f2data:
                with open(ino_pn, 'w') as f2:
                    f2.write(f1data)
        elif stat.S_ISLNK(istat.st_mode):
            pass  ## no way to change existing symlink
        elif stat.S_ISDIR(istat.st_mode):
            # XXX.
            pass
        else:
            raise Exception('cannot handle inode type',
                            stat.S_IFMT(istat.st_mode))
Beispiel #5
0
    def syscall_open(self, arg, ret):
        r = arg.data
        assert r.nr == syscall.NR_open
        assert ((r.args["path"].inode is None)
                or (r.args["path"].inode == r.ret.inode))

        inode = r.ret.inode
        dbg.syscallm("!", "#R<open#>: %s" % (str(r)))
        if runopts.dryrun:
            return ret.origdata

        pn = r.args['path'].path  # pathname to file

        # if not absolute pathname, retrieve with iget
        if not pn.startswith('/'):
            dentry = r.args['path'].entries[0]
            assert type(dentry) == sysarg.dentry
            pn = os.path.join("%s/%s" %
                              (kutil.get(dentry.parent), dentry.name))

        # flag == os.O_CREAT and only the case we really created an empty file
        if (r.args["path"].inode is None):
            src_pn = os.path.join(kutil.fsget(inode.dev), ".inodes",
                                  str(inode.ino))
            # to keep the inode
            os.rename(src_pn, pn)
            # make it empty when newly created
            with open(pn, "w") as f:
                pass
            dbg.syscallm("!", "#R<rename#>: %s -> %s" % (src_pn, pn))

        # if explicit truncate request
        if (r.args['flags'] & os.O_TRUNC):
            with open(pn, "w") as f:
                pass

        # If the syscall opened a _different_ inode than the file
        # points to now.
        path = r.args['path']
        arg_name = path.path
        dir_dev = path.entries[0].parent.dev
        dir_ino = path.entries[0].parent.ino

        dirent = fsmgr.DirentDataNode.get(dir_dev, dir_ino, arg_name)
        (cur_dev, cur_ino) = dirent.get_file_dev_ino()
        ret.data = deepcopy(ret.origdata)
        ret.data.ret.inode.ino, ret.data.ret.inode.dev = (cur_ino, cur_dev)

        return ret.data
Beispiel #6
0
def search_snap(dev, ino):
    ## XXX hack to find snapshots
    fs = kutil.fsget(dev)
    if fs in ['/'] or any(fs.startswith(d) for d in ['/proc', '/dev']):
        yield (mgrapi.MinusInfinity(), mgrapi.MinusInfinity(), fs)
        return
    if not fs.endswith('trunk'): return

    root = os.path.dirname(fs)

    for s in os.listdir(root):
        if s.startswith("snap"):
            t = (int(s.split("-")[-1]) * (10**9), )
            yield (t, t, os.path.join(root, s))

    mi = mgrapi.MinusInfinity()
    if os.path.exists(os.path.join(root, 'fresh')):
        yield (mi, mi, os.path.join(root, 'fresh'))
Beispiel #7
0
    def rollback(self, c):
        assert (isinstance(c, FileCheckpoint))

        # XXX. hack to ignore /proc entries
        if any(c.d_pn.startswith(d) for d in ["/proc", "/dev"]):
            return

        cp_ino = None  # ino of the directory _entry_

        cpn = c.pn()
        if cpn:
            cp_ino = self._get_inode(cpn, self.name_in_dir)

        dev_pn = kutil.fsget(self.dev)
        dir_pn = kutil.iget(dev_pn, self.ino)

        cur_ino = self._get_inode(dir_pn, self.name_in_dir)

        if cp_ino == cur_ino:
            return

        if cur_ino is not None:
            # backup
            src = os.path.join(dir_pn, self.name_in_dir)
            dst = os.path.join(dev_pn, ".inodes", str(cur_ino))

            dbg.infom("!", "#R<rename#>: %s -> %s" % (src, dst))
            dbg.infom("readers %s" % str(self.readers))
            dbg.infom("writers %s" % str(self.writers))

            if not runopts.dryrun:
                os.rename(src, dst)

        if cp_ino is not None:
            src = kutil.iget(dev_pn, cp_ino)
            dst = os.path.join(dir_pn, self.name_in_dir)

            dbg.infom("!", "#R<link#>: %s -> %s" % (src, dst))

            if not runopts.dryrun:
                os.link(src, dst)

        kutil.dcache_flush()