View | Details | Raw Unified | Return to bug 160403
Collapse All | Expand All

(-)etc/rc (-17 / +26 lines)
Lines 82-98 Link Here
82
# Do a first pass to get everything up to $early_late_divider so that
82
# Do a first pass to get everything up to $early_late_divider so that
83
# we can do a second pass that includes $local_startup directories
83
# we can do a second pass that includes $local_startup directories
84
#
84
#
85
files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null`
85
if checkyesno rc_concurrent; then
86
	rcorder -r ${skip} -a ${_boot} -l ${early_late_divider} /etc/rc.d/*
87
else
88
	files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null`
86
89
87
_rc_elem_done=' '
90
	_rc_elem_done=' '
88
for _rc_elem in ${files}; do
91
	for _rc_elem in ${files}; do
89
	run_rc_script ${_rc_elem} ${_boot}
92
		run_rc_script ${_rc_elem} ${_boot}
90
	_rc_elem_done="${_rc_elem_done}${_rc_elem} "
93
		_rc_elem_done="${_rc_elem_done}${_rc_elem} "
91
94
92
	case "$_rc_elem" in
95
		case "$_rc_elem" in
93
	*/${early_late_divider})	break ;;
96
		*/${early_late_divider})	break ;;
94
	esac
97
		esac
95
done
98
	done
