Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 199868 | Differences between
and this patch

Collapse All | Expand All

(-)portage.orig/pym/portage/__init__.py (-1 / +28 lines)
Lines 98-103 Link Here
98
		'portage.versions:best,catpkgsplit,catsplit,endversion_keys,' + \
98
		'portage.versions:best,catpkgsplit,catsplit,endversion_keys,' + \
99
			'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
99
			'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
100
		'portage.xpak',
100
		'portage.xpak',
101
		'portage.busy',
101
	)
102
	)
102
103
103
	import portage.const
104
	import portage.const
Lines 7503-7515 Link Here
7503
			bsd_chflags.chflags(os.path.dirname(dest), 0)
7504
			bsd_chflags.chflags(os.path.dirname(dest), 0)
7504
7505
7505
	if destexists:
7506
	if destexists:
7506
		if stat.S_ISLNK(dstat[stat.ST_MODE]):
7507
		# done for all but dir now, to assure that busy files are moved
7508
		# out of the way before moving in the new files.
7509
		#if stat.S_ISLNK(dstat[stat.ST_MODE]):
7510
		if not stat.S_ISDIR(dstat[stat.ST_MODE]):
7507
			try:
7511
			try:
7508
				os.unlink(dest)
7512
				os.unlink(dest)
7509
				destexists=0
7513
				destexists=0
7510
			except SystemExit as e:
7514
			except SystemExit as e:
7511
				raise
7515
				raise
7512
			except Exception as e:
7516
			except Exception as e:
7517
				# Failed to remove the existing file. Probably "Text file busy"
7518
				# FIXXME: how can i check whether its really a busy text file?
7519
				_getBusyFiles(mysettings).addBusyFile(dest)
7513
				pass
7520
				pass
7514
7521
7515
	if stat.S_ISLNK(sstat[stat.ST_MODE]):
7522
	if stat.S_ISLNK(sstat[stat.ST_MODE]):
Lines 9084-9089 Link Here
9084
		close_portdbapi_caches()
9091
		close_portdbapi_caches()
9085
		commit_mtimedb()
9092
		commit_mtimedb()
9086
9093
9094
		try:
9095
			_getBusyFiles().cleanBusyFiles()
9096
		except:
9097
			pass
9098
9087
atexit_register(portageexit)
9099
atexit_register(portageexit)
9088
9100
9089
def _global_updates(trees, prev_mtimes):
9101
def _global_updates(trees, prev_mtimes):
Lines 9470-9475 Link Here
9470
		"flushmtimedb"):
9482
		"flushmtimedb"):
9471
		globals()[k] = _LegacyGlobalProxy(k)
9483
		globals()[k] = _LegacyGlobalProxy(k)
9472
9484
9485
busyfiles=None
9486
def _getBusyFiles(mysettings=None):
9487
	global busyfiles
9488
9489
	# i know, if settings differ, you won't get another path to busydb, but
9490
	# as long as you get the same path _always_, this does not matter.
9491
	if busyfiles is None:
9492
		if mysettings is None:
9493
			global settings
9494
			mysettings = settings
9495
9496
		busyfiles = busy.BusyFiles(mysettings)
9497
9498
	return busyfiles
9499
9473
# Clear the cache
9500
# Clear the cache
9474
dircache={}
9501
dircache={}
9475
9502
(-)portage.orig/pym/portage/busy.py (+91 lines)
Line 0 Link Here
1
import portage
2
from portage.const import BUSY_PATH
3
from portage import os
4
5
try:
6
	import cPickle as pickle
7
except ImportError:
8
	import pickle
9
10
class BusyFiles:
11
	settings = None
12
	mypickle = None
13
14
	mybusy = []
15
16
	def __init__(self, settings):
17
		self.settings = settings
18
19
		if self.settings is None:
20
			self.settings = globals()["settings"]
21
22
		self.mypickle = os.path.join(self.settings["ROOT"], BUSY_PATH)
23
24
		try:
25
			my_f = open(self.mypickle, 'rb')
26
			self.mybusy = pickle.load(my_f)
27
			my_f.close()
28
		except Exception:
29
			# simply start with an empty list. the worst case here is, that
