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 / +736 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
					if len(mymergelist) > 1:
3346
						del mtimedb["resume"]["mergelist"][index]
3347
						mtimedb.commit()
3348
					del mymergelist[index]
3349
					# check if we need to restart portage
3350
					mysplit=portage.pkgsplit(pkg_compl[2])
3351
					if mysplit[0] == "sys-apps/portage" and pkgs[1] == "/":
3352
						self.restart_portage(pkgs, mergecount, totalcount, mtimedb)
3353
					break
3354
				index += 1
3355
		return (retval, pkg_compl)
3356
3357
	def merge(self, mylist, favorites, mtimedb, m_slots):
2897
		failed_fetches = []
3358
		failed_fetches = []
2898
		mymergelist=[]
3359
		mymergelist=[]
2899
		ldpath_mtimes = mtimedb["ldpath"]
3360
		ldpath_mtimes = mtimedb["ldpath"]
2900
		xterm_titles = "notitles" not in self.settings.features
3361
		xterm_titles = "notitles" not in self.settings.features
3362
		parallel = "parallel" in self.settings.features
3363
		build_prefix=self.settings["PORTAGE_TMPDIR"]+"/portage"
3364
3365
		# parallel merge will be painful to watch with debug or fetchonly. So, you get only one of these...:-)
3366
		if self.edebug or "--fetchonly" in self.myopts:
3367
			parallel = False
2901
3368
2902
		#check for blocking dependencies
3369
		#check for blocking dependencies
2903
		if "--fetchonly" not in self.myopts and \
3370
		if "--fetchonly" not in self.myopts and \
Lines 2914-2921 Link Here
2914
3381
2915
		if "--resume" in self.myopts:
3382
		if "--resume" in self.myopts:
2916
			# We're resuming.
3383
			# We're resuming.
2917
			print colorize("GOOD", "*** Resuming merge...")
2918
			emergelog(xterm_titles, " *** Resuming merge...")
2919
			mylist = mtimedb["resume"]["mergelist"][:]
3384
			mylist = mtimedb["resume"]["mergelist"][:]
2920
			if "--skipfirst" in self.myopts and mylist:
3385
			if "--skipfirst" in self.myopts and mylist:
2921
				del mtimedb["resume"]["mergelist"][0]
3386
				del mtimedb["resume"]["mergelist"][0]
Lines 2943-2949 Link Here
2943
				if not shown_verifying_msg:
3408
				if not shown_verifying_msg:
2944
					shown_verifying_msg = True
3409
					shown_verifying_msg = True
2945
					print ">>> Verifying ebuild Manifests..."
3410
					print ">>> Verifying ebuild Manifests..."
2946
				mytype, myroot, mycpv, mystatus = x
3411
				mytype, myroot, mycpv, mystatus, slott = x
2947
				portdb = self.trees[myroot]["porttree"].dbapi
3412
				portdb = self.trees[myroot]["porttree"].dbapi
2948
				quiet_config = quiet_settings[myroot]
3413
				quiet_config = quiet_settings[myroot]
2949
				quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
3414
				quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
Lines 2981-2988 Link Here
2981
					os.path.join(self.target_root, portage.WORLD_FILE),
3446
					os.path.join(self.target_root, portage.WORLD_FILE),
2982
					"\n".join(myfavdict.values()))
3447
					"\n".join(myfavdict.values()))
2983
3448
2984
			mtimedb["resume"]["mergelist"]=mymergelist[:]
3449
			if "--nodeps" not in self.myopts or len(mymergelist) > 1:
2985
			mtimedb.commit()
3450
				mtimedb["resume"]["mergelist"]=mymergelist[:]
3451
				mtimedb.commit()
3452
3453
		totalcount = len(mymergelist)
3454
		mergecount=1
3455
3456
		if "--resume" in self.myopts and "--fetchonly" not in self.myopts:
3457
			# We're resuming.
3458
			print colorize("GOOD", "*** Resuming merge...")
