Merge authors:
  James Hunt (jamesodhunt)
------------------------------------------------------------
revno: 1665 [merge]
committer: Steve Langasek <steve.langa...@canonical.com>
branch nick: upstream
timestamp: Sat 2015-04-25 14:01:27 -0400
message:
  Merge lp:~jamesodhunt/upstart/bug-1447756
modified:
  ChangeLog
  init/log.c
  init/tests/test_log.c


--
lp:upstart
https://code.launchpad.net/~upstart-devel/upstart/trunk

Your team Upstart Reviewers is subscribed to branch lp:upstart.
To unsubscribe from this branch go to 
https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'ChangeLog'
--- ChangeLog	2014-09-08 15:18:43 +0000
+++ ChangeLog	2015-04-24 12:57:48 +0000
@@ -1,3 +1,18 @@
+2015-04-24  James Hunt  <james.h...@ubuntu.com>
+
+	* init/log.c:
+	  - Make log_flushed public to allow tests to test
+	    log_handle_unflushed() properly.
+	  - log_handle_unflushed():
+	    - Make log a child of the list entry and the latter a child of the
+	      unflushed list.
+	  - log_clear_unflushed():
+	    - Ensure the list entry is freed along with the log to avoid an
+	      invalid entry remaining in the list (LP: #1447756).
+	* init/tests/test_log.c:
+	  - test_log_destroy(): Added new test:
+	    - "ensure unflushed data moved to unflushed list with uid 0"
+
 2014-09-08  James Hunt  <james.h...@ubuntu.com>
 
 	* util/telinit.c: Remove UPSTART_TELINIT_U_NO_WAIT check as it

=== modified file 'init/log.c'
--- init/log.c	2014-07-07 16:39:49 +0000
+++ init/log.c	2015-04-24 12:57:48 +0000
@@ -42,7 +42,7 @@
  *
  * TRUE if log_clear_unflushed() has been called successfully.
  **/
-static int log_flushed = 0;
+int log_flushed = 0;
 
 /**
  * log_unflushed_files:
@@ -758,23 +758,23 @@
 
 	log_unflushed_init ();
 
-	/* re-parent */
-	nih_ref (log, log_unflushed_files);
-	nih_unref (log, parent);
-
-	elem = nih_list_entry_new (log);
+	elem = nih_list_entry_new (log_unflushed_files);
 	if (! elem) {
 		/* If memory is low, we discard the unflushed
 		 * data buffer too.
 		 */
-		nih_unref (log, log_unflushed_files);
+		nih_unref (log, parent);
 		return -1;
 	}
 
+	/* re-parent */
+	nih_ref (log, elem);
+	nih_unref (log, parent);
+
 	/* Indicate separation from parent */
 	log->detached = 1;
 
-	elem->data = log;    
+	elem->data = log;
 	nih_list_add_after (log_unflushed_files, &elem->entry);
 
 	return 0;
@@ -800,6 +800,8 @@
 		elem = (NihListEntry *)iter;
 		log = elem->data;
 
+		nih_assert (log);
+
 		/* To be added to this list, log should have been
 		 * detached from its parent job.
 		 */
@@ -833,7 +835,7 @@
 			return -1;
 
 		/* This will handle any remaining unflushed log data */
-		nih_free (log);
+		nih_free (elem);
 	}
 
 	log_flushed = 1;

=== modified file 'init/tests/test_log.c'
--- init/tests/test_log.c	2013-11-23 22:18:28 +0000
+++ init/tests/test_log.c	2015-04-24 12:57:48 +0000
@@ -34,6 +34,8 @@
 #include "job.h"
 #include "test_util_common.h"
 
+extern int log_flushed;
+
 /*
  * To help with understanding the TEST_ALLOC_FAIL peculiarities
  * below...
@@ -1130,6 +1132,7 @@
 test_log_destroy (void)
 {
 	Log  *log;
+	Log  *tmp_log;
 	int   ret;
 	int   flags;
 	char  str[] = "hello, world!";
@@ -1138,6 +1141,8 @@
 	int   found_fd;
 	char  filename[1024];
 	int   fd;
+	NihListEntry *entry;
+	struct stat  statbuf;
 
 	TEST_FUNCTION ("log_destroy");
 
@@ -1207,8 +1212,88 @@
 	TEST_FREE (log->unflushed);
 
 	/************************************************************/
+	TEST_FEATURE ("ensure unflushed data moved to unflushed list with uid 0");
+
+	TEST_TRUE (NIH_LIST_EMPTY (log_unflushed_files));
+
+	TEST_EQ (openpty (&pty_master, &pty_slave, NULL, NULL, NULL), 0);
+
+	TEST_FILENAME (filename);
+
+	/* Make file inaccessible to ensure data cannot be written
+	 * and will thus be added to the unflushed buffer.
+	 */
+	fd = open (filename, O_CREAT | O_EXCL, 0);
+	TEST_NE (fd, -1);
+	close (fd);
+
+	log = log_new (NULL, filename, pty_master, 0);
+	TEST_NE_P (log, NULL);
+
+	ret = write (pty_slave, str, strlen (str));
+	TEST_GT (ret, 0);
+
+	TEST_WATCH_UPDATE ();
+	close (pty_slave);
+	TEST_NE_P (log->unflushed, NULL);
+	TEST_EQ (log->unflushed->len, strlen(str));
+	TEST_EQ_STR (log->unflushed->buf, str);
+	TEST_FREE_TAG (log);
+
+	/* reset */
+	log_flushed = 0;
+
+	TEST_TRUE (NIH_LIST_EMPTY (log_unflushed_files));
+	ret = log_handle_unflushed (NULL, log);
+
+	TEST_EQ (ret, 0);
+	TEST_FALSE (NIH_LIST_EMPTY (log_unflushed_files));
+
+	entry = (NihListEntry *)log_unflushed_files->next;
+	TEST_NE_P (entry, NULL);
+	TEST_FREE_TAG (entry);
+	TEST_ALLOC_PARENT (entry, log_unflushed_files);
+
+	tmp_log = entry->data;
+	TEST_EQ_P (tmp_log, log);
+	TEST_ALLOC_PARENT (log, entry);
+
+	/* make file accessible again */
+	assert0 (chmod (filename, 0755));
+
+	ret = log_clear_unflushed ();
+	assert0 (ret);
+
+	TEST_FREE (entry);
+	TEST_FREE (log);
+
+	assert0 (stat (filename, &statbuf));
+	TEST_EQ (statbuf.st_size, strlen (str));
+
+	TEST_TRUE (NIH_LIST_EMPTY (log_unflushed_files));
+
+	/* full reset */
+	log_flushed = 0;
+	nih_free (log_unflushed_files);
+	log_unflushed_files = NULL;
+	log_unflushed_init ();
+
+	nih_free (nih_io_watches);
+	nih_io_watches = NULL;
+	nih_io_init ();
+
+	assert0 (unlink (filename));
+
+	/************************************************************/
 	TEST_FEATURE ("ensure watch freed when log destroyed");
 
+	/* Make file inaccessible to ensure data cannot be written
+	 * and will thus be added to the unflushed buffer.
+	 */
+	fd = open (filename, O_CREAT | O_EXCL, 0);
+	TEST_NE (fd, -1);
+	close (fd);
+
 	TEST_EQ (openpty (&pty_master, &pty_slave, NULL, NULL, NULL), 0);
 
 	log = log_new (NULL, filename, pty_master, 0);

-- 
upstart-devel mailing list
upstart-devel@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/upstart-devel

Reply via email to