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

Collapse All | Expand All

(-)portage-2.1.2.orig/bin/emerge (-328 / +735 lines)
Lines 2008-2013 Link Here
2008
		ignore_priority_range.extend(
2008
		ignore_priority_range.extend(
2009
			xrange(DepPriority.MIN, DepPriority.MEDIUM + 1))
2009
			xrange(DepPriority.MIN, DepPriority.MEDIUM + 1))
2010
		tree_mode = "--tree" in self.myopts
2010
		tree_mode = "--tree" in self.myopts
2011
		slotcount = 0
2011
		while not mygraph.empty():
2012
		while not mygraph.empty():
2012
			ignore_priority = None
2013
			ignore_priority = None
2013
			nodes = None
2014
			nodes = None
Lines 2125-2131 Link Here
2125
				sys.exit(1)
2126
				sys.exit(1)
2126
2127
2127
			for node in selected_nodes:
2128
			for node in selected_nodes:
2128
				retlist.append(list(node))
2129
				node2 = list(node)
2130
				if len(node2) == 4:
2131
					node2.append(str(slotcount))
2132
				retlist.append(node2)
2129
				mygraph.remove(node)
2133
				mygraph.remove(node)
2130
				if not reversed and not circular_blocks and myblockers.contains(node):
2134
				if not reversed and not circular_blocks and myblockers.contains(node):
2131
					"""This node may have invalidated one or more blockers."""
2135
					"""This node may have invalidated one or more blockers."""
Lines 2139-2144 Link Here
2139
								self.blocker_parents[blocker] = unresolved
2143
								self.blocker_parents[blocker] = unresolved
2140
							else:
2144
							else:
2141
								del self.blocker_parents[blocker]
2145
								del self.blocker_parents[blocker]
2146
			slotcount += 1
2142
2147
2143
		if not reversed:
2148
		if not reversed:
2144
			"""Blocker validation does not work with reverse mode,
2149
			"""Blocker validation does not work with reverse mode,
Lines 2344-2350 Link Here
2344
			if "blocks" == x[0]:
2349
			if "blocks" == x[0]:
2345
				display_list.append((x, 0, True))
2350
				display_list.append((x, 0, True))
2346
				continue
2351
				continue
2347
			graph_key = tuple(x)
2352
			if len(x) > 4:
2353
				graph_key = tuple(x[:-1])
2354
			else:
2355
				graph_key = tuple(x)
2348
			if "--tree" in self.myopts:
2356
			if "--tree" in self.myopts:
2349
				depth = len(tree_nodes)
2357
				depth = len(tree_nodes)
2350
				while depth and graph_key not in \
2358
				while depth and graph_key not in \
Lines 2398-2404 Link Here
2398
				continue
2406
				continue
2399
			if "blocks" == graph_key[0]:
2407
			if "blocks" == graph_key[0]:
2400
				continue
2408
				continue
2401
			if ordered and graph_key[-1] != "nomerge":
2409
			if len(graph_key) > 4:
2410
				merge_op = graph_key[-2]
2411
			else:
2412
				merge_op = graph_key[-1]
2413
			if ordered and merge_op != "nomerge":
2402
				last_merge_depth = depth
2414
				last_merge_depth = depth
2403
				continue
2415
				continue
2404
			if depth >= last_merge_depth or \
2416
			if depth >= last_merge_depth or \
Lines 2607-2613 Link Here
2607
				if verbosity == 3:
2619
				if verbosity == 3:
2608
					# size verbose
2620
					# size verbose
2609
					mysize=0
2621
					mysize=0
2610
					if x[0] == "ebuild" and ordered and x[-1] != "nomerge":
2622
					if len(x) > 4:
2623
						merge_op = x[-2]
2624
					else:
2625
						merge_op = x[-1]
2626
					if x[0] == "ebuild" and ordered and merge_op != "nomerge":
2611
						try:
2627
						try:
2612
							myfilesdict = portdb.getfetchsizes(pkg_key,
2628
							myfilesdict = portdb.getfetchsizes(pkg_key,
2613
								useflags=self.useFlags[myroot][pkg_key],
2629
								useflags=self.useFlags[myroot][pkg_key],
Lines 2686-2692 Link Here
2686
							myprint=myprint+myoldbest
2702
							myprint=myprint+myoldbest
2687
							myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
2703
							myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
2688
					else:
2704
					else:
2689
						if x[-1] == "nomerge" or not ordered:
2705
						if len(x) > 4:
2706
							merge_op = x[-2]
2707
						else:
2708
							merge_op = x[-1]
2709
						if merge_op == "nomerge" or not ordered:
2690
							myprint = darkblue("[nomerge      ] ")
2710
							myprint = darkblue("[nomerge      ] ")
2691
						else:
2711
						else:
2692
							myprint = "[" + pkg_type + " " + addl + "] "
2712
							myprint = "[" + pkg_type + " " + addl + "] "
Lines 2893-2903 Link Here
2893
			self.pkgsettings["/"] = \
2913
			self.pkgsettings["/"] = \
2894
				portage.config(clone=trees["/"]["vartree"].settings)
2914
				portage.config(clone=trees["/"]["vartree"].settings)
2895
2915
2896
	def merge(self, mylist, favorites, mtimedb):
2916
	def restart_portage(self, x, mergecount, totalcount, mtimedb):
2917
		xterm_titles = "notitles" not in self.settings.features
2918
		# don't really restart if any of these is true
2919
		# XXXXX - seems like redundant check, but what the hell! sky is not falling as yet.
2920
		if "--pretend" in self.myopts or "--fetchonly" in self.myopts or \
2921
			"--fetch-all-uri" in self.myopts or "--buildpkgonly" in self.myopts:
2922
			return
2923
2924
		bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
2925
			"--resume"])
2926
		mysplit=portage.pkgsplit(x[2])
2927
		myver=mysplit[1]+"-"+mysplit[2]
2928
		if myver[-3:]=='-r0':
2929
			myver=myver[:-3]
2930
		if (myver != portage.VERSION) and \
2931
		   "livecvsportage" not in self.settings.features:
2932
			if totalcount > mergecount:
2933
				emergelog(xterm_titles,
2934
					" ::: completed emerge ("+ \
2935
					str(mergecount)+" of "+ \
2936
					str(totalcount)+") "+ \
2937
					x[2]+" to "+x[1])
2938
				emergelog(xterm_titles, " *** RESTARTING " + \
2939
					"emerge via exec() after change of " + \
2940
					"portage version.")
2941
				portage.run_exitfuncs()
2942
				mynewargv=[sys.argv[0],"--resume"]
2943
				resume_opts = self.myopts.copy()
2944
				# For automatic resume, we need to prevent
2945
				# any of bad_resume_opts from leaking in
2946
				# via EMERGE_DEFAULT_OPTS.
2947
				resume_opts["--ignore-default-opts"] = True
2948
				for myopt, myarg in resume_opts.iteritems():
2949
					if myopt not in bad_resume_opts:
2950
						if myarg is True:
2951
							mynewargv.append(myopt)
2952
						else:
2953
							mynewargv.append(myopt +"="+ myarg)
2954
				# priority only needs to be adjusted on the first run
2955
				os.environ["PORTAGE_NICENESS"] = "0"
2956
				os.execv(mynewargv[0], mynewargv)
2957
2958
	def fork_one_emerge(self, x, mergecount, totalcount, mtimedb, favorites, mysysdict):
2959
		xterm_titles = "notitles" not in self.settings.features
2960
		myfeat = self.settings.features[:]
2961
		ldpath_mtimes = mtimedb["ldpath"]
2962
		myroot=x[1]
2963
		pkg_key = x[2]
2964
		pkg_cat = x[2].split("/")[0]
2965
		pkg_pf = x[2].split("/")[1]
2966
		pkgindex=2
2967
		if x[0]=="blocks":
2968
			pkgindex=3
2969
2970
		build_prefix=self.settings["PORTAGE_TMPDIR"]+"/portage"
2971
		logid_path = None
2972
		null_log = 0
2973
2974
		if self.settings.get("PORT_LOGDIR", "") == "":
2975
			while "PORT_LOGDIR" in self.settings:
2976
				del self.settings["PORT_LOGDIR"]
2977
		if "PORT_LOGDIR" in self.settings:
2978
			port_logdir = self.settings["PORT_LOGDIR"]
2979
		else:
2980
			port_logdir = self.settings["ROOT"] + portage.DEF_LOGDIR
2981
2982
		try:
2983
			portage_util.ensure_dirs(port_logdir, uid=portage.portage_uid,
2984
						 gid=portage.portage_gid, mode=02770)
2985
		except portage_exception.PortageException, e:
2986
			writemsg("!!! %s\n" % str(e), noiselevel=-1)
2987
			writemsg("!!! Permission issues with PORT_LOGDIR='%s'\n" % \
2988
				self.settings["PORT_LOGDIR"], noiselevel=-1)
2989
			writemsg("!!! Because 'parallel' feature is enabled, you won't get any logs.\n", noiselevel=-1)
2990
			null_log = 1
2991
2992
		if not null_log:
2993
			logid_path = os.path.join(build_prefix, ".logid.")+pkg_cat+"."+pkg_pf
2994
			if not os.path.exists(logid_path):
2995
				f = open(logid_path, "w")
2996
				f.close()
2997
				del f
2998
			logid_time = time.strftime("%Y%m%d-%H%M%S",
2999
				time.gmtime(os.stat(logid_path).st_mtime))
