]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: emit warning if start is used with globs 13786/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 16 Oct 2019 15:33:32 +0000 (17:33 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 16 Oct 2019 15:33:40 +0000 (17:33 +0200)
Fixes #6379.

man/systemctl.xml
src/systemctl/systemctl.c

index 5884a5e4c1703b5d4c4e65af30071d5040d044a1..a519a2aec119c1b5c462d86b1f95e6b49c918c68 100644 (file)
@@ -155,14 +155,21 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
           <term><command>start <replaceable>PATTERN</replaceable>…</command></term>
 
           <listitem>
-            <para>Start (activate) one or more units specified on the
-            command line.</para>
-
-            <para>Note that glob patterns operate on the set of primary names of units currently in memory. Units which
-            are not active and are not in a failed state usually are not in memory, and will not be matched by any
-            pattern. In addition, in case of instantiated units, systemd is often unaware of the instance name until
-            the instance has been started. Therefore, using glob patterns with <command>start</command> has limited
-            usefulness. Also, secondary alias names of units are not considered.</para>
+            <para>Start (activate) one or more units specified on the command line.</para>
+
+            <para>Note that unit glob patterns expand to names of units currently in memory. Units which are
+            not active and are not in a failed state usually are not in memory, and will not be matched by
+            any pattern. In addition, in case of instantiated units, systemd is often unaware of the instance
+            name until the instance has been started. Therefore, using glob patterns with
+            <command>start</command> has limited usefulness. Also, secondary alias names of units are not
+            considered.</para>
+
+            <para>Option <option>--all</option> may be used to also operate on inactive units which are
+            referenced by other loaded units. Note that this is not the same as operating on "all" possible
+            units, because as the previous paragraph describes, such a list is ill-defined. Nevertheless,
+            <command>systemctl start --all <replaceable>GLOB</replaceable></command> may be useful if all the
+            units that should match the pattern are pulled in by some target which is known to be loaded.
+            </para>
           </listitem>
         </varlistentry>
         <varlistentry>
index 738b9af5363edf84436880fba9b809d1b3a73ada..e4b85d906ca68d9215b2fd23d42bc33512989588 100644 (file)
@@ -749,7 +749,7 @@ static int get_unit_list_recursive(
         return c;
 }
 
-static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
+static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret, bool *ret_expanded) {
         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
         char **name;
         int r, i;
@@ -778,7 +778,8 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
 
         /* Query the manager only if any of the names are a glob, since
          * this is fairly expensive */
-        if (!strv_isempty(globs)) {
+        bool expanded = !strv_isempty(globs);
+        if (expanded) {
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
                 _cleanup_free_ UnitInfo *unit_infos = NULL;
                 size_t allocated, n;
@@ -802,6 +803,9 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
                 }
         }
 
+        if (ret_expanded)
+                *ret_expanded = expanded;
+
         *ret = TAKE_PTR(mangled);
         return 0;
 }
@@ -1033,7 +1037,7 @@ static int list_sockets(int argc, char *argv[], void *userdata) {
 
         (void) pager_open(arg_pager_flags);
 
-        r = expand_names(bus, strv_skip(argv, 1), ".socket", &sockets_with_suffix);
+        r = expand_names(bus, strv_skip(argv, 1), ".socket", &sockets_with_suffix, NULL);
         if (r < 0)
                 return r;
 
@@ -1345,7 +1349,7 @@ static int list_timers(int argc, char *argv[], void *userdata) {
 
         (void) pager_open(arg_pager_flags);
 
-        r = expand_names(bus, strv_skip(argv, 1), ".timer", &timers_with_suffix);
+        r = expand_names(bus, strv_skip(argv, 1), ".timer", &timers_with_suffix, NULL);
         if (r < 0)
                 return r;
 
@@ -3118,9 +3122,20 @@ static int start_unit(int argc, char *argv[], void *userdata) {
                 if (!names)
                         return log_oom();
         } else {
-                r = expand_names(bus, strv_skip(argv, 1), suffix, &names);
+                bool expanded;
+
+                r = expand_names(bus, strv_skip(argv, 1), suffix, &names, &expanded);
                 if (r < 0)
                         return log_error_errno(r, "Failed to expand names: %m");
+
+                if (!arg_all && expanded && streq(job_type, "start") && !arg_quiet) {
+                        log_warning("Warning: %ssystemctl start called with a glob pattern.%s",
+                                    ansi_highlight_red(),
+                                    ansi_normal());
+                        log_notice("Hint: unit globs expand to loaded units, so start will usually have no effect.\n"
+                                   "      Passing --all will also load units which are pulled in by other units.\n"
+                                   "      See systemctl(1) for more details.");
+                }
         }
 
         if (!arg_no_block) {
@@ -3728,7 +3743,7 @@ static int check_unit_generic(int code, const UnitActiveState good_states[], int
         if (r < 0)
                 return r;
 
-        r = expand_names(bus, args, NULL, &names);
+        r = expand_names(bus, args, NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -3787,7 +3802,7 @@ static int kill_unit(int argc, char *argv[], void *userdata) {
         if (streq(arg_job_mode, "fail"))
                 kill_who = strjoina(arg_kill_who, "-fail");
 
-        r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+        r = expand_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -3832,7 +3847,7 @@ static int clean_unit(int argc, char *argv[], void *userdata) {
                         return log_oom();
         }
 
-        r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+        r = expand_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -5860,7 +5875,7 @@ static int show(int argc, char *argv[], void *userdata) {
                 if (!strv_isempty(patterns)) {
                         _cleanup_strv_free_ char **names = NULL;
 
-                        r = expand_names(bus, patterns, NULL, &names);
+                        r = expand_names(bus, patterns, NULL, &names, NULL);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -5910,7 +5925,7 @@ static int cat(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+        r = expand_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -6141,7 +6156,7 @@ static int reset_failed(int argc, char *argv[], void *userdata) {
 
         polkit_agent_open_maybe();
 
-        r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+        r = expand_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");
 
@@ -7575,7 +7590,7 @@ static int edit(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+        r = expand_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to expand names: %m");