diff --git a/tests/alias.c b/tests/alias.c
index a1415c6..4ac6425 100644
--- a/tests/alias.c
+++ b/tests/alias.c
@@ -3,10 +3,12 @@
 #include <setjmp.h>
 #include <stdio.h>
 #include <cmocka.h>
+#include "strbuf.h"
 #include "util.h"
 #include "alias.h"
 #include "test-log.h"
 #include <errno.h>
+#include <string.h>
 
 #include "globals.c"
 #include "../libmultipath/alias.c"
@@ -20,18 +22,6 @@
 #define MPATH_ID_INT_MAX_p1 "fxshrxx"
 #endif
 
-void __wrap_rewind(FILE *stream)
-{}
-
-char *__wrap_fgets(char *buf, int n, FILE *stream)
-{
-	char *val = mock_ptr_type(char *);
-	if (!val)
-		return NULL;
-	strlcpy(buf, val, n);
-	return buf;
-}
-
 static int __set_errno(int err)
 {
 	if (err >= 0) {
@@ -43,25 +33,46 @@ static int __set_errno(int err)
 	}
 }
 
-off_t __wrap_lseek(int fd, off_t offset, int whence)
-{
-	return __set_errno(mock_type(int));
-
-}
-
+/*
+ * allocate_binding -> write_bindings_file() writes the entire file, i.e. the
+ * header, any pre-existing bindings, and the new binding. The complete content
+ * depends on history and is different to predict here. Therefore we check only
+ * the newly added binding. Because add_binding() sorts entries, this new
+ * binding isn't necessarily the last one; receive it from will_return() and
+ * search for it with strstr().
+ * If the string to be written doesn't start with the bindings file
+ * header, it's a test of a partial write.
+ */
 ssize_t __wrap_write(int fd, const void *buf, size_t count)
 {
+	const char *binding, *start;
+
+#if DEBUG_WRITE
+	fprintf(stderr, "%s: %zx exp %zx\n===\n%s\n===\n", __func__, strlen(buf),
+		count, (const char *)buf);
+#endif
+	if (!strncmp((const char *)buf, BINDINGS_FILE_HEADER,
+		     sizeof(BINDINGS_FILE_HEADER) - 1))
+		start = (const char *)buf + sizeof(BINDINGS_FILE_HEADER) - 1;
+	else
+		start = buf;
+	binding = mock_ptr_type(char *);
+	start = strstr(start, binding);
 	check_expected(count);
-	check_expected(buf);
+	assert_ptr_not_equal(start, NULL);
 	return __set_errno(mock_type(int));
 }
 
-int __wrap_ftruncate(int fd, off_t length)
+int __wrap_rename(const char *old, const char *new)
 {
-	check_expected(length);
 	return __set_errno(mock_type(int));
 }
 
+int __wrap_mkstemp(char *template)
+{
+	return 10;
+}
+
 int __wrap_dm_map_present(const char * str)
 {
 	check_expected(str);
@@ -84,32 +95,6 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len)
 #define TEST_FDNO 1234
 #define TEST_FPTR ((FILE *) 0xaffe)
 
-int __wrap_open_file(const char *file, int *can_write, const char *header)
-{
-	int cw = mock_type(int);
-
-        *can_write = cw;
-	return TEST_FDNO;
-}
-
-FILE *__wrap_fdopen(int fd, const char *mode)
-{
-	assert_int_equal(fd, TEST_FDNO);
-	return TEST_FPTR;
-}
-
-int __wrap_fflush(FILE *f)
-{
-	assert_ptr_equal(f, TEST_FPTR);
-	return 0;
-}
-
-int __wrap_fclose(FILE *f)
-{
-	assert_ptr_equal(f, TEST_FPTR);
-	return 0;
-}
-
 /* strbuf wrapper for the old format_devname() */
 static int __format_devname(char *name, int id, size_t len, const char *prefix)
 {
@@ -466,22 +451,85 @@ static void mock_self_alias(const char *alias, const char *wwid)
 		expect_condlog(3, USED_STR(alias, wwid));		\
 	} while(0)
 
-static void mock_bindings_file(const char *content, int match_line)
+static int add_binding_unsorted(Bindings *bindings,
+				const char *alias, const char *wwid)
 {
-	static char cnt[1024];
-	char *token;
+	struct binding *bdg = calloc(1, sizeof(*bdg));
+
+	if (!bdg)
+		return -1;
+	bdg->wwid = strdup(wwid);
+	bdg->alias = strdup(alias);
+	if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) {
+		free(bdg->alias);
+		free(bdg->wwid);
+		free(bdg);
+		return BINDING_ERROR;
+	}
+	vector_set_slot(bindings, bdg);
+	return BINDING_ADDED;
+}
+
+static void __mock_bindings_file(const char *content,
+				 int (*add)(Bindings *, const char *, const char *))
+{
+	char *cnt __attribute__((cleanup(cleanup_charp))) = NULL;
+	char *token, *savep = NULL;
 	int i;
 
-	assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1);
+	cnt = strdup(content);
+	assert_ptr_not_equal(cnt, NULL);
 
-	for (token = strtok(cnt, "\n"), i = 0;
+	for (token = strtok_r(cnt, "\n", &savep), i = 0;
 	     token && *token;
-	     token = strtok(NULL, "\n"), i++) {
-		will_return(__wrap_fgets, token);
-		if (match_line == i)
-			return;
+	     token = strtok_r(NULL, "\n", &savep), i++) {
+		char *alias, *wwid;
+		int rc;
+
+		if (read_binding(token, i + 1, &alias, &wwid)
+		    == READ_BINDING_SKIP)
+			continue;
+
+		rc = add(&global_bindings, alias, wwid);
+		assert_int_equal(rc, BINDING_ADDED);
 	}
-	will_return(__wrap_fgets, NULL);
+}
+
+static void mock_bindings_file(const char *content) {
+	return __mock_bindings_file(content, add_binding);
+}
+
+static void mock_bindings_file_unsorted(const char *content) {
+	return __mock_bindings_file(content, add_binding_unsorted);
+}
+
+static int teardown_bindings(void **state)
+{
+	cleanup_bindings();
+	return 0;
+}
+
+static int lookup_binding(FILE *dummy, const char *wwid, char **alias,
+			  const char *prefix, int check_if_taken)
+{
+	const struct binding *bdg;
+	int id;
+
+	/*
+	 * get_free_id() always checks if aliases are taken.
+	 * Therefore if prefix is non-null, check_if_taken must be true.
+	 */
+	assert_true(!prefix || check_if_taken);
+	*alias = NULL;
+	bdg = get_binding_for_wwid(&global_bindings, wwid);
+	if (bdg) {
+		*alias = strdup(bdg->alias);
+		return 0;
+	} else if (!prefix && check_if_taken)
+		return -1;
+
+	id = get_free_id(&global_bindings, prefix, wwid);
+	return id;
 }
 
 static void lb_empty(void **state)