3000
			logfile = os.path.join(port_logdir, "%s:%s:%s.log" % \
3001
				(pkg_cat, pkg_pf, logid_time))
3002
			del logid_time
3003
		else:
3004
			logfile = "/dev/null"
3005
3006
		if "--pretend" not in self.myopts and "--fetchonly" not in self.myopts:
3007
			print ">>> Emerging (" + \
3008
				colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
3009
				colorize("MERGE_LIST_PROGRESS", str(totalcount)) + ") " + \
3010
				colorize("GOOD", x[pkgindex]) + " to " + x[1]
3011
			print ">>> Logfile in " + logfile
3012
			emergelog(xterm_titles, " >>> emerge ("+\
3013
				str(mergecount)+" of "+str(totalcount)+\
3014
				") "+x[pkgindex]+" to "+x[1])
3015
3016
		# need to spawn a --nodeps emerge in a separate process.
3017
		pkg="="+x[2]
3018
		merge_env = os.environ.copy()
3019
		merge_env["PORTAGE_INTERNAL_CALL"] = "1"
3020
		merge_env["FEATURES"] = merge_env.get("FEATURES", "") + " notitles -parallel"
3021
		merge_args = [sys.argv[0], "--nodeps", "--oneshot", "--nospinner", pkg]
3022
		good_nodeps_opts = set(["--buildpkg", "--buildpkgonly", "--fetchonly", "--fetch-all-uri", "--getbinpkg",\
3023
					"--usepkg", "--usepkgonly"])
3024
		fd_pipes = None
3025
		merge_logfd = None
3026
		for myopt, myarg in self.myopts.iteritems():
3027
			# don't clobber the logfile at the same time as parallel fetch is
3028
			# all log of parallel fetch will go /var/log/emerge-fetch.log
3029
			# so, just leave 0,1,2 alone.
3030
			if "parallel-fetch" in myfeat and myopt == "--fetchonly":
3031
				fd_pipes = {0:0, 1:1, 2:2}
3032
			if myopt in good_nodeps_opts:
3033
				if myarg is True:
3034
					merge_args.append(myopt)
3035
				else:
3036
					merge_args.append(myopt +"="+ myarg)
3037
		if not fd_pipes:
3038
			merge_logfd = open(logfile, "w")
3039
			# put in a start message. This also makes sure that this fd is pointing to a good file on disk
3040
			# and hence will be used throughout the other spawns that will happen in the children.
3041
			merge_logfd.write("Package "+x[pkgindex]+" started at "+time.ctime()+"\n\n")
3042
			merge_logfd.flush()
3043
			fd_pipes = {0:0, 1:merge_logfd.fileno(), 2:merge_logfd.fileno()}
3044
			portage_util.apply_secpass_permissions(logfile, uid=portage.portage_uid, gid=portage.portage_gid, mode=0660)
3045
3046
		mypids = portage.portage_exec.spawn(merge_args, env=merge_env, fd_pipes=fd_pipes, returnpid=True)
3047
		if merge_logfd:
3048
			merge_logfd.close() # child has exclusive rights to it now.
3049
		return mypids[0]
3050
3051
	def do_one_emerge(self, x, mergecount, totalcount, mtimedb, favorites, mysysdict):
3052
		xterm_titles = "notitles" not in self.settings.features
3053
		myfeat = self.settings.features[:]
3054
		ldpath_mtimes = mtimedb["ldpath"]
3055
		myroot=x[1]
3056
		pkg_key = x[2]
3057
		pkg_cat = x[2].split("/")[0]
3058
		pkg_pf = x[2].split("/")[1]
3059
		pkgindex=2
3060
		if x[0]=="blocks":
3061
			pkgindex=3
3062
3063
		if "--pretend" not in self.myopts and "--fetchonly" not in self.myopts:
3064
			print "\n>>> Emerging (" + \
3065
				colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
3066
				colorize("MERGE_LIST_PROGRESS", str(totalcount)) + ") " + \
3067
				colorize("GOOD", x[pkgindex]) + " to " + x[1]
3068
			emergelog(xterm_titles, " >>> emerge ("+\
3069
				str(mergecount)+" of "+str(totalcount)+\
3070
				") "+x[pkgindex]+" to "+x[1])
3071
3072
		portdb = self.trees[myroot]["porttree"].dbapi
3073
		bindb  = self.trees[myroot]["bintree"].dbapi
3074
		vartree = self.trees[myroot]["vartree"]
3075
		pkgsettings = self.pkgsettings[myroot]
3076
		y = portdb.findname(pkg_key)
3077
		pkgsettings["EMERGE_FROM"] = x[0]
3078
		pkgsettings.backup_changes("EMERGE_FROM")
3079
		pkgsettings.reset()
3080
3081
		#buildsyspkg: Check if we need to _force_ binary package creation
3082
		issyspkg = ("buildsyspkg" in myfeat) \
3083
				and x[0] != "blocks" \
3084
				and mysysdict.has_key(portage.cpv_getkey(x[2])) \
3085
				and "--buildpkg" not in self.myopts
3086
		if x[0] in ["ebuild","blocks"]:
3087
			if x[0] == "blocks" and "--fetchonly" not in self.myopts:
3088
				raise Exception, "Merging a blocker"
3089
			elif "--fetchonly" in self.myopts or \
3090
				"--fetch-all-uri" in self.myopts:
3091
				if "--fetch-all-uri" in self.myopts:
3092
					retval = portage.doebuild(y, "fetch", myroot,
3093
						pkgsettings, self.edebug,
3094
						"--pretend" in self.myopts, fetchonly=1,
3095
						fetchall=1, mydbapi=portdb, tree="porttree")
3096
				else:
3097
					retval = portage.doebuild(y, "fetch", myroot,
3098
						pkgsettings, self.edebug,
3099
						"--pretend" in self.myopts, fetchonly=1,
3100
						mydbapi=portdb, tree="porttree")
3101
				if (retval is None) or retval:
3102
					print
3103
					print "!!! Fetch for",y,"failed, continuing..."
3104
					print
3105
3106
				return retval
3107
3108
			portage.doebuild_environment(y, "setup", myroot,
3109
				pkgsettings, self.edebug, 1, portdb)
3110
			catdir = os.path.dirname(pkgsettings["PORTAGE_BUILDDIR"])
3111
			portage_util.ensure_dirs(os.path.dirname(catdir),
3112
				uid=portage.portage_uid, gid=portage.portage_gid,
3113
				mode=070, mask=0)
3114
			builddir_lock = None
3115
			catdir_lock = None
3116
			try:
3117
				catdir_lock = portage_locks.lockdir(catdir)
3118
				portage_util.ensure_dirs(catdir,
3119
					uid=portage.portage_uid, gid=portage.portage_gid,
3120
					mode=070, mask=0)
3121
				builddir_lock = portage_locks.lockdir(
3122
					pkgsettings["PORTAGE_BUILDDIR"])
3123
				try:
3124
					portage_locks.unlockdir(catdir_lock)
3125
				finally:
3126
					catdir_lock = None
3127
				msg = " === (%s of %s) Cleaning (%s::%s)" % \
3128
					(mergecount, totalcount, pkg_key, y)
3129
				short_msg = "emerge: (%s of %s) %s Clean" % \
3130
					(mergecount, totalcount, pkg_key)
3131
				emergelog(xterm_titles, msg, short_msg=short_msg)
3132
				retval = portage.doebuild(y, "clean", myroot,
3133
					pkgsettings, self.edebug, cleanup=1,
3134
					mydbapi=portdb, tree="porttree")
3135
3136
				if retval != os.EX_OK:
3137
					return retval
3138
				if "--buildpkg" in self.myopts or issyspkg:
3139
					if issyspkg:
3140
						print ">>> This is a system package, " + \
3141
							"let's pack a rescue tarball."
3142
					msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
3143
						(mergecount, totalcount, pkg_key, y)
3144
					short_msg = "emerge: (%s of %s) %s Compile" % \
3145
						(mergecount, totalcount, pkg_key)
3146
					emergelog(xterm_titles, msg, short_msg=short_msg)
3147
					self.trees[myroot]["bintree"].prevent_collision(pkg_key)
3148
					retval = portage.doebuild(y, "package", myroot,
3149
						pkgsettings, self.edebug, mydbapi=portdb,
3150
						tree="porttree")
3151
					if retval != os.EX_OK:
3152
						return retval
3153
					bintree = self.trees[myroot]["bintree"]
3154
					if bintree.populated:
3155
						bintree.inject(pkg_key)
3156
					if "--buildpkgonly" not in self.myopts:
3157
						msg = " === (%s of %s) Merging (%s::%s)" % \
3158
							(mergecount, totalcount, pkg_key, y)
3159
						short_msg = "emerge: (%s of %s) %s Merge" % \
3160
							(mergecount, totalcount, pkg_key)
3161
						emergelog(xterm_titles, msg, short_msg=short_msg)
3162
						retval = portage.merge(pkgsettings["CATEGORY"],
3163
							pkgsettings["PF"], pkgsettings["D"],
3164
							os.path.join(pkgsettings["PORTAGE_BUILDDIR"],
3165
							"build-info"), myroot, pkgsettings,
3166
							myebuild=pkgsettings["EBUILD"],
3167
							mytree="porttree", mydbapi=portdb,
3168
							vartree=vartree, prev_mtimes=ldpath_mtimes)