3459
			emergelog(xterm_titles, " *** Resuming merge...")
2986
3460
2987
		myfeat = self.settings.features[:]
3461
		myfeat = self.settings.features[:]
2988
		bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
3462
		bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
Lines 3000-3011 Link Here
3000
				print ">>> starting parallel fetching"
3474
				print ">>> starting parallel fetching"
3001
				fetch_log = "/var/log/emerge-fetch.log"
3475
				fetch_log = "/var/log/emerge-fetch.log"
3002
				logfile = open(fetch_log, "w")
3476
				logfile = open(fetch_log, "w")
3003
				fd_pipes = {1:logfile.fileno(), 2:logfile.fileno()}
3477
				fd_pipes = {0:0, 1:logfile.fileno(), 2:logfile.fileno()}
3004
				portage_util.apply_secpass_permissions(fetch_log,
3478
				portage_util.apply_secpass_permissions(fetch_log,
3005
					uid=portage.portage_uid, gid=portage.portage_gid,
3479
					uid=portage.portage_uid, gid=portage.portage_gid,
3006
					mode=0660)
3480
					mode=0660)
3007
				fetch_env = os.environ.copy()
3481
				fetch_env = os.environ.copy()
3008
				fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs"
3482
				fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs -parallel"
3009
				fetch_env["PORTAGE_NICENESS"] = "0"
3483
				fetch_env["PORTAGE_NICENESS"] = "0"
3010
				fetch_args = [sys.argv[0], "--resume", "--fetchonly"]
3484
				fetch_args = [sys.argv[0], "--resume", "--fetchonly"]
3011
				resume_opts = self.myopts.copy()
3485
				resume_opts = self.myopts.copy()
Lines 3025-3335 Link Here
3025
				del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
3499
				del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
3026
					resume_opts
3500
					resume_opts
3027
3501
3028
		mergecount=0
3502
		if not parallel:
3029
		for x in mymergelist:
3503
			failed_fetches = []
3030
			mergecount+=1
3504
			for x in mymergelist:
3031
			myroot=x[1]
3505
				retcode = self.do_one_emerge(x, mergecount, totalcount, mtimedb, favorites, mysysdict)
3032
			pkg_key = x[2]
3506
				mergecount += 1
3033
			pkgindex=2
3507
3034
			portdb = self.trees[myroot]["porttree"].dbapi
3508
				# need to short circuit the spawn with --nodeps
3035
			bindb  = self.trees[myroot]["bintree"].dbapi
3509
				if os.environ.get("PORTAGE_INTERNAL_CALL", "0") != "1":
3036
			vartree = self.trees[myroot]["vartree"]
3510
					if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3037
			pkgsettings = self.pkgsettings[myroot]
3511
						continue
3038
			if x[0]=="blocks":
3512
					if retcode != os.EX_OK:
3039
				pkgindex=3
3513
						if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3040
			y = portdb.findname(pkg_key)
3514
							failed_fetches.append(x[2])
3515
							continue
3516
						else:
3517
							return retcode
3518
					# Unsafe for parallel merges
3519
					del mtimedb["resume"]["mergelist"][0]
3520
					# Commit after each merge so that --resume may still work in
3521
					# in the event that portage is not allowed to exit normally
3522
					# due to power failure, SIGKILL, etc...
3523
					mtimedb.commit()
3524
3525
					# unlink the logid_path if any exists
3526
					logid_path = os.path.join(build_prefix, ".logid.")+x[2].split("/")[0]+"."+x[2].split("/")[1]
3527
					if os.path.exists(logid_path):
3528
						os.unlink(logid_path)
3529
					del logid_path
3530
  
3531
					# check if we need to restart portage
3532
					mysplit=portage.pkgsplit(x[2])
3533
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
3534
							self.restart_portage(x, mergecount, totalcount, mtimedb)
3535
  
3536
				else:
3537
					if retcode != os.EX_OK:
3538
						sys.exit(1)
3539
  					else:
3540
						sys.exit(0)
