Welcome to little lamb

Code » anopa » commit e4d3871

start/stop: Add --verbose (LOADFAIL->AUTOLOAD)

author Olivier Brunel
2015-11-07 12:58:18 UTC
committer Olivier Brunel
2015-11-12 17:04:19 UTC
parent 60c12676a4e21f49bddff8f03167efb6315de6d2

start/stop: Add --verbose (LOADFAIL->AUTOLOAD)

Rename AA_LOADFAIL_* to AA_AUTOLOAD_* and aa_loadfail_cb to aa_autoload_cb
and trigger the callback whenever a service is auto-added, not only on
error (The err argument will be zero on success).

Also trigger it on MODE_STOP, though there as usual things are "reversed":
si is of the service that is needed, and name of the main service.
IOW if foo needs bar, in MODE_STOP it will be bar's si and name="foo"
since (to stop) bar needs (to first stop) foo

This allows to add --verbose in both aa-{start,stop}

doc/aa-start.pod +10 -1
doc/aa-stop.pod +13 -1
src/anopa/aa-start.c +22 -4
src/anopa/aa-stop.c +21 -2
src/include/anopa/service.h +6 -6
src/libanopa/service.c +2 -2
src/libanopa/service_internal.h +1 -1
src/libanopa/service_start.c +21 -18
src/libanopa/service_stop.c +3 -0

diff --git a/doc/aa-start.pod b/doc/aa-start.pod
index af50dc3..03cef70 100644
--- a/doc/aa-start.pod
+++ b/doc/aa-start.pod
@@ -5,7 +5,7 @@ aa-start - Start services
 =head1 SYNOPSIS
 
 B<aa-start> [B<-D>] [B<-r> I<repodir>] [B<-l> I<listdir>] [B<-W>]
-[B<-t> I<timeout>] [B<-n>] [I<service...>]
+[B<-t> I<timeout>] [B<-n>] [B<-v>] [I<service...>]
 
 =head1 OPTIONS
 
@@ -51,6 +51,15 @@ Timeout can also be set in service in a file I<timeout> in its servicedir.
 
 Show version information and exit.
 
+=item B<-v, --verbose>
+
+Print auto-added dependencies (from "needs" and "wants"). Note that due to
+recursion they'll be printed in reverse order, e.g. "B needs C" then "A needs B"
+when starting A.
+
+This will be printed on stdout unless B<--dry-list> was used, then it goes to
+stderr.
+
 =item B<-W, --no-wants>
 
 Don't auto-start any services listed under directory I<wants> of a service
diff --git a/doc/aa-stop.pod b/doc/aa-stop.pod
index 90f726f..ef0b901 100644
--- a/doc/aa-stop.pod
+++ b/doc/aa-stop.pod
@@ -5,7 +5,7 @@ aa-stop - Stop services
 =head1 SYNOPSIS
 
 B<aa-stop> [B<-D>] [B<-r> I<repodir>] [B<-l> I<listdir>] [B<-a>]
-[B<-k> I<service>] [B<-t> I<timeout>] [B<-n>] [I<service...>]
+[B<-k> I<service>] [B<-t> I<timeout>] [B<-n>] [B<-v>] [I<service...>]
 
 =head1 OPTIONS
 
@@ -67,6 +67,18 @@ Timeout can also be set in service in a file I<timeout> in its servicedir.
 
 Show version information and exit.
 
+=item B<-v, --verbose>
+
+Print auto-added dependencies (from "needs").  Note that dependencies are
+"reversed" here, i.e. if foo needs bar, B<aa-stop>(1) will print "bar needs foo"
+as to indicate that stopping bar needs to (first) stop foo.
+
+Also note that this will always print dependencies for all started services,
+whether or not they'll apply to the requested operation.
+
+This will be printed on stdout unless B<--dry-list> was used, then it goes to
+stderr.
+
 =back
 
 =head1 DESCRIPTION
diff --git a/src/anopa/aa-start.c b/src/anopa/aa-start.c
index 611d506..990bda6 100644
--- a/src/anopa/aa-start.c
+++ b/src/anopa/aa-start.c
@@ -66,6 +66,7 @@ static genalloc ga_unknown = GENALLOC_ZERO;
 static genalloc ga_io = GENALLOC_ZERO;
 static aa_mode mode = AA_MODE_START;
 static int no_wants = 0;