99
fi
96
100
97
unset files local_rc
101
unset files local_rc
98
102
Lines 104-118 Link Here
104
*)	find_local_scripts_new ;;
108
*)	find_local_scripts_new ;;
105
esac
109
esac
106
110
107
files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
111
if checkyesno rc_concurrent; then
108
for _rc_elem in ${files}; do
112
	rcorder -r ${skip} -a ${_boot} -f ${early_late_divider} /etc/rc.d/* \
109
	case "$_rc_elem_done" in
113
		${local_rc}
110
	*" $_rc_elem "*)	continue ;;
114
	echo "rc_concurrent finished"
111
	esac
115
else
116
	files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
117
	for _rc_elem in ${files}; do
118
		case "$_rc_elem_done" in
119
		*" $_rc_elem "*)	continue ;;
120
		esac
112
121
113
	run_rc_script ${_rc_elem} ${_boot}
122
		run_rc_script ${_rc_elem} ${_boot}
114
done
123
	done
115
124
fi
116
echo ''
125
echo ''
117
date
126
date
118
exit 0
127
exit 0
(-)etc/Makefile (-1 / +1 lines)
Lines 102-108 Link Here
102
.endif
102
.endif
103
103
104
# -rwxr-xr-x root:wheel, for the new cron root:wheel
104
# -rwxr-xr-x root:wheel, for the new cron root:wheel
105
BIN2=	netstart pccard_ether rc.suspend rc.resume
105
BIN2=	netstart pccard_ether rc.suspend rc.resume rc.trampoline
106
106
107
MTREE=	BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist
107
MTREE=	BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist
108
.if ${MK_SENDMAIL} != "no"
108
.if ${MK_SENDMAIL} != "no"
(-)etc/rc.d/abi (+1 lines)
Lines 6-11 Link Here
6
# PROVIDE: abi
6
# PROVIDE: abi
7
# REQUIRE: archdep
7
# REQUIRE: archdep
8
# KEYWORD: nojail
8
# KEYWORD: nojail
9
# BEFORE: cleartmp
9
10
10
. /etc/rc.subr
11
. /etc/rc.subr
11
12
(-)etc/rc.d/jail (-1 / +1 lines)
Lines 4-10 Link Here
4
#
4
#
5
5
6
# PROVIDE: jail
6
# PROVIDE: jail
7
# REQUIRE: LOGIN cleanvar
7
# REQUIRE: LOGIN cleanvar cleartmp
8
# BEFORE: securelevel
8
# BEFORE: securelevel
9
# KEYWORD: nojail shutdown
9
# KEYWORD: nojail shutdown
10
10
(-)etc/rc.d/motd (-1 / +1 lines)
Lines 5-11 Link Here
5
5
6
# PROVIDE: motd
6
# PROVIDE: motd
7
# REQUIRE: mountcritremote
7
# REQUIRE: mountcritremote
8
# BEFORE:  LOGIN
8
# BEFORE:  LOGIN cleartmp
9
9
10
. /etc/rc.subr
10
. /etc/rc.subr
11
11
(-)etc/defaults/rc.conf (+1 lines)
Lines 25-30 Link Here
25
rc_info="NO"		# Enables display of informational messages at boot.
25
rc_info="NO"		# Enables display of informational messages at boot.
26
rc_startmsgs="YES" 	# Show "Starting foo:" messages at boot
26
rc_startmsgs="YES" 	# Show "Starting foo:" messages at boot
27
rcshutdown_timeout="30" # Seconds to wait before terminating rc.shutdown
27
rcshutdown_timeout="30" # Seconds to wait before terminating rc.shutdown
28
rc_concurrent="NO"	# start rc scripts concurrently.
28
early_late_divider="FILESYSTEMS"	# Script that separates early/late
29
early_late_divider="FILESYSTEMS"	# Script that separates early/late
29
			# stages of the boot process.  Make sure you know
30
			# stages of the boot process.  Make sure you know
30
			# the ramifications if you change this.
31
			# the ramifications if you change this.
(-)etc/rc.trampoline (+11 lines)
Line 0 Link Here
1
#!/bin/sh
2
. /etc/rc.subr
3
load_rc_config 'XXX'
4
5
if test -n "$_RCORDER_RUN_DEBUG"; then
6
	echo '_RCORDER_RUN_DEBUG' $1 $2
7
	sleep 0.02
8
	exit 0
9
fi
10
11
run_rc_script $1 $2
(-)sbin/rcorder/rcorder.c (-9 / +390 lines)
Lines 3-8 Link Here
3
#endif
3
#endif
4
4
5
/*
5
/*
6
 * Copyright (c) 2011 Kilian Klimek
6
 * Copyright (c) 1998, 1999 Matthew R. Green
7
 * Copyright (c) 1998, 1999 Matthew R. Green
7
 * All rights reserved.
8
 * All rights reserved.
8
 * Copyright (c) 1998
9
 * Copyright (c) 1998
Lines 46-51 Link Here
46
#include <string.h>
47
#include <string.h>
47
#include <unistd.h>
48
#include <unistd.h>
48
#include <util.h>
49
#include <util.h>
50
#include <sys/types.h>
51
#include <sys/event.h>
52
#include <sys/time.h>
53
#include <sys/wait.h>
54
#include <errno.h>
55
#include <libgen.h>
49
56
50
#include "ealloc.h"
57
#include "ealloc.h"
51
#include "sprite.h"
58
#include "sprite.h"
Lines 76-81 Link Here
76
int exit_code;
83
int exit_code;
77
int file_count;
84
int file_count;
78
char **file_list;
85
char **file_list;
86
int kq;
87
int childs = 0;
88
char d_script_arg[] = "faststart";
89
char d_trampoline[] = "/etc/rc.trampoline";
90
char *trampoline = d_trampoline;
91
char *script_arg = d_script_arg;
92
char *rc_first = NULL;
93
char *rc_last = NULL;
79
94
80
typedef int bool;
95
typedef int bool;
81
#define TRUE 1
96
#define TRUE 1
Lines 83-88 Link Here
83
typedef bool flag;
98
typedef bool flag;
84
#define SET TRUE
99
#define SET TRUE
85
#define RESET FALSE
100
#define RESET FALSE
101
#define RUNNING 2
102
#define FIRST 3
103
#define LAST 4
86
104
87
Hash_Table provide_hash_s, *provide_hash;
105
Hash_Table provide_hash_s, *provide_hash;
88
106
Lines 90-95 Link Here
90
typedef struct filenode filenode;
108
typedef struct filenode filenode;
91
typedef struct f_provnode f_provnode;
109
typedef struct f_provnode f_provnode;
92
typedef struct f_reqnode f_reqnode;
110
typedef struct f_reqnode f_reqnode;
111
typedef struct f_neednode f_neednode;
93
typedef struct strnodelist strnodelist;
112
typedef struct strnodelist strnodelist;
94
113
95
struct provnode {
114
struct provnode {
Lines 109-114 Link Here
109
	f_reqnode	*next;
128
	f_reqnode	*next;
110
};
129
};
111
130
131
struct f_neednode {
132
	filenode	*entry;
133
	f_neednode	*next;
134
};
135
112
struct strnodelist {
136
struct strnodelist {
113
	filenode	*node;
137
	filenode	*node;
114
	strnodelist	*next;
138
	strnodelist	*next;
Lines 122-127 Link Here
122
	f_reqnode	*req_list;
146
	f_reqnode	*req_list;
123
	f_provnode	*prov_list;
147
	f_provnode	*prov_list;
124
	strnodelist	*keyword_list;
148
	strnodelist	*keyword_list;
149
	f_neednode	*need_list;
125
};
150
};
126
151
127
filenode fn_head_s, *fn_head;
152
filenode fn_head_s, *fn_head;
Lines 151-167 Link Here
151
void initialize(void);
176
void initialize(void);
152
void generate_ordering(void);
177
void generate_ordering(void);
153
int main(int, char *[]);
178
int main(int, char *[]);
179
static pid_t spawn(filenode *);
180
static int wait_child(void);
181
static void run_scripts(void);
182
static void filenode_unlink(filenode *);
183
static int can_run(filenode *);
184
static void check_start(filenode *);
185
static void generate_needs(void);
154
186
155
int
187
int
156
main(int argc, char *argv[])
188
main(int argc, char *argv[])
157
{
189
{
158
	int ch;
190
	int ch;
191
	int run = 0;
192
	struct stat st;
159
193
160
	while ((ch = getopt(argc, argv, "dk:s:")) != -1)
194
	while ((ch = getopt(argc, argv, "a:df:k:l:rs:T:")) != -1)
161
		switch (ch) {
195
		switch (ch) {
196
		case 'a':
197
			script_arg = optarg;
198
			break;
162
		case 'd':
199
		case 'd':
163
#ifdef DEBUG
200
#ifdef DEBUG
164
			debug = 1;
201
			debug = 1;
202
			/* inherited by the trampoline script */
