Skip to content

Commit 51befb4

Browse files
committed
Allow conflicting services to start when conflict is resolved
These changes add a new svc_block_t type: SVC_BLOCK_CONFLICT so a user can more clearly see why a run/task/service has not been started by Finit. The reason for the block is by default logged, which can be escaped by using the `nowarn` flag. Also, when the conflict is resolved, allow the service to start. With these changes, the system/hotplug.conf should work better and cause less questions about "strange" log messages. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 parent 7850378 commit 51befb4

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

src/api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static int stop(svc_t *svc, void *user_data)
6565
service_timeout_cancel(svc);
6666
svc_stop(svc);
6767
service_step(svc);
68+
service_step_all(SVC_TYPE_ANY);
6869

6970
return 0;
7071
}
@@ -77,6 +78,7 @@ static int start(svc_t *svc, void *user_data)
7778
service_timeout_cancel(svc);
7879
svc_start(svc);
7980
service_step(svc);
81+
service_step_all(SVC_TYPE_ANY);
8082

8183
return 0;
8284
}

src/service.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -610,13 +610,6 @@ static int service_start(svc_t *svc)
610610
}
611611
}
612612

613-
/* Don't start if it conflicts with something else already started */
614-
if (svc_conflicts(svc)) {
615-
logit(LOG_INFO, "Not starting %s, conflicts with %s",
616-
svc_ident(svc, NULL, 0), svc->conflict);
617-
return 1;
618-
}
619-
620613
compose_cmdline(svc, cmdline, sizeof(cmdline));
621614
if (svc_is_sysv(svc))
622615
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline);
@@ -1737,6 +1730,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
17371730
else
17381731
memset(svc->ifstmt, 0, sizeof(svc->ifstmt));
17391732
svc->manual = manual;
1733+
svc->nowarn = nowarn;
17401734
svc->respawn = respawn;
17411735
svc->forking = forking;
17421736
svc->restart_max = restart_max;
@@ -2276,6 +2270,15 @@ int service_step(svc_t *svc)
22762270
case SVC_HALTED_STATE:
22772271
if (enabled)
22782272
svc_set_state(svc, SVC_WAITING_STATE);
2273+
else {
2274+
if (svc_is_conflict(svc)) {
2275+
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
2276+
"%s in conflict with %s, checking again ...",
2277+
svc_ident(svc, NULL, 0), svc->conflict);
2278+
if (!svc_conflicts(svc))
2279+
svc_unblock(svc);
2280+
}
2281+
}
22792282
break;
22802283

22812284
case SVC_DONE_STATE:
@@ -2342,6 +2345,16 @@ int service_step(svc_t *svc)
23422345
if (sm_is_in_teardown(&sm))
23432346
break;
23442347

2348+
/* Don't start if it conflicts with something else already started */
2349+
if (svc_conflicts(svc)) {
2350+
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
2351+
"Not starting %s, conflicts with %s",
2352+
svc_ident(svc, NULL, 0), svc->conflict);
2353+
svc_conflict(svc);
2354+
svc_set_state(svc, SVC_HALTED_STATE);
2355+
break;
2356+
}
2357+
23452358
if (svc_has_pre(svc)) {
23462359
svc_set_state(svc, SVC_SETUP_STATE);
23472360
service_pre_script(svc);

src/svc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ typedef enum {
7474
SVC_BLOCK_USER,
7575
SVC_BLOCK_BUSY,
7676
SVC_BLOCK_RESTARTING,
77+
SVC_BLOCK_CONFLICT,
7778
} svc_block_t;
7879

7980
typedef enum {
@@ -125,6 +126,7 @@ typedef struct svc {
125126
svc_type_t type; /* Service, run, task, ... */
126127
char protect; /* Services like dbus-daemon & udev by Finit */
127128
char manual; /* run/task that require `initctl start foo` */
129+
char nowarn; /* Skip or log warning if cmd missing or conflicts */
128130
const int dirty; /* 0: unmodified, 1: modified */
129131
const int removed;
130132
int starting; /* ... waiting for pidfile to be re-asserted */
@@ -270,6 +272,7 @@ static inline int svc_is_busy (svc_t *svc) { return svc && svc->block == SV
270272
static inline int svc_is_missing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_MISSING; }
271273
static inline int svc_is_crashing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_CRASHING; }
272274
static inline int svc_is_restart (svc_t *svc) { return svc && svc->block == SVC_BLOCK_RESTARTING; }
275+
static inline int svc_is_conflict (svc_t *svc) { return svc && svc->block == SVC_BLOCK_CONFLICT; }
273276

274277
static inline void svc_unblock (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_NONE; }
275278
#define svc_start(svc) svc_unblock(svc)
@@ -278,6 +281,7 @@ static inline void svc_busy (svc_t *svc) { if (svc) svc->block = SVC_BLOC
278281
static inline void svc_missing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_MISSING; }
279282
static inline void svc_restarting (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_RESTARTING; }
280283
static inline void svc_crashing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CRASHING; }
284+
static inline void svc_conflict (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CONFLICT; }
281285

282286
/* Has condition in configuration and cond is allowed? */
283287
static inline int svc_has_cond(svc_t *svc)
@@ -350,6 +354,9 @@ static inline char *svc_status(svc_t *svc)
350354

351355
case SVC_BLOCK_RESTARTING:
352356
return "restart";
357+
case SVC_BLOCK_CONFLICT:
358+
return "conflict";
359+
353360
}
354361
return "unknown";
355362

0 commit comments

Comments
 (0)