* [PATCH 01/10] build/msg: Cleanup verbose option handling
@ 2020-08-24 16:53 Richard Purdie
2020-08-24 16:53 ` [PATCH 02/10] cooker/cookerdata/main: Improve loglevel handling Richard Purdie
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
The levels of indirection to set these verbose logging options is rather
crazy. This attempts to turn things into two specific options with
much more specific meanings. For now its all still controlled by the
commandline verbose option and should funciton as previously, with
the addition that the BB_VERBOSE_LOGS option can now be task specific.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
bin/bitbake-worker | 4 ++--
lib/bb/build.py | 7 +++++--
lib/bb/cooker.py | 5 -----
lib/bb/cookerdata.py | 7 ++++++-
lib/bb/msg.py | 6 ------
lib/bb/runqueue.py | 4 ++--
6 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/bin/bitbake-worker b/bin/bitbake-worker
index 97cc0fd60f..9334f11fb8 100755
--- a/bin/bitbake-worker
+++ b/bin/bitbake-worker
@@ -413,9 +413,9 @@ class BitbakeWorker(object):
def handle_workerdata(self, data):
self.workerdata = pickle.loads(data)
+ bb.build.verboseShellLogging = self.workerdata["build_verbose_shell"]
+ bb.build.verboseStdoutLogging = self.workerdata["build_verbose_stdout"]
bb.msg.loggerDefaultLogLevel = self.workerdata["logdefaultlevel"]
- bb.msg.loggerDefaultVerbose = self.workerdata["logdefaultverbose"]
- bb.msg.loggerVerboseLogs = self.workerdata["logdefaultverboselogs"]
bb.msg.loggerDefaultDomains = self.workerdata["logdefaultdomain"]
for mc in self.databuilder.mcdata:
self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"])
diff --git a/lib/bb/build.py b/lib/bb/build.py
index 94f9cb371c..974d2ff065 100644
--- a/lib/bb/build.py
+++ b/lib/bb/build.py
@@ -29,6 +29,9 @@ from bb import data, event, utils
bblogger = logging.getLogger('BitBake')
logger = logging.getLogger('BitBake.Build')
+verboseShellLogging = False
+verboseStdoutLogging = False
+
__mtime_cache = {}
def cached_mtime_noerror(f):
@@ -413,7 +416,7 @@ def exec_func_shell(func, d, runfile, cwd=None):
bb.data.emit_func(func, script, d)
- if bb.msg.loggerVerboseLogs:
+ if verboseShellLogging or bb.utils.to_boolean(d.getVar("BB_VERBOSE_LOGS", False)):
script.write("set -x\n")
if cwd:
script.write("cd '%s'\n" % cwd)
@@ -433,7 +436,7 @@ exit $ret
if fakerootcmd:
cmd = [fakerootcmd, runfile]
- if bb.msg.loggerDefaultVerbose:
+ if verboseStdoutLogging:
logfile = LogTee(logger, StdoutNoopContextManager())
else:
logfile = StdoutNoopContextManager()
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 33452e7b93..57caf38c2a 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -413,11 +413,6 @@ class BBCooker:
self.data.disableTracking()
def parseConfiguration(self):
- # Set log file verbosity
- verboselogs = bb.utils.to_boolean(self.data.getVar("BB_VERBOSE_LOGS", False))
- if verboselogs:
- bb.msg.loggerVerboseLogs = True
-
# Change nice level if we're asked to
nice = self.data.getVar("BB_NICE_LEVEL")
if nice:
diff --git a/lib/bb/cookerdata.py b/lib/bb/cookerdata.py
index b86e7d446b..6bf411bcd2 100644
--- a/lib/bb/cookerdata.py
+++ b/lib/bb/cookerdata.py
@@ -58,11 +58,14 @@ class ConfigParameters(object):
def updateToServer(self, server, environment):
options = {}
for o in ["abort", "force", "invalidate_stamp",
- "verbose", "debug", "dry_run", "dump_signatures",
+ "debug", "dry_run", "dump_signatures",
"debug_domains", "extra_assume_provided", "profile",
"prefile", "postfile", "server_timeout"]:
options[o] = getattr(self.options, o)
+ options['build_verbose_shell'] = self.options.verbose
+ options['build_verbose_stdout'] = self.options.verbose
+
ret, error = server.runCommand(["updateConfig", options, environment, sys.argv])
if error:
raise Exception("Unable to update the server configuration with local parameters: %s" % error)
@@ -125,6 +128,8 @@ class CookerConfiguration(object):
self.skipsetscene = False
self.invalidate_stamp = False
self.dump_signatures = []
+ self.build_verbose_shell = False
+ self.build_verbose_stdout = False
self.dry_run = False
self.tracking = False
self.xmlrpcinterface = []
diff --git a/lib/bb/msg.py b/lib/bb/msg.py
index 2d88c4e72d..1b1a23bb50 100644
--- a/lib/bb/msg.py
+++ b/lib/bb/msg.py
@@ -146,18 +146,12 @@ class LogFilterLTLevel(logging.Filter):
#
loggerDefaultLogLevel = BBLogFormatter.NOTE
-loggerDefaultVerbose = False
-loggerVerboseLogs = False
loggerDefaultDomains = {}
def init_msgconfig(verbose, debug, debug_domains=None):
"""
Set default verbosity and debug levels config the logger
"""
- bb.msg.loggerDefaultVerbose = verbose
- if verbose:
- bb.msg.loggerVerboseLogs = True
-
if debug:
bb.msg.loggerDefaultLogLevel = BBLogFormatter.DEBUG - debug + 1
elif verbose:
diff --git a/lib/bb/runqueue.py b/lib/bb/runqueue.py
index 02a261e30c..6370ce50a1 100644
--- a/lib/bb/runqueue.py
+++ b/lib/bb/runqueue.py
@@ -1263,8 +1263,8 @@ class RunQueue:
"fakerootnoenv" : self.rqdata.dataCaches[mc].fakerootnoenv,
"sigdata" : bb.parse.siggen.get_taskdata(),
"logdefaultlevel" : bb.msg.loggerDefaultLogLevel,
- "logdefaultverbose" : bb.msg.loggerDefaultVerbose,
- "logdefaultverboselogs" : bb.msg.loggerVerboseLogs,
+ "build_verbose_shell" : self.cooker.configuration.build_verbose_shell,
+ "build_verbose_stdout" : self.cooker.configuration.build_verbose_stdout,
"logdefaultdomain" : bb.msg.loggerDefaultDomains,
"prhost" : self.cooker.prhost,
"buildname" : self.cfgData.getVar("BUILDNAME"),
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 02/10] cooker/cookerdata/main: Improve loglevel handling
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 03/10] cookerdata: Ensure UI options are updated to the server Richard Purdie
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Rather than passing debug/verbose/debug_domains around, pass the
computed output of these. Ensure that the cooker sets the levels
to match the levels currently set in the UI and generally try and
make it easier to understand what the code is doing.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/cooker.py | 7 ++++++-
lib/bb/cookerdata.py | 10 ++++++----
lib/bb/main.py | 8 ++++----
3 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 57caf38c2a..c34de303fb 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -446,7 +446,12 @@ class BBCooker:
logger.debug(1, "Marking as dirty due to '%s' option change to '%s'" % (o, options[o]))
print("Marking as dirty due to '%s' option change to '%s'" % (o, options[o]))
clean = False
- setattr(self.configuration, o, options[o])
+ if hasattr(self.configuration, o):
+ setattr(self.configuration, o, options[o])
+
+ bb.msg.loggerDefaultLogLevel = self.configuration.default_loglevel
+ bb.msg.loggerDefaultDomains = self.configuration.debug_domains
+
for k in bb.utils.approved_variables():
if k in environment and k not in self.configuration.env:
logger.debug(1, "Updating new environment variable %s to %s" % (k, environment[k]))
diff --git a/lib/bb/cookerdata.py b/lib/bb/cookerdata.py
index 6bf411bcd2..f43610e7f8 100644
--- a/lib/bb/cookerdata.py
+++ b/lib/bb/cookerdata.py
@@ -58,13 +58,15 @@ class ConfigParameters(object):
def updateToServer(self, server, environment):
options = {}
for o in ["abort", "force", "invalidate_stamp",
- "debug", "dry_run", "dump_signatures",
- "debug_domains", "extra_assume_provided", "profile",
+ "dry_run", "dump_signatures",
+ "extra_assume_provided", "profile",
"prefile", "postfile", "server_timeout"]:
options[o] = getattr(self.options, o)
options['build_verbose_shell'] = self.options.verbose
options['build_verbose_stdout'] = self.options.verbose
+ options['default_loglevel'] = bb.msg.loggerDefaultLogLevel
+ options['debug_domains'] = bb.msg.loggerDefaultDomains
ret, error = server.runCommand(["updateConfig", options, environment, sys.argv])
if error:
@@ -114,11 +116,11 @@ class CookerConfiguration(object):
"""
def __init__(self):
- self.debug_domains = []
+ self.debug_domains = bb.msg.loggerDefaultDomains
+ self.default_loglevel = bb.msg.loggerDefaultLogLevel
self.extra_assume_provided = []
self.prefile = []
self.postfile = []
- self.debug = 0
self.cmd = None
self.abort = True
self.force = False
diff --git a/lib/bb/main.py b/lib/bb/main.py
index af2880f8d5..e483cce1ae 100755
--- a/lib/bb/main.py
+++ b/lib/bb/main.py
@@ -357,11 +357,11 @@ def bitbake_main(configParams, configuration):
if "BBDEBUG" in os.environ:
level = int(os.environ["BBDEBUG"])
- if level > configuration.debug:
- configuration.debug = level
+ if level > configParams.debug:
+ configParams.debug = level
- bb.msg.init_msgconfig(configParams.verbose, configuration.debug,
- configuration.debug_domains)
+ bb.msg.init_msgconfig(configParams.verbose, configParams.debug,
+ configParams.debug_domains)
server_connection, ui_module = setup_bitbake(configParams, configuration)
# No server connection
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 03/10] cookerdata: Ensure UI options are updated to the server
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
2020-08-24 16:53 ` [PATCH 02/10] cooker/cookerdata/main: Improve loglevel handling Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 04/10] cooker/cookerdata: Ensure UI event log is updated from commandline Richard Purdie
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
There were some options which were not being passed to the server. This
was breaking, particularly in memory resident bitbake mode.
Add the missing options to the correct place to ensure the server is
updated correctly.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/cookerdata.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/bb/cookerdata.py b/lib/bb/cookerdata.py
index f43610e7f8..9eddf7cf6a 100644
--- a/lib/bb/cookerdata.py
+++ b/lib/bb/cookerdata.py
@@ -60,7 +60,9 @@ class ConfigParameters(object):
for o in ["abort", "force", "invalidate_stamp",
"dry_run", "dump_signatures",
"extra_assume_provided", "profile",
- "prefile", "postfile", "server_timeout"]:
+ "prefile", "postfile", "server_timeout",
+ "nosetscene", "setsceneonly", "skipsetscene",
+ "runall", "runonly"]:
options[o] = getattr(self.options, o)
options['build_verbose_shell'] = self.options.verbose
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 04/10] cooker/cookerdata: Ensure UI event log is updated from commandline
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
2020-08-24 16:53 ` [PATCH 02/10] cooker/cookerdata/main: Improve loglevel handling Richard Purdie
2020-08-24 16:53 ` [PATCH 03/10] cookerdata: Ensure UI options are updated to the server Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 05/10] cooker: Defer configuration init to after UI connection Richard Purdie
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Currently the eventlog is not handled correctly for memory resident
bitbake. Fix this by allowing adpations to configuration changes.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/cooker.py | 18 +++++++++++-------
lib/bb/cookerdata.py | 2 +-
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index c34de303fb..3f351cbea6 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -150,6 +150,7 @@ class BBCooker:
def __init__(self, configuration, featureSet=None, idleCallBackRegister=None):
self.recipecaches = None
+ self.eventlog = None
self.skiplist = {}
self.featureset = CookerFeatures()
if featureSet:
@@ -199,13 +200,6 @@ class BBCooker:
bb.debug(1, "BBCooker parsed base configuration %s" % time.time())
sys.stdout.flush()
- # we log all events to a file if so directed
- if self.configuration.writeeventlog:
- # register the log file writer as UI Handler
- writer = EventWriter(self, self.configuration.writeeventlog)
- EventLogWriteHandler = namedtuple('EventLogWriteHandler', ['event'])
- bb.event.register_UIHhandler(EventLogWriteHandler(writer))
-
self.inotify_modified_files = []
def _process_inotify_updates(server, cooker, abort):
@@ -449,6 +443,16 @@ class BBCooker:
if hasattr(self.configuration, o):
setattr(self.configuration, o, options[o])
+ if self.configuration.writeeventlog:
+ if self.eventlog and self.eventlog[0] != self.configuration.writeeventlog:
+ bb.event.unregister_UIHhandler(self.eventlog[1])
+ if not self.eventlog or self.eventlog[0] != self.configuration.writeeventlog:
+ # we log all events to a file if so directed
+ # register the log file writer as UI Handler
+ writer = EventWriter(self, self.configuration.writeeventlog)
+ EventLogWriteHandler = namedtuple('EventLogWriteHandler', ['event'])
+ self.eventlog = (self.configuration.writeeventlog, bb.event.register_UIHhandler(EventLogWriteHandler(writer)))
+
bb.msg.loggerDefaultLogLevel = self.configuration.default_loglevel
bb.msg.loggerDefaultDomains = self.configuration.debug_domains
diff --git a/lib/bb/cookerdata.py b/lib/bb/cookerdata.py
index 9eddf7cf6a..3baa9ade1b 100644
--- a/lib/bb/cookerdata.py
+++ b/lib/bb/cookerdata.py
@@ -62,7 +62,7 @@ class ConfigParameters(object):
"extra_assume_provided", "profile",
"prefile", "postfile", "server_timeout",
"nosetscene", "setsceneonly", "skipsetscene",
- "runall", "runonly"]:
+ "runall", "runonly", "writeeventlog"]:
options[o] = getattr(self.options, o)
options['build_verbose_shell'] = self.options.verbose
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 05/10] cooker: Defer configuration init to after UI connection
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (2 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 04/10] cooker/cookerdata: Ensure UI event log is updated from commandline Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 06/10] server/process: Move the socket code to server process only Richard Purdie
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Currently we end up parsing the base configuration multiple times as
initially, the right settings haven't come from the UI. We can defer
this until later in startup using runCommand as a trigger.
The advantage to doing this is improved startup times and ultimately
we should be able to avoid the double parse of the base configuration.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/command.py | 9 ++++++++-
lib/bb/cooker.py | 17 ++++++++---------
lib/bb/server/process.py | 38 +++++++++++++++++++++-----------------
3 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/lib/bb/command.py b/lib/bb/command.py
index 4d152ff4c0..d4dcc653a0 100644
--- a/lib/bb/command.py
+++ b/lib/bb/command.py
@@ -54,13 +54,20 @@ class Command:
self.cooker = cooker
self.cmds_sync = CommandsSync()
self.cmds_async = CommandsAsync()
- self.remotedatastores = bb.remotedata.RemoteDatastores(cooker)
+ self.remotedatastores = None
# FIXME Add lock for this
self.currentAsyncCommand = None
def runCommand(self, commandline, ro_only = False):
command = commandline.pop(0)
+
+ # Ensure cooker is ready for commands
+ if command != "updateConfig" and command != "setFeatures":
+ self.cooker.init_configdata()
+ if not self.remotedatastores:
+ self.remotedatastores = bb.remotedata.RemoteDatastores(self.cooker)
+
if hasattr(CommandsSync, command):
# Can run synchronous commands straight away
command_method = getattr(self.cmds_sync, command)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 3f351cbea6..3f9cb75434 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -195,11 +195,6 @@ class BBCooker:
self.hashserv = None
self.hashservaddr = None
- self.initConfigurationData()
-
- bb.debug(1, "BBCooker parsed base configuration %s" % time.time())
- sys.stdout.flush()
-
self.inotify_modified_files = []
def _process_inotify_updates(server, cooker, abort):
@@ -233,6 +228,13 @@ class BBCooker:
bb.debug(1, "BBCooker startup complete %s" % time.time())
sys.stdout.flush()
+ def init_configdata(self):
+ if not hasattr(self, "data"):
+ self.initConfigurationData()
+ bb.debug(1, "BBCooker parsed base configuration %s" % time.time())
+ sys.stdout.flush()
+ self.handlePRServ()
+
def process_inotify_updates(self):
for n in [self.confignotifier, self.notifier]:
if n.check_events(timeout=0):
@@ -318,7 +320,7 @@ class BBCooker:
for feature in features:
self.featureset.setFeature(feature)
bb.debug(1, "Features set %s (was %s)" % (original_featureset, list(self.featureset)))
- if (original_featureset != list(self.featureset)) and self.state != state.error:
+ if (original_featureset != list(self.featureset)) and self.state != state.error and hasattr(self, "data"):
self.reset()
def initConfigurationData(self):
@@ -1658,9 +1660,6 @@ class BBCooker:
return pkgs_to_build
def pre_serve(self):
- # We now are in our own process so we can call this here.
- # PRServ exits if its parent process exits
- self.handlePRServ()
return
def post_serve(self):
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index 65e1eab527..b037e0fb6c 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -58,6 +58,7 @@ class ProcessServer():
self.sockname = sockname
self.server_timeout = server_timeout
+ self.timeout = self.server_timeout
self.xmlrpcinterface = xmlrpcinterface
def register_idle_function(self, function, data):
@@ -72,21 +73,6 @@ class ProcessServer():
print("Bitbake XMLRPC server address: %s, server port: %s" % (self.xmlrpc.host, self.xmlrpc.port))
- heartbeat_event = self.cooker.data.getVar('BB_HEARTBEAT_EVENT')
- if heartbeat_event:
- try:
- self.heartbeat_seconds = float(heartbeat_event)
- except:
- bb.warn('Ignoring invalid BB_HEARTBEAT_EVENT=%s, must be a float specifying seconds.' % heartbeat_event)
-
- self.timeout = self.server_timeout or self.cooker.data.getVar('BB_SERVER_TIMEOUT')
- try:
- if self.timeout:
- self.timeout = float(self.timeout)
- except:
- bb.warn('Ignoring invalid BB_SERVER_TIMEOUT=%s, must be a float specifying seconds.' % self.timeout)
-
-
try:
self.bitbake_lock.seek(0)
self.bitbake_lock.truncate()
@@ -129,6 +115,7 @@ class ProcessServer():
fds = [self.sock]
if self.xmlrpc:
fds.append(self.xmlrpc)
+ seendata = False
print("Entering server connection loop")
def disconnect_client(self, fds):
@@ -228,6 +215,22 @@ class ProcessServer():
if self.xmlrpc in ready:
self.xmlrpc.handle_requests()
+ if not seendata and hasattr(self.cooker, "data"):
+ heartbeat_event = self.cooker.data.getVar('BB_HEARTBEAT_EVENT')
+ if heartbeat_event:
+ try:
+ self.heartbeat_seconds = float(heartbeat_event)
+ except:
+ bb.warn('Ignoring invalid BB_HEARTBEAT_EVENT=%s, must be a float specifying seconds.' % heartbeat_event)
+
+ self.timeout = self.server_timeout or self.cooker.data.getVar('BB_SERVER_TIMEOUT')
+ try:
+ if self.timeout:
+ self.timeout = float(self.timeout)
+ except:
+ bb.warn('Ignoring invalid BB_SERVER_TIMEOUT=%s, must be a float specifying seconds.' % self.timeout)
+ seendata = True
+
ready = self.idle_commands(.1, fds)
print("Exiting")
@@ -323,8 +326,9 @@ class ProcessServer():
self.next_heartbeat += self.heartbeat_seconds
if self.next_heartbeat <= now:
self.next_heartbeat = now + self.heartbeat_seconds
- heartbeat = bb.event.HeartbeatEvent(now)
- bb.event.fire(heartbeat, self.cooker.data)
+ if hasattr(self.cooker, "data"):
+ heartbeat = bb.event.HeartbeatEvent(now)
+ bb.event.fire(heartbeat, self.cooker.data)
if nextsleep and now + nextsleep > self.next_heartbeat:
# Shorten timeout so that we we wake up in time for
# the heartbeat.
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 06/10] server/process: Move the socket code to server process only
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (3 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 05/10] cooker: Defer configuration init to after UI connection Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 07/10] main/server/process: Drop configuration object passing Richard Purdie
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
The sock object isn't used client side so we can just created it in
the server process and save passing around the fd/object.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/server/process.py | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index b037e0fb6c..8f5abb32bf 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -402,27 +402,11 @@ class BitBakeServer(object):
self.bitbake_lock = lock
self.readypipe, self.readypipein = os.pipe()
- # Create server control socket
- if os.path.exists(sockname):
- os.unlink(sockname)
-
# Place the log in the builddirectory alongside the lock file
logfile = os.path.join(os.path.dirname(self.bitbake_lock.name), "bitbake-cookerdaemon.log")
- self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- # AF_UNIX has path length issues so chdir here to workaround
- cwd = os.getcwd()
- try:
- os.chdir(os.path.dirname(sockname))
- self.sock.bind(os.path.basename(sockname))
- finally:
- os.chdir(cwd)
- self.sock.listen(1)
-
- os.set_inheritable(self.sock.fileno(), True)
startdatetime = datetime.datetime.now()
bb.daemonize.createDaemon(self._startServer, logfile)
- self.sock.close()
self.bitbake_lock.close()
os.close(self.readypipein)
@@ -478,7 +462,21 @@ class BitBakeServer(object):
sys.stdout.flush()
try:
- server = ProcessServer(self.bitbake_lock, self.sock, self.sockname, self.configuration.server_timeout, self.configuration.xmlrpcinterface)
+ # Create server control socket
+ if os.path.exists(self.sockname):
+ os.unlink(self.sockname)
+
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ # AF_UNIX has path length issues so chdir here to workaround
+ cwd = os.getcwd()
+ try:
+ os.chdir(os.path.dirname(self.sockname))
+ sock.bind(os.path.basename(self.sockname))
+ finally:
+ os.chdir(cwd)
+ sock.listen(1)
+
+ server = ProcessServer(self.bitbake_lock, sock, self.sockname, self.configuration.server_timeout, self.configuration.xmlrpcinterface)
os.close(self.readypipe)
writer = ConnectionWriter(self.readypipein)
try:
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 07/10] main/server/process: Drop configuration object passing
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (4 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 06/10] server/process: Move the socket code to server process only Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 08/10] cooker: Ensure BB_ORIGENV is updated by changes to configuration.env Richard Purdie
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
The first thing the UIs do is update the server config from the UI. We
can just rely upon that and start the server with a standard config,
removing the need to pass the confusing configuration object around
as well as configParams, which contains a similar copy of some of the
data.
This makes memory resident bitbake work the same way as the normal
mode, removing the opportunity for some class of bugs.
The xmlrpcinterface and server_timeout values are passed in at server
startup time now and there no longer a second option in the
configuration which is effective ignored once the server starts.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/cooker.py | 4 ++--
lib/bb/cookerdata.py | 9 ---------
lib/bb/main.py | 10 ++++------
lib/bb/server/process.py | 9 +++++----
lib/bb/tinfoil.py | 8 +-------
5 files changed, 12 insertions(+), 28 deletions(-)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 3f9cb75434..99605e5844 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -148,7 +148,7 @@ class BBCooker:
Manages one bitbake build run
"""
- def __init__(self, configuration, featureSet=None, idleCallBackRegister=None):
+ def __init__(self, featureSet=None, idleCallBackRegister=None):
self.recipecaches = None
self.eventlog = None
self.skiplist = {}
@@ -157,7 +157,7 @@ class BBCooker:
for f in featureSet:
self.featureset.setFeature(f)
- self.configuration = configuration
+ self.configuration = bb.cookerdata.CookerConfiguration()
self.idleCallBackRegister = idleCallBackRegister
diff --git a/lib/bb/cookerdata.py b/lib/bb/cookerdata.py
index 3baa9ade1b..190ff3ab82 100644
--- a/lib/bb/cookerdata.py
+++ b/lib/bb/cookerdata.py
@@ -136,22 +136,13 @@ class CookerConfiguration(object):
self.build_verbose_stdout = False
self.dry_run = False
self.tracking = False
- self.xmlrpcinterface = []
- self.server_timeout = None
self.writeeventlog = False
- self.server_only = False
self.limited_deps = False
self.runall = []
self.runonly = []
self.env = {}
- def setConfigParameters(self, parameters):
- for key in self.__dict__.keys():
- if key in parameters.options.__dict__:
- setattr(self, key, parameters.options.__dict__[key])
- self.env = parameters.environment.copy()
-
def __getstate__(self):
state = {}
for key in self.__dict__.keys():
diff --git a/lib/bb/main.py b/lib/bb/main.py
index e483cce1ae..7990195eac 100755
--- a/lib/bb/main.py
+++ b/lib/bb/main.py
@@ -344,8 +344,6 @@ def bitbake_main(configParams, configuration):
except:
pass
- configuration.setConfigParameters(configParams)
-
if configParams.server_only and configParams.remote_server:
raise BBMainException("FATAL: The '--server-only' option conflicts with %s.\n" %
("the BBSERVER environment variable" if "BBSERVER" in os.environ \
@@ -363,7 +361,7 @@ def bitbake_main(configParams, configuration):
bb.msg.init_msgconfig(configParams.verbose, configParams.debug,
configParams.debug_domains)
- server_connection, ui_module = setup_bitbake(configParams, configuration)
+ server_connection, ui_module = setup_bitbake(configParams)
# No server connection
if server_connection is None:
if configParams.status_only:
@@ -390,7 +388,7 @@ def bitbake_main(configParams, configuration):
return 1
-def setup_bitbake(configParams, configuration, extrafeatures=None):
+def setup_bitbake(configParams, extrafeatures=None):
# Ensure logging messages get sent to the UI as events
handler = bb.event.LogHandler()
if not configParams.status_only:
@@ -431,11 +429,11 @@ def setup_bitbake(configParams, configuration, extrafeatures=None):
logger.info("bitbake server is not running.")
lock.close()
return None, None
- # we start a server with a given configuration
+ # we start a server with a given featureset
logger.info("Starting bitbake server...")
# Clear the event queue since we already displayed messages
bb.event.ui_queue = []
- server = bb.server.process.BitBakeServer(lock, sockname, configuration, featureset)
+ server = bb.server.process.BitBakeServer(lock, sockname, featureset, configParams.server_timeout, configParams.xmlrpcinterface)
else:
logger.info("Reconnecting to bitbake server...")
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index 8f5abb32bf..03cdde04ee 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -394,9 +394,10 @@ class BitBakeServer(object):
start_log_format = '--- Starting bitbake server pid %s at %s ---'
start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
- def __init__(self, lock, sockname, configuration, featureset):
+ def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
- self.configuration = configuration
+ self.server_timeout = server_timeout
+ self.xmlrpcinterface = xmlrpcinterface
self.featureset = featureset
self.sockname = sockname
self.bitbake_lock = lock
@@ -476,11 +477,11 @@ class BitBakeServer(object):
os.chdir(cwd)
sock.listen(1)
- server = ProcessServer(self.bitbake_lock, sock, self.sockname, self.configuration.server_timeout, self.configuration.xmlrpcinterface)
+ server = ProcessServer(self.bitbake_lock, sock, self.sockname, self.server_timeout, self.xmlrpcinterface)
os.close(self.readypipe)
writer = ConnectionWriter(self.readypipein)
try:
- self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset, server.register_idle_function)
+ self.cooker = bb.cooker.BBCooker(self.featureset, server.register_idle_function)
except bb.BBHandledException:
return None
writer.send("r")
diff --git a/lib/bb/tinfoil.py b/lib/bb/tinfoil.py
index dccbe0ebb5..e19d9cff04 100644
--- a/lib/bb/tinfoil.py
+++ b/lib/bb/tinfoil.py
@@ -22,7 +22,6 @@ import bb.taskdata
import bb.utils
import bb.command
import bb.remotedata
-from bb.cookerdata import CookerConfiguration
from bb.main import setup_bitbake, BitBakeConfigParameters
import bb.fetch2
@@ -381,18 +380,13 @@ class Tinfoil:
if not config_params:
config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet)
- cookerconfig = CookerConfiguration()
- cookerconfig.setConfigParameters(config_params)
-
if not config_only:
# Disable local loggers because the UI module is going to set up its own
for handler in self.localhandlers:
self.logger.handlers.remove(handler)
self.localhandlers = []
- self.server_connection, ui_module = setup_bitbake(config_params,
- cookerconfig,
- extrafeatures)
+ self.server_connection, ui_module = setup_bitbake(config_params, extrafeatures)
self.ui_module = ui_module
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 08/10] cooker: Ensure BB_ORIGENV is updated by changes to configuration.env
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (5 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 07/10] main/server/process: Drop configuration object passing Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 09/10] server/process: Log extra threads at exit Richard Purdie
2020-08-24 16:53 ` [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process Richard Purdie
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Changes to configuration.env were not updating BB_ORIGENV, fix this.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/cooker.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 99605e5844..754303813b 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -458,6 +458,12 @@ class BBCooker:
bb.msg.loggerDefaultLogLevel = self.configuration.default_loglevel
bb.msg.loggerDefaultDomains = self.configuration.debug_domains
+ if hasattr(self, "data"):
+ origenv = bb.data.init()
+ for k in environment:
+ origenv.setVar(k, environment[k])
+ self.data.setVar("BB_ORIGENV", origenv)
+
for k in bb.utils.approved_variables():
if k in environment and k not in self.configuration.env:
logger.debug(1, "Updating new environment variable %s to %s" % (k, environment[k]))
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 09/10] server/process: Log extra threads at exit
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (6 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 08/10] cooker: Ensure BB_ORIGENV is updated by changes to configuration.env Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-24 16:53 ` [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process Richard Purdie
8 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Dump info into the logs if there are extra threads left at process exit
time.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/server/process.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index 03cdde04ee..915651084e 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -233,6 +233,9 @@ class ProcessServer():
ready = self.idle_commands(.1, fds)
+ if len(threading.enumerate()) != 1:
+ print("More than one thread left?: " + str(threading.enumerate()))
+
print("Exiting")
# Remove the socket file so we don't get any more connections to avoid races
try:
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
` (7 preceding siblings ...)
2020-08-24 16:53 ` [PATCH 09/10] server/process: Log extra threads at exit Richard Purdie
@ 2020-08-24 16:53 ` Richard Purdie
2020-08-25 16:06 ` [bitbake-devel] " Joshua Watt
8 siblings, 1 reply; 14+ messages in thread
From: Richard Purdie @ 2020-08-24 16:53 UTC (permalink / raw)
To: bitbake-devel
Trying to have a new python process forked off an original doesn't work
out well and ends up having race issues. To avoid this, exec() a new
bitbake server process. This starts with a fresh python interpreter
and resolves various atexit and other multiprocessing issues once
and for all.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
lib/bb/server/process.py | 92 +++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 39 deletions(-)
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index 915651084e..d248570cd2 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -38,7 +38,7 @@ class ProcessServer():
profile_filename = "profile.log"
profile_processed_filename = "profile.log.processed"
- def __init__(self, lock, sock, sockname, server_timeout, xmlrpcinterface):
+ def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
self.command_channel = False
self.command_channel_reply = False
self.quit = False
@@ -54,6 +54,7 @@ class ProcessServer():
self._idlefuns = {}
self.bitbake_lock = lock
+ self.bitbake_lock_name = lockname
self.sock = sock
self.sockname = sockname
@@ -259,7 +260,7 @@ class ProcessServer():
# Finally release the lockfile but warn about other processes holding it open
lock = self.bitbake_lock
- lockfile = lock.name
+ lockfile = self.bitbake_lock_name
lock.close()
lock = None
@@ -393,9 +394,10 @@ class BitBakeProcessServerConnection(object):
self.connection.recv.close()
return
+start_log_format = '--- Starting bitbake server pid %s at %s ---'
+start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
+
class BitBakeServer(object):
- start_log_format = '--- Starting bitbake server pid %s at %s ---'
- start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
@@ -429,7 +431,7 @@ class BitBakeServer(object):
ready.close()
bb.error("Unable to start bitbake server (%s)" % str(r))
if os.path.exists(logfile):
- logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
+ logstart_re = re.compile(start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
started = False
lines = []
lastlines = []
@@ -441,7 +443,7 @@ class BitBakeServer(object):
lastlines.append(line)
res = logstart_re.match(line.rstrip())
if res:
- ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
+ ldatetime = datetime.datetime.strptime(res.group(2), start_log_datetime_format)
if ldatetime >= startdatetime:
started = True
lines.append(line)
@@ -462,42 +464,54 @@ class BitBakeServer(object):
ready.close()
def _startServer(self):
- print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
- sys.stdout.flush()
+ os.close(self.readypipe)
+ os.set_inheritable(self.bitbake_lock.fileno(), True)
+ os.set_inheritable(self.readypipein, True)
+ os.execlp("bitbake-server", "bitbake-server", "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.bitbake_lock.name, self.sockname, str(self.server_timeout), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
- try:
- # Create server control socket
- if os.path.exists(self.sockname):
- os.unlink(self.sockname)
+def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpcinterface):
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- # AF_UNIX has path length issues so chdir here to workaround
- cwd = os.getcwd()
- try:
- os.chdir(os.path.dirname(self.sockname))
- sock.bind(os.path.basename(self.sockname))
- finally:
- os.chdir(cwd)
- sock.listen(1)
-
- server = ProcessServer(self.bitbake_lock, sock, self.sockname, self.server_timeout, self.xmlrpcinterface)
- os.close(self.readypipe)
- writer = ConnectionWriter(self.readypipein)
- try:
- self.cooker = bb.cooker.BBCooker(self.featureset, server.register_idle_function)
- except bb.BBHandledException:
- return None
- writer.send("r")
- writer.close()
- server.cooker = self.cooker
- print("Started bitbake server pid %d" % os.getpid())
- sys.stdout.flush()
-
- server.run()
+ import bb.cookerdata
+ import bb.cooker
+
+ print(start_log_format % (os.getpid(), datetime.datetime.now().strftime(start_log_datetime_format)))
+ sys.stdout.flush()
+
+ try:
+ bitbake_lock = os.fdopen(lockfd, "w")
+
+ # Create server control socket
+ if os.path.exists(sockname):
+ os.unlink(sockname)
+
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ # AF_UNIX has path length issues so chdir here to workaround
+ cwd = os.getcwd()
+ try:
+ os.chdir(os.path.dirname(sockname))
+ sock.bind(os.path.basename(sockname))
finally:
- # Flush any ,essages/errors to the logfile before exit
- sys.stdout.flush()
- sys.stderr.flush()
+ os.chdir(cwd)
+ sock.listen(1)
+
+ server = ProcessServer(bitbake_lock, lockname, sock, sockname, server_timeout, xmlrpcinterface)
+ writer = ConnectionWriter(readypipeinfd)
+ try:
+ featureset = []
+ cooker = bb.cooker.BBCooker(featureset, server.register_idle_function)
+ except bb.BBHandledException:
+ return None
+ writer.send("r")
+ writer.close()
+ server.cooker = cooker
+ print("Started bitbake server pid %d" % os.getpid())
+ sys.stdout.flush()
+
+ server.run()
+ finally:
+ # Flush any ,essages/errors to the logfile before exit
+ sys.stdout.flush()
+ sys.stderr.flush()
def connectProcessServer(sockname, featureset):
# Connect to socket
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [bitbake-devel] [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process
2020-08-24 16:53 ` [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process Richard Purdie
@ 2020-08-25 16:06 ` Joshua Watt
2020-08-25 17:06 ` Richard Purdie
0 siblings, 1 reply; 14+ messages in thread
From: Joshua Watt @ 2020-08-25 16:06 UTC (permalink / raw)
To: Richard Purdie; +Cc: bitbake-devel
On Mon, Aug 24, 2020 at 11:53 AM Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
>
> Trying to have a new python process forked off an original doesn't work
> out well and ends up having race issues. To avoid this, exec() a new
> bitbake server process. This starts with a fresh python interpreter
> and resolves various atexit and other multiprocessing issues once
> and for all.
>
> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
> lib/bb/server/process.py | 92 +++++++++++++++++++++++-----------------
> 1 file changed, 53 insertions(+), 39 deletions(-)
>
> diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
> index 915651084e..d248570cd2 100644
> --- a/lib/bb/server/process.py
> +++ b/lib/bb/server/process.py
> @@ -38,7 +38,7 @@ class ProcessServer():
> profile_filename = "profile.log"
> profile_processed_filename = "profile.log.processed"
>
> - def __init__(self, lock, sock, sockname, server_timeout, xmlrpcinterface):
> + def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
> self.command_channel = False
> self.command_channel_reply = False
> self.quit = False
> @@ -54,6 +54,7 @@ class ProcessServer():
> self._idlefuns = {}
>
> self.bitbake_lock = lock
> + self.bitbake_lock_name = lockname
> self.sock = sock
> self.sockname = sockname
>
> @@ -259,7 +260,7 @@ class ProcessServer():
>
> # Finally release the lockfile but warn about other processes holding it open
> lock = self.bitbake_lock
> - lockfile = lock.name
> + lockfile = self.bitbake_lock_name
> lock.close()
> lock = None
>
> @@ -393,9 +394,10 @@ class BitBakeProcessServerConnection(object):
> self.connection.recv.close()
> return
>
> +start_log_format = '--- Starting bitbake server pid %s at %s ---'
> +start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
> +
> class BitBakeServer(object):
> - start_log_format = '--- Starting bitbake server pid %s at %s ---'
> - start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
>
> def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
>
> @@ -429,7 +431,7 @@ class BitBakeServer(object):
> ready.close()
> bb.error("Unable to start bitbake server (%s)" % str(r))
> if os.path.exists(logfile):
> - logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> + logstart_re = re.compile(start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> started = False
> lines = []
> lastlines = []
> @@ -441,7 +443,7 @@ class BitBakeServer(object):
> lastlines.append(line)
> res = logstart_re.match(line.rstrip())
> if res:
> - ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
> + ldatetime = datetime.datetime.strptime(res.group(2), start_log_datetime_format)
> if ldatetime >= startdatetime:
> started = True
> lines.append(line)
> @@ -462,42 +464,54 @@ class BitBakeServer(object):
> ready.close()
>
> def _startServer(self):
> - print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
> - sys.stdout.flush()
> + os.close(self.readypipe)
> + os.set_inheritable(self.bitbake_lock.fileno(), True)
> + os.set_inheritable(self.readypipein, True)
> + os.execlp("bitbake-server", "bitbake-server", "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.bitbake_lock.name, self.sockname, str(self.server_timeout), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
You may want to do:
os.execl(sys.executable, sys.executable, "bitbake-server", ....)
This ensures that the same python interpreter is used for the server
and UI front end.
>
> - try:
> - # Create server control socket
> - if os.path.exists(self.sockname):
> - os.unlink(self.sockname)
> +def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpcinterface):
>
> - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
> - # AF_UNIX has path length issues so chdir here to workaround
> - cwd = os.getcwd()
> - try:
> - os.chdir(os.path.dirname(self.sockname))
> - sock.bind(os.path.basename(self.sockname))
> - finally:
> - os.chdir(cwd)
> - sock.listen(1)
> -
> - server = ProcessServer(self.bitbake_lock, sock, self.sockname, self.server_timeout, self.xmlrpcinterface)
> - os.close(self.readypipe)
> - writer = ConnectionWriter(self.readypipein)
> - try:
> - self.cooker = bb.cooker.BBCooker(self.featureset, server.register_idle_function)
> - except bb.BBHandledException:
> - return None
> - writer.send("r")
> - writer.close()
> - server.cooker = self.cooker
> - print("Started bitbake server pid %d" % os.getpid())
> - sys.stdout.flush()
> -
> - server.run()
> + import bb.cookerdata
> + import bb.cooker
> +
> + print(start_log_format % (os.getpid(), datetime.datetime.now().strftime(start_log_datetime_format)))
> + sys.stdout.flush()
> +
> + try:
> + bitbake_lock = os.fdopen(lockfd, "w")
> +
> + # Create server control socket
> + if os.path.exists(sockname):
> + os.unlink(sockname)
> +
> + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
> + # AF_UNIX has path length issues so chdir here to workaround
> + cwd = os.getcwd()
> + try:
> + os.chdir(os.path.dirname(sockname))
> + sock.bind(os.path.basename(sockname))
> finally:
> - # Flush any ,essages/errors to the logfile before exit
> - sys.stdout.flush()
> - sys.stderr.flush()
> + os.chdir(cwd)
> + sock.listen(1)
> +
> + server = ProcessServer(bitbake_lock, lockname, sock, sockname, server_timeout, xmlrpcinterface)
> + writer = ConnectionWriter(readypipeinfd)
> + try:
> + featureset = []
> + cooker = bb.cooker.BBCooker(featureset, server.register_idle_function)
> + except bb.BBHandledException:
> + return None
> + writer.send("r")
> + writer.close()
> + server.cooker = cooker
> + print("Started bitbake server pid %d" % os.getpid())
> + sys.stdout.flush()
> +
> + server.run()
> + finally:
> + # Flush any ,essages/errors to the logfile before exit
> + sys.stdout.flush()
> + sys.stderr.flush()
>
> def connectProcessServer(sockname, featureset):
> # Connect to socket
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [bitbake-devel] [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process
2020-08-25 16:06 ` [bitbake-devel] " Joshua Watt
@ 2020-08-25 17:06 ` Richard Purdie
2020-08-25 17:19 ` Joshua Watt
0 siblings, 1 reply; 14+ messages in thread
From: Richard Purdie @ 2020-08-25 17:06 UTC (permalink / raw)
To: Joshua Watt; +Cc: bitbake-devel
On Tue, 2020-08-25 at 11:06 -0500, Joshua Watt wrote:
> On Mon, Aug 24, 2020 at 11:53 AM Richard Purdie
> <richard.purdie@linuxfoundation.org> wrote:
> > Trying to have a new python process forked off an original doesn't work
> > out well and ends up having race issues. To avoid this, exec() a new
> > bitbake server process. This starts with a fresh python interpreter
> > and resolves various atexit and other multiprocessing issues once
> > and for all.
> >
> > Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> > ---
> > lib/bb/server/process.py | 92 +++++++++++++++++++++++-----------------
> > 1 file changed, 53 insertions(+), 39 deletions(-)
> >
> > diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
> > index 915651084e..d248570cd2 100644
> > --- a/lib/bb/server/process.py
> > +++ b/lib/bb/server/process.py
> > @@ -38,7 +38,7 @@ class ProcessServer():
> > profile_filename = "profile.log"
> > profile_processed_filename = "profile.log.processed"
> >
> > - def __init__(self, lock, sock, sockname, server_timeout, xmlrpcinterface):
> > + def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
> > self.command_channel = False
> > self.command_channel_reply = False
> > self.quit = False
> > @@ -54,6 +54,7 @@ class ProcessServer():
> > self._idlefuns = {}
> >
> > self.bitbake_lock = lock
> > + self.bitbake_lock_name = lockname
> > self.sock = sock
> > self.sockname = sockname
> >
> > @@ -259,7 +260,7 @@ class ProcessServer():
> >
> > # Finally release the lockfile but warn about other processes holding it open
> > lock = self.bitbake_lock
> > - lockfile = lock.name
> > + lockfile = self.bitbake_lock_name
> > lock.close()
> > lock = None
> >
> > @@ -393,9 +394,10 @@ class BitBakeProcessServerConnection(object):
> > self.connection.recv.close()
> > return
> >
> > +start_log_format = '--- Starting bitbake server pid %s at %s ---'
> > +start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
> > +
> > class BitBakeServer(object):
> > - start_log_format = '--- Starting bitbake server pid %s at %s ---'
> > - start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
> >
> > def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
> >
> > @@ -429,7 +431,7 @@ class BitBakeServer(object):
> > ready.close()
> > bb.error("Unable to start bitbake server (%s)" % str(r))
> > if os.path.exists(logfile):
> > - logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> > + logstart_re = re.compile(start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> > started = False
> > lines = []
> > lastlines = []
> > @@ -441,7 +443,7 @@ class BitBakeServer(object):
> > lastlines.append(line)
> > res = logstart_re.match(line.rstrip())
> > if res:
> > - ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
> > + ldatetime = datetime.datetime.strptime(res.group(2), start_log_datetime_format)
> > if ldatetime >= startdatetime:
> > started = True
> > lines.append(line)
> > @@ -462,42 +464,54 @@ class BitBakeServer(object):
> > ready.close()
> >
> > def _startServer(self):
> > - print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
> > - sys.stdout.flush()
> > + os.close(self.readypipe)
> > + os.set_inheritable(self.bitbake_lock.fileno(), True)
> > + os.set_inheritable(self.readypipein, True)
> > + os.execlp("bitbake-server", "bitbake-server", "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.bitbake_lock.name, self.sockname, str(self.server_timeout), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
>
> You may want to do:
>
> os.execl(sys.executable, sys.executable, "bitbake-server", ....)
>
> This ensures that the same python interpreter is used for the server
> and UI front end.
Yes, good point, although leaving arg0 as bitbake-server is probably
helpful for debugging so you can see the server process in a process
listing?
I had to change the code slightly in master-next to use execl() with
"../../../bitbake-server" based upon __file__ as it would break in
cases where we've messed around with PATH.
Cheers,
Richard
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [bitbake-devel] [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process
2020-08-25 17:06 ` Richard Purdie
@ 2020-08-25 17:19 ` Joshua Watt
2020-08-25 17:23 ` Richard Purdie
0 siblings, 1 reply; 14+ messages in thread
From: Joshua Watt @ 2020-08-25 17:19 UTC (permalink / raw)
To: Richard Purdie; +Cc: bitbake-devel
On 8/25/20 12:06 PM, Richard Purdie wrote:
> On Tue, 2020-08-25 at 11:06 -0500, Joshua Watt wrote:
>> On Mon, Aug 24, 2020 at 11:53 AM Richard Purdie
>> <richard.purdie@linuxfoundation.org> wrote:
>>> Trying to have a new python process forked off an original doesn't work
>>> out well and ends up having race issues. To avoid this, exec() a new
>>> bitbake server process. This starts with a fresh python interpreter
>>> and resolves various atexit and other multiprocessing issues once
>>> and for all.
>>>
>>> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
>>> ---
>>> lib/bb/server/process.py | 92 +++++++++++++++++++++++-----------------
>>> 1 file changed, 53 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
>>> index 915651084e..d248570cd2 100644
>>> --- a/lib/bb/server/process.py
>>> +++ b/lib/bb/server/process.py
>>> @@ -38,7 +38,7 @@ class ProcessServer():
>>> profile_filename = "profile.log"
>>> profile_processed_filename = "profile.log.processed"
>>>
>>> - def __init__(self, lock, sock, sockname, server_timeout, xmlrpcinterface):
>>> + def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
>>> self.command_channel = False
>>> self.command_channel_reply = False
>>> self.quit = False
>>> @@ -54,6 +54,7 @@ class ProcessServer():
>>> self._idlefuns = {}
>>>
>>> self.bitbake_lock = lock
>>> + self.bitbake_lock_name = lockname
>>> self.sock = sock
>>> self.sockname = sockname
>>>
>>> @@ -259,7 +260,7 @@ class ProcessServer():
>>>
>>> # Finally release the lockfile but warn about other processes holding it open
>>> lock = self.bitbake_lock
>>> - lockfile = lock.name
>>> + lockfile = self.bitbake_lock_name
>>> lock.close()
>>> lock = None
>>>
>>> @@ -393,9 +394,10 @@ class BitBakeProcessServerConnection(object):
>>> self.connection.recv.close()
>>> return
>>>
>>> +start_log_format = '--- Starting bitbake server pid %s at %s ---'
>>> +start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
>>> +
>>> class BitBakeServer(object):
>>> - start_log_format = '--- Starting bitbake server pid %s at %s ---'
>>> - start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
>>>
>>> def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
>>>
>>> @@ -429,7 +431,7 @@ class BitBakeServer(object):
>>> ready.close()
>>> bb.error("Unable to start bitbake server (%s)" % str(r))
>>> if os.path.exists(logfile):
>>> - logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
>>> + logstart_re = re.compile(start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
>>> started = False
>>> lines = []
>>> lastlines = []
>>> @@ -441,7 +443,7 @@ class BitBakeServer(object):
>>> lastlines.append(line)
>>> res = logstart_re.match(line.rstrip())
>>> if res:
>>> - ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
>>> + ldatetime = datetime.datetime.strptime(res.group(2), start_log_datetime_format)
>>> if ldatetime >= startdatetime:
>>> started = True
>>> lines.append(line)
>>> @@ -462,42 +464,54 @@ class BitBakeServer(object):
>>> ready.close()
>>>
>>> def _startServer(self):
>>> - print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
>>> - sys.stdout.flush()
>>> + os.close(self.readypipe)
>>> + os.set_inheritable(self.bitbake_lock.fileno(), True)
>>> + os.set_inheritable(self.readypipein, True)
>>> + os.execlp("bitbake-server", "bitbake-server", "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.bitbake_lock.name, self.sockname, str(self.server_timeout), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
>> You may want to do:
>>
>> os.execl(sys.executable, sys.executable, "bitbake-server", ....)
>>
>> This ensures that the same python interpreter is used for the server
>> and UI front end.
> Yes, good point, although leaving arg0 as bitbake-server is probably
> helpful for debugging so you can see the server process in a process
> listing?
Ya, that's seems fine:
os.execl(sys.executable, "bitbake-server", bitbake_server_path, ....)
looks like it would work
>
> I had to change the code slightly in master-next to use execl() with
> "../../../bitbake-server" based upon __file__ as it would break in
> cases where we've messed around with PATH.
>
> Cheers,
>
> Richard
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [bitbake-devel] [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process
2020-08-25 17:19 ` Joshua Watt
@ 2020-08-25 17:23 ` Richard Purdie
0 siblings, 0 replies; 14+ messages in thread
From: Richard Purdie @ 2020-08-25 17:23 UTC (permalink / raw)
To: Joshua Watt; +Cc: bitbake-devel
On Tue, 2020-08-25 at 12:19 -0500, Joshua Watt wrote:
> On 8/25/20 12:06 PM, Richard Purdie wrote:
> > On Tue, 2020-08-25 at 11:06 -0500, Joshua Watt wrote:
> > > On Mon, Aug 24, 2020 at 11:53 AM Richard Purdie
> > > <richard.purdie@linuxfoundation.org> wrote:
> > > > Trying to have a new python process forked off an original doesn't work
> > > > out well and ends up having race issues. To avoid this, exec() a new
> > > > bitbake server process. This starts with a fresh python interpreter
> > > > and resolves various atexit and other multiprocessing issues once
> > > > and for all.
> > > >
> > > > Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> > > > ---
> > > > lib/bb/server/process.py | 92 +++++++++++++++++++++++-----------------
> > > > 1 file changed, 53 insertions(+), 39 deletions(-)
> > > >
> > > > diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
> > > > index 915651084e..d248570cd2 100644
> > > > --- a/lib/bb/server/process.py
> > > > +++ b/lib/bb/server/process.py
> > > > @@ -38,7 +38,7 @@ class ProcessServer():
> > > > profile_filename = "profile.log"
> > > > profile_processed_filename = "profile.log.processed"
> > > >
> > > > - def __init__(self, lock, sock, sockname, server_timeout, xmlrpcinterface):
> > > > + def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
> > > > self.command_channel = False
> > > > self.command_channel_reply = False
> > > > self.quit = False
> > > > @@ -54,6 +54,7 @@ class ProcessServer():
> > > > self._idlefuns = {}
> > > >
> > > > self.bitbake_lock = lock
> > > > + self.bitbake_lock_name = lockname
> > > > self.sock = sock
> > > > self.sockname = sockname
> > > >
> > > > @@ -259,7 +260,7 @@ class ProcessServer():
> > > >
> > > > # Finally release the lockfile but warn about other processes holding it open
> > > > lock = self.bitbake_lock
> > > > - lockfile = lock.name
> > > > + lockfile = self.bitbake_lock_name
> > > > lock.close()
> > > > lock = None
> > > >
> > > > @@ -393,9 +394,10 @@ class BitBakeProcessServerConnection(object):
> > > > self.connection.recv.close()
> > > > return
> > > >
> > > > +start_log_format = '--- Starting bitbake server pid %s at %s ---'
> > > > +start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
> > > > +
> > > > class BitBakeServer(object):
> > > > - start_log_format = '--- Starting bitbake server pid %s at %s ---'
> > > > - start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
> > > >
> > > > def __init__(self, lock, sockname, featureset, server_timeout, xmlrpcinterface):
> > > >
> > > > @@ -429,7 +431,7 @@ class BitBakeServer(object):
> > > > ready.close()
> > > > bb.error("Unable to start bitbake server (%s)" % str(r))
> > > > if os.path.exists(logfile):
> > > > - logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> > > > + logstart_re = re.compile(start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
> > > > started = False
> > > > lines = []
> > > > lastlines = []
> > > > @@ -441,7 +443,7 @@ class BitBakeServer(object):
> > > > lastlines.append(line)
> > > > res = logstart_re.match(line.rstrip())
> > > > if res:
> > > > - ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
> > > > + ldatetime = datetime.datetime.strptime(res.group(2), start_log_datetime_format)
> > > > if ldatetime >= startdatetime:
> > > > started = True
> > > > lines.append(line)
> > > > @@ -462,42 +464,54 @@ class BitBakeServer(object):
> > > > ready.close()
> > > >
> > > > def _startServer(self):
> > > > - print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
> > > > - sys.stdout.flush()
> > > > + os.close(self.readypipe)
> > > > + os.set_inheritable(self.bitbake_lock.fileno(), True)
> > > > + os.set_inheritable(self.readypipein, True)
> > > > + os.execlp("bitbake-server", "bitbake-server", "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.bitbake_lock.name, self.sockname, str(self.server_timeout), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
> > > You may want to do:
> > >
> > > os.execl(sys.executable, sys.executable, "bitbake-server", ....)
> > >
> > > This ensures that the same python interpreter is used for the server
> > > and UI front end.
> > Yes, good point, although leaving arg0 as bitbake-server is probably
> > helpful for debugging so you can see the server process in a process
> > listing?
>
> Ya, that's seems fine:
>
> os.execl(sys.executable, "bitbake-server", bitbake_server_path, ....)
>
> looks like it would work
It does. I'm handling this as a followup patch since the original set
was tested and ready to merge (now merged).
This one will test and then merge if all the corner cases work out ok.
Cheers,
Richard
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-08-25 17:23 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-24 16:53 [PATCH 01/10] build/msg: Cleanup verbose option handling Richard Purdie
2020-08-24 16:53 ` [PATCH 02/10] cooker/cookerdata/main: Improve loglevel handling Richard Purdie
2020-08-24 16:53 ` [PATCH 03/10] cookerdata: Ensure UI options are updated to the server Richard Purdie
2020-08-24 16:53 ` [PATCH 04/10] cooker/cookerdata: Ensure UI event log is updated from commandline Richard Purdie
2020-08-24 16:53 ` [PATCH 05/10] cooker: Defer configuration init to after UI connection Richard Purdie
2020-08-24 16:53 ` [PATCH 06/10] server/process: Move the socket code to server process only Richard Purdie
2020-08-24 16:53 ` [PATCH 07/10] main/server/process: Drop configuration object passing Richard Purdie
2020-08-24 16:53 ` [PATCH 08/10] cooker: Ensure BB_ORIGENV is updated by changes to configuration.env Richard Purdie
2020-08-24 16:53 ` [PATCH 09/10] server/process: Log extra threads at exit Richard Purdie
2020-08-24 16:53 ` [PATCH 10/10] server/process: Add bitbake-server and exec() a new server process Richard Purdie
2020-08-25 16:06 ` [bitbake-devel] " Joshua Watt
2020-08-25 17:06 ` Richard Purdie
2020-08-25 17:19 ` Joshua Watt
2020-08-25 17:23 ` Richard Purdie
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.