commit:     33d3f33b3ca7dd2ce616b8182d588d0743c2f124
Author:     Ian Stakenvicius <axs <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 26 19:20:58 2015 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Thu Nov 12 18:32:45 2015 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=33d3f33b

Implement "want" dependency

The want dependency is similar to the use dependency. If a service
script, for example called service1, adds "want service2" to its depend
function, OpenRC will attempt to start service2, if it exists on the
system,  when service1 is started.

However, service1 will start regardless of the status of
service2.

X-Gentoo-Bug: 406021
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=406021

 man/openrc-run.8         |  2 ++
 sh/gendepends.sh.in      |  3 +++
 sh/openrc-run.sh.in      |  3 +++
 src/librc/librc-depend.c |  8 +++++-
 src/rc/openrc-run.c      | 66 ++++++++++++++++++++++++++++++------------------
 src/rc/rc-status.c       |  3 ++-
 src/rc/rc.c              | 34 +++++++++++++------------
 7 files changed, 77 insertions(+), 42 deletions(-)

diff --git a/man/openrc-run.8 b/man/openrc-run.8
index 4637fd0..12c1919 100644
--- a/man/openrc-run.8
+++ b/man/openrc-run.8
@@ -175,6 +175,8 @@ will refuse to stop until any services that need it have 
stopped.
 .It Ic use
 The service will attempt to start any services we use that have been added
 to the runlevel.
+.It Ic want
+The service will attempt to start any services we want.
 .It Ic after
 The service will start after these services and stop before these services.
 .It Ic before

diff --git a/sh/gendepends.sh.in b/sh/gendepends.sh.in
index dfe7444..36caeb7 100644
--- a/sh/gendepends.sh.in
+++ b/sh/gendepends.sh.in
@@ -16,6 +16,9 @@ need() {
 use() {
        [ -n "$*" ] && echo "$RC_SVCNAME iuse $*" >&3
 }
+want() {
+       [ -n "$*" ] && echo "$RC_SVCNAME iwant $*" >&3
+}
 before() {
        [ -n "$*" ] && echo "$RC_SVCNAME ibefore $*" >&3
 }

diff --git a/sh/openrc-run.sh.in b/sh/openrc-run.sh.in
index 749af2c..c169204 100644
--- a/sh/openrc-run.sh.in
+++ b/sh/openrc-run.sh.in
@@ -66,6 +66,9 @@ need() {
 use() {
        [ -n "$*" ] && echo "use $*"
 }
+want() {
+       [ -n "$*" ] && echo "want $*"
+}
 before() {
        [ -n "$*" ] && echo "before $*"
 }

diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index d7a8ae1..c9c06ad 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -192,7 +192,9 @@ valid_service(const char *runlevel, const char *service, 
const char *type)
 
        if (!runlevel ||
            strcmp(type, "ineed") == 0 ||
-           strcmp(type, "needsme") == 0)
+           strcmp(type, "needsme") == 0  ||
+           strcmp(type, "iwant") == 0 ||
+           strcmp(type, "wantsme") == 0)
                return true;
 
        if (rc_service_in_runlevel(service, runlevel))
@@ -543,6 +545,7 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char 
*runlevel, int options)
        types = rc_stringlist_new();
        rc_stringlist_add(types, "ineed");
        rc_stringlist_add(types, "iuse");
+       rc_stringlist_add(types, "iwant");
        rc_stringlist_add(types, "iafter");
        services = rc_deptree_depends(deptree, types, list, runlevel,
                                      RC_DEP_STRICT | RC_DEP_TRACE | options);