3169
						if retval != os.EX_OK:
3170
							return retval
3171
					elif "noclean" not in pkgsettings.features:
3172
						portage.doebuild(y, "clean", myroot,
3173
							pkgsettings, self.edebug, mydbapi=portdb,
3174
							tree="porttree")
3175
				else:
3176
					msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
3177
						(mergecount, totalcount, pkg_key, y)
3178
					short_msg = "emerge: (%s of %s) %s Compile" % \
3179
						(mergecount, totalcount, pkg_key)
3180
					emergelog(xterm_titles, msg, short_msg=short_msg)
3181
					retval = portage.doebuild(y, "merge", myroot,
3182
						pkgsettings, self.edebug, vartree=vartree,
3183
						mydbapi=portdb, tree="porttree",
3184
						prev_mtimes=ldpath_mtimes)
3185
					if retval != os.EX_OK:
3186
						return retval
3187
			finally:
3188
				if builddir_lock:
3189
					portage_locks.unlockdir(builddir_lock)
3190
				try:
3191
					if not catdir_lock:
3192
						# Lock catdir for removal if empty.
3193
						catdir_lock = portage_locks.lockdir(catdir)
3194
				finally:
3195
					if catdir_lock:
3196
						try:
3197
							os.rmdir(catdir)
3198
						except OSError, e:
3199
							if e.errno not in (errno.ENOENT,
3200
								errno.ENOTEMPTY, errno.EEXIST):
3201
								raise
3202
							del e
3203
						portage_locks.unlockdir(catdir_lock)
3204
3205
		elif x[0]=="binary":
3206
			#merge the tbz2
3207
			mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
3208
			if "--getbinpkg" in self.myopts:
3209
				tbz2_lock = None
3210
				try:
3211
					if "distlocks" in pkgsettings.features and \
3212
						os.access(pkgsettings["PKGDIR"], os.W_OK):
3213
						portage_util.ensure_dirs(os.path.dirname(mytbz2))
3214
						tbz2_lock = portage_locks.lockfile(mytbz2,
3215
							wantnewlockfile=1)
3216
					if self.trees[myroot]["bintree"].isremote(pkg_key):
3217
						msg = " --- (%s of %s) Fetching Binary (%s::%s)" %\
3218
							(mergecount, totalcount, pkg_key, mytbz2)
3219
						short_msg = "emerge: (%s of %s) %s Fetch" % \
3220
							(mergecount, totalcount, pkg_key)
3221
						emergelog(xterm_titles, msg, short_msg=short_msg)
3222
						if not self.trees[myroot]["bintree"].gettbz2(
3223
							pkg_key):
3224
							return 1
3225
				finally:
3226
					if tbz2_lock:
3227
						portage_locks.unlockfile(tbz2_lock)
3228
3229
			if "--fetchonly" in self.myopts or \
3230
				"--fetch-all-uri" in self.myopts:
3231
				return os.EX_OK
3232
3233
			short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Merge Binary"
3234
			emergelog(xterm_titles, " === ("+str(mergecount)+\
3235
				" of "+str(totalcount)+") Merging Binary ("+\
3236
				x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
3237
3238
			retval = portage.pkgmerge(mytbz2, x[1], pkgsettings,
3239
				mydbapi=bindb,
3240
				vartree=self.trees[myroot]["vartree"],
3241
				prev_mtimes=ldpath_mtimes)
3242
			if retval != os.EX_OK:
3243
				return retval
3244
			#need to check for errors
3245
3246
		# clean up the older version which emerged on top of
3247
		if "--buildpkgonly" not in self.myopts and \
3248
			"--pretend" not in self.myopts and \
3249
			"--fetchonly" not in self.myopts and \
3250
			"--fetch-all-uri" not in self.myopts:
3251
			# Clean the old package that we have merged over top of it.
3252
			if pkgsettings.get("AUTOCLEAN", "yes") == "yes":
3253
				xsplit=portage.pkgsplit(x[2])
3254
				emergelog(xterm_titles, " >>> AUTOCLEAN: " + xsplit[0])
3255
				retval = unmerge(pkgsettings, self.myopts, vartree,
3256
					"clean", [xsplit[0]], ldpath_mtimes, autoclean=1)
3257
				if not retval:
3258
					emergelog(xterm_titles,
3259
						" --- AUTOCLEAN: Nothing unmerged.")
3260
			else:
3261
				portage.writemsg_stdout(colorize("WARN", "WARNING:")
3262
					+ " AUTOCLEAN is disabled.  This can cause serious"
3263
					+ " problems due to overlapping packages.\n")
3264
3265
		if "--pretend" not in self.myopts and \
3266
			"--fetchonly" not in self.myopts and \
3267
			"--fetch-all-uri" not in self.myopts:
3268
			if "noclean" not in self.settings.features:
3269
				short_msg = "emerge: (%s of %s) %s Clean Post" % \
3270
					(mergecount, totalcount, x[pkgindex])
3271
				emergelog(xterm_titles, (" === (%s of %s) " + \
3272
					"Post-Build Cleaning (%s::%s)") % \
3273
					(mergecount, totalcount, x[pkgindex], y),
3274
					short_msg=short_msg)
3275
			emergelog(xterm_titles, " ::: completed emerge ("+\
3276
				str(mergecount)+" of "+str(totalcount)+") "+\
3277
				x[2]+" to "+x[1])
3278
3279
		return os.EX_OK
3280
3281
	def add_one_emerge_to_world(self, x, mergecount, totalcount, favorites, mysysdict):
3282
		xterm_titles = "notitles" not in self.settings.features
3283
		pkgindex=2
3284
		if x[0]=="blocks":
3285
			pkgindex=3
3286
3287
		if "--buildpkgonly" not in self.myopts:
3288
			self.trees[x[1]]["vartree"].inject(x[2])
3289
			myfavkey=portage.cpv_getkey(x[2])
3290
			if "--fetchonly" not in self.myopts and \
3291
				"--fetch-all-uri" not in self.myopts and \
3292
				myfavkey in favorites:
3293
				myfavs = portage.grabfile(os.path.join(x[1], portage.WORLD_FILE))
3294
				myfavdict=genericdict(myfavs)
3295
				#don't record if already in system profile or already recorded
3296
				if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
3297
					#we don't have a favorites entry for this package yet; add one
3298
					myfavdict[myfavkey]=myfavkey
3299
					print ">>> Recording",myfavkey,"in \"world\" favorites file..."
3300
					emergelog(xterm_titles, " === ("+\
3301
						str(mergecount)+" of "+\
3302
						str(totalcount)+\
3303
						") Updating world file ("+x[pkgindex]+")")
3304
					portage.write_atomic(
3305
					os.path.join(x[1], portage.WORLD_FILE),
3306
					"\n".join(myfavdict.values()))
3307
3308
	def print_status(self, totalcount, donec, qsize, failedc, spawnd_pkg, failed):
3309
		smsg = ""
3310
		fmsg = ""
3311
		if spawnd_pkg:
3312
			for pkgs in spawnd_pkg.values():
3313
				smsg = smsg+" "+pkgs[0][2]
3314
		if failed:
3315
			for pkgs in failed:
3316
				fmsg = fmsg+" "+pkgs
3317
		print ">>> Jobs [Total = "+colorize("blue", str(totalcount))+"] [Done = "+\
3318
			colorize("GOOD", str(donec))+"] [Running = "+colorize("WARN", str(qsize)+smsg)+\
3319
			"] [Failed = "+colorize("BAD", str(failedc)+fmsg)+"]"
3320
		xtermTitle("Jobs [Total="+str(totalcount)+"] [Done="+str(donec)+"] [Running="+str(qsize)+"] [Failed="+str(failedc)+"]")
3321
3322
	def wait_one_emerge(self, spawnd_pids, spawnd_pkg, mergecount, totalcount, mymergelist, mtimedb):
3323
		build_prefix=self.settings["PORTAGE_TMPDIR"]+"/portage"
3324
		# let's wait for one of the jobs to finish
3325
		onepid = -1
3326
		while onepid not in spawnd_pids:
3327
			onepid , retval = os.waitpid(-1, 0)
3328
		spawnd_pids.remove(onepid)
3329
3330
		pkg_compl = spawnd_pkg[onepid][0]
3331
		pkg_slot = spawnd_pkg[onepid][1]
3332
		del spawnd_pkg[onepid]
3333
3334
		if not retval:
3335
			# unlink the logid_path
3336
			logid_path = os.path.join(build_prefix, ".logid.")+pkg_compl[2].split("/")[0]+"."+pkg_compl[2].split("/")[1]
3337
			if os.path.exists(logid_path):
3338
				os.unlink(logid_path)
3339
			index = 0
3340
			print ">>> Package "+colorize("GOOD", pkg_compl[2])+" finished emerging."
3341
			# we need to remove this pkg from resume DB
3342
			# this is the dirtiest shit I have ever written
3343
			for pkgs in mymergelist:
3344
				if pkgs[2] == pkg_compl[2]:
3345
					del mymergelist[index]
3346
					del mtimedb["resume"]["mergelist"][index]
3347
					mtimedb.commit()
3348
					# check if we need to restart portage
3349
					mysplit=portage.pkgsplit(pkg_compl[2])
3350
					if mysplit[0] == "sys-apps/portage" and pkgs[1] == "/":
3351
						self.restart_portage(pkgs, mergecount, totalcount, mtimedb)
3352
					break
3353
				index += 1
3354
		return (retval, pkg_compl)
3355
3356
	def merge(self, mylist, favorites, mtimedb, m_slots):
2897
		failed_fetches = []
3357
		failed_fetches = []
2898
		mymergelist=[]
3358
		mymergelist=[]
2899
		ldpath_mtimes = mtimedb["ldpath"]
3359
		ldpath_mtimes = mtimedb["ldpath"]
2900
		xterm_titles = "notitles" not in self.settings.features
3360
		xterm_titles = "notitles" not in self.settings.features
3361
		parallel = "parallel" in self.settings.features
3362
		build_prefix=self.settings["PORTAGE_TMPDIR"]+"/portage"
3363
3364
		# parallel merge will be painful to watch with debug or fetchonly. So, you get only one of these...:-)
3365
		if self.edebug or "--fetchonly" in self.myopts:
3366
			parallel = False
2901
3367
2902
		#check for blocking dependencies
3368
		#check for blocking dependencies
2903
		if "--fetchonly" not in self.myopts and \
3369
		if "--fetchonly" not in self.myopts and \
Lines 2914-2921 Link Here
2914
3380
2915
		if "--resume" in self.myopts:
3381
		if "--resume" in self.myopts:
2916
			# We're resuming.
3382
			# We're resuming.
2917
			print colorize("GOOD", "*** Resuming merge...")
2918
			emergelog(xterm_titles, " *** Resuming merge...")
2919
			mylist = mtimedb["resume"]["mergelist"][:]
3383
			mylist = mtimedb["resume"]["mergelist"][:]
2920
			if "--skipfirst" in self.myopts and mylist:
3384
			if "--skipfirst" in self.myopts and mylist:
2921
				del mtimedb["resume"]["mergelist"][0]
3385
				del mtimedb["resume"]["mergelist"][0]
Lines 2943-2949 Link Here
2943
				if not shown_verifying_msg:
3407
				if not shown_verifying_msg:
2944
					shown_verifying_msg = True
3408
					shown_verifying_msg = True
2945
					print ">>> Verifying ebuild Manifests..."
3409
					print ">>> Verifying ebuild Manifests..."
2946
				mytype, myroot, mycpv, mystatus = x
3410
				mytype, myroot, mycpv, mystatus, slott = x
2947
				portdb = self.trees[myroot]["porttree"].dbapi
3411
				portdb = self.trees[myroot]["porttree"].dbapi
2948
				quiet_config = quiet_settings[myroot]
3412
				quiet_config = quiet_settings[myroot]
2949
				quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
3413
				quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
Lines 2981-2988 Link Here
2981
					os.path.join(self.target_root, portage.WORLD_FILE),
3445
					os.path.join(self.target_root, portage.WORLD_FILE),
2982
					"\n".join(myfavdict.values()))