@@ -489,7 +537,7 @@ static void lb_empty(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0);
 	assert_int_equal(rc, 1);
@@ -501,7 +549,7 @@ static void lb_empty_unused(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	mock_unused_alias("MPATHa");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
@@ -515,10 +563,10 @@ static void lb_empty_failed(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	mock_failed_alias("MPATHa", "WWID0");
 	mock_unused_alias("MPATHb");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
@@ -530,10 +578,10 @@ static void lb_empty_1_used(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	mock_used_alias("MPATHa", "WWID0");
 	mock_unused_alias("MPATHb");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
@@ -545,10 +593,10 @@ static void lb_empty_1_used_self(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	mock_used_alias("MPATHa", "WWID0");
 	mock_self_alias("MPATHb", "WWID0");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
@@ -560,9 +608,9 @@ static void lb_match_a(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("MPATHa WWID0\n", 0);
+	mock_bindings_file("MPATHa WWID0\n");
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
-	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0);
+	rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1);
 	assert_int_equal(rc, 0);
 	assert_ptr_not_equal(alias, NULL);
 	assert_string_equal(alias, "MPATHa");
@@ -574,9 +622,10 @@ static void lb_nomatch_a(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("MPATHa WWID0\n", -1);
+	mock_bindings_file("MPATHa WWID0\n");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
-	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0);
+	mock_unused_alias("MPATHb");
+	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
 }
@@ -586,8 +635,8 @@ static void lb_nomatch_a_bad_check(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("MPATHa WWID0\n", -1);
-	expect_condlog(0, NOMORE_STR);
+	mock_bindings_file("MPATHa WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 	rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1);
 	assert_int_equal(rc, -1);
 	assert_ptr_equal(alias, NULL);
@@ -598,7 +647,7 @@ static void lb_nomatch_a_unused(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("MPATHa WWID0\n", -1);
+	mock_bindings_file("MPATHa WWID0\n");
 	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
@@ -611,27 +660,27 @@ static void lb_nomatch_a_3_used_failed_self(void **state)
 	int rc;
 	char *alias;
 
-	mock_bindings_file("MPATHa WWID0\n", -1);
+	mock_bindings_file("MPATHa WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 	mock_used_alias("MPATHb", "WWID1");
 	mock_used_alias("MPATHc", "WWID1");
 	mock_used_alias("MPATHd", "WWID1");
 	mock_failed_alias("MPATHe", "WWID1");
 	mock_self_alias("MPATHf", "WWID1");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
 	assert_int_equal(rc, 6);
 	assert_ptr_equal(alias, NULL);
 }
 
-static void do_lb_match_c(void **state, int check_if_taken)
+static void do_lb_match_c(void **state)
 {
 	int rc;
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHc WWID1", 1);
+			   "MPATHc WWID1");
 	expect_condlog(3, FOUND_STR("MPATHc", "WWID1"));
-	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken);
+	rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1);
 	assert_int_equal(rc, 0);
 	assert_ptr_not_equal(alias, NULL);
 	assert_string_equal(alias, "MPATHc");
@@ -640,12 +689,12 @@ static void do_lb_match_c(void **state, int check_if_taken)
 
 static void lb_match_c(void **state)
 {
-	do_lb_match_c(state, 0);
+	do_lb_match_c(state);
 }
 
 static void lb_match_c_check(void **state)
 {
-	do_lb_match_c(state, 1);
+	do_lb_match_c(state);
 }
 
 static void lb_nomatch_a_c(void **state)
@@ -654,9 +703,10 @@ static void lb_nomatch_a_c(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHc WWID1", -1);
+			   "MPATHc WWID1");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
+	mock_unused_alias("MPATHb");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
 }
@@ -667,7 +717,7 @@ static void lb_nomatch_a_d_unused(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHd WWID1", -1);
+			   "MPATHd WWID1");
 	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
@@ -681,10 +731,10 @@ static void lb_nomatch_a_d_1_used(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHd WWID1", -1);
+			   "MPATHd WWID1");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	mock_used_alias("MPATHb", "WWID2");
 	mock_unused_alias("MPATHc");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 3);
 	assert_ptr_equal(alias, NULL);
@@ -696,11 +746,11 @@ static void lb_nomatch_a_d_2_used(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHd WWID1", -1);
+			   "MPATHd WWID1");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	mock_used_alias("MPATHb", "WWID2");
 	mock_used_alias("MPATHc", "WWID2");
 	mock_unused_alias("MPATHe");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 5);
 	assert_ptr_equal(alias, NULL);
@@ -712,12 +762,12 @@ static void lb_nomatch_a_d_3_used(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHd WWID1", -1);
+			   "MPATHd WWID1");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	mock_used_alias("MPATHb", "WWID2");
 	mock_used_alias("MPATHc", "WWID2");
 	mock_used_alias("MPATHe", "WWID2");
 	mock_unused_alias("MPATHf");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 6);
 	assert_ptr_equal(alias, NULL);
@@ -729,9 +779,10 @@ static void lb_nomatch_c_a(void **state)
 	char *alias;
 
 	mock_bindings_file("MPATHc WWID1\n"
-			   "MPATHa WWID0\n", -1);
+			   "MPATHa WWID0\n");
+	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
 }
@@ -743,7 +794,7 @@ static void lb_nomatch_d_a_unused(void **state)
 
 	mock_bindings_file("MPATHc WWID1\n"
 			   "MPATHa WWID0\n"
-			   "MPATHd WWID0\n", -1);
+			   "MPATHd WWID0\n");
 	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
@@ -758,10 +809,10 @@ static void lb_nomatch_d_a_1_used(void **state)
 
 	mock_bindings_file("MPATHc WWID1\n"
 			   "MPATHa WWID0\n"
-			   "MPATHd WWID0\n", -1);
+			   "MPATHd WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	mock_used_alias("MPATHb", "WWID2");
 	mock_unused_alias("MPATHe");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 5);
 	assert_ptr_equal(alias, NULL);
@@ -774,9 +825,10 @@ static void lb_nomatch_a_b(void **state)
 
 	mock_bindings_file("MPATHa WWID0\n"
 			   "MPATHz WWID26\n"
-			   "MPATHb WWID1\n", -1);
+			   "MPATHb WWID1\n");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
+	mock_unused_alias("MPATHc");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 3);
 	assert_ptr_equal(alias, NULL);
 }
@@ -786,13 +838,19 @@ static void lb_nomatch_a_b_bad(void **state)
 	int rc;
 	char *alias;
 
