| 
														
															@@ -1,4 +1,5 @@ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import errno 
														 | 
														
														 | 
														
															 import errno 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+import mmap 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import os 
														 | 
														
														 | 
														
															 import os 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import shutil 
														 | 
														
														 | 
														
															 import shutil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import struct 
														 | 
														
														 | 
														
															 import struct 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1305,25 +1306,28 @@ class LoggedIO: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             header = fd.read(self.header_fmt.size) 
														 | 
														
														 | 
														
															             header = fd.read(self.header_fmt.size) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def recover_segment(self, segment, filename): 
														 | 
														
														 | 
														
															     def recover_segment(self, segment, filename): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        logger.info('attempting to recover ' + filename) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if segment in self.fds: 
														 | 
														
														 | 
														
															         if segment in self.fds: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             del self.fds[segment] 
														 | 
														
														 | 
														
															             del self.fds[segment] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        with open(filename, 'rb') as fd: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            # XXX: Rather use mmap, this loads the entire segment (up to 500 MB by default) into memory. 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            data = memoryview(fd.read()) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        os.rename(filename, filename + '.beforerecover') 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        logger.info('attempting to recover ' + filename) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        with open(filename, 'wb') as fd: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            fd.write(MAGIC) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            while len(data) >= self.header_fmt.size: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                crc, size, tag = self.header_fmt.unpack(data[:self.header_fmt.size]) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                if size < self.header_fmt.size or size > len(data): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    data = data[1:] 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    continue 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                if crc32(data[4:size]) & 0xffffffff != crc: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    data = data[1:] 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                    continue 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                fd.write(data[:size]) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-                data = data[size:] 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        backup_filename = filename + '.beforerecover' 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        os.rename(filename, backup_filename) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        with open(backup_filename, 'rb') as backup_fd: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            # note: file must not be 0 size (windows can't create 0 size mapping) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            with mmap.mmap(backup_fd.fileno(), 0, access=mmap.ACCESS_READ) as mm: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                data = memoryview(mm) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                with open(filename, 'wb') as fd: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                    fd.write(MAGIC) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                    while len(data) >= self.header_fmt.size: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        crc, size, tag = self.header_fmt.unpack(data[:self.header_fmt.size]) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        if size < self.header_fmt.size or size > len(data): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                            data = data[1:] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                            continue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        if crc32(data[4:size]) & 0xffffffff != crc: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                            data = data[1:] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                            continue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        fd.write(data[:size]) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                        data = data[size:] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                data.release() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def read(self, segment, offset, id, read_data=True): 
														 | 
														
														 | 
														
															     def read(self, segment, offset, id, read_data=True): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         """ 
														 | 
														
														 | 
														
															         """ 
														 |