3446
					"\n".join(myfavdict.values()))
2983
3447
2984
			mtimedb["resume"]["mergelist"]=mymergelist[:]
3448
			if "--nodeps" not in self.myopts or len(mymergelist) > 1:
2985
			mtimedb.commit()
3449
				mtimedb["resume"]["mergelist"]=mymergelist[:]
3450
				mtimedb.commit()
3451
3452
		totalcount = len(mymergelist)
3453
		mergecount=1
3454
3455
		if "--resume" in self.myopts and "--fetchonly" not in self.myopts:
3456
			# We're resuming.
3457
			print colorize("GOOD", "*** Resuming merge...")
3458
			emergelog(xterm_titles, " *** Resuming merge...")
2986
3459
2987
		myfeat = self.settings.features[:]
3460
		myfeat = self.settings.features[:]
2988
		bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
3461
		bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
Lines 3000-3011 Link Here
3000
				print ">>> starting parallel fetching"
3473
				print ">>> starting parallel fetching"
3001
				fetch_log = "/var/log/emerge-fetch.log"
3474
				fetch_log = "/var/log/emerge-fetch.log"
3002
				logfile = open(fetch_log, "w")
3475
				logfile = open(fetch_log, "w")
3003
				fd_pipes = {1:logfile.fileno(), 2:logfile.fileno()}
3476
				fd_pipes = {0:0, 1:logfile.fileno(), 2:logfile.fileno()}
3004
				portage_util.apply_secpass_permissions(fetch_log,
3477
				portage_util.apply_secpass_permissions(fetch_log,
3005
					uid=portage.portage_uid, gid=portage.portage_gid,
3478
					uid=portage.portage_uid, gid=portage.portage_gid,
3006
					mode=0660)
3479
					mode=0660)
3007
				fetch_env = os.environ.copy()
3480
				fetch_env = os.environ.copy()
3008
				fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs"
3481
				fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs -parallel"
3009
				fetch_env["PORTAGE_NICENESS"] = "0"
3482
				fetch_env["PORTAGE_NICENESS"] = "0"
3010
				fetch_args = [sys.argv[0], "--resume", "--fetchonly"]
3483
				fetch_args = [sys.argv[0], "--resume", "--fetchonly"]
3011
				resume_opts = self.myopts.copy()
3484
				resume_opts = self.myopts.copy()
Lines 3025-3335 Link Here
3025
				del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
3498
				del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
3026
					resume_opts
3499
					resume_opts
3027
3500
3028
		mergecount=0
3501
		if not parallel:
3029
		for x in mymergelist:
3502
			failed_fetches = []
3030
			mergecount+=1
3503
			for x in mymergelist:
3031
			myroot=x[1]
3504
				retcode = self.do_one_emerge(x, mergecount, totalcount, mtimedb, favorites, mysysdict)
3032
			pkg_key = x[2]
3505
				mergecount += 1
3033
			pkgindex=2
3506
3034
			portdb = self.trees[myroot]["porttree"].dbapi
3507
				# need to short circuit the spawn with --nodeps
3035
			bindb  = self.trees[myroot]["bintree"].dbapi
3508
				if os.environ.get("PORTAGE_INTERNAL_CALL", "0") != "1":
3036
			vartree = self.trees[myroot]["vartree"]
3509
					if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3037
			pkgsettings = self.pkgsettings[myroot]
3510
						continue
3038
			if x[0]=="blocks":
3511
					if retcode != os.EX_OK:
3039
				pkgindex=3
3512
						if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3040
			y = portdb.findname(pkg_key)
3513
							failed_fetches.append(x[2])
3514
							continue
3515
						else:
3516
							return retcode
3517
					# Unsafe for parallel merges
3518
					del mtimedb["resume"]["mergelist"][0]
3519
					# Commit after each merge so that --resume may still work in
3520
					# in the event that portage is not allowed to exit normally
3521
					# due to power failure, SIGKILL, etc...
3522
					mtimedb.commit()
3523
3524
					# unlink the logid_path if any exists
3525
					logid_path = os.path.join(build_prefix, ".logid.")+x[2].split("/")[0]+"."+x[2].split("/")[1]
3526
					if os.path.exists(logid_path):
3527
						os.unlink(logid_path)
3528
					del logid_path
3529
  
3530
					# check if we need to restart portage
3531
					mysplit=portage.pkgsplit(x[2])
3532
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
3533
							self.restart_portage(x, mergecount, totalcount, mtimedb)
3534
  
3535
				else:
3536
					if retcode != os.EX_OK:
3537
						sys.exit(1)
3538
  					else:
3539
						sys.exit(0)
3540
  
3041
			if "--pretend" not in self.myopts:
3541
			if "--pretend" not in self.myopts:
3042
				print "\n>>> Emerging (" + \
3542
				emergelog(xterm_titles, " *** Finished. Cleaning up...")
3043
					colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
3543
  
3044
					colorize("MERGE_LIST_PROGRESS", str(len(mymergelist))) + ") " + \
3544
			# We're out of the loop... We're done. Delete the resume data.
3045
					colorize("GOOD", x[pkgindex]) + " to " + x[1]
3545
			if mtimedb.has_key("resume"):
3046
				emergelog(xterm_titles, " >>> emerge ("+\
3546
				del mtimedb["resume"]
3047
					str(mergecount)+" of "+str(len(mymergelist))+\
3547
			mtimedb.commit()
3048
					") "+x[pkgindex]+" to "+x[1])
3548
			
3049
3549
			#by doing an exit this way, --fetchonly can continue to try to
3050
			pkgsettings["EMERGE_FROM"] = x[0]
3550
			#fetch everything even if a particular download fails.
3051
			pkgsettings.backup_changes("EMERGE_FROM")
3551
			if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3052
			pkgsettings.reset()
3552
				if failed_fetches:
3053
3553
					sys.stderr.write("\n\n!!! Some fetch errors were " + \
3054
			#buildsyspkg: Check if we need to _force_ binary package creation
3554
						"encountered.  Please see above for details.\n\n")
3055
			issyspkg = ("buildsyspkg" in myfeat) \
3555
					for cpv in failed_fetches:
3056
					and x[0] != "blocks" \
3556
						sys.stderr.write("   ")
3057
					and mysysdict.has_key(portage.cpv_getkey(x[2])) \
3557
						sys.stderr.write(cpv)
3058
					and "--buildpkg" not in self.myopts
3558
						sys.stderr.write("\n")
3059
			if x[0] in ["ebuild","blocks"]:
3559
					sys.stderr.write("\n")
3060
				if x[0] == "blocks" and "--fetchonly" not in self.myopts:
3560
					sys.exit(1)
3061
					raise Exception, "Merging a blocker"
3561
				else:
3062
				elif "--fetchonly" in self.myopts or \
3562
					sys.exit(0)
3063
					"--fetch-all-uri" in self.myopts:
3563
			return os.EX_OK
3064
					if "--fetch-all-uri" in self.myopts:
3564
  
3065
						retval = portage.doebuild(y, "fetch", myroot,
3565
		# parallel code - dirty starts here...;-)
3066
							pkgsettings, self.edebug,
3566
		one_in_slot_failed=0
3067
							"--pretend" in self.myopts, fetchonly=1,
3567
		spawnd_pids=[]
3068
							fetchall=1, mydbapi=portdb, tree="porttree")
3568
3069
					else:
3569
		# dirty little trick to get number of cpus from the system
3070
						retval = portage.doebuild(y, "fetch", myroot,
3570
		fd_cpuinfo = os.popen("cat /proc/cpuinfo","r")
3071
							pkgsettings, self.edebug,
3571
		cpu_count = 0
3072
							"--pretend" in self.myopts, fetchonly=1,
3572
		for data_cpuinfo in fd_cpuinfo.readlines():
3073
							mydbapi=portdb, tree="porttree")
3573
			if data_cpuinfo.find("cpu MHz") > -1 :
3074
					if (retval is None) or retval:
3574
				cpu_count += 1
3075
						print
3575
		fd_cpuinfo.close()
3076
						print "!!! Fetch for",y,"failed, continuing..."
3576
3077
						print
3577
		# if someone really screwed with /proc/cpuinfo output, we should not suffer
3078
						failed_fetches.append(pkg_key)
3578
		if cpu_count == 0:
3079
					continue
3579
			cpu_count = 1
3080
3580
3081
				portage.doebuild_environment(y, "setup", myroot,
3581
		spawnd_pkg = {}
3082
					pkgsettings, self.edebug, 1, portdb)
3582
		donec = 0
3083
				catdir = os.path.dirname(pkgsettings["PORTAGE_BUILDDIR"])
3583
		failedc = 0
3084
				portage_util.ensure_dirs(os.path.dirname(catdir),
3584
		failedPkgs = []
3085
					uid=portage.portage_uid, gid=portage.portage_gid,
3585
		logid_path = None
3086
					mode=070, mask=0)
3586
		mylist = m_slots.keys()
3087
				builddir_lock = None
3587
		mylist.sort()
3088
				catdir_lock = None
3588
		for x in mylist:
3089
				try:
3589
			# if slot is empty, go on
3090
					catdir_lock = portage_locks.lockdir(catdir)
3590
			if not m_slots[x]:
3091
					portage_util.ensure_dirs(catdir,
3591
				continue
3092
						uid=portage.portage_uid, gid=portage.portage_gid,
3093
						mode=070, mask=0)
3094
					builddir_lock = portage_locks.lockdir(
3095
						pkgsettings["PORTAGE_BUILDDIR"])
3096
					try:
3097
						portage_locks.unlockdir(catdir_lock)
3098
					finally:
3099
						catdir_lock = None
3100
					msg = " === (%s of %s) Cleaning (%s::%s)" % \
3101
						(mergecount, len(mymergelist), pkg_key, y)
3102
					short_msg = "emerge: (%s of %s) %s Clean" % \
3103
						(mergecount, len(mymergelist), pkg_key)
3104
					emergelog(xterm_titles, msg, short_msg=short_msg)
3105
					retval = portage.doebuild(y, "clean", myroot,
3106
						pkgsettings, self.edebug, cleanup=1,
3107
						mydbapi=portdb, tree="porttree")
3108
					if retval != os.EX_OK:
3109
						return retval
3110
					if "--buildpkg" in self.myopts or issyspkg:
3111
						if issyspkg:
3112
							print ">>> This is a system package, " + \
3113
								"let's pack a rescue tarball."
3114
						msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
3115
							(mergecount, len(mymergelist), pkg_key, y)
3116
						short_msg = "emerge: (%s of %s) %s Compile" % \
3117
							(mergecount, len(mymergelist), pkg_key)
3118
						emergelog(xterm_titles, msg, short_msg=short_msg)
3119
						self.trees[myroot]["bintree"].prevent_collision(pkg_key)
3120
						retval = portage.doebuild(y, "package", myroot,
3121
							pkgsettings, self.edebug, mydbapi=portdb,
3122
							tree="porttree")
3123
						if retval != os.EX_OK:
3124
							return retval
3125
						bintree = self.trees[myroot]["bintree"]
3126
						if bintree.populated:
3127
							bintree.inject(pkg_key)
3128
						if "--buildpkgonly" not in self.myopts:
3129
							msg = " === (%s of %s) Merging (%s::%s)" % \
3130
								(mergecount, len(mymergelist), pkg_key, y)
3131
							short_msg = "emerge: (%s of %s) %s Merge" % \
3132
								(mergecount, len(mymergelist), pkg_key)
3133
							emergelog(xterm_titles, msg, short_msg=short_msg)
3134
							retval = portage.merge(pkgsettings["CATEGORY"],
3135
								pkgsettings["PF"], pkgsettings["D"],
3136
								os.path.join(pkgsettings["PORTAGE_BUILDDIR"],
3137
								"build-info"), myroot, pkgsettings,
3138
								myebuild=pkgsettings["EBUILD"],
3139
								mytree="porttree", mydbapi=portdb,
3140
								vartree=vartree, prev_mtimes=ldpath_mtimes)
3141
							if retval != os.EX_OK:
3142
								return retval
3143
						elif "noclean" not in pkgsettings.features:
3144
							portage.doebuild(y, "clean", myroot,
3145
								pkgsettings, self.edebug, mydbapi=portdb,
3146
								tree="porttree")
3147
					else:
3148
						msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
3149
							(mergecount, len(mymergelist), pkg_key, y)
3150
						short_msg = "emerge: (%s of %s) %s Compile" % \
3151
							(mergecount, len(mymergelist), pkg_key)
3152
						emergelog(xterm_titles, msg, short_msg=short_msg)
3153
						retval = portage.doebuild(y, "merge", myroot,
3154
							pkgsettings, self.edebug, vartree=vartree,
3155
							mydbapi=portdb, tree="porttree",
3156
							prev_mtimes=ldpath_mtimes)
3157
						if retval != os.EX_OK:
3158
							return retval
3159
				finally:
3160
					if builddir_lock:
3161
						portage_locks.unlockdir(builddir_lock)
3162
					try:
3163
						if not catdir_lock:
3164
							# Lock catdir for removal if empty.
3165
							catdir_lock = portage_locks.lockdir(catdir)
3166
					finally:
3167
						if catdir_lock:
3168
							try:
3169
								os.rmdir(catdir)
3170
							except OSError, e:
3171
								if e.errno not in (errno.ENOENT,
3172
									errno.ENOTEMPTY, errno.EEXIST):
3173
									raise
3174
								del e
3175
							portage_locks.unlockdir(catdir_lock)
3176
3177
			elif x[0]=="binary":
3178
				#merge the tbz2
3179
				mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
3180
				if "--getbinpkg" in self.myopts:
3181
					tbz2_lock = None
3182
					try:
3183
						if "distlocks" in pkgsettings.features and \
3184
							os.access(pkgsettings["PKGDIR"], os.W_OK):
3185
							portage_util.ensure_dirs(os.path.dirname(mytbz2))
3186
							tbz2_lock = portage_locks.lockfile(mytbz2,
3187
								wantnewlockfile=1)
3188
						if self.trees[myroot]["bintree"].isremote(pkg_key):
3189
							msg = " --- (%s of %s) Fetching Binary (%s::%s)" %\
3190
								(mergecount, len(mymergelist), pkg_key, mytbz2)
3191
							short_msg = "emerge: (%s of %s) %s Fetch" % \
3192
								(mergecount, len(mymergelist), pkg_key)
3193
							emergelog(xterm_titles, msg, short_msg=short_msg)
3194
							if not self.trees[myroot]["bintree"].gettbz2(
3195
								pkg_key):
3196
								return 1
3197
					finally:
3198
						if tbz2_lock:
3199
							portage_locks.unlockfile(tbz2_lock)
3200
3201
				if "--fetchonly" in self.myopts or \
3202
					"--fetch-all-uri" in self.myopts:
3203
					continue
3204
3592
3205
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
3593
			# if previous slot failed, discontinue the emerge
3206
				emergelog(xterm_titles, " === ("+str(mergecount)+\
3594
			if one_in_slot_failed and not ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts):
3207
					" of "+str(len(mymergelist))+") Merging Binary ("+\
3595
				break
3208
					x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
3209
				retval = portage.pkgmerge(mytbz2, x[1], pkgsettings,
3210
					mydbapi=bindb,
3211
					vartree=self.trees[myroot]["vartree"],
3212
					prev_mtimes=ldpath_mtimes)
3213
				if retval != os.EX_OK:
3214
					return retval
3215
				#need to check for errors
3216
			if "--buildpkgonly" not in self.myopts:
3217
				self.trees[x[1]]["vartree"].inject(x[2])
3218
				myfavkey=portage.cpv_getkey(x[2])
3219
				if "--fetchonly" not in self.myopts and \
3220
					"--fetch-all-uri" not in self.myopts and \
3221
					myfavkey in favorites:
3222
					myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
