Пример #1
0
    def create_backup_entries(self, fst_list):
        """
        Scan the BackupGroup.parent_dev for sub-entries and add those to the bu_list
        """
        pt_entries = partition.get_pt_entries(self.parent_dev)
        if pt_entries:
            self._pt_entries = pt_entries
            
            for index, entry in enumerate(pt_entries, start=0):
                fst = fs.get_fstype(self.parent_dev, fst_list,
                                    seek = (entry.start * 512))
                if not fst:
                    fst = defaultFST

                if fst.name.lower().strip() == "ufs_bsd"  and entry.name.endswith("p1"):
                    print "Skipping dummy BSD Partition", entry.name
                    pt_entries.pop(index)
                    continue
                
                #Create BackupEntry in persistent storage:
                e_persist = self.Persist_cur.add_entry(mapping_start=entry.start,mapping_end=entry.end)
                
                tmp = BackupEntry(entry.name, fst, self.destpath, needs_mapping = True,
                                  compressor=self._group_compression,
                                  compress_threads = self._compress_threads,
                                  compress_level = self._compress_level,
                                  persist_obj = e_persist)
                self.add_entry(tmp)

        else:
            self._pt_entries = []
            fst = fs.get_fstype(self.parent_dev,fst_list)
            if fst:
                e_persist = self.Persist_cur.add_entry()
                tmp = BackupEntry(self.name, fst, self.destpath, needs_mapping = False,
                                  compressor = self._group_compression,
                                  compress_threads = self._compress_threads,
                                  compress_level = self._compress_level, persist_obj = e_persist)
                self.add_entry(tmp)

        
        #Having added all the entries, check if any of them actually need backup,
        #if so, this function handles all the entries to see whether it needs
        #processing, and if none of them need processing the entire BackupGroup
        #is skipped, no snapshots are created, no mappings are made etc.
        self._determine_actions()        
Пример #2
0
    def fscopy(self, infile, outpath, **kwargs):
        #Import this list at call-time rather than at initialization:
        from fst_defs import fst_list

        #Let's make some assumptions:
        #(1): nested LVM will contain only Linux filesytems and possibly swap space
        #(2): we are mapped and infile is an actual device node
        #(3): We are not part of a mirrored/striped setup
        #(4): No snapshot is needed. Assume we are being fed a mapping which is already
        #     part of a snapshot
        ##############
        #Steps:
        # I. First have LVM pick up the volume group
        # II. Assume our filesystems are either mountable Linux or swap.
        # III. We need a single outfile, we will  make a single tar archive containing
        #      each filesystem, the LVM metadata (first 384 blocks of the volume), and
        #      a mapping (in simple key=value format) of which files within the tar
        #      archive belong to which LVM LV.. or better yet, simply name the internal
        #      files as the LV  itself
        
        #After horribly hacking common.py to give us a compress mechanism and also pass us
        #actual paths and not file objects, we have a lot more to work with
        
        #Determine the VG name:
        p = Popen(['pvs', infile, '--noheadings', '-o', 'vg_name'], stderr=PIPE, stdout=PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            raise LVMNestedError(stderr)
        vg_name = stdout.strip()
        
        self._persistent_vars['vg_name'] = vg_name
        
        #Activate our VG
        lvm.vg_activate(vg_name)
        
        try:
            os.mkdir(outpath)
        except OSError as err:
            if err.errno != errno.EEXIST:
                raise

        for bdev in glob(os.path.join('/dev', vg_name, '*')):
            fst = get_fstype(bdev, fst_list)
            if not fst or fst.name.lower() == "lvm":
                backupmethod = ImageDump
            else:
                backupmethod = fst.backupmethod
            
            #Set up names
            outname = ".".join([os.path.basename(bdev), backupmethod.suffix, kwargs['compressor'].suffix])
            outfile = open(os.path.join(outpath, outname), "wb")
            
            #Establish pipeline:
            pipeline_read, pipeline_write = os.pipe()
            pipeline_read = os.fdopen(pipeline_read, "r")
            pipeline_write = os.fdopen(pipeline_write, "w")
            
            #Establish compression and fscopy threads:
            compress_th = threading.Thread(
                name = "compress_lvm",
                target=kwargs['compressor'](level=kwargs['level'],threads=kwargs['threads']).compress,
                args = (pipeline_read, outfile))
            
            fscopy_th = threading.Thread(name="fst_bumethod_lvm", target=backupmethod, args=(bdev,pipeline_write))
            
            compress_th.start()
            fscopy_th.start()
            
            compress_th.join()
            fscopy_th.join()
        
        #Copy LVM metadata:
        metadata=open(infile,"rb").read(512*384)
        open(os.path.join(outpath, "lvm_metadata"),"wb").write(metadata)