+static int verbose = 0;
 static int rc = 0;
 
 void
@@ -97,9 +98,20 @@ check_essential (int si)
 }
 
 static void
-load_fail_cb (int si, aa_lf lf, const char *name, int err)
+autoload_cb (int si, aa_al al, const char *name, int err)
 {
-    if (lf == AA_LOADFAIL_WANTS)
+    if (verbose)
+    {
+        int aa = (mode & AA_MODE_IS_DRY) ? AA_ERR : AA_OUT;
+
+        aa_bs_noflush (aa, "auto-add: ");
+        aa_bs_noflush (aa, aa_service_name (aa_service (si)));
+        aa_bs_noflush (aa, (al == AA_AUTOLOAD_NEEDS) ? " needs " : " wants ");
+        aa_bs_noflush (aa, name);
+        aa_bs_flush (aa, "\n");
+    }
+
+    if (al == AA_AUTOLOAD_WANTS && err > 0)
     {
         put_warn (aa_service_name (aa_service (si)), "Skipping wanted service ", 0);
         add_warn (name);
@@ -121,7 +133,7 @@ add_service (const char *name, void *data)
     if (type < 0)
         r = type;
     else
-        r = aa_mark_service (mode, si, type == AA_SERVICE_FROM_MAIN, no_wants, load_fail_cb);
+        r = aa_mark_service (mode, si, type == AA_SERVICE_FROM_MAIN, no_wants, autoload_cb);
     if (r < 0)
     {
         if (r == -ERR_UNKNOWN)
@@ -218,6 +230,7 @@ dieusage (int rc)
             " -W, --no-wants                Don't auto-start services from 'wants'\n"
             " -t, --timeout SECS            Use SECS seconds as default timeout\n"
             " -n, --dry-list                Only show service names (don't start anything)\n"
+            " -v, --verbose                 Print auto-added dependencies\n"
             " -h, --help                    Show this help screen and exit\n"
             " -V, --version                 Show version information and exit\n"
             );
@@ -248,12 +261,13 @@ main (int argc, char * const argv[])
             { "repodir",            required_argument,  NULL,   'r' },
             { "timeout",            required_argument,  NULL,   't' },
             { "version",            no_argument,        NULL,   'V' },
+            { "verbose",            no_argument,        NULL,   'v' },
             { "no-wants",           no_argument,        NULL,   'W' },
             { NULL, 0, 0, 0 }
         };
         int c;
 
-        c = getopt_long (argc, argv, "Dhl:nr:t:VW", longopts, NULL);
+        c = getopt_long (argc, argv, "Dhl:nr:t:VvW", longopts, NULL);
         if (c == -1)
             break;
         switch (c)
@@ -290,6 +304,10 @@ main (int argc, char * const argv[])
             case 'V':
                 aa_die_version ();
 
+            case 'v':
+                verbose = 1;
+                break;
+
             case 'W':
                 no_wants = 1;
                 break;
diff --git a/src/anopa/aa-stop.c b/src/anopa/aa-stop.c
index 330fef9..4f2da5c 100644
--- a/src/anopa/aa-stop.c
+++ b/src/anopa/aa-stop.c
@@ -55,6 +55,7 @@ static genalloc ga_unknown = GENALLOC_ZERO;
 static genalloc ga_depend = GENALLOC_ZERO;
 static genalloc ga_io = GENALLOC_ZERO;
 static aa_mode mode = AA_MODE_STOP;
+static int verbose = 0;
 static int rc = 0;
 static const char *skip = NULL;
 
@@ -64,6 +65,18 @@ check_essential (int si)
     /* required by start-stop.c; only used by aa-start.c */
 }
 
