Merge pull request #66 from ifupdown-ng/feature/refcounting
refcounting
This commit is contained in:
		
						commit
						277ecaf78a
					
				
					 13 changed files with 240 additions and 42 deletions
				
			
		|  | @ -63,7 +63,7 @@ print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, st | |||
| 	if (!lif_lifecycle_query_dependents(&exec_opts, iface, iface->ifname)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (iface->is_up) | ||||
| 	if (iface->refcount > 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (parent != NULL) | ||||
|  | @ -87,7 +87,7 @@ print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, st | |||
| 		struct lif_interface *child_if = lif_interface_collection_find(collection, tokenp); | ||||
| 
 | ||||
| 		print_interface_dot(collection, child_if, iface); | ||||
| 		child_if->is_up = true; | ||||
| 		child_if->refcount++; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -215,7 +215,8 @@ list_state(struct lif_dict *state, struct match_options *opts) | |||
| 		    fnmatch(opts->include_pattern, entry->key, 0)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		printf("%s=%s\n", entry->key, (const char *) entry->data); | ||||
| 		struct lif_state_record *rec = entry->data; | ||||
| 		printf("%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -93,6 +93,29 @@ acquire_state_lock(const char *state_path, const char *lifname) | |||
| 	return fd; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
| skip_interface(struct lif_interface *iface, const char *ifname) | ||||
| { | ||||
| 	if (exec_opts.force) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (up && iface->refcount > 0) | ||||
| 	{ | ||||
| 		fprintf(stderr, "%s: skipping %s (already configured), use --force to force configuration\n", | ||||
| 			argv0, ifname); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!up && iface->refcount == 0) | ||||
| 	{ | ||||
| 		fprintf(stderr, "%s: skipping %s (already deconfigured), use --force to force deconfiguration\n", | ||||
| 			argv0, ifname); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
| change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname) | ||||
| { | ||||
|  | @ -104,6 +127,14 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (skip_interface(iface, ifname)) | ||||
| 	{ | ||||
| 		if (lockfd != -1) | ||||
| 			close(lockfd); | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	if (exec_opts.verbose) | ||||
| 	{ | ||||
| 		fprintf(stderr, "%s: changing state of interface %s to '%s'\n", | ||||
|  | @ -155,6 +186,27 @@ change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, stru | |||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| update_state_file_and_exit(int rc, struct lif_dict *state) | ||||
| { | ||||
| 	if (exec_opts.mock) | ||||
| 	{ | ||||
| 		exit(rc); | ||||
| 		return rc; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!lif_state_write_path(state, exec_opts.state_file)) | ||||
| 	{ | ||||
| 		fprintf(stderr, "%s: could not update %s\n", argv0, exec_opts.state_file); | ||||
| 
 | ||||
| 		exit(EXIT_FAILURE); | ||||
| 		return EXIT_FAILURE; | ||||
| 	} | ||||
| 
 | ||||
| 	exit(rc); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| ifupdown_main(int argc, char *argv[]) | ||||
| { | ||||
|  | @ -186,9 +238,9 @@ ifupdown_main(int argc, char *argv[]) | |||
| 	if (match_opts.is_auto) | ||||
| 	{ | ||||
| 		if (!change_auto_interfaces(&collection, &state, &match_opts)) | ||||
| 			return EXIT_FAILURE; | ||||
| 			return update_state_file_and_exit(EXIT_FAILURE, &state); | ||||
| 
 | ||||
| 		return EXIT_SUCCESS; | ||||
| 		return update_state_file_and_exit(EXIT_SUCCESS, &state); | ||||
| 	} | ||||
| 	else if (optind >= argc) | ||||
| 		generic_usage(self_applet, EXIT_FAILURE); | ||||
|  | @ -217,23 +269,17 @@ ifupdown_main(int argc, char *argv[]) | |||
| 			if (entry == NULL) | ||||
| 			{ | ||||
| 				fprintf(stderr, "%s: unknown interface %s\n", argv0, argv[idx]); | ||||
| 				return EXIT_FAILURE; | ||||
| 				return update_state_file_and_exit(EXIT_FAILURE, &state); | ||||
| 			} | ||||
| 
 | ||||
| 			iface = entry->data; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!change_interface(iface, &collection, &state, ifname)) | ||||
| 			return EXIT_FAILURE; | ||||
| 			return update_state_file_and_exit(EXIT_FAILURE, &state); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!exec_opts.mock && !lif_state_write_path(&state, exec_opts.state_file)) | ||||
| 	{ | ||||
| 		fprintf(stderr, "%s: could not update %s\n", argv0, exec_opts.state_file); | ||||
| 		return EXIT_FAILURE; | ||||
| 	} | ||||
| 
 | ||||
| 	return EXIT_SUCCESS; | ||||
| 	return update_state_file_and_exit(EXIT_SUCCESS, &state); | ||||
| } | ||||
| 
 | ||||
| struct if_applet ifup_applet = { | ||||
|  |  | |||
|  | @ -68,13 +68,14 @@ set_no_lock(const char *opt_arg) | |||
| } | ||||
| 
 | ||||
| static void | ||||
| no_op(const char *opt_arg) | ||||
| set_force(const char *opt_arg) | ||||
| { | ||||
| 	(void) opt_arg; | ||||
| 	exec_opts.force = true; | ||||
| } | ||||
| 
 | ||||
| static struct if_option exec_options[] = { | ||||
| 	{'f', "force", NULL, "force (de)configuration", false, no_op}, | ||||
| 	{'f', "force", NULL, "force (de)configuration", false, set_force}, | ||||
| 	{'i', "interfaces", "interfaces FILE", "use FILE for interface definitions", true, set_interfaces_file}, | ||||
| 	{'l', "no-lock", NULL, "do not use a lockfile to serialize state changes", false, set_no_lock}, | ||||
| 	{'n', "no-act", NULL, "do not actually run any commands", false, set_no_act}, | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ struct lif_execute_opts { | |||
| 	bool verbose; | ||||
| 	bool mock; | ||||
| 	bool no_lock; | ||||
| 	bool force; | ||||
| 	const char *executor_path; | ||||
| 	const char *interfaces_file; | ||||
| 	const char *state_file; | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ struct lif_interface { | |||
| 
 | ||||
| 	struct lif_dict vars; | ||||
| 
 | ||||
| 	bool is_up; | ||||
| 	size_t refcount;	/* >= 0 if up, else 0 */ | ||||
| }; | ||||
| 
 | ||||
| #define LIF_INTERFACE_COLLECTION_FOREACH(iter, collection) \ | ||||
|  |  | |||
|  | @ -261,6 +261,36 @@ handle_error: | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| /* this function returns true if we can skip processing the interface for now,
 | ||||
|  * otherwise false. | ||||
|  */ | ||||
| static bool | ||||
| handle_refcounting(struct lif_dict *state, struct lif_interface *iface, bool up) | ||||
| { | ||||
| 	size_t orig_refcount = iface->refcount; | ||||
| 
 | ||||
| 	if (up) | ||||
| 		lif_state_ref_if(state, iface->ifname, iface); | ||||
| 	else | ||||
| 		lif_state_unref_if(state, iface->ifname, iface); | ||||
| 
 | ||||
| #ifdef DEBUG_REFCOUNTING | ||||
| 	fprintf(stderr, "handle_refcounting(): orig_refcount=%zu, refcount=%zu, direction=%s\n", | ||||
| 		orig_refcount, iface->refcount, up ? "UP" : "DOWN"); | ||||
| #endif | ||||
| 
 | ||||
| 	/* if going up and orig_refcount > 0 -- we're already configured. */ | ||||
| 	if (up && orig_refcount > 0) | ||||
| 		return true; | ||||
| 
 | ||||
| 	/* if going down and iface->refcount > 1 -- we still have other dependents. */ | ||||
| 	if (!up && iface->refcount > 1) | ||||
| 		return true; | ||||
| 
 | ||||
| 	/* we can change this interface -- no blocking dependents. */ | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *parent, struct lif_dict *collection, struct lif_dict *state, bool up) | ||||
| { | ||||
|  | @ -278,12 +308,17 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par | |||
| 	{ | ||||
| 		struct lif_interface *iface = lif_interface_collection_find(collection, tokenp); | ||||
| 
 | ||||
| 		/* already up or down, skip */ | ||||
| 		if (up == iface->is_up) | ||||
| 		/* if handle_refcounting returns true, it means we've already
 | ||||
| 		 * configured the interface, or it is too soon to deconfigure | ||||
| 		 * the interface. | ||||
| 		 */ | ||||
| 		if (handle_refcounting(state, iface, up)) | ||||
| 		{ | ||||
| 			if (opts->verbose) | ||||
| 				fprintf(stderr, "ifupdown: skipping dependent interface %s (of %s)\n", | ||||
| 					iface->ifname, parent->ifname); | ||||
| 				fprintf(stderr, "ifupdown: skipping dependent interface %s (of %s) -- %s\n", | ||||
| 					iface->ifname, parent->ifname, | ||||
| 					up ? "already configured" : "transient dependencies still exist"); | ||||
| 
 | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -328,7 +363,7 @@ lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *ifa | |||
| 
 | ||||
| 		lif_state_upsert(state, lifname, iface); | ||||
| 
 | ||||
| 		iface->is_up = true; | ||||
| 		lif_state_ref_if(state, lifname, iface); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | @ -345,9 +380,7 @@ lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *ifa | |||
| 		if (!handle_dependents(opts, iface, collection, state, up)) | ||||
| 			return false; | ||||
| 
 | ||||
| 		lif_state_delete(state, lifname); | ||||
| 
 | ||||
| 		iface->is_up = false; | ||||
| 		lif_state_unref_if(state, lifname, iface); | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
|  |  | |||
|  | @ -13,27 +13,41 @@ | |||
|  * from the use of this software. | ||||
|  */ | ||||
| 
 | ||||
| #include <limits.h> | ||||
| #include <string.h> | ||||
| #include "libifupdown/state.h" | ||||
| #include "libifupdown/fgetline.h" | ||||
| #include "libifupdown/tokenize.h" | ||||
| 
 | ||||
| bool | ||||
| lif_state_read(struct lif_dict *state, FILE *fd) | ||||
| { | ||||
| 	char linebuf[4096]; | ||||
| 
 | ||||
| 	while (lif_fgetline(linebuf, sizeof linebuf, fd)) | ||||
| 	{ | ||||
| 		char *ifname = linebuf; | ||||
| 		char *bufp = linebuf; | ||||
| 		char *ifname = lif_next_token(&bufp); | ||||
| 		char *refcount = lif_next_token(&bufp); | ||||
| 		size_t rc = 1; | ||||
| 		char *equals_p = strchr(linebuf, '='); | ||||
| 
 | ||||
| 		if (*refcount) | ||||
| 		{ | ||||
| 			rc = strtoul(refcount, NULL, 10); | ||||
| 
 | ||||
| 			if (rc == 0 || rc == ULONG_MAX) | ||||
| 				rc = 1; | ||||
| 		} | ||||
| 
 | ||||
| 		if (equals_p == NULL) | ||||
| 		{ | ||||
| 			lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname }); | ||||
| 			lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname, .refcount = rc }); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		*equals_p++ = '\0'; | ||||
| 		lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p }); | ||||
| 		lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p, .refcount = rc }); | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
|  | @ -55,10 +69,38 @@ lif_state_read_path(struct lif_dict *state, const char *path) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| lif_state_ref_if(struct lif_dict *state, const char *ifname, struct lif_interface *iface) | ||||
| { | ||||
| 	iface->refcount++; | ||||
| 	lif_state_upsert(state, ifname, iface); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| lif_state_unref_if(struct lif_dict *state, const char *ifname, struct lif_interface *iface) | ||||
| { | ||||
| 	if (iface->refcount == 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	iface->refcount--; | ||||
| 
 | ||||
| 	if (iface->refcount) | ||||
| 		lif_state_upsert(state, ifname, iface); | ||||
| 	else | ||||
| 		lif_state_delete(state, ifname); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| lif_state_upsert(struct lif_dict *state, const char *ifname, struct lif_interface *iface) | ||||
| { | ||||
| 	lif_dict_add(state, ifname, strdup(iface->ifname)); | ||||
| 	lif_state_delete(state, ifname); | ||||
| 
 | ||||
| 	struct lif_state_record *rec = calloc(1, sizeof(*rec)); | ||||
| 
 | ||||
| 	rec->mapped_if = strdup(iface->ifname); | ||||
| 	rec->refcount = iface->refcount; | ||||
| 
 | ||||
| 	lif_dict_add(state, ifname, rec); | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -69,7 +111,10 @@ lif_state_delete(struct lif_dict *state, const char *ifname) | |||
| 	if (entry == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	free(entry->data); | ||||
| 	struct lif_state_record *rec = entry->data; | ||||
| 	free(rec->mapped_if); | ||||
| 	free(rec); | ||||
| 
 | ||||
| 	lif_dict_delete_entry(state, entry); | ||||
| } | ||||
| 
 | ||||
|  | @ -81,8 +126,9 @@ lif_state_write(const struct lif_dict *state, FILE *f) | |||
| 	LIF_DICT_FOREACH(iter, state) | ||||
| 	{ | ||||
| 		struct lif_dict_entry *entry = iter->data; | ||||
| 		struct lif_state_record *rec = entry->data; | ||||
| 
 | ||||
| 		fprintf(f, "%s=%s\n", entry->key, (const char *) entry->data); | ||||
| 		fprintf(f, "%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -108,7 +154,8 @@ lif_state_lookup(struct lif_dict *state, struct lif_dict *if_collection, const c | |||
| 	if (entry == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	struct lif_dict_entry *if_entry = lif_dict_find(if_collection, (const char *) entry->data); | ||||
| 	struct lif_state_record *rec = entry->data; | ||||
| 	struct lif_dict_entry *if_entry = lif_dict_find(if_collection, rec->mapped_if); | ||||
| 
 | ||||
| 	if (if_entry == NULL) | ||||
| 		return NULL; | ||||
|  | @ -124,9 +171,10 @@ lif_state_sync(struct lif_dict *state, struct lif_dict *if_collection) | |||
| 	LIF_DICT_FOREACH(iter, state) | ||||
| 	{ | ||||
| 		struct lif_dict_entry *entry = iter->data; | ||||
| 		struct lif_interface *iface = lif_interface_collection_find(if_collection, entry->key); | ||||
| 		struct lif_state_record *rec = entry->data; | ||||
| 		struct lif_interface *iface = lif_interface_collection_find(if_collection, rec->mapped_if); | ||||
| 
 | ||||
| 		iface->is_up = true; | ||||
| 		iface->refcount = rec->refcount; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
|  |  | |||
|  | @ -19,9 +19,16 @@ | |||
| #include <stdio.h> | ||||
| #include "libifupdown/interface.h" | ||||
| 
 | ||||
| struct lif_state_record { | ||||
| 	char *mapped_if; | ||||
| 	size_t refcount; | ||||
| }; | ||||
| 
 | ||||
| extern bool lif_state_read(struct lif_dict *state, FILE *f); | ||||
| extern bool lif_state_read_path(struct lif_dict *state, const char *path); | ||||
| extern void lif_state_upsert(struct lif_dict *state, const char *ifname, struct lif_interface *iface); | ||||
| extern void lif_state_ref_if(struct lif_dict *state, const char *ifname, struct lif_interface *iface); | ||||
| extern void lif_state_unref_if(struct lif_dict *state, const char *ifname, struct lif_interface *iface); | ||||
| extern void lif_state_delete(struct lif_dict *state, const char *ifname); | ||||
| extern void lif_state_write(const struct lif_dict *state, FILE *f); | ||||
| extern bool lif_state_write_path(const struct lif_dict *state, const char *path); | ||||
|  |  | |||
							
								
								
									
										6
									
								
								tests/fixtures/deferred-teardown-1.ifstate
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/fixtures/deferred-teardown-1.ifstate
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| lo=lo 1 | ||||
| br0=br0 1 | ||||
| bond0=bond0 2 | ||||
| eth0=eth0 3 | ||||
| eth1=eth1 2 | ||||
| tun0=tun0 1 | ||||
							
								
								
									
										9
									
								
								tests/fixtures/deferred-teardown-1.interfaces
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/fixtures/deferred-teardown-1.interfaces
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| auto br0 | ||||
| iface br0 | ||||
| 	requires bond0 | ||||
| 
 | ||||
| iface bond0 | ||||
| 	requires eth0 eth1 | ||||
| 
 | ||||
| iface tun0 | ||||
| 	requires eth0 | ||||
							
								
								
									
										5
									
								
								tests/fixtures/deferred-teardown-2.ifstate
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/fixtures/deferred-teardown-2.ifstate
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| eth0=eth0 5 | ||||
| tun0=tun0 1 | ||||
| tun1=tun1 1 | ||||
| tun2=tun2 1 | ||||
| tun3=tun3 1 | ||||
							
								
								
									
										11
									
								
								tests/fixtures/deferred-teardown-2.interfaces
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/fixtures/deferred-teardown-2.interfaces
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| iface tun0 | ||||
| 	requires eth0 | ||||
| 
 | ||||
| iface tun1 | ||||
| 	requires eth0 | ||||
| 
 | ||||
| iface tun2 | ||||
| 	requires eth0 | ||||
| 
 | ||||
| iface tun3 | ||||
| 	requires eth0 | ||||
|  | @ -19,6 +19,9 @@ tests_init \ | |||
| 	learned_dependency_2 \ | ||||
| 	learned_executor \ | ||||
| 	implicit_vlan \ | ||||
| 	deferred_teardown_1 \ | ||||
| 	deferred_teardown_2 \ | ||||
| 	deferred_teardown_3 \ | ||||
| 	regress_opt_f | ||||
| 
 | ||||
| noargs_body() { | ||||
|  | @ -27,56 +30,56 @@ noargs_body() { | |||
| 
 | ||||
| lo_always_auto_body() { | ||||
| 	atf_check -s exit:0 -e ignore -o match:'executors/link' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i/dev/null -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i/dev/null -n -a | ||||
| } | ||||
| 
 | ||||
| dual_stack_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/static' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| static_ipv4_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/static' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v4.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v4.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| static_ipv4_netmask_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/static' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v4-netmask.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v4-netmask.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| static_ipv6_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/static' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v6.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v6.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| static_ipv6_netmask_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/static' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v6-netmask.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/static-eth0-v6-netmask.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| inet_dhcp_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/dhcp' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/dhcp-eth0.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/dhcp-eth0.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| use_dhcp_body() { | ||||
| 	atf_check -s exit:0 -e ignore \ | ||||
| 		-o match:'executors/link' \ | ||||
| 		-o match:'executors/dhcp' \ | ||||
| 		ifdown -S/dev/null -E $EXECUTORS -i $FIXTURES/use-dhcp-eth0.interfaces -n -a | ||||
| 		ifdown -f -S/dev/null -E $EXECUTORS -i $FIXTURES/use-dhcp-eth0.interfaces -n -a | ||||
| } | ||||
| 
 | ||||
| alias_eth0_home_body() { | ||||
|  | @ -142,6 +145,33 @@ implicit_vlan_body() { | |||
| 		ifdown -n -S $FIXTURES/vlan.ifstate -E $EXECUTORS -i $FIXTURES/vlan.interfaces eth0.8 | ||||
| } | ||||
| 
 | ||||
| deferred_teardown_1_body() { | ||||
| 	atf_check -s exit:0 -o ignore \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of bond0\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"changing state of dependent interface eth1 \\(of bond0\\) to down" \ | ||||
| 		ifdown -n -S $FIXTURES/deferred-teardown-1.ifstate -E $EXECUTORS \ | ||||
| 			-i $FIXTURES/deferred-teardown-1.interfaces br0 | ||||
| } | ||||
| 
 | ||||
| deferred_teardown_2_body() { | ||||
| 	atf_check -s exit:0 -o ignore \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun0\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun1\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun2\\) -- transient dependencies still exist" \ | ||||
| 		ifdown -n -S $FIXTURES/deferred-teardown-2.ifstate -E $EXECUTORS \ | ||||
| 			-i $FIXTURES/deferred-teardown-2.interfaces tun0 tun1 tun2 | ||||
| } | ||||
| 
 | ||||
| deferred_teardown_3_body() { | ||||
| 	atf_check -s exit:0 -o ignore \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun0\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun1\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"skipping dependent interface eth0 \\(of tun2\\) -- transient dependencies still exist" \ | ||||
| 		-e match:"changing state of dependent interface eth0 \\(of tun3\\) to down" \ | ||||
| 		ifdown -n -S $FIXTURES/deferred-teardown-2.ifstate -E $EXECUTORS \ | ||||
| 			-i $FIXTURES/deferred-teardown-2.interfaces tun0 tun1 tun2 tun3 | ||||
| } | ||||
| 
 | ||||
| regress_opt_f_body() { | ||||
| 	atf_check -s exit:0 -o ignore -e ignore \ | ||||
| 		ifdown -n -S $FIXTURES/vlan.ifstate -E $EXECUTORS -i $FIXTURES/vlan.interfaces -f eth0.8 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue