|
0 |
Description: Added option to control loop solver's warnings
|
|
1 |
Author: Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
|
|
2 |
Origin: https://github.com/xaionaro/openrc
|
|
3 |
Last-Update: 2014-02-06
|
|
4 |
|
|
5 |
--- openrc-0.12.4+20131230.orig/etc/rc.conf.in
|
|
6 |
+++ openrc-0.12.4+20131230/etc/rc.conf.in
|
|
7 |
@@ -135,3 +135,6 @@
|
|
8 |
# This is mainly used for saying which servies do NOT provide net.
|
|
9 |
#rc_net_tap0_provide="!net"
|
|
10 |
|
|
11 |
+# Comment this line to disable warnings about dependency loops
|
|
12 |
+rc_loopsolver_warnings="YES"
|
|
13 |
+
|
|
14 |
--- openrc-0.12.4+20131230.orig/src/librc/librc-depend.c
|
|
15 |
+++ openrc-0.12.4+20131230/src/librc/librc-depend.c
|
|
16 |
@@ -891,13 +891,17 @@ deptype2char(unapm_type_t type) {
|
|
17 |
* @param svc_id2depinfo_bt ptr to binary tree root to get depinfo by svc id
|
|
18 |
* @param end_dep_num looping dependency id in use/need/after/provide matrix line */
|
|
19 |
static loopfound_t
|
|
20 |
-rc_deptree_solve_loop(service_id_t **unap_matrix[UNAPM_MAX], service_id_t service_id, void *svc_id2depinfo_bt, int end_dep_num) {
|
|
21 |
+rc_deptree_solve_loop(service_id_t **unap_matrix[UNAPM_MAX], service_id_t service_id, void *svc_id2depinfo_bt, int end_dep_num, RC_DT_FLAGS flags) {
|
|
22 |
char **chain_strs = NULL;
|
|
23 |
service_id_t **chains;
|
|
24 |
unapm_type_t **deptypes;
|
|
25 |
unapm_type_t minimal_cost;
|
|
26 |
int chains_size = unap_matrix[0][0][0], chain_count;
|
|
27 |
|
|
28 |
+ /* svc_id2depinfo_bt may be NULL while any unit tests to simplify them */
|
|
29 |
+ char printwarn = (svc_id2depinfo_bt != NULL) && (flags & RCDTFLAGS_WARNINGS);
|
|
30 |
+ char printerr = svc_id2depinfo_bt != NULL;
|
|
31 |
+
|
|
32 |
chains = xmalloc(chains_size * sizeof(*chains));
|
|
33 |
|
|
34 |
/* building all dependency chains of the service */
|
|
35 |
@@ -1060,9 +1064,9 @@ rc_deptree_solve_loop(service_id_t **una
|
|
36 |
}
|
|
37 |
}
|
|
38 |
|
|
39 |
- /* printing */
|
|
40 |
+ /* preparing services chain for further printing */
|
|
41 |
|
|
42 |
- if (svc_id2depinfo_bt != NULL) {
|
|
43 |
+ if (printwarn || printerr) {
|
|
44 |
int chain_num;
|
|
45 |
chain_strs = xmalloc(chain_count * sizeof(*chain_strs));
|
|
46 |
|
|
47 |
@@ -1157,19 +1161,21 @@ rc_deptree_solve_loop(service_id_t **una
|
|
48 |
|
|
49 |
minimal_cost = MAX(minimal_cost, chain_cost);
|
|
50 |
|
|
51 |
- if (svc_id2depinfo_bt != NULL) {
|
|
52 |
/*
|
|
53 |
- RC_DEPINFO *depinfo;
|
|
54 |
- ENTRY item, **item_pp;
|
|
55 |
- item.key = (void *)(long)service_id;
|
|
56 |
- item_pp = tfind(&item, &svc_id2depinfo_bt, svc_id2depinfo_bt_compare);
|
|
57 |
- depinfo = (RC_DEPINFO *)((ENTRY *)*item_pp)->data;
|
|
58 |
+ RC_DEPINFO *depinfo;
|
|
59 |
+ ENTRY item, **item_pp;
|
|
60 |
+ item.key = (void *)(long)service_id;
|
|
61 |
+ item_pp = tfind(&item, &svc_id2depinfo_bt, svc_id2depinfo_bt_compare);
|
|
62 |
+ depinfo = (RC_DEPINFO *)((ENTRY *)*item_pp)->data;
|
|
63 |
*/
|
|
64 |
- if (minimal_cost > UNAPM_AFTER)
|
|
65 |
+ if (minimal_cost > UNAPM_AFTER) {
|
|
66 |
+ if (printerr)
|
|
67 |
eerror("Found an unresolvable dependency: %s.", chain_strs[i]);
|
|
68 |
- else
|
|
69 |
+ } else {
|
|
70 |
+ if (printwarn)
|
|
71 |
ewarn("Found a solvable dependency loop: %s.", chain_strs[i]);
|
|
72 |
}
|
|
73 |
+
|
|
74 |
i++;
|
|
75 |
}
|
|
76 |
/*printf("minimal cost: %i\n", minimal_cost);*/
|
|
77 |
@@ -1339,7 +1345,7 @@ rc_deptree_solve_loop(service_id_t **una
|
|
78 |
return;
|
|
79 |
}
|
|
80 |
|
|
81 |
- if (svc_id2depinfo_bt != NULL) {
|
|
82 |
+ if (printwarn) {
|
|
83 |
item.key = (void *)(long)service_id_from;
|
|
84 |
item_pp = tfind(&item, &svc_id2depinfo_bt, svc_id2depinfo_bt_compare);
|
|
85 |
depinfo_from = (RC_DEPINFO *)((ENTRY *)*item_pp)->data;
|
|
86 |
@@ -1370,13 +1376,13 @@ rc_deptree_solve_loop(service_id_t **una
|
|
87 |
|
|
88 |
i = 0;
|
|
89 |
while (i < chain_count) {
|
|
90 |
- if (svc_id2depinfo_bt != NULL)
|
|
91 |
+ if (printwarn || printerr)
|
|
92 |
free(chain_strs[i]);
|
|
93 |
free(deptypes[i]);
|
|
94 |
free(chains[i]);
|
|
95 |
i++;
|
|
96 |
}
|
|
97 |
- if (svc_id2depinfo_bt != NULL)
|
|
98 |
+ if (printwarn || printerr)
|
|
99 |
free(chain_strs);
|
|
100 |
free(deptypes);
|
|
101 |
free(chains);
|
|
102 |
@@ -1454,7 +1460,7 @@ rc_deptree_unapm_prepare_mixed(service_i
|
|
103 |
Phase 7 saves the depinfo object to disk
|
|
104 |
*/
|
|
105 |
bool
|
|
106 |
-rc_deptree_update(void)
|
|
107 |
+rc_deptree_update(RC_DT_FLAGS flags)
|
|
108 |
{
|
|
109 |
FILE *fp;
|
|
110 |
RC_DEPTREE *deptree, *providers;
|
|
111 |
@@ -1790,7 +1796,7 @@ rc_deptree_update(void)
|
|
112 |
while (dep_num < dep_count) {
|
|
113 |
dep_num++;
|
|
114 |
if (unap_matrix[UNAPM_MIXED_EXPANDED][service_id][dep_num] == service_id) {
|
|
115 |
- loopfound = rc_deptree_solve_loop(unap_matrix, service_id, svc_id2depinfo_bt, dep_num);
|
|
116 |
+ loopfound = rc_deptree_solve_loop(unap_matrix, service_id, svc_id2depinfo_bt, dep_num, flags);
|
|
117 |
loopsolver_counter++;
|
|
118 |
break;
|
|
119 |
}
|
|
120 |
--- openrc-0.12.4+20131230.orig/src/librc/rc.h.in
|
|
121 |
+++ openrc-0.12.4+20131230/src/librc/rc.h.in
|
|
122 |
@@ -373,13 +373,21 @@ bool rc_older_than(const char *, const c
|
|
123 |
* @return pointer to the value, otherwise NULL */
|
|
124 |
char *rc_proc_getent(const char *);
|
|
125 |
|
|
126 |
+/*! @brief flags that may be passed to rc_deptree_update() */
|
|
127 |
+typedef enum
|
|
128 |
+{
|
|
129 |
+ /* Print warnings about found loops */
|
|
130 |
+ RCDTFLAGS_WARNINGS = 0x0001,
|
|
131 |
+} RC_DT_FLAGS;
|
|
132 |
+
|
|
133 |
/*! Update the cached dependency tree if it's older than any init script,
|
|
134 |
* its configuration file or an external configuration file the init script
|
|
135 |
* has specified.
|
|
136 |
* time_t returns the time of the newest file that the dependency tree
|
|
137 |
* will be checked against.
|
|
138 |
+ * @param flags
|
|
139 |
* @return true if successful, otherwise false */
|
|
140 |
-bool rc_deptree_update(void);
|
|
141 |
+bool rc_deptree_update(RC_DT_FLAGS flags);
|
|
142 |
|
|
143 |
/*! Check if the cached dependency tree is older than any init script,
|
|
144 |
* its configuration file or an external configuration file the init script
|
|
145 |
--- openrc-0.12.4+20131230.orig/src/rc/rc-depend.c
|
|
146 |
+++ openrc-0.12.4+20131230/src/rc/rc-depend.c
|
|
147 |
@@ -76,7 +76,7 @@ _rc_deptree_load(int force, int *regen)
|
|
148 |
if (regen)
|
|
149 |
*regen = 1;
|
|
150 |
ebegin("Caching service dependencies");
|
|
151 |
- retval = rc_deptree_update() ? 0 : -1;
|
|
152 |
+ retval = rc_deptree_update(rc_conf_yesno("rc_loopsolver_warnings")?RCDTFLAGS_WARNINGS:0) ? 0 : -1;
|
|
153 |
eend (retval, "Failed to update the dependency tree");
|
|
154 |
|
|
155 |
if (retval == 0) {
|
|
156 |
--- openrc-0.12.4+20131230.orig/src/test/units/early_loop_detector
|
|
157 |
+++ openrc-0.12.4+20131230/src/test/units/early_loop_detector
|
|
158 |
@@ -93,7 +93,7 @@ int main() {
|
|
159 |
while (dep_num < dep_count) {
|
|
160 |
dep_num++;
|
|
161 |
if (unap_matrix[UNAPM_MIXED_EXPANDED][service_id][dep_num] == service_id) {
|
|
162 |
- loopfound = rc_deptree_solve_loop(unap_matrix, service_id, NULL, dep_num);
|
|
163 |
+ loopfound = rc_deptree_solve_loop(unap_matrix, service_id, NULL, dep_num, 0);
|
|
164 |
loopsolver_counter++;
|
|
165 |
break;
|
|
166 |
}
|