+	expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n");
+	/*
+	 * The broken line will be ignored when constructing the bindings vector.
+	 * Thus in lookup_binding() MPATHb is never encountered,
+	 * and MPATHb appears usable.
+	 */
 	mock_bindings_file("MPATHa WWID0\n"
 			   "MPATHz WWID26\n"
-			   "MPATHb\n", -1);
-	expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
+			   "MPATHb\n");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
-	assert_int_equal(rc, 3);
+	mock_unused_alias("MPATHb");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	assert_int_equal(rc, 2);
 	assert_ptr_equal(alias, NULL);
 }
 
@@ -801,28 +859,140 @@ static void lb_nomatch_a_b_bad_self(void **state)
 	int rc;
 	char *alias;
 
+	expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n");
 	mock_bindings_file("MPATHa WWID0\n"
 			   "MPATHz WWID26\n"
-			   "MPATHb\n", -1);
-	expect_condlog(3, "Ignoring malformed line 3 in bindings file\n");
-	mock_self_alias("MPATHc", "WWID2");
+			   "MPATHb\n");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
+	mock_self_alias("MPATHb", "WWID2");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	assert_int_equal(rc, 2);
+	assert_ptr_equal(alias, NULL);
+}
+
+static void lb_nomatch_b_z_a(void **state)
+{
+	int rc;
+	char *alias;
+
+	/*
+	 * add_bindings() sorts alphabetically. Therefore get_free_id()
+	 * finds MPATHc as a free entry.
+	 */
+	mock_bindings_file("MPATHb WWID1\n"
+			   "MPATHz WWID26\n"
+			   "MPATHa WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
+	mock_unused_alias("MPATHc");
 	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
 	assert_int_equal(rc, 3);
 	assert_ptr_equal(alias, NULL);
 }
 
+static void lb_nomatch_b_aa_a(void **state)
+{
+	int rc;
+	char *alias;
+
+	/*
+	 * add_bindings() sorts alphabetically. ("a", "aa", b").
+	 * The get_free_id() algorithm finds the "hole" after "b".
+	 */
+	mock_bindings_file("MPATHb WWID1\n"
+			   "MPATHz WWID26\n"
+			   "MPATHa WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
+	mock_unused_alias("MPATHc");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	assert_int_equal(rc, 3);
+	assert_ptr_equal(alias, NULL);
+}
+
+static void fill_bindings(struct strbuf *buf, int start, int end)
+{
+	int i;
+
+	for (i = start; i <= end; i++) {
+		print_strbuf(buf,  "MPATH");
+		format_devname(buf, i + 1);
+		print_strbuf(buf,  " WWID%d\n", i);
+	}
+}
+
+static void lb_nomatch_b_a_aa(void **state)
+{
+	int rc;
+	char *alias;
+	STRBUF_ON_STACK(buf);
+
+	/*
+	 * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...)
+	 * lookup_binding finds MPATHac as next free entry.
+	 */
+	fill_bindings(&buf, 0, 26);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID28"));
+	mock_unused_alias("MPATHab");
+	rc = lookup_binding(NULL, "WWID28", &alias, "MPATH", 1);
+	assert_int_equal(rc, 28);
+	assert_ptr_equal(alias, NULL);
+}
+
+static void lb_nomatch_b_a_aa_zz(void **state)
+{
+	int rc;
+	char *alias;
+	STRBUF_ON_STACK(buf);
+
+	/*
+	 * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...)
+	 * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is
+	 * found before MPATHb, and MPATHzz was in the bindings, too.
+	 */
+	for (i = 0; i <= 26; i++) {
+		print_strbuf(&buf,  "MPATH");
+		format_devname(&buf, i + 1);
+		print_strbuf(&buf,  " WWID%d\n", i);
+	}
+	print_strbuf(&buf, "MPATHzz WWID676\n");
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID703"));
+	mock_unused_alias("MPATHaaa");
+	rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1);
+	assert_int_equal(rc, 703);
+	assert_ptr_equal(alias, NULL);
+}
+
+static void lb_nomatch_b_z_a_unsorted(void **state)
+{
+	int rc;
+	char *alias;
+
+	/*
+	 * With unsorted bindings (shouldn't happen normally), get_free_id()
+	 * plays safe and returns MPATHaa as first free entry.
+	 */
+	mock_bindings_file_unsorted("MPATHb WWID1\n"
+				    "MPATHz WWID26\n"
+				    "MPATHa WWID0\n");
+	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
+	mock_unused_alias("MPATHaa");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	assert_int_equal(rc, 27);
+	assert_ptr_equal(alias, NULL);
+}
+
 static void lb_nomatch_b_a(void **state)
 {
 	int rc;
 	char *alias;
 
 	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATHz WWID26\n"
-			   "MPATHa WWID0\n", -1);
+			   "MPATHa WWID0\n");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
-	assert_int_equal(rc, 27);
+	mock_unused_alias("MPATHc");
+	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	assert_int_equal(rc, 3);
 	assert_ptr_equal(alias, NULL);
 }
 
@@ -830,55 +1000,59 @@ static void lb_nomatch_b_a_3_used(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATHz WWID26\n"
-			   "MPATHa WWID0\n", -1);
-	mock_used_alias("MPATHaa", "WWID2");
-	mock_used_alias("MPATHab", "WWID2");
-	mock_used_alias("MPATHac", "WWID2");
-	mock_unused_alias("MPATHad");
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
-	assert_int_equal(rc, 30);
+	fill_bindings(&buf, 0, 26);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID31"));
+	mock_used_alias("MPATHab", "WWID31");
+	mock_used_alias("MPATHac", "WWID31");
+	mock_used_alias("MPATHad", "WWID31");
+	mock_unused_alias("MPATHae");
+	rc = lookup_binding(NULL, "WWID31", &alias, "MPATH", 1);
+	assert_int_equal(rc, 31);
 	assert_ptr_equal(alias, NULL);
 }
 
 #ifdef MPATH_ID_INT_MAX
-static void do_lb_nomatch_int_max(void **state, int check_if_taken)
+/*
+ * The bindings will be sorted by alias, alphabetically, which is not
+ * the same as the "numeric" sort order for user-friendly aliases.
+ * get_free_id() selects the highest used ID + 1 if an unsorted entry
+ * is encountered in the bindings table and it's id is equal to the
+ * next "expected" id. This happens if all IDs from "a" to "aa" are
+ * in the table. If the INT_MAX entry is in the table, too, it will
+ * overflow.
+ */
+static void lb_nomatch_int_max(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"
-			   "MPATHa WWID0\n", -1);
+	fill_bindings(&buf, 0, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE"));
 	expect_condlog(0, NOMORE_STR);
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken);
+	rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1);
 	assert_int_equal(rc, -1);
 	assert_ptr_equal(alias, NULL);
 }
 