3223
					myfavdict=genericdict(myfavs)
3224
					#don't record if already in system profile or already recorded
3225
					if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
3226
						#we don't have a favorites entry for this package yet; add one
3227
						myfavdict[myfavkey]=myfavkey
3228
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
3229
						emergelog(xterm_titles, " === ("+\
3230
							str(mergecount)+" of "+\
3231
							str(len(mymergelist))+\
3232
							") Updating world file ("+x[pkgindex]+")")
3233
						portage.write_atomic(
3234
						os.path.join(myroot, portage.WORLD_FILE),
3235
						"\n".join(myfavdict.values()))
3236
3237
				if "--pretend" not in self.myopts and \
3238
					"--fetchonly" not in self.myopts and \
3239
					"--fetch-all-uri" not in self.myopts:
3240
					# Clean the old package that we have merged over top of it.
3241
					if pkgsettings.get("AUTOCLEAN", "yes") == "yes":
3242
						xsplit=portage.pkgsplit(x[2])
3243
						emergelog(xterm_titles, " >>> AUTOCLEAN: " + xsplit[0])
3244
						retval = unmerge(pkgsettings, self.myopts, vartree,
3245
							"clean", [xsplit[0]], ldpath_mtimes, autoclean=1)
3246
						if not retval:
3247
							emergelog(xterm_titles,
3248
								" --- AUTOCLEAN: Nothing unmerged.")
3249
					else:
3250
						portage.writemsg_stdout(colorize("WARN", "WARNING:")
3251
							+ " AUTOCLEAN is disabled.  This can cause serious"
3252
							+ " problems due to overlapping packages.\n")
3253
3596
3254
					# Figure out if we need a restart.
3597
			# start multiple merges in parallel mode
3255
					mysplit=portage.pkgsplit(x[2])
3598
			num_at_atime = cpu_count + 1
3256
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
3257
						myver=mysplit[1]+"-"+mysplit[2]
3258
						if myver[-3:]=='-r0':
3259
							myver=myver[:-3]
3260
						if (myver != portage.VERSION) and \
3261
						   "livecvsportage" not in self.settings.features:
3262
							if len(mymergelist) > mergecount:
3263
								emergelog(xterm_titles,
3264
									" ::: completed emerge ("+ \
3265
									str(mergecount)+" of "+ \
3266
									str(len(mymergelist))+") "+ \
3267
									x[2]+" to "+x[1])
3268
								emergelog(xterm_titles, " *** RESTARTING " + \
3269
									"emerge via exec() after change of " + \
3270
									"portage version.")
3271
								del mtimedb["resume"]["mergelist"][0]
3272
								mtimedb.commit()
3273
								portage.run_exitfuncs()
3274
								mynewargv=[sys.argv[0],"--resume"]
3275
								resume_opts = self.myopts.copy()
3276
								# For automatic resume, we need to prevent
3277
								# any of bad_resume_opts from leaking in
3278
								# via EMERGE_DEFAULT_OPTS.
3279
								resume_opts["--ignore-default-opts"] = True
3280
								for myopt, myarg in resume_opts.iteritems():
3281
									if myopt not in bad_resume_opts:
3282
										if myarg is True:
3283
											mynewargv.append(myopt)
3284
										else:
3285
											mynewargv.append(myopt +"="+ myarg)
3286
								# priority only needs to be adjusted on the first run
3287
								os.environ["PORTAGE_NICENESS"] = "0"
3288
								os.execv(mynewargv[0], mynewargv)
3289
3290
			if "--pretend" not in self.myopts and \
3291
				"--fetchonly" not in self.myopts and \
3292
				"--fetch-all-uri" not in self.myopts:
3293
				if "noclean" not in self.settings.features:
3294
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
3295
						(mergecount, len(mymergelist), x[pkgindex])
3296
					emergelog(xterm_titles, (" === (%s of %s) " + \
3297
						"Post-Build Cleaning (%s::%s)") % \
3298
						(mergecount, len(mymergelist), x[pkgindex], y),
3299
						short_msg=short_msg)
3300
				emergelog(xterm_titles, " ::: completed emerge ("+\
3301
					str(mergecount)+" of "+str(len(mymergelist))+") "+\
3302
					x[2]+" to "+x[1])
3303
3599
3304
			# Unsafe for parallel merges
3600
			qsize = 0
3305
			del mtimedb["resume"]["mergelist"][0]
3601
			for y in m_slots[x]:
3306
			# Commit after each merge so that --resume may still work in
3602
				# these all can go in parallel, so fork one after the other
3307
			# in the event that portage is not allowed to exit normally
3603
				# but num_at_atime at most
3308
			# due to power failure, SIGKILL, etc...
3604
				if num_at_atime:
3309
			mtimedb.commit()
3605
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
3606
					spawnd_pids.append(onepid)
3607
					spawnd_pkg[onepid] = (y, x)
3608
					num_at_atime -= 1
3609
					mergecount += 1
3610
					qsize += 1
3611
				else:
3612
					self.print_status(totalcount, donec, qsize, failedc, spawnd_pkg, failedPkgs)
3613
					# let's wait for one of the jobs to finish
3614
					(retval, pkg_compl) = self.wait_one_emerge(spawnd_pids, spawnd_pkg, mergecount, totalcount, mymergelist, mtimedb)
3615
3616
					# if it failed, I need to fail next slot but continue to merge all in this slot
3617
					if retval:
3618
						one_in_slot_failed = retval
3619
						failedc += 1
3620
						failedPkgs.append(pkg_compl[2])
3621
  					else:
3622
						donec += 1
3623
						self.add_one_emerge_to_world(pkg_compl, mergecount, totalcount, favorites, mysysdict)
3624
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
3625
					spawnd_pids.append(onepid)
3626
					spawnd_pkg[onepid] = (y, x)
3627
					mergecount += 1
3628
3629
			# this slot is exhausted, so wait for all of the forks to finish
3630
			while spawnd_pids:
3631
				self.print_status(totalcount, donec, qsize, failedc, spawnd_pkg, failedPkgs)
3632
				# let's wait for one of the jobs to finish
3633
				(retval, pkg_compl) = self.wait_one_emerge(spawnd_pids, spawnd_pkg, mergecount, totalcount, mymergelist, mtimedb)
3634
3635
				qsize -= 1
3636
				if retval:
3637
					one_in_slot_failed = retval
3638
					failedc += 1
3639
					failedPkgs.append(pkg_compl[2])
3640
				else:
3641
					donec += 1
3642
					self.add_one_emerge_to_world(pkg_compl, mergecount, totalcount, favorites, mysysdict)
3643
		if totalcount:
3644
			self.print_status(totalcount, donec, qsize, failedc, None, failedPkgs)
3645
  
3646
		if one_in_slot_failed:
3647
			portage.writemsg_stdout(red("\nSome packages failed to emerge, summary follows:\n"))
3648
  
3649
		for pkgs in failedPkgs:
3650
			if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3651
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
3652
				sys.exit(1)
3310
3653
3654
			portage.writemsg_stdout(red("\nPackage "+pkgs+" failed to emerge\n"))
3655
			logfile = None
3656
			if "PORT_LOGDIR" in self.settings:
3657
				port_logdir = self.settings["PORT_LOGDIR"]
3658
			else:
3659
				port_logdir = self.settings["ROOT"] + portage.DEF_LOGDIR
3660
3661
			pkg_cat = pkgs.split("/")[0]
3662
			pkg_pf = pkgs.split("/")[1]
3663
			logid_path = os.path.join(build_prefix, ".logid.")+pkg_cat+"."+pkg_pf
3664
			if os.path.exists(logid_path):
3665
				logid_time = time.strftime("%Y%m%d-%H%M%S", time.gmtime(os.stat(logid_path).st_mtime))
3666
				logfile = os.path.join(port_logdir, "%s:%s:%s.log" % \
3667
					(pkg_cat, pkg_pf, logid_time))
3668
				del logid_time
3669
3670
			if logfile and os.path.exists(logfile):
3671
				portage.portage_exec.spawn(('tail', '-n', '20', logfile), returnpid=False)
3672
3673
			if logfile and os.path.exists(logfile):
3674
				portage.writemsg_stdout(red("Please take a look at the file "+logfile+"\n"))
3675
				os.unlink(logid_path)
3676
		if one_in_slot_failed:
3677
			sys.exit(1)
3311
		if "--pretend" not in self.myopts:
3678
		if "--pretend" not in self.myopts:
3312
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
3679
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
3313
3680
3681
		# see if there are any extraneous files in build_prefix, which we might have leftover
3682
		import glob
3683
		for fnames in glob.glob(os.path.join(build_prefix, ".logid.")+"*"):
3684
			os.unlink(fnames)
3685
3314
		# We're out of the loop... We're done. Delete the resume data.
3686
		# We're out of the loop... We're done. Delete the resume data.
3315
		if mtimedb.has_key("resume"):
3687
		if mtimedb.has_key("resume"):
3316
			del mtimedb["resume"]
3688
			del mtimedb["resume"]
3317
		mtimedb.commit()
3689
		mtimedb.commit()
3318
3690
3319
		#by doing an exit this way, --fetchonly can continue to try to
3320
		#fetch everything even if a particular download fails.
3321
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3691
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3322
			if failed_fetches:
3692
			sys.exit(0)
3323
				sys.stderr.write("\n\n!!! Some fetch errors were " + \
3693
3324
					"encountered.  Please see above for details.\n\n")
3325
				for cpv in failed_fetches:
3326
					sys.stderr.write("   ")
3327
					sys.stderr.write(cpv)
3328
					sys.stderr.write("\n")
3329
				sys.stderr.write("\n")
3330
				sys.exit(1)
3331
			else:
3332
				sys.exit(0)
3333
		return os.EX_OK
3694
		return os.EX_OK
3334
3695
3335
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
3696
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
Lines 3769-3775 Link Here
3769
def validate_merge_list(trees, mergelist):
4130
def validate_merge_list(trees, mergelist):
3770
	"""Validate the list to make sure all the packages are still available.
4131
	"""Validate the list to make sure all the packages are still available.
3771
	This is needed for --resume."""
4132
	This is needed for --resume."""
3772
	for (pkg_type, myroot, pkg_key, action) in mergelist:
4133
	for (pkg_type, myroot, pkg_key, action, merge_slot) in mergelist:
3773
		if pkg_type == "binary" and \
4134
		if pkg_type == "binary" and \
3774
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
4135
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
3775
			pkg_type == "ebuild" and \
4136
			pkg_type == "ebuild" and \
Lines 4662-4668 Link Here
4662
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
5023
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
4663
		emergelog(xterm_titles, " >>> depclean")
5024
		emergelog(xterm_titles, " >>> depclean")
4664
5025
4665
	if "--quiet" not in myopts:
5026
	if "--quiet" not in myopts and "--nodeps" not in myopts:
4666
		print "\nCalculating dependencies  ",
5027
		print "\nCalculating dependencies  ",
4667
5028
4668
	soft = 0
5029
	soft = 0
Lines 4764-4769 Link Here
4764
	else:
5125
	else:
4765
		print "Number removed:       "+str(len(cleanlist))
5126
		print "Number removed:       "+str(len(cleanlist))
4766
5127
5128
def mergelist_to_merge_slot(mergelist, myopts, printonly=False, parallel=False):
5129
	merge_slots = {}
5130
	for pkg in mergelist:
5131
		if pkg[0] != 'blocks' and pkg[3] == 'merge':
5132
			slot = int(pkg[4])
5133
			try:
5134
				if pkg not in merge_slots[slot]:
5135
					merge_slots[slot].append(pkg)
5136
			except KeyError:
5137
				merge_slots[slot] = [pkg]
5138
	# print the merge slots
5139
	max_slot = 0
5140
	mylist = merge_slots.keys()
5141
	mylist.sort()
5142
	for x in mylist:
5143
		if x > max_slot:
5144
			max_slot = x
5145
		if parallel:
5146
			print "Package list for slot = "+str(x)
5147
			for y in merge_slots[x]:
5148
				print "	",y
5149
	if printonly:
5150
		return
5151
5152
	# make one last pass at the merge_slots and initialize the missing slots to None
5153
	x = 0
5154
	while x < max_slot:
5155
		if x not in merge_slots.keys():
5156
			merge_slots[x] = None
5157
		x += 1
5158
	return merge_slots
5159
4767
def action_build(settings, trees, mtimedb,
5160
def action_build(settings, trees, mtimedb,
4768
	myopts, myaction, myfiles, spinner):
5161
	myopts, myaction, myfiles, spinner):
4769
	ldpath_mtimes = mtimedb["ldpath"]
5162
	ldpath_mtimes = mtimedb["ldpath"]
Lines 4880-4892 Link Here
4880
			if len(mymergelist) == 0:
5273
			if len(mymergelist) == 0:
4881
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5274
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
4882
				sys.exit(0)
5275
				sys.exit(0)
5276
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
4883
			mydepgraph.display(mymergelist)
5277
			mydepgraph.display(mymergelist)
4884
			prompt="Would you like to resume merging these packages?"
5278
			prompt="Would you like to resume merging these packages?"
4885
		else:
5279
		else:
4886
			mydepgraph.display(
5280
			mymergelist = mydepgraph.altlist(reversed=("--tree" in myopts))
4887
				mydepgraph.altlist(reversed=("--tree" in myopts)))
5281
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
5282
			mydepgraph.display(mymergelist)
4888
			mergecount=0
5283
			mergecount=0
4889
			for x in mydepgraph.altlist():
5284
			for x in mymergelist:
4890
				if x[0] != "blocks" and x[3] != "nomerge":
5285
				if x[0] != "blocks" and x[3] != "nomerge":
4891
					mergecount+=1
5286
					mergecount+=1
4892
				#check for blocking dependencies
5287
				#check for blocking dependencies
Lines 4931-4940 Link Here
4931
			if len(mymergelist) == 0:
5326
			if len(mymergelist) == 0:
4932
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5327
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
4933
				sys.exit(0)
5328
				sys.exit(0)
5329
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
4934
			mydepgraph.display(mymergelist)
5330
			mydepgraph.display(mymergelist)
4935
		else:
5331
		else:
4936
			mydepgraph.display(
5332
			# mydepgraph.digraph.debug_print()
4937
				mydepgraph.altlist(reversed=("--tree" in myopts)))
5333
			mymergelist = mydepgraph.altlist(reversed=("--tree" in myopts))
5334
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
5335
			mydepgraph.display(mymergelist)
4938
	else:
5336
	else:
4939
		if ("--buildpkgonly" in myopts):
5337
		if ("--buildpkgonly" in myopts):
4940
			if not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
5338
			if not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
Lines 4950-4972 Link Here
4950
				it to write the mtimedb"""
5348
				it to write the mtimedb"""
4951
				mtimedb.filename = None
5349
				mtimedb.filename = None
4952
				time.sleep(3) # allow the parent to have first fetch
5350
				time.sleep(3) # allow the parent to have first fetch
5351
			mymergelist = mtimedb["resume"]["mergelist"]
5352
			if "--skipfirst" in myopts:
5353
				mymergelist = mymergelist[1:]
5354
			if len(mymergelist) == 0:
5355
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5356
				sys.exit(0)
5357
			merge_slots = mergelist_to_merge_slot(mymergelist, myopts, False, False)
4953
			del mydepgraph
5358
			del mydepgraph
4954
			retval = mergetask.merge(
5359
			retval = mergetask.merge(mymergelist, favorites, mtimedb, merge_slots)
4955
				mtimedb["resume"]["mergelist"], favorites, mtimedb)
4956
			if retval != os.EX_OK:
5360
			if retval != os.EX_OK:
4957
				sys.exit(retval)
5361
				sys.exit(retval)
4958
		else:
5362
		else:
4959
			if "resume" in mtimedb and \
5363
			mymergelist = mydepgraph.altlist()
4960
			"mergelist" in mtimedb["resume"] and \
5364
			merge_slots = mergelist_to_merge_slot(mymergelist, myopts, False, False)
4961
			len(mtimedb["resume"]["mergelist"]) > 1:
5365
			if "--nodeps" not in myopts or len(mymergelist) > 1:
4962
				mtimedb["resume_backup"] = mtimedb["resume"]
5366
				if "resume" in mtimedb and \
4963
				del mtimedb["resume"]
5367
				"mergelist" in mtimedb["resume"] and \
4964
				mtimedb.commit()
5368
				len(mtimedb["resume"]["mergelist"]) > 1:
4965
			mtimedb["resume"]={}
5369
					mtimedb["resume_backup"] = mtimedb["resume"]
4966
			# XXX: Stored as a list for backward compatibility.
5370
					del mtimedb["resume"]
4967
			mtimedb["resume"]["myopts"] = \
5371
					mtimedb.commit()
4968
				[k for k in myopts if myopts[k] is True]
5372
				mtimedb["resume"]={}
4969
			mtimedb["resume"]["favorites"]=favorites
5373
				# XXX: Stored as a list for backward compatibility.
5374
				mtimedb["resume"]["myopts"] = \
5375
					[k for k in myopts if myopts[k] is True]
5376
				mtimedb["resume"]["favorites"]=favorites
4970
			if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
5377
			if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
4971
				for pkgline in mydepgraph.altlist():
5378
				for pkgline in mydepgraph.altlist():
4972
					if pkgline[0]=="ebuild" and pkgline[3]=="merge":
5379
					if pkgline[0]=="ebuild" and pkgline[3]=="merge":
Lines 4982-4999 Link Here
4982
							tree="porttree")
5389
							tree="porttree")
4983
			if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
5390
			if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
4984
				pkglist = []
5391
				pkglist = []
4985
				for pkg in mydepgraph.altlist():
5392
				for pkg in mymergelist:
4986
					if pkg[0] != "blocks":
5393
					if pkg[0] != "blocks":
4987
						pkglist.append(pkg)
5394
						pkglist.append(pkg)
4988
			else:
5395
			else:
4989
				pkglist = mydepgraph.altlist()
5396
				pkglist = mymergelist
4990
			del mydepgraph
5397
			del mydepgraph
4991
			mergetask = MergeTask(settings, trees, myopts)
5398
			mergetask = MergeTask(settings, trees, myopts)
4992
			retval = mergetask.merge(pkglist, favorites, mtimedb)
5399
			retval = mergetask.merge(pkglist, favorites, mtimedb, merge_slots)
4993
			if retval != os.EX_OK:
5400
			if retval != os.EX_OK:
4994
				sys.exit(retval)
5401
				sys.exit(retval)
4995
5402
4996
		if mtimedb.has_key("resume"):