203
			setenv("_RCORDER_RUN_DEBUG", "yes", 1);
165
#else
204
#else
166
			warnx("debugging not compiled in, -d ignored");
205
			warnx("debugging not compiled in, -d ignored");
167
#endif
206
#endif
Lines 169-177 Link Here
169
		case 'k':
208
		case 'k':
170
			strnode_add(&keep_list, optarg, 0);
209
			strnode_add(&keep_list, optarg, 0);
171
			break;
210
			break;
211
		case 'r':
212
			run = 1;
213
			break;
172
		case 's':
214
		case 's':
173
			strnode_add(&skip_list, optarg, 0);
215
			strnode_add(&skip_list, optarg, 0);
174
			break;
216
			break;
217
		case 'T':
218
			trampoline = optarg;
219
			break;
220
		case 'f':
221
			rc_first = optarg;
222
			break;
223
		case 'l':
224
			rc_last = optarg;
225
			break;
175
		default:
226
		default:
176
			/* XXX should crunch it? */
227
			/* XXX should crunch it? */
177
			break;
228
			break;
Lines 187-195 Link Here
187
	DPRINTF((stderr, "initialize\n"));
238
	DPRINTF((stderr, "initialize\n"));
188
	crunch_all_files();
239
	crunch_all_files();
189
	DPRINTF((stderr, "crunch_all_files\n"));
240
	DPRINTF((stderr, "crunch_all_files\n"));
190
	generate_ordering();
241
	if (run) {
191
	DPRINTF((stderr, "generate_ordering\n"));
242
		/* do some sanity checking on the trampoline script */
243
		if (stat(trampoline, &st) == -1)
244
			err(1, "failed to stat %s", trampoline);
192
245
246
		if (!S_ISREG(st.st_mode))
247
			errx(1, "not a regular file: %s", trampoline);
248
249
		if ((st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)
250
			errx(1, "not executable: %s", trampoline);
251
252
		if ((kq = kqueue()) == -1)
253
			err(1, "kqueue failed");
254
255
		run_scripts();
256
		DPRINTF((stderr, "run_scripts\n"));
257
	} else {
258
		generate_ordering();
259
		DPRINTF((stderr, "generate_ordering\n"));
260
	}
261
193
	exit(exit_code);
262
	exit(exit_code);
194
}
263
}
195
264
Lines 240-246 Link Here
240
	temp->req_list = NULL;