-static void lb_nomatch_int_max(void **state)
-{
-	do_lb_nomatch_int_max(state, 0);
-}
-
-static void lb_nomatch_int_max_check(void **state)
-{
-	do_lb_nomatch_int_max(state, 1);
-}
-
 static void lb_nomatch_int_max_used(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1);
-	mock_used_alias("MPATHa", "WWID2");
+	fill_bindings(&buf, 1, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE"));
+	mock_used_alias("MPATHa", "WWIDNOMORE");
 	expect_condlog(0, NOMORE_STR);
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1);
 	assert_int_equal(rc, -1);
 	assert_ptr_equal(alias, NULL);
 }
@@ -887,12 +1061,14 @@ static void lb_nomatch_int_max_m1(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"
-			   "MPATHa WWID0\n", -1);
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0);
+	fill_bindings(&buf, 0, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
+	mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
+	rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
 	assert_int_equal(rc, INT_MAX);
 	assert_ptr_equal(alias, NULL);
 }
@@ -901,13 +1077,15 @@ static void lb_nomatch_int_max_m1_used(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"
-			   "MPATHa WWID0\n", -1);
-	mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
+	fill_bindings(&buf, 0, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
+	mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX");
 	expect_condlog(0, NOMORE_STR);
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
 	assert_int_equal(rc, -1);
 	assert_ptr_equal(alias, NULL);
 }
@@ -916,13 +1094,15 @@ static void lb_nomatch_int_max_m1_1_used(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1);
-	mock_used_alias("MPATHa", "WWID2");
+	fill_bindings(&buf, 1, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
+	mock_used_alias("MPATHa", "WWIDMAX");
 	mock_unused_alias("MPATH" MPATH_ID_INT_MAX);
-	expect_condlog(3, NOMATCH_WWID_STR("WWID2"));
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
 	assert_int_equal(rc, INT_MAX);
 	assert_ptr_equal(alias, NULL);
 }
@@ -931,13 +1111,17 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
 {
 	int rc;
 	char *alias;
+	STRBUF_ON_STACK(buf);
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1);
-	mock_used_alias("MPATHa", "WWID2");
-	mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2");
+	fill_bindings(&buf, 1, 26);
+	print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1);
+	mock_bindings_file(get_strbuf_str(&buf));
+
+	expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX"));
+	mock_used_alias("MPATHa", "WWIDMAX");
+	mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX");
 	expect_condlog(0, NOMORE_STR);
-	rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1);
+	rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1);
 	assert_int_equal(rc, -1);
 	assert_ptr_equal(alias, NULL);
 }
@@ -946,52 +1130,68 @@ static void lb_nomatch_int_max_m1_2_used(void **state)
 static int test_lookup_binding(void)
 {
 	const struct CMUnitTest tests[] = {
-		cmocka_unit_test(lb_empty),
-		cmocka_unit_test(lb_empty_unused),
-		cmocka_unit_test(lb_empty_failed),
-		cmocka_unit_test(lb_empty_1_used),
-		cmocka_unit_test(lb_empty_1_used_self),
-		cmocka_unit_test(lb_match_a),
-		cmocka_unit_test(lb_nomatch_a),
-		cmocka_unit_test(lb_nomatch_a_bad_check),
-		cmocka_unit_test(lb_nomatch_a_unused),
-		cmocka_unit_test(lb_nomatch_a_3_used_failed_self),
-		cmocka_unit_test(lb_match_c),
-		cmocka_unit_test(lb_match_c_check),
-		cmocka_unit_test(lb_nomatch_a_c),
-		cmocka_unit_test(lb_nomatch_a_d_unused),
-		cmocka_unit_test(lb_nomatch_a_d_1_used),
-		cmocka_unit_test(lb_nomatch_a_d_2_used),
-		cmocka_unit_test(lb_nomatch_a_d_3_used),
-		cmocka_unit_test(lb_nomatch_c_a),
-		cmocka_unit_test(lb_nomatch_d_a_unused),
-		cmocka_unit_test(lb_nomatch_d_a_1_used),
-		cmocka_unit_test(lb_nomatch_a_b),
-		cmocka_unit_test(lb_nomatch_a_b_bad),
-		cmocka_unit_test(lb_nomatch_a_b_bad_self),
-		cmocka_unit_test(lb_nomatch_b_a),
-		cmocka_unit_test(lb_nomatch_b_a_3_used),
+		cmocka_unit_test_teardown(lb_empty, teardown_bindings),
+		cmocka_unit_test_teardown(lb_empty_unused, teardown_bindings),
+		cmocka_unit_test_teardown(lb_empty_failed, teardown_bindings),
+		cmocka_unit_test_teardown(lb_empty_1_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_empty_1_used_self, teardown_bindings),
+		cmocka_unit_test_teardown(lb_match_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_bad_check, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_unused, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_3_used_failed_self, teardown_bindings),
+		cmocka_unit_test_teardown(lb_match_c, teardown_bindings),
+		cmocka_unit_test_teardown(lb_match_c_check, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_c, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_d_unused, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_d_1_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_d_2_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_d_3_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_c_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_d_a_unused, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_d_a_1_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_b, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_b_bad, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_a_b_bad_self, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_z_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings),
 #ifdef MPATH_ID_INT_MAX
-		cmocka_unit_test(lb_nomatch_int_max),
-		cmocka_unit_test(lb_nomatch_int_max_check),
-		cmocka_unit_test(lb_nomatch_int_max_used),
-		cmocka_unit_test(lb_nomatch_int_max_m1),
-		cmocka_unit_test(lb_nomatch_int_max_m1_used),
-		cmocka_unit_test(lb_nomatch_int_max_m1_1_used),
-		cmocka_unit_test(lb_nomatch_int_max_m1_2_used),
+		cmocka_unit_test_teardown(lb_nomatch_int_max, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_int_max_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_int_max_m1, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_int_max_m1_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_int_max_m1_1_used, teardown_bindings),
+		cmocka_unit_test_teardown(lb_nomatch_int_max_m1_2_used, teardown_bindings),
 #endif
 	};
 
 	return cmocka_run_group_tests(tests, NULL, NULL);
 }
 
+static int rlookup_binding(FILE *dummy, char *buf, const char *alias) {
+
+	const struct binding *bdg;
+
+	bdg = get_binding_for_alias(&global_bindings, alias);
+	if (!bdg) {
+		return -1;
+	}
+	strlcpy(buf, bdg->wwid, WWID_SIZE);
+	return 0;
+}
+
 static void rl_empty(void **state)
 {
 	int rc;
 	char buf[WWID_SIZE];
 
 	buf[0] = '\0';
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_STR("MPATHa"));
 	rc = rlookup_binding(NULL, buf, "MPATHa");
 	assert_int_equal(rc, -1);