5403
		if mtimedb.has_key("resume") and ("--nodeps" not in myopts or len(mymergelist) > 1):
4997
			del mtimedb["resume"]
5404
			del mtimedb["resume"]
4998
		if settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
5405
		if settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
4999
			portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
5406
			portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
(-)portage-2.1.2.orig/pym/portage.py (-10 / +27 lines)
Lines 64-70 Link Here
64
	from output import bold, colorize, green, red, yellow
64
	from output import bold, colorize, green, red, yellow
65
65
66
	import portage_const
66
	import portage_const
67
	from portage_const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \
67
	from portage_const import VDB_PATH, PRIVATE_PATH, DEF_LOGDIR, CACHE_PATH, DEPCACHE_PATH, \
68
	  USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \
68
	  USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \
69
	  PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \
69
	  PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \
70
	  EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \
70
	  EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \
Lines 2194-2212 Link Here
2194
	mypids = []
2194
	mypids = []
2195
	pw = None
2195
	pw = None
2196
	if logfile:
2196
	if logfile:
2197
		del keywords["logfile"]
2197
		tee_good = 1
2198
		fd_pipes = keywords.get("fd_pipes")
2198
		fd_pipes = keywords.get("fd_pipes")
2199
		if fd_pipes is None:
2199
		if fd_pipes is None:
2200
			fd_pipes = {0:0, 1:1, 2:2}
2200
			fd_pipes = {0:0, 1:1, 2:2}
2201
		elif 1 not in fd_pipes or 2 not in fd_pipes:
2201
		elif 1 not in fd_pipes or 2 not in fd_pipes:
2202
			raise ValueError(fd_pipes)
2202
			raise ValueError(fd_pipes)
2203
		pr, pw = os.pipe()
2203
		try:
2204
		mypids.extend(portage_exec.spawn(('tee', '-i', '-a', logfile),
2204
			statinfo1 = os.stat(logfile)
2205
			 returnpid=True, fd_pipes={0:pr, 1:fd_pipes[1], 2:fd_pipes[2]}))
2205
			statinfo2 = os.fstat(fd_pipes[1])
2206
		os.close(pr)
2206
			statinfo3 = os.fstat(fd_pipes[2])
2207
		fd_pipes[1] = pw
2207
			# if they are pointing to same file as logfile, no 'tee' is required.
2208
		fd_pipes[2] = pw
2208
			if statinfo1 == statinfo2 and statinfo2 == statinfo3:
2209
		keywords["fd_pipes"] = fd_pipes
2209
				tee_good = 0
2210
		except:
2211
			tee_good = 1
2212
2213
		if tee_good:
2214
2215
			del keywords["logfile"]
2216
			pr, pw = os.pipe()
2217
			mypids.extend(portage_exec.spawn(('tee', '-i', '-a', logfile),
2218
			 	returnpid=True, fd_pipes={0:pr, 1:fd_pipes[1], 2:fd_pipes[2]}))
2219
			os.close(pr)
2220
			fd_pipes[1] = pw
2221
			fd_pipes[2] = pw
2222
			keywords["fd_pipes"] = fd_pipes
2210
2223
2211
	features = mysettings.features
2224
	features = mysettings.features
2212
	# XXX: Negative RESTRICT word
2225
	# XXX: Negative RESTRICT word
Lines 3236-3241 Link Here
3236
	if mysettings.get("PORT_LOGDIR", "") == "":
3249
	if mysettings.get("PORT_LOGDIR", "") == "":
3237
		while "PORT_LOGDIR" in mysettings:
3250
		while "PORT_LOGDIR" in mysettings:
3238
			del mysettings["PORT_LOGDIR"]
3251
			del mysettings["PORT_LOGDIR"]
3252
3253
	if not "PORT_LOGDIR" in mysettings and "parallel" in mysettings.features:
3254
		mysettings["PORT_LOGDIR"] = mysettings["ROOT"] + DEF_LOGDIR
3255
3239
	if "PORT_LOGDIR" in mysettings:
3256
	if "PORT_LOGDIR" in mysettings:
3240
		try:
3257
		try:
3241
			portage_util.ensure_dirs(mysettings["PORT_LOGDIR"],
3258
			portage_util.ensure_dirs(mysettings["PORT_LOGDIR"],
Lines 3248-3254 Link Here
3248
			while "PORT_LOGDIR" in mysettings:
3265
			while "PORT_LOGDIR" in mysettings:
3249
				del mysettings["PORT_LOGDIR"]
3266
				del mysettings["PORT_LOGDIR"]
3250
	if "PORT_LOGDIR" in mysettings:
3267
	if "PORT_LOGDIR" in mysettings:
3251
		logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid")
3268
		logid_path = os.path.join(mysettings["BUILD_PREFIX"], ".logid.")+mysettings["CATEGORY"]+"."+ mysettings["PF"]
3252
		if not os.path.exists(logid_path):
3269
		if not os.path.exists(logid_path):
3253
			f = open(logid_path, "w")
3270
			f = open(logid_path, "w")
3254
			f.close()
3271
			f.close()
(-)portage-2.1.2.orig/pym/portage_const.py (+1 lines)
Lines 12-17 Link Here
12
12
13
VDB_PATH                = "var/db/pkg"
13
VDB_PATH                = "var/db/pkg"
14
PRIVATE_PATH            = "var/lib/portage"
14
PRIVATE_PATH            = "var/lib/portage"
15
DEF_LOGDIR              = "var/log/portage"
15
CACHE_PATH              = "/var/cache/edb"
16
CACHE_PATH              = "/var/cache/edb"
16
DEPCACHE_PATH           = CACHE_PATH+"/dep"
17
DEPCACHE_PATH           = CACHE_PATH+"/dep"
17
18
(-)portage-2.1.2.orig/pym/portage_exec.py (-16 / +32 lines)
Lines 19-24 Link Here
19
19
20
if os.path.isdir("/proc/%i/fd" % os.getpid()):
20
if os.path.isdir("/proc/%i/fd" % os.getpid()):
21
	def get_open_fds():
21
	def get_open_fds():
22
		# there is a race here - fd used by listdir may be in the list but closed
23
		# before this method returns.
22
		return map(int, [fd for fd in os.listdir("/proc/%i/fd" % os.getpid()) if fd.isdigit()])
24
		return map(int, [fd for fd in os.listdir("/proc/%i/fd" % os.getpid()) if fd.isdigit()])
23
else:
25
else:
24
	def get_open_fds():
26
	def get_open_fds():
Lines 167-193 Link Here
167
	# mypids will hold the pids of all processes created.
169
	# mypids will hold the pids of all processes created.
168
	mypids = []
170
	mypids = []
169
171
172
	pw = None
170
	if logfile:
173
	if logfile:
171
		# Using a log file requires that stdout and stderr
174
		# Using a log file requires that stdout and stderr
172
		# are assigned to the process we're running.
175
		# are assigned to the process we're running.
173
		if 1 not in fd_pipes or 2 not in fd_pipes:
176
		if 1 not in fd_pipes or 2 not in fd_pipes:
174
			raise ValueError(fd_pipes)
177
			raise ValueError(fd_pipes)
175
178
176
		# Create a pipe
179
		tee_good = 1
177
		(pr, pw) = os.pipe()
180
		try:
178
181
			statinfo1 = os.stat(logfile)
179
		# Create a tee process, giving it our stdout and stderr
182
			statinfo2 = os.fstat(fd_pipes[1])
180
		# as well as the read end of the pipe.
183
			statinfo3 = os.fstat(fd_pipes[2])
181
		mypids.extend(spawn(('tee', '-i', '-a', logfile),
184
			# if they are pointing to same file as logfile, no 'tee' is required.
182
		              returnpid=True, fd_pipes={0:pr,
185
			if statinfo1 == statinfo2 and statinfo2 == statinfo3:
183
		              1:fd_pipes[1], 2:fd_pipes[2]}))
186
				tee_good = 0
184
187
		except:
185
		# We don't need the read end of the pipe, so close it.
188
			tee_good = 1
186
		os.close(pr)
189
187
190
		if tee_good:
188
		# Assign the write end of the pipe to our stdout and stderr.
191
189
		fd_pipes[1] = pw
192
			# Create a pipe
190
		fd_pipes[2] = pw
193
			(pr, pw) = os.pipe()
194
195
			# Create a tee process, giving it our stdout and stderr
196
			# as well as the read end of the pipe.
197
			mypids.extend(spawn(('tee', '-i', '-a', logfile),
198
					returnpid=True, fd_pipes={0:pr,
199
					1:fd_pipes[1], 2:fd_pipes[2]}))
200
201
			# We don't need the read end of the pipe, so close it.
202
			os.close(pr)
203
204
			# Assign the write end of the pipe to our stdout and stderr.
205
			fd_pipes[1] = pw
206
			fd_pipes[2] = pw
191
207
192
	pid = os.fork()
208
	pid = os.fork()
193
209
Lines 209-215 Link Here
209
225
210
	# If we started a tee process the write side of the pipe is no
226
	# If we started a tee process the write side of the pipe is no
211
	# longer needed, so close it.
227
	# longer needed, so close it.
212
	if logfile:
228
	if logfile and pw:
213
		os.close(pw)
229
		os.close(pw)
214
230
215
	# If the caller wants to handle cleaning up the processes, we tell
231
	# If the caller wants to handle cleaning up the processes, we tell

Return to bug 147516