30
			# we have temporary files floating around in var/tmp/busy
31
			pass
32
33
		self.cleanBusyFiles()
34
	
35
	def getDestFilename(self, srcfile):
36
		"""calculate a destination filename based on the srcfile filename."""
37
		my_fn = ".$busy-" + srcfile + "."
38
		my_num = 0
39
		
40
		while os.access(my_fn + str(my_num), os.F_OK):
41
			my_num += 1
42
43
		return my_fn + str(my_num)
44
	
45
	def addBusyFile(self, srcfile):
46
		"""moves a source file to the busy file path and remembers it in the busydb."""
47
48
		# before doing something expensive, try to (again) remove the file.
49
		try:
50
			os.unlink(srcfile)
51
			return
52
		except:
53
			pass
54
55
		# ok, the file really insists on beeing busy, try to move it to the
56
		# busy file db.
57
		dst_dir = os.path.dirname(srcfile)
58
		src_nam = os.path.basename(srcfile)
59
60
		destfile = os.path.join(dst_dir, self.getDestFilename(src_nam))
61
62
		try:
63
			os.rename(srcfile, destfile)
64
			self.mybusy.append(destfile)
65
		except:
66
			# uh oh... cannot add busy file, something went wrong - let movefile
67
			# blow up like in the good-old-days...
68
			return
69
70
		self.flush()
71
	
72
	def flush(self):
73
		"""flushes the busydb file (pickles the current file list)."""
74
		my_f = open(self.mypickle, 'wb')
75
		pickle.dump(self.mybusy, my_f)
76
		my_f.close()
77
		pass
78
79
	def cleanBusyFiles(self):
80
		for file in self.mybusy:
81
			if not os.access(file, os.F_OK):
82
				self.mybusy.remove(file)
83
				continue
84
85
			try:
86
				os.unlink(file)
87
				self.mybusy.remove(file)
88
			except:
89
				pass
90
91
		self.flush()
(-)portage.orig/pym/portage/const.py (+1 lines)
Lines 57-62 Link Here
57
# variables used with target_root (these need to be absolute, but not
57
# variables used with target_root (these need to be absolute, but not
58
# have a leading '/' since they are used directly with os.path.join)
58
# have a leading '/' since they are used directly with os.path.join)
59
VDB_PATH                 = EPREFIX_LSTRIP + "/" + "var/db/pkg"
59
VDB_PATH                 = EPREFIX_LSTRIP + "/" + "var/db/pkg"
60
BUSY_PATH                = EPREFIX_LSTRIP + "/" + "var/db/busydb"
60
CACHE_PATH               = EPREFIX_LSTRIP + "/" + "var/cache/edb"
61
CACHE_PATH               = EPREFIX_LSTRIP + "/" + "var/cache/edb"
61
PRIVATE_PATH             = EPREFIX_LSTRIP + "/" + "var/lib/portage"
62
PRIVATE_PATH             = EPREFIX_LSTRIP + "/" + "var/lib/portage"
62
WORLD_FILE               = PRIVATE_PATH + "/world"
63
WORLD_FILE               = PRIVATE_PATH + "/world"
(-)portage.orig/pym/portage/dbapi/vartree.py (-1 / +6 lines)
Lines 3417-3423 Link Here
3417
						# Remove permissions to ensure that any hardlinks to
3417
						# Remove permissions to ensure that any hardlinks to
3418
						# suid/sgid files are rendered harmless.
3418
						# suid/sgid files are rendered harmless.
3419
						os.chmod(file_name, 0)
3419
						os.chmod(file_name, 0)
3420
					os.unlink(file_name)
3420
					try:
3421
						os.unlink(file_name)
3422
					except:
3423
						# rather than failing, we'll use the BusyFiles registry to
3424
						# get the file out of our way, and have it deleted later.
3425
						portage._getBusyFiles(self.settings).addBusyFile(file_name)
3421
				finally:
3426
				finally:
3422
					if bsd_chflags and pflags != 0:
3427
					if bsd_chflags and pflags != 0:
3423
						# Restore the parent flags we saved before unlinking
3428
						# Restore the parent flags we saved before unlinking

Return to bug 199868