309
	temp->req_list = NULL;
241
	temp->prov_list = NULL;
310
	temp->prov_list = NULL;
242
	temp->keyword_list = NULL;
311
	temp->keyword_list = NULL;
243
	temp->in_progress = RESET;
312
	temp->need_list = NULL;
313
314
	if (rc_first != NULL && strncmp(rc_first, basename(filename), strlen(rc_first)) == 0) {
315
		temp->in_progress = FIRST;
316
	} else if (rc_last != NULL && strncmp(rc_last, basename(filename), strlen(rc_last)) == 0) {
317
		temp->in_progress = LAST;
318
	} else {
319
		temp->in_progress = RESET;
320
	}
321
244
	/*
322
	/*
245
	 * link the filenode into the list of filenodes.
323
	 * link the filenode into the list of filenodes.
246
	 * note that the double linking means we can delete a
324
	 * note that the double linking means we can delete a
Lines 720-728 Link Here
720
	} else
798
	} else
721
		was_set = 0;
799
		was_set = 0;
722
800
723
	/* mark fnode */
724
	fnode->in_progress = SET;
725
726
	/*
801
	/*
727
	 * for each requirement of fnode -> r
802
	 * for each requirement of fnode -> r
728
	 *	satisfy_req(r, filename)
803
	 *	satisfy_req(r, filename)
Lines 739-744 Link Here
739
	}
814
	}
740
	fnode->req_list = NULL;
815
	fnode->req_list = NULL;
741
816
817
	/* mark fnode */
818
	if (fnode->in_progress != FIRST && fnode->in_progress != LAST)
819
		fnode->in_progress = SET;
820
742
	/*
821
	/*
743
	 * for each provision of fnode -> p
822
	 * for each provision of fnode -> p
744
	 *	remove fnode from provision list for p in hash table
823
	 *	remove fnode from provision list for p in hash table
Lines 763-770 Link Here
763
	DPRINTF((stderr, "next do: "));
842
	DPRINTF((stderr, "next do: "));
764
843
765
	/* if we were already in progress, don't print again */
844
	/* if we were already in progress, don't print again */
766
	if (was_set == 0 && skip_ok(fnode) && keep_ok(fnode))
845
	if (was_set == 0 && skip_ok(fnode) && keep_ok(fnode)) {
767
		printf("%s\n", fnode->filename);
846
		if (rc_first == NULL)
847
			printf("%s\n", fnode->filename);
848
		if (fnode->in_progress == FIRST)
849
			rc_first = NULL;
850
		else if (fnode->in_progress == LAST)
851
			exit(0);
852
	}
768
	
853
	
769
	if (fnode->next != NULL) {
854
	if (fnode->next != NULL) {
770
		fnode->next->last = fnode->last;
855
		fnode->next->last = fnode->last;
Lines 805-807 Link Here
805
		do_file(fn_head->next);
890
		do_file(fn_head->next);
806
	}
891
	}
807
}
892
}
893
894
/*
895
 * Check if fn_this can be started by checking its requirements and status.
896
 */
897
static int
898
can_run(filenode *fn_this) {
899
	provnode	*p;
900
	Hash_Entry	*entry;
901
	f_reqnode	*r;
902
	int		all_set;
903
904
	if (fn_this->in_progress == RUNNING
905
			|| fn_this->in_progress == LAST
906
			|| fn_this->in_progress == SET)
907
		return (0);
908
909
	all_set = 1;
910
911
	if (fn_this->req_list != NULL) {
912
		r = fn_this->req_list;
913
914
		/* check if all requirements are satisfied */
915
		while (r != NULL) {
916
			entry = r->entry;
917
			p = Hash_GetValue(entry);
918
919
			if (p != NULL && p->head == SET)
920
				p = p->next;
921
922
			if (p != NULL) {
923
				all_set = 0;
924
				break;
925
			}
926
927
			r = r->next;
928
		}
929
	}
930
	return (all_set);
931
}
932
933
/*
934
 * Generate the need_list for all nodes. This has to happen after all
935
 * dependencies have been resolved.
936
 */