3541
  
3041
			if "--pretend" not in self.myopts:
3542
			if "--pretend" not in self.myopts:
3042
				print "\n>>> Emerging (" + \
3543
				emergelog(xterm_titles, " *** Finished. Cleaning up...")
3043
					colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
3544
  
3044
					colorize("MERGE_LIST_PROGRESS", str(len(mymergelist))) + ") " + \
3545
			# We're out of the loop... We're done. Delete the resume data.
3045
					colorize("GOOD", x[pkgindex]) + " to " + x[1]
3546
			if mtimedb.has_key("resume"):
3046
				emergelog(xterm_titles, " >>> emerge ("+\
3547
				del mtimedb["resume"]
3047
					str(mergecount)+" of "+str(len(mymergelist))+\
3548
			mtimedb.commit()
3048
					") "+x[pkgindex]+" to "+x[1])
3549
			
3049
3550
			#by doing an exit this way, --fetchonly can continue to try to
3050
			pkgsettings["EMERGE_FROM"] = x[0]
3551
			#fetch everything even if a particular download fails.
3051
			pkgsettings.backup_changes("EMERGE_FROM")
3552
			if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3052
			pkgsettings.reset()
3553
				if failed_fetches:
3053
3554
					sys.stderr.write("\n\n!!! Some fetch errors were " + \
3054
			#buildsyspkg: Check if we need to _force_ binary package creation
3555
						"encountered.  Please see above for details.\n\n")
3055
			issyspkg = ("buildsyspkg" in myfeat) \
3556
					for cpv in failed_fetches:
3056
					and x[0] != "blocks" \
3557
						sys.stderr.write("   ")
3057
					and mysysdict.has_key(portage.cpv_getkey(x[2])) \
3558
						sys.stderr.write(cpv)
3058
					and "--buildpkg" not in self.myopts
3559
						sys.stderr.write("\n")
3059
			if x[0] in ["ebuild","blocks"]:
3560
					sys.stderr.write("\n")
3060
				if x[0] == "blocks" and "--fetchonly" not in self.myopts:
3561
					sys.exit(1)
3061
					raise Exception, "Merging a blocker"
3562
				else:
3062
				elif "--fetchonly" in self.myopts or \
3563
					sys.exit(0)
3063
					"--fetch-all-uri" in self.myopts:
3564
			return os.EX_OK
3064
					if "--fetch-all-uri" in self.myopts:
3565
  
3065
						retval = portage.doebuild(y, "fetch", myroot,
3566
		# parallel code - dirty starts here...;-)
3066
							pkgsettings, self.edebug,
3567
		one_in_slot_failed=0
3067
							"--pretend" in self.myopts, fetchonly=1,
3568
		spawnd_pids=[]
3068
							fetchall=1, mydbapi=portdb, tree="porttree")
3569
3069
					else:
3570
		# dirty little trick to get number of cpus from the system
3070
						retval = portage.doebuild(y, "fetch", myroot,
3571
		fd_cpuinfo = os.popen("cat /proc/cpuinfo","r")
3071
							pkgsettings, self.edebug,
3572
		cpu_count = 0
3072
							"--pretend" in self.myopts, fetchonly=1,
3573
		for data_cpuinfo in fd_cpuinfo.readlines():
3073
							mydbapi=portdb, tree="porttree")
3574
			if data_cpuinfo.find("cpu MHz") > -1 :
3074
					if (retval is None) or retval:
3575
				cpu_count += 1
3075
						print
3576
		fd_cpuinfo.close()
3076
						print "!!! Fetch for",y,"failed, continuing..."
3577
3077
						print
3578
		# if someone really screwed with /proc/cpuinfo output, we should not suffer
3078
						failed_fetches.append(pkg_key)
3579
		if cpu_count == 0:
3079
					continue
3580
			cpu_count = 1
3080
3581
3081
				portage.doebuild_environment(y, "setup", myroot,
3582
		spawnd_pkg = {}
3082
					pkgsettings, self.edebug, 1, portdb)
3583
		donec = 0
3083
				catdir = os.path.dirname(pkgsettings["PORTAGE_BUILDDIR"])
3584
		failedc = 0
3084
				portage_util.ensure_dirs(os.path.dirname(catdir),
3585
		failedPkgs = []
3085
					uid=portage.portage_uid, gid=portage.portage_gid,
3586
		logid_path = None
3086
					mode=070, mask=0)
3587
		mylist = m_slots.keys()
3087
				builddir_lock = None
3588
		mylist.sort()
3088
				catdir_lock = None
3589
		for x in mylist:
3089
				try:
3590
			# if slot is empty, go on
3090
					catdir_lock = portage_locks.lockdir(catdir)
3591
			if not m_slots[x]:
3091
					portage_util.ensure_dirs(catdir,
3592
				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
3593
3205
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
3594
			# if previous slot failed, discontinue the emerge
3206
				emergelog(xterm_titles, " === ("+str(mergecount)+\
3595
			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 ("+\
3596
				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
3597
3254
					# Figure out if we need a restart.
3598
			# start multiple merges in parallel mode
3255
					mysplit=portage.pkgsplit(x[2])
3599
			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
3600
3304
			# Unsafe for parallel merges
3601
			qsize = 0
3305
			del mtimedb["resume"]["mergelist"][0]
3602
			for y in m_slots[x]:
3306
			# Commit after each merge so that --resume may still work in
3603
				# these all can go in parallel, so fork one after the other
3307
			# in the event that portage is not allowed to exit normally
3604
				# but num_at_atime at most
3308
			# due to power failure, SIGKILL, etc...
3605
				if num_at_atime:
3309
			mtimedb.commit()
3606
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
3607
					spawnd_pids.append(onepid)
3608
					spawnd_pkg[onepid] = (y, x)
3609
					num_at_atime -= 1
3610
					mergecount += 1
3611
					qsize += 1
3612
				else:
3613
					self.print_status(totalcount, donec, qsize, failedc, spawnd_pkg, failedPkgs)
3614
					# let's wait for one of the jobs to finish
3615
					(retval, pkg_compl) = self.wait_one_emerge(spawnd_pids, spawnd_pkg, mergecount, totalcount, mymergelist, mtimedb)
3616
3617
					# if it failed, I need to fail next slot but continue to merge all in this slot
3618
					if retval:
3619
						one_in_slot_failed = retval
3620
						failedc += 1
3621
						failedPkgs.append(pkg_compl[2])
3622
  					else:
3623
						donec += 1
3624
						self.add_one_emerge_to_world(pkg_compl, mergecount, totalcount, favorites, mysysdict)
3625
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
3626
					spawnd_pids.append(onepid)
3627
					spawnd_pkg[onepid] = (y, x)
3628
					mergecount += 1
3629
3630
			# this slot is exhausted, so wait for all of the forks to finish
3631
			while spawnd_pids:
3632
				self.print_status(totalcount, donec, qsize, failedc, spawnd_pkg, failedPkgs)
3633
				# let's wait for one of the jobs to finish
3634
				(retval, pkg_compl) = self.wait_one_emerge(spawnd_pids, spawnd_pkg, mergecount, totalcount, mymergelist, mtimedb)
3635
3636
				qsize -= 1
3637
				if retval:
3638
					one_in_slot_failed = retval
3639
					failedc += 1
3640
					failedPkgs.append(pkg_compl[2])
3641
				else:
3642
					donec += 1
3643
					self.add_one_emerge_to_world(pkg_compl, mergecount, totalcount, favorites, mysysdict)
3644
		if totalcount:
3645
			self.print_status(totalcount, donec, qsize, failedc, None, failedPkgs)
3646
  
3647
		if one_in_slot_failed:
3648
			portage.writemsg_stdout(red("\nSome packages failed to emerge, summary follows:\n"))
3649
  
3650
		for pkgs in failedPkgs:
3651
			if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3652
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
3653
				sys.exit(1)
3310
3654
3655
			portage.writemsg_stdout(red("\nPackage "+pkgs+" failed to emerge\n"))
3656
			logfile = None
3657
			if "PORT_LOGDIR" in self.settings:
3658
				port_logdir = self.settings["PORT_LOGDIR"]
3659
			else:
3660
				port_logdir = self.settings["ROOT"] + portage.DEF_LOGDIR
3661
3662
			pkg_cat = pkgs.split("/")[0]
3663
			pkg_pf = pkgs.split("/")[1]
3664
			logid_path = os.path.join(build_prefix, ".logid.")+pkg_cat+"."+pkg_pf
3665
			if os.path.exists(logid_path):
3666
				logid_time = time.strftime("%Y%m%d-%H%M%S", time.gmtime(os.stat(logid_path).st_mtime))
3667
				logfile = os.path.join(port_logdir, "%s:%s:%s.log" % \
3668
					(pkg_cat, pkg_pf, logid_time))
3669
				del logid_time
3670
3671
			if logfile and os.path.exists(logfile):
3672
				portage.portage_exec.spawn(('tail', '-n', '20', logfile), returnpid=False)
3673
3674
			if logfile and os.path.exists(logfile):
3675
				portage.writemsg_stdout(red("Please take a look at the file "+logfile+"\n"))
3676
				os.unlink(logid_path)
3677
		if one_in_slot_failed:
3678
			sys.exit(1)
3311
		if "--pretend" not in self.myopts:
3679
		if "--pretend" not in self.myopts:
3312
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
3680
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
3313
3681
3682
		# see if there are any extraneous files in build_prefix, which we might have leftover
3683
		import glob
3684
		for fnames in glob.glob(os.path.join(build_prefix, ".logid.")+"*"):
3685
			os.unlink(fnames)
3686
3314
		# We're out of the loop... We're done. Delete the resume data.
3687
		# We're out of the loop... We're done. Delete the resume data.
3315
		if mtimedb.has_key("resume"):
3688
		if mtimedb.has_key("resume"):
3316
			del mtimedb["resume"]
3689
			del mtimedb["resume"]
3317
		mtimedb.commit()
3690
		mtimedb.commit()
3318
3691
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:
3692
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3322
			if failed_fetches:
3693
			sys.exit(0)
3323
				sys.stderr.write("\n\n!!! Some fetch errors were " + \
3694
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
3695
		return os.EX_OK
3334
3696
3335
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
3697
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
Lines 3769-3775 Link Here
3769
def validate_merge_list(trees, mergelist):
4131
def validate_merge_list(trees, mergelist):
3770
	"""Validate the list to make sure all the packages are still available.
4132
	"""Validate the list to make sure all the packages are still available.
3771
	This is needed for --resume."""
4133
	This is needed for --resume."""
3772
	for (pkg_type, myroot, pkg_key, action) in mergelist:
4134
	for (pkg_type, myroot, pkg_key, action, merge_slot) in mergelist:
3773
		if pkg_type == "binary" and \
4135
		if pkg_type == "binary" and \
3774
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
4136
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
3775
			pkg_type == "ebuild" and \
4137
			pkg_type == "ebuild" and \
Lines 4662-4668 Link Here
4662
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
5024
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
4663
		emergelog(xterm_titles, " >>> depclean")
5025
		emergelog(xterm_titles, " >>> depclean")
4664
5026
4665
	if "--quiet" not in myopts:
5027
	if "--quiet" not in myopts and "--nodeps" not in myopts:
4666
		print "\nCalculating dependencies  ",
5028
		print "\nCalculating dependencies  ",
4667
5029
4668
	soft = 0
5030
	soft = 0
Lines 4764-4769 Link Here
4764
	else:
5126
	else:
4765
		print "Number removed:       "+str(len(cleanlist))
5127
		print "Number removed:       "+str(len(cleanlist))
4766
5128
5129
def mergelist_to_merge_slot(mergelist, myopts, printonly=False, parallel=False):
5130
	merge_slots = {}
5131
	for pkg in mergelist:
5132
		if pkg[0] != 'blocks' and pkg[3] == 'merge':
5133
			slot = int(pkg[4])
5134
			try:
5135
				if pkg not in merge_slots[slot]:
5136
					merge_slots[slot].append(pkg)
5137
			except KeyError:
5138
				merge_slots[slot] = [pkg]
5139
	# print the merge slots
5140
	max_slot = 0
5141
	mylist = merge_slots.keys()
5142
	mylist.sort()
5143
	for x in mylist:
5144
		if x > max_slot:
5145
			max_slot = x
5146
		if parallel:
5147
			print "Package list for slot = "+str(x)
5148
			for y in merge_slots[x]:
5149
				print "	",y
5150
	if printonly:
5151
		return
5152
5153
	# make one last pass at the merge_slots and initialize the missing slots to None
5154
	x = 0
5155
	while x < max_slot:
5156
		if x not in merge_slots.keys():
5157
			merge_slots[x] = None
5158
		x += 1
5159
	return merge_slots
5160
4767
def action_build(settings, trees, mtimedb,
5161
def action_build(settings, trees, mtimedb,
4768
	myopts, myaction, myfiles, spinner):
5162
	myopts, myaction, myfiles, spinner):
4769
	ldpath_mtimes = mtimedb["ldpath"]
5163
	ldpath_mtimes = mtimedb["ldpath"]
Lines 4880-4892 Link Here
4880
			if len(mymergelist) == 0:
5274
			if len(mymergelist) == 0:
4881
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5275
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
4882
				sys.exit(0)
5276
				sys.exit(0)
5277
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
4883
			mydepgraph.display(mymergelist)
5278
			mydepgraph.display(mymergelist)
4884
			prompt="Would you like to resume merging these packages?"
5279
			prompt="Would you like to resume merging these packages?"
4885
		else:
5280
		else:
4886
			mydepgraph.display(
5281
			mymergelist = mydepgraph.altlist(reversed=("--tree" in myopts))
4887
				mydepgraph.altlist(reversed=("--tree" in myopts)))
5282
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
5283
			mydepgraph.display(mymergelist)
4888
			mergecount=0
5284
			mergecount=0
4889
			for x in mydepgraph.altlist():
5285
			for x in mymergelist:
4890
				if x[0] != "blocks" and x[3] != "nomerge":
5286
				if x[0] != "blocks" and x[3] != "nomerge":
4891
					mergecount+=1
5287
					mergecount+=1
4892
				#check for blocking dependencies
5288
				#check for blocking dependencies
Lines 4931-4940 Link Here
4931
			if len(mymergelist) == 0:
5327
			if len(mymergelist) == 0:
4932
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5328
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
4933
				sys.exit(0)
5329
				sys.exit(0)
5330
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
4934
			mydepgraph.display(mymergelist)
5331
			mydepgraph.display(mymergelist)
4935
		else:
5332
		else:
4936
			mydepgraph.display(
5333
			# mydepgraph.digraph.debug_print()
4937
				mydepgraph.altlist(reversed=("--tree" in myopts)))
5334
			mymergelist = mydepgraph.altlist(reversed=("--tree" in myopts))
5335
			mergelist_to_merge_slot(mymergelist, myopts, True, "parallel" in settings.features)
5336
			mydepgraph.display(mymergelist)
4938
	else:
5337
	else:
4939
		if ("--buildpkgonly" in myopts):
5338
		if ("--buildpkgonly" in myopts):
4940
			if not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
5339
			if not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
Lines 4950-4972 Link Here
4950
				it to write the mtimedb"""
5349
				it to write the mtimedb"""
4951
				mtimedb.filename = None
5350
				mtimedb.filename = None
4952
				time.sleep(3) # allow the parent to have first fetch
5351
				time.sleep(3) # allow the parent to have first fetch
5352
			mymergelist = mtimedb["resume"]["mergelist"]
5353
			if "--skipfirst" in myopts:
5354
				mymergelist = mymergelist[1:]
5355
			if len(mymergelist) == 0:
5356
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5357
				sys.exit(0)
5358
			merge_slots = mergelist_to_merge_slot(mymergelist, myopts, False, False)
4953
			del mydepgraph
5359
			del mydepgraph
4954
			retval = mergetask.merge(
5360
			retval = mergetask.merge(mymergelist, favorites, mtimedb, merge_slots)
4955
				mtimedb["resume"]["mergelist"], favorites, mtimedb)
4956
			if retval != os.EX_OK:
5361
			if retval != os.EX_OK:
4957
				sys.exit(retval)
5362
				sys.exit(retval)
4958
		else:
5363
		else:
4959
			if "resume" in mtimedb and \
5364
			mymergelist = mydepgraph.altlist()
4960
			"mergelist" in mtimedb["resume"] and \
5365
			merge_slots = mergelist_to_merge_slot(mymergelist, myopts, False, False)
4961
			len(mtimedb["resume"]["mergelist"]) > 1:
5366
			if "--nodeps" not in myopts or len(mymergelist) > 1:
4962
				mtimedb["resume_backup"] = mtimedb["resume"]
5367
				if "resume" in mtimedb and \
4963
				del mtimedb["resume"]
5368
				"mergelist" in mtimedb["resume"] and \
4964
				mtimedb.commit()
5369
				len(mtimedb["resume"]["mergelist"]) > 1:
4965
			mtimedb["resume"]={}
5370
					mtimedb["resume_backup"] = mtimedb["resume"]
4966
			# XXX: Stored as a list for backward compatibility.
5371
					del mtimedb["resume"]
4967
			mtimedb["resume"]["myopts"] = \
5372
					mtimedb.commit()
4968
				[k for k in myopts if myopts[k] is True]
5373
				mtimedb["resume"]={}
4969
			mtimedb["resume"]["favorites"]=favorites
5374
				# XXX: Stored as a list for backward compatibility.
5375
				mtimedb["resume"]["myopts"] = \
5376
					[k for k in myopts if myopts[k] is True]
5377
				mtimedb["resume"]["favorites"]=favorites
4970
			if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
5378
			if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
4971
				for pkgline in mydepgraph.altlist():
5379
				for pkgline in mydepgraph.altlist():
4972
					if pkgline[0]=="ebuild" and pkgline[3]=="merge":
5380
					if pkgline[0]=="ebuild" and pkgline[3]=="merge":
Lines 4982-4999 Link Here
4982
							tree="porttree")
5390
							tree="porttree")
4983
			if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
5391
			if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
4984
				pkglist = []
5392
				pkglist = []
4985
				for pkg in mydepgraph.altlist():
5393
				for pkg in mymergelist:
4986
					if pkg[0] != "blocks":
5394
					if pkg[0] != "blocks":
4987
						pkglist.append(pkg)
5395
						pkglist.append(pkg)
4988
			else:
5396
			else:
4989
				pkglist = mydepgraph.altlist()
5397
				pkglist = mymergelist
4990
			del mydepgraph
5398
			del mydepgraph
4991
			mergetask = MergeTask(settings, trees, myopts)
5399
			mergetask = MergeTask(settings, trees, myopts)
4992
			retval = mergetask.merge(pkglist, favorites, mtimedb)
5400
			retval = mergetask.merge(pkglist, favorites, mtimedb, merge_slots)
4993
			if retval != os.EX_OK:
5401
			if retval != os.EX_OK:
4994
				sys.exit(retval)
5402
				sys.exit(retval)
4995
5403
4996
		if mtimedb.has_key("resume"):
5404
		if mtimedb.has_key("resume") and ("--nodeps" not in myopts or len(mymergelist) > 1):
4997
			del mtimedb["resume"]
5405
			del mtimedb["resume"]
4998
		if settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
5406
		if settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
4999
			portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
5407
			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