@@ -648,6 +651,7 @@ typedef struct deppair
 static const DEPPAIR deppairs[] = {
        { "ineed",      "needsme" },
        { "iuse",       "usesme" },
+       { "iwant",      "wantsme" },
        { "iafter",     "ibefore" },
        { "ibefore",    "iafter" },
        { "iprovide",   "providedby" },
@@ -844,6 +848,7 @@ rc_deptree_update(void)
                        /* If we're after something, remove us from the before 
list */
                        if (strcmp(type, "iafter") == 0 ||
                            strcmp(type, "ineed") == 0 ||
+                           strcmp(type, "iwant") == 0 ||
                            strcmp(type, "iuse") == 0) {
                                if ((dt = get_deptype(depinfo, "ibefore")))
                                        rc_stringlist_delete(dt->services, 
depend);
@@ -957,6 +962,7 @@ rc_deptree_update(void)
        /* Phase 5 - Remove broken before directives */
        types = rc_stringlist_new();
        rc_stringlist_add(types, "ineed");
+       rc_stringlist_add(types, "iwant");
        rc_stringlist_add(types, "iuse");
        rc_stringlist_add(types, "iafter");
        TAILQ_FOREACH(depinfo, deptree, entries) {

diff --git a/src/rc/openrc-run.c b/src/rc/openrc-run.c
index 2af95ec..ccdaddf 100644
--- a/src/rc/openrc-run.c
+++ b/src/rc/openrc-run.c
@@ -78,19 +78,23 @@ static const char *applet;
 static char *service, *runlevel, *ibsave, *prefix;
 static RC_DEPTREE *deptree;
 static RC_STRINGLIST *applet_list, *services, *tmplist;
-static RC_STRINGLIST *restart_services, *need_services, *use_services;
+static RC_STRINGLIST *restart_services;
+static RC_STRINGLIST *need_services;
+static RC_STRINGLIST *use_services;
+static RC_STRINGLIST *want_services;
 static RC_HOOK hook_out;
 static int exclusive_fd = -1, master_tty = -1;
 static bool sighup, in_background, deps, dry_run;
 static pid_t service_pid;
 static int signal_pipe[2] = { -1, -1 };
 
-static RC_STRINGLIST *deptypes_b;
-static RC_STRINGLIST *deptypes_n;
-static RC_STRINGLIST *deptypes_nu;
-static RC_STRINGLIST *deptypes_nua;
-static RC_STRINGLIST *deptypes_m;
-static RC_STRINGLIST *deptypes_mua;
+static RC_STRINGLIST *deptypes_b;      /* broken deps */
+static RC_STRINGLIST *deptypes_n;      /* needed deps */
+static RC_STRINGLIST *deptypes_nw;     /* need+want deps */
+static RC_STRINGLIST *deptypes_nwu;    /* need+want+use deps */
+static RC_STRINGLIST *deptypes_nwua;   /* need+want+use+after deps */
+static RC_STRINGLIST *deptypes_m;      /* needed deps for stopping */
+static RC_STRINGLIST *deptypes_mwua;   /* need+want+use+after deps for 
stopping */
 
 static void
 handle_signal(int sig)
@@ -237,14 +241,16 @@ cleanup(void)
 #ifdef DEBUG_MEMORY
        rc_stringlist_free(deptypes_b);
        rc_stringlist_free(deptypes_n);
-       rc_stringlist_free(deptypes_nu);
-       rc_stringlist_free(deptypes_nua);
+       rc_stringlist_free(deptypes_nw);
+       rc_stringlist_free(deptypes_nwu);
+       rc_stringlist_free(deptypes_nwua);
        rc_stringlist_free(deptypes_m);
-       rc_stringlist_free(deptypes_mua);
+       rc_stringlist_free(deptypes_mwua);
        rc_deptree_free(deptree);
        rc_stringlist_free(restart_services);
        rc_stringlist_free(need_services);
        rc_stringlist_free(use_services);
+       rc_stringlist_free(want_services);
        rc_stringlist_free(services);
        rc_stringlist_free(applet_list);
        rc_stringlist_free(tmplist);
@@ -530,22 +536,29 @@ setup_deptypes(void)
        deptypes_n = rc_stringlist_new();
        rc_stringlist_add(deptypes_n, "ineed");
 
-       deptypes_nu = rc_stringlist_new();
-       rc_stringlist_add(deptypes_nu, "ineed");
-       rc_stringlist_add(deptypes_nu, "iuse");
+       deptypes_nw = rc_stringlist_new();
+       rc_stringlist_add(deptypes_nw, "ineed");
+       rc_stringlist_add(deptypes_nw, "iwant");
 
-       deptypes_nua = rc_stringlist_new();
-       rc_stringlist_add(deptypes_nua, "ineed");
-       rc_stringlist_add(deptypes_nua, "iuse");
-       rc_stringlist_add(deptypes_nua, "iafter");
+       deptypes_nwu = rc_stringlist_new();
+       rc_stringlist_add(deptypes_nwu, "ineed");
+       rc_stringlist_add(deptypes_nwu, "iwant");
+       rc_stringlist_add(deptypes_nwu, "iuse");
+
+       deptypes_nwua = rc_stringlist_new();
+       rc_stringlist_add(deptypes_nwua, "ineed");
+       rc_stringlist_add(deptypes_nwua, "iwant");
+       rc_stringlist_add(deptypes_nwua, "iuse");
+       rc_stringlist_add(deptypes_nwua, "iafter");
 
        deptypes_m = rc_stringlist_new();
        rc_stringlist_add(deptypes_m, "needsme");
 
-       deptypes_mua = rc_stringlist_new();
-       rc_stringlist_add(deptypes_mua, "needsme");
-       rc_stringlist_add(deptypes_mua, "usesme");
-       rc_stringlist_add(deptypes_mua, "beforeme");
+       deptypes_mwua = rc_stringlist_new();
+       rc_stringlist_add(deptypes_mwua, "needsme");
+       rc_stringlist_add(deptypes_mwua, "wantsme");
+       rc_stringlist_add(deptypes_mwua, "usesme");
+       rc_stringlist_add(deptypes_mwua, "beforeme");
 }
 
 static void
@@ -631,7 +644,9 @@ svc_start_deps(void)
 
        need_services = rc_deptree_depends(deptree, deptypes_n,
            applet_list, runlevel, depoptions);
-       use_services = rc_deptree_depends(deptree, deptypes_nu,
+       want_services = rc_deptree_depends(deptree, deptypes_nw,
+           applet_list, runlevel, depoptions);
+       use_services = rc_deptree_depends(deptree, deptypes_nwu,
            applet_list, runlevel, depoptions);
 
        if (!rc_runlevel_starting()) {
@@ -659,7 +674,7 @@ svc_start_deps(void)
                return;
 
        /* Now wait for them to start */
-       services = rc_deptree_depends(deptree, deptypes_nua, applet_list,
+       services = rc_deptree_depends(deptree, deptypes_nwua, applet_list,
            runlevel, depoptions);
        /* We use tmplist to hold our scheduled by list */
        tmplist = rc_stringlist_new();
@@ -674,6 +689,7 @@ svc_start_deps(void)
                    state & RC_SERVICE_WASINACTIVE)
                {
                        if (!rc_stringlist_find(need_services, svc->value) &&
+                           !rc_stringlist_find(want_services, svc->value) &&
                            !rc_stringlist_find(use_services, svc->value))
                                continue;
                }
@@ -927,7 +943,7 @@ svc_stop_deps(RC_SERVICE state)
 
        /* We now wait for other services that may use us and are
         * stopping. This is important when a runlevel stops */
-       services = rc_deptree_depends(deptree, deptypes_mua, applet_list,
+       services = rc_deptree_depends(deptree, deptypes_mwua, applet_list,
            runlevel, depoptions);
        TAILQ_FOREACH(svc, services, entries) {
                if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
@@ -1298,8 +1314,10 @@ openrc_run(int argc, char **argv)
                        prefix = save;
                } else if (strcmp(optarg, "ineed") == 0 ||
                    strcmp(optarg, "iuse") == 0 ||
+                   strcmp(optarg, "iwant") == 0 ||
                    strcmp(optarg, "needsme") == 0 ||
                    strcmp(optarg, "usesme") == 0 ||
+                   strcmp(optarg, "wantsme") == 0 ||
                    strcmp(optarg, "iafter") == 0 ||
                    strcmp(optarg, "ibefore") == 0 ||
                    strcmp(optarg, "iprovide") == 0)

diff --git a/src/rc/rc-status.c b/src/rc/rc-status.c
index 1f67b75..968d32b 100644
--- a/src/rc/rc-status.c
+++ b/src/rc/rc-status.c
@@ -343,6 +343,7 @@ rc_status(int argc, char **argv)
                }
                needsme = rc_stringlist_new();
                rc_stringlist_add(needsme, "needsme");
+               rc_stringlist_add(needsme, "wantsme");
                nservices = rc_stringlist_new();
                alist = rc_stringlist_new();
                l = rc_stringlist_add(alist, "");
@@ -365,7 +366,7 @@ rc_status(int argc, char **argv)
                 * be added to the list
                 */
                unsetenv("RC_SVCNAME");
-               print_level("Dynamic", "needed");
+               print_level("Dynamic", "needed/wanted");
                print_services(NULL, nservices);
                print_level("Dynamic", "manual");
                print_services(NULL, services);

diff --git a/src/rc/rc.c b/src/rc/rc.c
index dd35482..d96aa45 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -155,8 +155,8 @@ cleanup(void)
        rc_stringlist_free(hotplugged_services);
        rc_stringlist_free(stop_services);
        rc_stringlist_free(start_services);
-       rc_stringlist_free(types_n);
-       rc_stringlist_free(types_nua);
+       rc_stringlist_free(types_nw);
+       rc_stringlist_free(types_nwua);
        rc_deptree_free(deptree);
        free(runlevel);
 #endif
@@ -519,7 +519,7 @@ runlevel_config(const char *service, const char *level)
 }
 
 static void
-do_stop_services(RC_STRINGLIST *types_n, RC_STRINGLIST *start_services,
+do_stop_services(RC_STRINGLIST *types_nw, RC_STRINGLIST *start_services,
                                 const RC_STRINGLIST *stop_services, const 
RC_DEPTREE *deptree,
                                 const char *newlevel, bool parallel, bool 
going_down)
 {
@@ -530,9 +530,10 @@ do_stop_services(RC_STRINGLIST *types_n, RC_STRINGLIST 
*start_services,
        RC_STRINGLIST *nostop;
        bool crashed, nstop;
 
-       if (!types_n) {
-               types_n = rc_stringlist_new();
-               rc_stringlist_add(types_n, "needsme");
+       if (!types_nw) {
+               types_nw = rc_stringlist_new();
+               rc_stringlist_add(types_nw, "needsme");
+               rc_stringlist_add(types_nw, "wantsme");
        }
 
        crashed = rc_conf_yesno("rc_crashed_stop");
@@ -591,7 +592,7 @@ do_stop_services(RC_STRINGLIST *types_n, RC_STRINGLIST 
*start_services,
                if (!svc1) {
                        tmplist = rc_stringlist_new();
                        rc_stringlist_add(tmplist, service->value);
-                       deporder = rc_deptree_depends(deptree, types_n,
+                       deporder = rc_deptree_depends(deptree, types_nw,
                            tmplist, newlevel ? newlevel : runlevel,
                            RC_DEP_STRICT | RC_DEP_TRACE);
                        rc_stringlist_free(tmplist);
@@ -754,8 +755,8 @@ main(int argc, char **argv)
        static RC_STRINGLIST *hotplugged_services;
        static RC_STRINGLIST *stop_services;
        static RC_STRINGLIST *start_services;
-       static RC_STRINGLIST *types_n;
-       static RC_STRINGLIST *types_nua;
+       static RC_STRINGLIST *types_nw;
+       static RC_STRINGLIST *types_nwua;
        static RC_DEPTREE *deptree;
        RC_STRINGLIST *deporder = NULL;
        RC_STRINGLIST *tmplist;
@@ -996,13 +997,14 @@ main(int argc, char **argv)
        if (stop_services)
                rc_stringlist_sort(&stop_services);
 
-       types_nua = rc_stringlist_new();
-       rc_stringlist_add(types_nua, "ineed");
-       rc_stringlist_add(types_nua, "iuse");
-       rc_stringlist_add(types_nua, "iafter");
+       types_nwua = rc_stringlist_new();
+       rc_stringlist_add(types_nwua, "ineed");
+       rc_stringlist_add(types_nwua, "iwant");
+       rc_stringlist_add(types_nwua, "iuse");
+       rc_stringlist_add(types_nwua, "iafter");
 
        if (stop_services) {
-               tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
+               tmplist = rc_deptree_depends(deptree, types_nwua, stop_services,
                    runlevel, depoptions | RC_DEP_STOP);
                rc_stringlist_free(stop_services);
                stop_services = tmplist;
@@ -1047,7 +1049,7 @@ main(int argc, char **argv)
 
        /* Now stop the services that shouldn't be running */
        if (stop_services && !nostop)
-               do_stop_services(types_n, start_services, stop_services, 
deptree, newlevel, parallel, going_down);
+               do_stop_services(types_nw, start_services, stop_services, 
deptree, newlevel, parallel, going_down);
 
        /* Wait for our services to finish */
        wait_for_services();
@@ -1109,7 +1111,7 @@ main(int argc, char **argv)
 
                        /* Start those services. */
                        rc_stringlist_sort(&run_services);
-                       deporder = rc_deptree_depends(deptree, types_nua, 
run_services, rlevel->value, depoptions | RC_DEP_START);
+                       deporder = rc_deptree_depends(deptree, types_nwua, 
run_services, rlevel->value, depoptions | RC_DEP_START);
                        rc_stringlist_free(run_services);
                        run_services = deporder;
                        do_start_services(run_services, parallel);

Reply via email to