937
static void
938
generate_needs(void)
939
{
940
	provnode	*p;
941
	Hash_Entry	*entry;
942
	f_reqnode	*r;
943
	filenode	*fn_this;
944
	f_neednode	*n;
945
946
	for(fn_this = fn_head->next; fn_this != NULL; fn_this = fn_this->next) {
947
		if (fn_this->req_list != NULL) {
948
			r = fn_this->req_list;
949
950
			while (r != NULL) {
951
				entry = r->entry;
952
				p = Hash_GetValue(entry);
953
954
				if (p != NULL && p->head == SET)
955
					p = p->next;
956
957
				while (p != NULL) {
958
					if(p->fnode == NULL) {
959
						p = p->next;
960
						continue;
961
					}
962
963
					n = emalloc(sizeof(f_neednode));
964
					n->next = NULL;
965
					n->entry = fn_this;
966
					n->next = p->fnode->need_list;
967
					p->fnode->need_list = n;
968
					p = p->next;
969
				}
970
				r = r->next;
971
			}
972
		}
973
	}
974
}
975
976
/*
977
 * fill the need lists and start everything that has no requirements.
978
 */
979
static void
980
run_scripts(void)
981
{
982
	filenode	*fn_this,
983
			*t = NULL;
984
985
	generate_needs();
986
987
	DPRINTF((stderr, "init...\n"));
988
	fn_this = fn_head->next;
989
	while (fn_this != NULL) {
990
		if (fn_this->in_progress == FIRST) {
991
			t = fn_this;
992
		} else {
993
			if (can_run(fn_this))
994
				spawn(fn_this);
995
		}
996
		fn_this = fn_this->next;
997
	}
998
999
	/*
1000
	 * If rc_first was set, we have to skip the dependecies before
1001
	 * rc_first. We can't unset rc_first in the loop above because
1002
	 * that would allow scripts, that should not started, to run.
1003
	 */
1004
	if (t) {
1005
		rc_first = NULL;
1006
		t->in_progress = RESET;
1007
		spawn(t);
1008
		fn_this = fn_head->next;
1009
		while (fn_this != NULL) {
1010
			if (can_run(fn_this))
1011
				spawn(fn_this);
1012
			fn_this = fn_this->next;
1013
		}
1014
	}
1015
1016
	DPRINTF((stderr, "wait ...\n"));
1017
	while (childs > 0)
1018
		wait_child();
1019
	exit(0);
1020
}
1021
1022
1023
/*
1024
 * Start a rc script for a filenode.
1025
 */
1026
static pid_t
1027
spawn(filenode *fn)
1028
{
1029
	struct kevent	event;
1030
	pid_t		p;
1031
	char		*args[] = {trampoline, fn->filename, script_arg, NULL};
1032
1033
	if (fn->in_progress == SET || fn->in_progress == RUNNING)
1034
		return (0);
1035
1036
	if (fn->in_progress == FIRST)
1037
		return (0);
1038
1039
	if (fn->in_progress == LAST)
1040
		return (0);
1041
1042
	if (rc_first != NULL) {
1043
		filenode_unlink(fn);
1044
		check_start(fn);
1045
		return (1);
1046
	}
1047
1048
	if (!(skip_ok(fn) && keep_ok(fn))) {
1049
		filenode_unlink(fn);
1050
		check_start(fn);
1051
		return (1);
1052
	}
1053
1054
	DPRINTF((stderr, "spawn: %s\n", fn->filename));
1055
	childs++;
1056
	p = fork();
1057
1058
	if (p == -1) {
1059
		if (errno == EAGAIN)
1060
			return (0);
1061
		err(1, "fork");
1062
	}
1063
1064
	/* parent */
1065
	if (p > 0) {
1066
		EV_SET(&event, p, EVFILT_PROC,
1067
				EV_ADD | EV_ENABLE | EV_ONESHOT,
1068
				NOTE_EXIT, 0, fn);
1069
1070
		if (kevent(kq, &event, 1, NULL, 0, NULL) == -1) {
1071
			if (errno == EINTR)
1072
				return (0);
1073
			err(1, "kevent");
1074
		}
1075
1076
		fn->in_progress = RUNNING;
1077
		return (p);
1078
	}
1079
1080
	/* child */
1081
	execv(args[0], args);
1082
	exit(1);
1083
}
1084
1085
/*
1086
 * Wait for at least one child process to exit. We block for a maximum
1087
 * of 20 seconds. After that, collect what is available.
1088
 */