@@ -1004,7 +1204,7 @@ static void rl_match_a(void **state)
 	char buf[WWID_SIZE];
 
 	buf[0] = '\0';
-	mock_bindings_file("MPATHa WWID0\n", 0);
+	mock_bindings_file("MPATHa WWID0\n");
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0"));
 	rc = rlookup_binding(NULL, buf, "MPATHa");
 	assert_int_equal(rc, 0);
@@ -1017,7 +1217,7 @@ static void rl_nomatch_a(void **state)
 	char buf[WWID_SIZE];
 
 	buf[0] = '\0';
-	mock_bindings_file("MPATHa WWID0\n", -1);
+	mock_bindings_file("MPATHa WWID0\n");
 	expect_condlog(3, NOMATCH_STR("MPATHb"));
 	rc = rlookup_binding(NULL, buf, "MPATHb");
 	assert_int_equal(rc, -1);
@@ -1030,8 +1230,8 @@ static void rl_malformed_a(void **state)
 	char buf[WWID_SIZE];
 
 	buf[0] = '\0';
-	mock_bindings_file("MPATHa     \n", -1);
-	expect_condlog(3, "Ignoring malformed line 1 in bindings file\n");
+	expect_condlog(1, "invalid line 1 in bindings file, missing WWID\n");
+	mock_bindings_file("MPATHa     \n");
 	expect_condlog(3, NOMATCH_STR("MPATHa"));
 	rc = rlookup_binding(NULL, buf, "MPATHa");
 	assert_int_equal(rc, -1);
@@ -1049,8 +1249,8 @@ static void rl_overlong_a(void **state)
 	snprintf(line + sizeof(line) - 2, 2, "\n");
 
 	buf[0] = '\0';
-	mock_bindings_file(line, -1);
 	expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n");
+	mock_bindings_file(line);
 	expect_condlog(3, NOMATCH_STR("MPATHa"));
 	rc = rlookup_binding(NULL, buf, "MPATHa");
 	assert_int_equal(rc, -1);
@@ -1065,7 +1265,7 @@ static void rl_match_b(void **state)
 	buf[0] = '\0';
 	mock_bindings_file("MPATHa WWID0\n"
 			   "MPATHz WWID26\n"
-			   "MPATHb WWID2\n", 2);
+			   "MPATHb WWID2\n");
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2"));
 	rc = rlookup_binding(NULL, buf, "MPATHb");
 	assert_int_equal(rc, 0);
@@ -1075,31 +1275,41 @@ static void rl_match_b(void **state)
 static int test_rlookup_binding(void)
 {
 	const struct CMUnitTest tests[] = {
-		cmocka_unit_test(rl_empty),
-		cmocka_unit_test(rl_match_a),
-		cmocka_unit_test(rl_nomatch_a),
-		cmocka_unit_test(rl_malformed_a),
-		cmocka_unit_test(rl_overlong_a),
-		cmocka_unit_test(rl_match_b),
+		cmocka_unit_test_teardown(rl_empty, teardown_bindings),
+		cmocka_unit_test_teardown(rl_match_a, teardown_bindings),
+		cmocka_unit_test_teardown(rl_nomatch_a, teardown_bindings),
+		cmocka_unit_test_teardown(rl_malformed_a, teardown_bindings),
+		cmocka_unit_test_teardown(rl_overlong_a, teardown_bindings),
+		cmocka_unit_test_teardown(rl_match_b, teardown_bindings),
 	};
 
 	return cmocka_run_group_tests(tests, NULL, NULL);
 }
 
+void check_bindings_size(int n)
+{
+	/* avoid -Waddress problem */
+	Bindings *bindings = &global_bindings;
+
+	assert_int_equal(VECTOR_SIZE(bindings), n);
+}
+
 static void al_a(void **state)
 {
 	static const char ln[] = "MPATHa WWIDa\n";
 	char *alias;
 
-	will_return(__wrap_lseek, 0);
-	expect_value(__wrap_write, count, strlen(ln));
-	expect_string(__wrap_write, buf, ln);
-	will_return(__wrap_write, strlen(ln));
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_rename, 0);
+	expect_condlog(1, "updated bindings file foo");
 	expect_condlog(3, NEW_STR("MPATHa", "WWIDa"));
 
-	alias = allocate_binding(0, "WWIDa", 1, "MPATH");
+	alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
 	assert_ptr_not_equal(alias, NULL);
 	assert_string_equal(alias, "MPATHa");
+	check_bindings_size(1);
 	free(alias);
 }
 
@@ -1108,15 +1318,17 @@ static void al_zz(void **state)
 	static const char ln[] = "MPATHzz WWIDzz\n";
 	char *alias;
 
-	will_return(__wrap_lseek, 0);
-	expect_value(__wrap_write, count, strlen(ln));
-	expect_string(__wrap_write, buf, ln);
-	will_return(__wrap_write, strlen(ln));
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_rename, 0);
+	expect_condlog(1, "updated bindings file foo");
 	expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz"));
 
-	alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH");
+	alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH");
 	assert_ptr_not_equal(alias, NULL);
 	assert_string_equal(alias, "MPATHzz");
+	check_bindings_size(1);
 	free(alias);
 }
 
@@ -1127,6 +1339,7 @@ static void al_0(void **state)
 	expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n");
 	alias = allocate_binding(0, "WWIDa", 0, "MPATH");
 	assert_ptr_equal(alias, NULL);
+	check_bindings_size(0);
 }
 
 static void al_m2(void **state)
@@ -1136,71 +1349,137 @@ static void al_m2(void **state)
 	expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n");
 	alias = allocate_binding(0, "WWIDa", -2, "MPATH");
 	assert_ptr_equal(alias, NULL);
+	check_bindings_size(0);
 }
 
-static void al_lseek_err(void **state)
+static void al_write_partial(void **state)
 {
+	static const char ln[] = "MPATHa WWIDa\n";
 	char *alias;
 
-	will_return(__wrap_lseek, -ENODEV);
-	expect_condlog(0, "Cannot seek to end of bindings file : No such device\n");
-	alias = allocate_binding(0, "WWIDa", 1, "MPATH");
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1);
+	expect_value(__wrap_write, count, 1);
+	will_return(__wrap_write, ln + sizeof(ln) - 2);
+	will_return(__wrap_write, 1);
+	will_return(__wrap_rename, 0);
+	expect_condlog(1, "updated bindings file foo");
+	expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n");
+
+	alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
+	assert_ptr_not_equal(alias, NULL);
+	assert_string_equal(alias, "MPATHa");
+	check_bindings_size(1);
+	free(alias);
+}
+
+static void al_write_short(void **state)
+{
+	static const char ln[] = "MPATHa WWIDa\n";
+	char *alias;
+
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1);
+	expect_value(__wrap_write, count, 1);
+	will_return(__wrap_write, ln + sizeof(ln) - 2);
+	will_return(__wrap_write, 0);
+	expect_condlog(2, "write_bindings_file: short write");
+	expect_condlog(1, "failed to write new bindings file");
+	expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
+
+	alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
 	assert_ptr_equal(alias, NULL);