+static void
+autoload_cb (int si, aa_al al, const char *name, int err)
+{
+    int aa = (mode & AA_MODE_IS_DRY) ? AA_ERR : AA_OUT;
+
+    aa_bs_noflush (aa, "auto-add: ");
+    aa_bs_noflush (aa, aa_service_name (aa_service (si)));
+    aa_bs_noflush (aa, " needs ");
+    aa_bs_noflush (aa, name);
+    aa_bs_flush (aa, "\n");
+}
+
 static int
 preload_service (const char *name)
 {
@@ -78,7 +91,7 @@ preload_service (const char *name)
     if (type < 0)
         r = type;
     else
-        r = aa_ensure_service_loaded (si, AA_MODE_STOP, 0, NULL);
+        r = aa_ensure_service_loaded (si, AA_MODE_STOP, 0, (verbose) ? autoload_cb : NULL);
     if (r < 0)
     {
         /* there shouldn't be much errors possible here... basically only ERR_IO
@@ -258,6 +271,7 @@ dieusage (int rc)
             " -t, --timeout SECS            Use SECS seconds as default timeout\n"
             " -a, --all                     Stop all running services\n"
             " -n, --dry-list                Only show service names (don't stop anything)\n"
+            " -v, --verbose                 Print auto-added dependencies\n"
             " -h, --help                    Show this help screen and exit\n"
             " -V, --version                 Show version information and exit\n"
             );
@@ -290,11 +304,12 @@ main (int argc, char * const argv[])
             { "repodir",            required_argument,  NULL,   'r' },
             { "timeout",            required_argument,  NULL,   't' },
             { "version",            no_argument,        NULL,   'V' },
+            { "verbose",            no_argument,        NULL,   'v' },
             { NULL, 0, 0, 0 }
         };
         int c;
 
-        c = getopt_long (argc, argv, "aDhk:l:nr:t:V", longopts, NULL);
+        c = getopt_long (argc, argv, "aDhk:l:nr:t:Vv", longopts, NULL);
         if (c == -1)
             break;
         switch (c)
@@ -336,6 +351,10 @@ main (int argc, char * const argv[])
             case 'V':
                 aa_die_version ();
 
+            case 'v':
+                verbose = 1;
+                break;
+
             default:
                 dieusage (1);
         }
diff --git a/src/include/anopa/service.h b/src/include/anopa/service.h
index ffd34ff..a15e2ca 100644
--- a/src/include/anopa/service.h
+++ b/src/include/anopa/service.h
@@ -62,9 +62,9 @@ typedef enum
 
 typedef enum
 {
-    AA_LOADFAIL_NEEDS = 0,
-    AA_LOADFAIL_WANTS,
-} aa_lf;
+    AA_AUTOLOAD_NEEDS = 0,
+    AA_AUTOLOAD_WANTS,
+} aa_al;
 
 typedef enum
 {
@@ -99,7 +99,7 @@ typedef struct
 } aa_service;
 
 typedef void (*aa_close_fd_fn) (int fd);
-typedef void (*aa_load_fail_cb) (int si, aa_lf lf, const char *name, int err);
+typedef void (*aa_autoload_cb) (int si, aa_al al, const char *name, int err);
 typedef void (*aa_prepare_cb) (int si, int si_next, int is_needs, int first);
 typedef void (*aa_scan_cb) (int si, int sni);
 typedef void (*aa_exec_cb) (int si, aa_evt evt, pid_t pid);
@@ -108,9 +108,9 @@ extern void aa_free_services (aa_close_fd_fn close_fd_fn);
 extern int  aa_add_name (const char *name);
 extern int  aa_get_service (const char *name, int *si, int new_in_main);
 extern void aa_unmark_service (int si);
-extern int  aa_mark_service (aa_mode mode, int si, int in_main, int no_wants, aa_load_fail_cb lf_cb);
+extern int  aa_mark_service (aa_mode mode, int si, int in_main, int no_wants, aa_autoload_cb al_cb);
 extern int  aa_preload_service (int si);
-extern int  aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_load_fail_cb lf_cb);
+extern int  aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_autoload_cb al_cb);
 extern int  aa_prepare_mainlist (aa_prepare_cb prepare_cb, aa_exec_cb exec_cb);
 extern void aa_scan_mainlist (aa_scan_cb scan_cb, aa_mode mode);
 extern int  aa_exec_service (int si, aa_mode mode);
diff --git a/src/libanopa/service.c b/src/libanopa/service.c
index 34e9c8a..eda7af5 100644
--- a/src/libanopa/service.c
+++ b/src/libanopa/service.c
@@ -212,14 +212,14 @@ aa_preload_service (int si)
 }
 
 int
-aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_load_fail_cb lf_cb)
+aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_autoload_cb al_cb)
 {
     stralloc sa = STRALLOC_ZERO;
     struct it_data it_data = {
         .mode = mode,
         .si = si,
         .no_wants = no_wants,
-        .lf_cb = lf_cb
+        .al_cb = al_cb
     };
     int r;
 
diff --git a/src/libanopa/service_internal.h b/src/libanopa/service_internal.h
index a2d5ab6..6daee72 100644
--- a/src/libanopa/service_internal.h
+++ b/src/libanopa/service_internal.h
@@ -34,7 +34,7 @@ struct it_data
     aa_mode mode;
     int si;
     int no_wants;
-    aa_load_fail_cb lf_cb;
+    aa_autoload_cb al_cb;
 };
 
 extern int _is_valid_service_name (const char *name, int len);
diff --git a/src/libanopa/service_start.c b/src/libanopa/service_start.c
index 7a558d9..56e2151 100644
--- a/src/libanopa/service_start.c
+++ b/src/libanopa/service_start.c
@@ -47,11 +47,11 @@ aa_unmark_service (int si)
 }
 
 int
-aa_mark_service (aa_mode mode, int si, int in_main, int no_wants, aa_load_fail_cb lf_cb)
+aa_mark_service (aa_mode mode, int si, int in_main, int no_wants, aa_autoload_cb al_cb)
 {
     int r;
 
-    r = aa_ensure_service_loaded (si, mode, no_wants, lf_cb);
+    r = aa_ensure_service_loaded (si, mode, no_wants, al_cb);
     if (r < 0)
     {
         if (in_main)
@@ -85,7 +85,7 @@ _name_start_needs (const char *name, struct it_data *it_data)
         r = type;
     else
         r = aa_mark_service (it_data->mode, sni, type == AA_SERVICE_FROM_MAIN,
-                it_data->no_wants, it_data->lf_cb);
+                it_data->no_wants, it_data->al_cb);
     if (r == -ERR_ALREADY_UP)
         return 0;
     else if (r < 0)
@@ -112,15 +112,19 @@ _name_start_needs (const char *name, struct it_data *it_data)
                 aa_strerr_warnu2sys ("write service status file for ", aa_service_name (s));
         }
 
-        if (it_data->lf_cb)
-            it_data->lf_cb (it_data->si, AA_LOADFAIL_NEEDS, name, -r);
+        r = -ERR_DEPEND;
+    }
 
-        return -ERR_DEPEND;
+    if (r == 0)
+    {
+        add_to_list (&aa_service (it_data->si)->needs, sni, 0);
+        add_to_list (&aa_service (it_data->si)->after, sni, 1);
     }
 
-    add_to_list (&aa_service (it_data->si)->needs, sni, 0);
-    add_to_list (&aa_service (it_data->si)->after, sni, 1);
-    return 0;
+    if (it_data->al_cb)
+        it_data->al_cb (it_data->si, AA_AUTOLOAD_NEEDS, name, -r);
+
+    return r;
 }
 
 int
@@ -143,18 +147,17 @@ _it_start_wants (direntry *d, void *data)
         r = type;
     else
         r = aa_mark_service (it_data->mode, swi, type == AA_SERVICE_FROM_MAIN,
-                it_data->no_wants, it_data->lf_cb);
+                it_data->no_wants, it_data->al_cb);
     if (r == -ERR_ALREADY_UP)
         return 0;
-    if (r < 0)
-    {
-        if (it_data->lf_cb)
-            it_data->lf_cb (it_data->si, AA_LOADFAIL_WANTS, d->d_name, -r);
-        return r;
-    }
 
-    add_to_list (&aa_service (it_data->si)->wants, swi, 0);
-    return 0;
+    if (r == 0)
+        add_to_list (&aa_service (it_data->si)->wants, swi, 0);
+
+    if (it_data->al_cb)
+        it_data->al_cb (it_data->si, AA_AUTOLOAD_WANTS, d->d_name, -r);
+
+    return r;
 }
 
 int
diff --git a/src/libanopa/service_stop.c b/src/libanopa/service_stop.c
index 84e9f52..d7d21c4 100644
--- a/src/libanopa/service_stop.c
+++ b/src/libanopa/service_stop.c
@@ -36,6 +36,9 @@ _name_stop_needs (const char *name, struct it_data *it_data)
     if (r < 0)
         return 0;
 
+    if (it_data->al_cb)
+        it_data->al_cb (sni, AA_AUTOLOAD_NEEDS, aa_service_name (aa_service (it_data->si)), 0);
+
     add_to_list (&aa_service (sni)->needs, it_data->si, 0);
     add_to_list (&aa_service (sni)->after, it_data->si, 1);
     return 0;