1089
static int
1090
wait_child(void)
1091
{
1092
	struct kevent	event;
1093
	filenode	*f;
1094
	int		ret;
1095
	struct timespec	ts;
1096
1097
	ts.tv_sec = 20;
1098
	ts.tv_nsec = 0;
1099
1100
	while (1) {
1101
		ret = kevent(kq, NULL, 0, &event, 1, &ts);
1102
1103
		if (ret == 0)
1104
			break;
1105
1106
		ts.tv_sec = 0;
1107
1108
		if (ret == -1) {
1109
			if (errno == EINTR)
1110
				break;
1111
			err(1, "kevent");
1112
		}
1113
1114
		/*
1115
		 * ignore waitpid errors and exit status; nothing we can do.
1116
		 * just collect childs.
1117
		 */
1118
		waitpid(event.ident, NULL, WNOHANG);
1119
		childs--;
1120
1121
		f = (filenode *) event.udata;
1122
1123
		if (event.fflags & NOTE_EXIT) {
1124
			DPRINTF((stderr, "exit: %s (%d)\n", f->filename, event.ident));
1125
			filenode_unlink(f);
1126
			check_start(f);
1127
		}
1128
	}
1129
1130
	return (0);
1131
}
1132
1133
/*
1134
 * For f check which nodes that require it can be started. and start them.
1135
 */
1136
static void
1137
check_start(filenode *f)
1138
{
1139
	filenode *fn;
1140
	f_neednode *n;
1141
1142
	if (f->need_list == NULL)
1143
		return;
1144
1145
	n = f->need_list;
1146
	while (n != NULL) {
1147
		fn = n->entry;
1148
		if(can_run(fn))
1149
			spawn(fn);
1150
		n = n->next;
1151
	}
1152
}
1153
1154
/*
1155
 * Remove filenode from list.
1156
 */