+	check_bindings_size(0);
 }
 
 static void al_write_err(void **state)
 {
 	static const char ln[] = "MPATHa WWIDa\n";
-	const int offset = 20;
 	char *alias;
 
-	will_return(__wrap_lseek, offset);
-	expect_value(__wrap_write, count, strlen(ln));
-	expect_string(__wrap_write, buf, ln);
-	will_return(__wrap_write, strlen(ln) - 1);
-	expect_value(__wrap_ftruncate, length, offset);
-	will_return(__wrap_ftruncate, 0);
-	expect_condlog(0, "Cannot write binding to bindings file :");
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, -EPERM);
+	expect_condlog(1, "failed to write new bindings file");
+	expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
 
-	alias = allocate_binding(0, "WWIDa", 1, "MPATH");
+	alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
 	assert_ptr_equal(alias, NULL);
+	check_bindings_size(0);
+}
+
+static void al_rename_err(void **state)
+{
+	static const char ln[] = "MPATHa WWIDa\n";
+	char *alias;
+
+	expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_write, ln);
+	will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln));
+	will_return(__wrap_rename, -EROFS);
+
+	expect_condlog(0, "update_bindings_file: rename: Read-only file system");
+	expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa");
+	alias = allocate_binding("foo", "WWIDa", 1, "MPATH");
+	assert_ptr_equal(alias, NULL);
+	check_bindings_size(0);
 }
 
 static int test_allocate_binding(void)
 {
 	const struct CMUnitTest tests[] = {
-		cmocka_unit_test(al_a),
-		cmocka_unit_test(al_zz),
-		cmocka_unit_test(al_0),
-		cmocka_unit_test(al_m2),
-		cmocka_unit_test(al_lseek_err),
-		cmocka_unit_test(al_write_err),
+		cmocka_unit_test_teardown(al_a, teardown_bindings),
+		cmocka_unit_test_teardown(al_zz, teardown_bindings),
+		cmocka_unit_test_teardown(al_0, teardown_bindings),
+		cmocka_unit_test_teardown(al_m2, teardown_bindings),
+		cmocka_unit_test_teardown(al_write_partial, teardown_bindings),
+		cmocka_unit_test_teardown(al_write_short, teardown_bindings),
+		cmocka_unit_test_teardown(al_write_err, teardown_bindings),
+		cmocka_unit_test_teardown(al_rename_err, teardown_bindings),
 	};
 
 	return cmocka_run_group_tests(tests, NULL, NULL);
 }
 
-#define mock_allocate_binding(alias, wwid)				\
+#define mock_allocate_binding_err_len(alias, wwid, len, err, msg)	\
 	do {								\
 		static const char ln[] = BINDING_STR(alias, wwid);	\
 									\
-		will_return(__wrap_lseek, 0);				\
-		expect_value(__wrap_write, count, strlen(ln));		\
-		expect_string(__wrap_write, buf, ln);			\
-		will_return(__wrap_write, strlen(ln));			\
-		expect_condlog(3, NEW_STR(alias, wwid));		\
+		expect_value(__wrap_write, count,			\
+			     strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \
+		will_return(__wrap_write, ln);				\
+		will_return(__wrap_write,				\
+			    strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \
+		will_return(__wrap_rename, err);			\
+		if (err == 0) {						\
+			expect_condlog(1, "updated bindings file x\n");	\
+			expect_condlog(3, NEW_STR(alias, wwid));	\
+		} else {						\
+			expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \
+			expect_condlog(1, "allocate_binding: deleting binding "	\
+				       alias " for " wwid "\n");	\
+		}							\
 	} while (0)
 
+#define mock_allocate_binding_err(alias, wwid, err, msg)	\
+	mock_allocate_binding_err_len(alias, wwid, 0, err, msg)
+
+#define mock_allocate_binding(alias, wwid)			\
+	mock_allocate_binding_err(alias, wwid, 0, "")
+
+#define mock_allocate_binding_len(alias, wwid, len)			\
+	mock_allocate_binding_err_len(alias, wwid, len, 0, "")
+
 static void gufa_empty_new_rw(void **state) {
 	char *alias;
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	mock_unused_alias("MPATHa");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
-
 	mock_allocate_binding("MPATHa", "WWID0");
+
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHa");
 	free(alias);
@@ -1208,10 +1487,11 @@ static void gufa_empty_new_rw(void **state) {
 
 static void gufa_empty_new_ro_1(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, false);
-	mock_bindings_file("", -1);
+
+	mock_bindings_file("");
 	mock_unused_alias("MPATHa");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
+	mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system");
 
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
 	assert_ptr_equal(alias, NULL);
@@ -1220,11 +1500,9 @@ static void gufa_empty_new_ro_1(void **state) {
 static void gufa_empty_new_ro_2(void **state) {
 	char *alias;
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file("", -1);
-	mock_unused_alias("MPATHa");
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
+	mock_unused_alias("MPATHa");
 
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
 	assert_ptr_equal(alias, NULL);
@@ -1233,11 +1511,10 @@ static void gufa_empty_new_ro_2(void **state) {
 static void gufa_match_a_unused(void **state) {
 	char *alias;
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file("MPATHa WWID0", 0);
+	mock_bindings_file("MPATHa WWID0");
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
 	mock_unused_alias("MPATHa");
+	expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
 
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
 	assert_string_equal(alias, "MPATHa");
@@ -1247,11 +1524,10 @@ static void gufa_match_a_unused(void **state) {
 static void gufa_match_a_self(void **state) {
 	char *alias;
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file("MPATHa WWID0", 0);
+	mock_bindings_file("MPATHa WWID0");
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
 	mock_self_alias("MPATHa", "WWID0");
+	expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
 
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true);
 	assert_string_equal(alias, "MPATHa");
@@ -1261,9 +1537,8 @@ static void gufa_match_a_self(void **state) {
 static void gufa_match_a_used(void **state) {
 	char *alias;
 
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file("MPATHa WWID0", 0);
+	mock_bindings_file("MPATHa WWID0");
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
 	mock_used_alias("MPATHa", "WWID0");
 
@@ -1273,15 +1548,14 @@ static void gufa_match_a_used(void **state) {
 
 static void gufa_nomatch_a_c(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
+	static const char bindings[] = ("MPATHa WWID0\n"
+					"MPATHc WWID2\n");
 
-	mock_bindings_file("MPATHa WWID0\n"
-			   "MPATHc WWID2",
-			   -1);
+	mock_bindings_file(bindings);
 	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 
-	mock_allocate_binding("MPATHb", "WWID1");
+	mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings));
 
 	alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHb");
@@ -1290,15 +1564,14 @@ static void gufa_nomatch_a_c(void **state) {
 
 static void gufa_nomatch_c_a(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
+	const char bindings[] = ("MPATHc WWID2\n"
+				 "MPATHa WWID0\n");
 
-	mock_bindings_file("MPATHc WWID2\n"
-			   "MPATHa WWID0",
-			   -1);
+	mock_bindings_file(bindings);
 	mock_unused_alias("MPATHb");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID1"));
 
-	mock_allocate_binding("MPATHb", "WWID1");
+	mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1);
 
 	alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHb");
@@ -1307,15 +1580,14 @@ static void gufa_nomatch_c_a(void **state) {
 
 static void gufa_nomatch_c_b(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
+	const char bindings[] = ("MPATHc WWID2\n"
+				 "MPATHb WWID1\n");
 
-	mock_bindings_file("MPATHc WWID2\n"
-			   "MPATHb WWID1\n",
-			   -1);
-	mock_unused_alias("MPATHa");
+	mock_bindings_file(bindings);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
+	mock_unused_alias("MPATHa");
 
-	mock_allocate_binding("MPATHa", "WWID0");
+	mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1);
 
 	alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHa");
@@ -1324,16 +1596,15 @@ static void gufa_nomatch_c_b(void **state) {
 
 static void gufa_nomatch_c_b_used(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
+	const char bindings[] = ("MPATHc WWID2\n"
+				 "MPATHb WWID1\n");
 
-	mock_bindings_file("MPATHc WWID2\n"
-			   "MPATHb WWID1",
-			   -1);
-	mock_used_alias("MPATHa", "WWID4");
+	mock_bindings_file(bindings);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID4"));
+	mock_used_alias("MPATHa", "WWID4");
 	mock_unused_alias("MPATHd");
 
-	mock_allocate_binding("MPATHd", "WWID4");
+	mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1);
 
 	alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHd");
@@ -1342,34 +1613,60 @@ static void gufa_nomatch_c_b_used(void **state) {
 
 static void gufa_nomatch_b_f_a(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
+	const char bindings[] = ("MPATHb WWID1\n"
+				 "MPATHf WWID6\n"
+				 "MPATHa WWID0\n");
 
-	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATHf WWID6\n"
-			   "MPATHa WWID0\n",
-			   -1);
+	mock_bindings_file_unsorted(bindings);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID7"));
 	mock_unused_alias("MPATHg");
 
-	mock_allocate_binding("MPATHg", "WWID7");
+	mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1);
 
 	alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
 	assert_string_equal(alias, "MPATHg");
 	free(alias);
 }
 
+static void gufa_nomatch_b_aa_a(void **state) {
+	char *alias;
+	STRBUF_ON_STACK(buf);
+
+	fill_bindings(&buf, 0, 26);
+	mock_bindings_file(get_strbuf_str(&buf));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID28"));
+	mock_unused_alias("MPATHab");
+	mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf));
+
+	alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false);
+	assert_string_equal(alias, "MPATHab");
+	free(alias);
+}
+
+static void gufa_nomatch_b_f_a_sorted(void **state) {
+	char *alias;
+	const char bindings[] = ("MPATHb WWID1\n"
+				 "MPATHf WWID6\n"
+				 "MPATHa WWID0\n");
+
+	mock_bindings_file(bindings);
+	expect_condlog(3, NOMATCH_WWID_STR("WWID7"));
+	mock_unused_alias("MPATHc");
+
+	mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1);
+
+	alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false);
+	assert_string_equal(alias, "MPATHc");
+	free(alias);
+}
+
 static void gufa_old_empty(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
 	/* rlookup_binding for ALIAS */
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
-
-	/* lookup_binding */
-	mock_bindings_file("", -1);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
-
 	mock_unused_alias("MPATHz");
 
 	mock_allocate_binding("MPATHz", "WWID0");
@@ -1382,12 +1679,11 @@ static void gufa_old_empty(void **state) {
 
 static void gufa_old_empty_self(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	mock_self_alias("MPATHz", "WWID0");
 
@@ -1401,15 +1697,14 @@ static void gufa_old_empty_self(void **state) {
 
 static void gufa_old_empty_used(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file("", -1);
+	mock_bindings_file("");
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
 
-	mock_bindings_file("", -1);
-	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
+	mock_bindings_file("");
 	mock_used_alias("MPATHz", "WWID0");
 	expect_condlog(0, ERR_STR("MPATHz", "WWID0"));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 
 	alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
 	assert_ptr_equal(alias, NULL);
@@ -1417,11 +1712,9 @@ static void gufa_old_empty_used(void **state) {
 
 static void gufa_old_match(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
 	mock_bindings_file("MPATHb WWID1\n"
-			   "MPATHz WWID0",
-			   1);
+			   "MPATHz WWID0");
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0"));
 	mock_unused_alias("MPATHz");
 
@@ -1432,9 +1725,8 @@ static void gufa_old_match(void **state) {
 
 static void gufa_old_match_self(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file("MPATHz WWID0", 0);
+	mock_bindings_file("MPATHz WWID0");
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0"));
 	mock_self_alias("MPATHz", "WWID0");
 
@@ -1445,9 +1737,8 @@ static void gufa_old_match_self(void **state) {
 
 static void gufa_old_match_used(void **state) {
 	char *alias;
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file("MPATHz WWID0", 0);
+	mock_bindings_file("MPATHz WWID0");
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0"));
 	mock_used_alias("MPATHz", "WWID0");
 	expect_condlog(0, ERR_STR("MPATHz", "WWID0"));
@@ -1458,19 +1749,15 @@ static void gufa_old_match_used(void **state) {
 
 static void gufa_old_match_other(void **state) {
 	char *alias;
-	static const char bindings[] = "MPATHz WWID9";
+	static const char bindings[] = "MPATHz WWID9\n";
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, 0);
+	mock_bindings_file(bindings);
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
 	expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
-
-	mock_bindings_file(bindings, -1);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 	mock_unused_alias("MPATHa");
 
-	mock_allocate_binding("MPATHa", "WWID0");
+	mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1);
 
 	alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
 	assert_string_equal(alias, "MPATHa");
@@ -1479,21 +1766,16 @@ static void gufa_old_match_other(void **state) {
 
 static void gufa_old_match_other_used(void **state) {
 	char *alias;
-	static const char bindings[] = "MPATHz WWID9";
+	static const char bindings[] = "MPATHz WWID9\n";
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, 0);
+	mock_bindings_file(bindings);
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
 	expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
-
-	mock_bindings_file(bindings, -1);
-	mock_used_alias("MPATHa", "WWID0");
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
+	mock_used_alias("MPATHa", "WWID0");
 	mock_unused_alias("MPATHb");
 
-	mock_allocate_binding("MPATHb", "WWID0");
-
+	mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1);
 	alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
 	assert_string_equal(alias, "MPATHb");
 	free(alias);
@@ -1503,15 +1785,13 @@ static void gufa_old_match_other_wwidmatch(void **state) {
 	char *alias;
 	static const char bindings[] = ("MPATHz WWID9\n"
 					"MPATHc WWID2");
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file(bindings, 0);
+	mock_bindings_file(bindings);
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
 	expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
-
-	mock_bindings_file(bindings, 1);
 	expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
 	mock_unused_alias("MPATHc");
+	expect_condlog(3, EXISTING_STR("MPATHc", "WWID2"));
 
 	alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false);
 	assert_string_equal(alias, "MPATHc");
@@ -1523,13 +1803,9 @@ static void gufa_old_match_other_wwidmatch_used(void **state) {
 	static const char bindings[] = ("MPATHz WWID9\n"
 					"MPATHc WWID2");
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, 0);
+	mock_bindings_file(bindings);
 	expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9"));
 	expect_condlog(0, REUSE_STR("MPATHz", "WWID9"));
-
-	mock_bindings_file(bindings, 1);
 	expect_condlog(3, FOUND_STR("MPATHc", "WWID2"));
 	mock_used_alias("MPATHc", "WWID2");
 
@@ -1541,12 +1817,9 @@ static void gufa_old_nomatch_wwidmatch(void **state) {
 	char *alias;
 	static const char bindings[] = "MPATHa WWID0";
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, -1);
+	mock_bindings_file(bindings);
+	mock_unused_alias("MPATHz");
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
-
-	mock_bindings_file(bindings, 0);
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
 	mock_unused_alias("MPATHa");
 	expect_condlog(3, EXISTING_STR("MPATHa", "WWID0"));
@@ -1559,12 +1832,10 @@ static void gufa_old_nomatch_wwidmatch(void **state) {
 static void gufa_old_nomatch_wwidmatch_used(void **state) {
 	char *alias;
 	static const char bindings[] = "MPATHa WWID0";
-	will_return(__wrap_open_file, true);
 
-	mock_bindings_file(bindings, -1);
+	mock_bindings_file(bindings);
+	mock_unused_alias("MPATHz");
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
-
-	mock_bindings_file(bindings, 0);
 	expect_condlog(3, FOUND_STR("MPATHa", "WWID0"));
 	mock_used_alias("MPATHa", "WWID0");
 
@@ -1574,19 +1845,14 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) {
 
 static void gufa_old_nomatch_nowwidmatch(void **state) {
 	char *alias;
-	static const char bindings[] = "MPATHb WWID1";
+	static const char bindings[] = "MPATHb WWID1\n";
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, -1);
+	mock_bindings_file(bindings);
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
-
-	mock_bindings_file(bindings, -1);
 	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
-
 	mock_unused_alias("MPATHz");
 
-	mock_allocate_binding("MPATHz", "WWID0");
+	mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1);
 	expect_condlog(2, ALLOC_STR("MPATHz", "WWID0"));
 
 	alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
@@ -1598,16 +1864,12 @@ static void gufa_old_nomatch_nowwidmatch_used(void **state) {
 	char *alias;
 	static const char bindings[] = "MPATHb WWID1";
 
-	will_return(__wrap_open_file, true);
-
-	mock_bindings_file(bindings, -1);
+	mock_bindings_file(bindings);
 	expect_condlog(3, NOMATCH_STR("MPATHz"));
 
-	mock_bindings_file(bindings, -1);
-	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
-
 	mock_used_alias("MPATHz", "WWID0");
 	expect_condlog(0, ERR_STR("MPATHz", "WWID0"));
+	expect_condlog(3, NOMATCH_WWID_STR("WWID0"));
 
 	alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false);
 	assert_ptr_equal(alias, NULL);
@@ -1616,31 +1878,33 @@ static void gufa_old_nomatch_nowwidmatch_used(void **state) {
 static int test_get_user_friendly_alias()
 {
 	const struct CMUnitTest tests[] = {
-		cmocka_unit_test(gufa_empty_new_rw),
-		cmocka_unit_test(gufa_empty_new_ro_1),
-		cmocka_unit_test(gufa_empty_new_ro_2),
-		cmocka_unit_test(gufa_match_a_unused),
-		cmocka_unit_test(gufa_match_a_self),
-		cmocka_unit_test(gufa_match_a_used),
-		cmocka_unit_test(gufa_nomatch_a_c),
-		cmocka_unit_test(gufa_nomatch_c_a),
-		cmocka_unit_test(gufa_nomatch_c_b),
-		cmocka_unit_test(gufa_nomatch_c_b_used),
-		cmocka_unit_test(gufa_nomatch_b_f_a),
-		cmocka_unit_test(gufa_old_empty),
-		cmocka_unit_test(gufa_old_empty_self),
-		cmocka_unit_test(gufa_old_empty_used),
-		cmocka_unit_test(gufa_old_match),
-		cmocka_unit_test(gufa_old_match_self),
-		cmocka_unit_test(gufa_old_match_used),
-		cmocka_unit_test(gufa_old_match_other),
-		cmocka_unit_test(gufa_old_match_other_used),
-		cmocka_unit_test(gufa_old_match_other_wwidmatch),
-		cmocka_unit_test(gufa_old_match_other_wwidmatch_used),
-		cmocka_unit_test(gufa_old_nomatch_wwidmatch),
-		cmocka_unit_test(gufa_old_nomatch_wwidmatch_used),
-		cmocka_unit_test(gufa_old_nomatch_nowwidmatch),
-		cmocka_unit_test(gufa_old_nomatch_nowwidmatch_used),
+		cmocka_unit_test_teardown(gufa_empty_new_rw, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_empty_new_ro_1, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_empty_new_ro_2, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_match_a_unused, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_match_a_self, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_match_a_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_a_c, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_c_a, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_c_b, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_c_b_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_b_f_a, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_b_aa_a, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_nomatch_b_f_a_sorted, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_empty, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_empty_self, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_empty_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_self, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_other, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_other_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings),
+		cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch_used, teardown_bindings),
 	};
 
 	return cmocka_run_group_tests(tests, NULL, NULL);
@@ -1656,7 +1920,6 @@ int main(void)
 	ret += test_lookup_binding();
 	ret += test_rlookup_binding();
 	ret += test_allocate_binding();
-	ret += test_allocate_binding();
 	ret += test_get_user_friendly_alias();
 
 	return ret;
