[Merge] lp:~upstart-devel/upstart/stateful-reexec into lp:upstart
Steve Langasek
steve.langasek at canonical.com
Tue Nov 13 13:04:22 UTC 2012
Review: Approve
Hi James,
Reviewing just the parts of the diff that are new since the last time I looked at the branch.
This part of init/session.c looks strange:
+ if (getenv ("UPSTART_TESTS"))
+ return;
+
if (conf_source_reload (source) < 0) {
NihError *err;
The commit message only says:
- session_create_conf_source(): Don't reload conf sources when in
testing mode.
without explaining why.
In init/tests/test_util.c:
+ * Returns 0 if strings are identical or both NULL, else 1.
+ **/
+int
+string_check (const char *a, const char *b)
+{
+ if ((a == b) && !a)
+ return 0;
+
This '&& !a' seems unnecessary - surely if a == b and are /not/ null, there's no need to call strcmp to confirm that the strings are equal.
=== modified file 'init/blocked.c'
--- init/blocked.c 2012-07-30 14:07:37 +0000
+++ init/blocked.c 2012-11-13 06:01:51 +0000
@@ -131,6 +131,9 @@ blocked_type_enum_to_str (BlockedType ty
BlockedType
blocked_type_str_to_enum (const char *type)
{
+ if (! type)
+ goto error;
+
state_str_to_enum (BLOCKED_JOB, type);
state_str_to_enum (BLOCKED_EVENT, type);
state_str_to_enum (BLOCKED_EMIT_METHOD, type);
@@ -141,5 +144,6 @@ blocked_type_str_to_enum (const char *ty
state_str_to_enum (BLOCKED_INSTANCE_STOP_METHOD, type);
state_str_to_enum (BLOCKED_INSTANCE_RESTART_METHOD, type);
+error:
return -1;
}
The above is documented as "Made resilient to error conditions". But this doesn't appear to be a real-world error condition at all; the only place in the code that blocked_type_str_to_enum() is called is in state.c:
if (! state_get_json_string_var_strict (json, "type", NULL, blocked_type_str))
goto error;
blocked_type = blocked_type_str_to_enum (blocked_type_str);
This means there's no possibility of the function ever being called with a null argument (and likewise for the other str_to_enum functions), so this must be here just for the test suite. I don't think it's a good idea to complicate either the code or the test suite by handling errors that the code is written to never allow! I've pushed a branch to address this at
lp:~vorlon/upstart/stateful-reexec-dont-shape-code-to-impossible-tests and raised an MP for your consideration.
=== modified file 'init/job_process.c'
--- init/job_process.c 2012-08-25 08:53:37 +0000
+++ init/job_process.c 2012-11-13 10:47:50 +0000
@@ -211,7 +211,7 @@ job_process_run (Job *job,
while (p && (*p == '\n'))
p++;
- if ((! nl) || (! *p)) {
+ if ((! nl) || (p && ! *p)) {
/* Strip off the newline(s) */
if (nl)
*nl = '\0';
This change is documented as "Stop potential NULL-pointer dereference". But here's the full context:
p = nl = strchr (script, '\n');
while (p && (*p == '\n'))
p++;
if ((! nl) || (p && ! *p)) {
/* Strip off the newline(s) */
if (nl)
*nl = '\0';
So the only way p can be NULL is if 'script' contains no newlines. In that case, nl is also null, and the first part of the if will short-circuit without ever trying to dereference p. Why did you consider this a potential NULL dereference? Did this come from a compiler warning?
init/log.c, log_deserialise():
- /* Stop fd leaking to children */
- if (log->fd != -1) {
- if (state_toggle_cloexec (log->fd, TRUE) < 0)
- goto error;
- }
+ /* re-apply CLOEXEC flag to stop log file fd being leaked to children */
+ if (log->fd != -1 && state_toggle_cloexec (log->fd, TRUE) < 0)
+ return NULL;
Neither of these is quite right. By this point, we've already successfully deserialized the log object. Returning NULL if we fail to set CLOEXEC doesn't help us - in fact, it means upstart will lose all track of the fd and will *never* close it, even when the associated job stops. So we should just ignore failures to set CLOEXEC on deserialization, so that we at least have a chance to clean up the fd later. Fix for this pushed to the branch.
--- init/session.c 2012-09-24 14:43:33 +0000
+++ init/session.c 2012-10-10 13:24:51 +0000
@@ -467,9 +467,9 @@
static Session *
session_deserialise (json_object *json)
{
- Session *session;
+ Session *session = NULL;
nih_local const char *chroot = NULL;
- uid_t user;
+ uid_t user = (uid_t)-1;
nih_assert (json);
This is a misleading initialization. -1 is a perfectly valid value for a uid_t; it MUST NOT be used as an error sentinel. Fortunately nothing in the code below uses it this way, but it would be better to avoid such confusion.
+ * _state_get_json_str_array_generic:
+ *
+ * @parent: parent object for new array (may be NULL),
+ * @json: json_object pointer,
+ * @array: array to hold output,
+ * @len: length of @array,
+ * @env: TRUE if @json represents an array of environment variables,
+ * else FALSE,
The 'env' parameter to this macro is completely unused. Not sure what the difference is meant to be between an env array and a regular string array?
Otherwise this looks good to me. I think it's ready to land, with or without <lp:~vorlon/upstart/stateful-reexec-dont-shape-code-to-impossible-tests>.
--
https://code.launchpad.net/~upstart-devel/upstart/stateful-reexec/+merge/133275
Your team Upstart Reviewers is subscribed to branch lp:upstart.
More information about the upstart-devel
mailing list