1157
static void
1158
filenode_unlink(filenode *f)
1159
{
1160
	f_provnode	*p,
1161
			*p_tmp;
1162
	provnode	*pnode;
1163
1164
	f->in_progress = SET;
1165
	if (f->next != NULL)
1166
		f->next->last = f->last;
1167
	if (f->last != NULL)
1168
		f->last->next = f->next;
1169
	f->req_list = NULL;
1170
1171
	/*
1172
	 * for each provision of fnode -> p
1173
	 *	remove fnode from provision list for p in hash table
1174
	 */
1175
	p = f->prov_list;
1176
	while (p != NULL) {
1177
		p_tmp = p;
1178
		pnode = p->pnode;
1179
		if (pnode->next != NULL)
1180
			pnode->next->last = pnode->last;
1181
		if (pnode->last != NULL)
1182
			pnode->last->next = pnode->next;
1183
		free(pnode);
1184
		p = p->next;
1185
		free(p_tmp);
1186
	}
1187
	f->prov_list = NULL;
1188
}
(-)sbin/rcorder/rcorder.8 (+73 lines)
Lines 39-46 Link Here
39
.Nd print a dependency ordering of interdependent files
39
.Nd print a dependency ordering of interdependent files
40
.Sh SYNOPSIS
40
.Sh SYNOPSIS
41
.Nm
41
.Nm
42
.Op Fl a Ar action
43
.Op Fl f Ar first
42
.Op Fl k Ar keep
44
.Op Fl k Ar keep
45
.Op Fl l Ar last
46
.Op Fl r
43
.Op Fl s Ar skip
47
.Op Fl s Ar skip
48
.Op Fl T Ar trampoline_script
44
.Ar
49
.Ar
45
.Sh DESCRIPTION
50
.Sh DESCRIPTION
46
The
51
The
Lines 95-112 Link Here
95
.Pp
100
.Pp
96
The options are as follows:
101
The options are as follows:
97
.Bl -tag -width indent
102
.Bl -tag -width indent
103
.It Fl a Ar action
104
Argument passed to rc scripts by the trampoline script.
105
.It Fl f Ar first
106
Act as if the requirement
107
.Ar first,
108
and requirements leading up to it, have already been satisfied (see
109
.Sx CAVEATS
110
sections).
98
.It Fl k
111
.It Fl k
99
Add the specified keyword to the
112
Add the specified keyword to the
100
.Dq "keep list" .
113
.Dq "keep list" .
101
If any
114
If any
102
.Fl k
115
.Fl k
103
option is given, only those files containing the matching keyword are listed.
116
option is given, only those files containing the matching keyword are listed.
117
.It Fl l Ar last
118
Stop when the requirement
119
.Ar last
120
has been satisfied (see
121
.Sx CAVEATS
122
sections).
123
.It Fl r
124
Instead of printing the ordered list of rc scripts, execute them concurrently
125
as
126
.Nm
127
sees fit.
104
.It Fl s
128
.It Fl s
105
Add the specified keyword to the
129
Add the specified keyword to the
106
.Dq "skip list" .
130
.Dq "skip list" .
107
If any
131
If any
108
.Fl s
132
.Fl s
109
option is given, files containing the matching keyword are not listed.
133
option is given, files containing the matching keyword are not listed.
134
.It Fl T Ar trampoline_script
135
When running with the
136
.Fl r
137
flag, use the specified argument as the
138
.Ar trampoline_script.
139
It is called with the rc script to start as the first argument and the action
140
(e.g. faststart) to take as the second argument.
110
.El
141
.El
111
.Pp
142
.Pp
112
An example block follows:
143
An example block follows:
Lines 155-160 Link Here
155
A set of files has a circular dependency which was detected while
186
A set of files has a circular dependency which was detected while
156
processing the stated file.
187
processing the stated file.
157
.El
188
.El
189
.Sh CAVEATS
190
When running with the
191
.Fl r
192
flag, the arguments passed to
193
.Fl f
194
or
195
.Fl l
196
must be one of the check-points (or "placeholders") mentioned in
197
.Xr rc 8 .
198
.Pp
199
The ordering generated when running with or without the
200
.Fl r
201
flag is different. Without the
202
.Fl r
203
flag, and with the
204
.Fl l
205
flag,
206
.Nm
207
produces an ordering that only guarantees that the check-point will
208
be satisfied. With the
209
.Fl r
210
flag,
211
.Nm
212
will guarantee that all and only the requirements leading up to the
213
check-point will be satisfied.
214
.Pp
215
Likewise, with the
216
.Fl f
217
flag and the
218
.Fl r
219
flag set,
220
.Nm
221
will assume all and only the requirements before the check-point are
222
satisfied. Without the
223
.Fl r
224
flag, the ordering will complement the ordering generated of the same
225
.Nm
226
run with the
227
.Fl f
228
replaced with
229
.Fl l
230
flag.
158
.Sh SEE ALSO
231
.Sh SEE ALSO
159
.Xr rc 8
232
.Xr rc 8
160
.Sh HISTORY
233
.Sh HISTORY
(-)share/man/man5/rc.conf.5 (+5 lines)
Lines 114-119 Link Here
114
show
114
show
115
.Dq Starting foo:
115
.Dq Starting foo:
116
when faststart is used (e.g., at boot time).
116
when faststart is used (e.g., at boot time).
117
.It Va rc_concurrent
118
.Pq Vt bool
119
If set to
120
.Dq Li YES ,
121
start rc scripts concurrently.
117
.It Va early_late_divider
122
.It Va early_late_divider
118
.Pq Vt str
123
.Pq Vt str
119
The name of the script that should be used as the
124
The name of the script that should be used as the

Return to bug 160403