From 8401f1533d6936add337a621c5e58e3bbe9f346a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 23 Feb 2011 14:03:59 +0100 Subject: [PATCH 01/36] systemadm: break timestamp formatting out into a seperate function Since the timezone is always local, it doesn't make much sense to display it. The timestamp is now formatted without the timezone. I guess it can be further improved, which should be easier now that it is tucked-away in a separate function. --- src/systemadm.vala | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index d45ec64ca4..988e9f173c 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -23,6 +23,13 @@ using Pango; static bool user = false; +public string format_time(uint64 time_ns) { + if (time_ns <= 0) + return ""; + Time timestamp = Time.local((time_t) (time_ns / 1000000)); + return timestamp.format("%a, %d %b %Y %H:%M:%S"); +} + public class LeftLabel : Label { public LeftLabel(string? text = null) { if (text != null) @@ -515,19 +522,10 @@ public class MainWindow : Window { else unit_fragment_path_label.set_text_or_na(); - uint64 t = unit.active_enter_timestamp; - if (t > 0) { - Time timestamp = Time.local((time_t) (t / 1000000)); - unit_active_enter_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z")); - } else - unit_active_enter_timestamp_label.set_text_or_na(); - t = unit.active_exit_timestamp; - if (t > 0) { - Time timestamp = Time.local((time_t) (t / 1000000)); - unit_active_exit_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z")); - } else - unit_active_exit_timestamp_label.set_text_or_na(); + unit_active_enter_timestamp_label.set_text_or_na(format_time(unit.active_enter_timestamp)); + + unit_active_exit_timestamp_label.set_text_or_na(format_time(unit.active_exit_timestamp)); bool b = unit.can_start; start_button.set_sensitive(b); From 661ece1029ea454ff76093a5f1b40e9209cac86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 24 Feb 2011 16:29:24 +0100 Subject: [PATCH 02/36] systemadm: allow sorting of jobs and units --- src/systemadm.vala | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index 988e9f173c..21177bf396 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -30,6 +30,13 @@ public string format_time(uint64 time_ns) { return timestamp.format("%a, %d %b %Y %H:%M:%S"); } +public void new_column(TreeView view, int column_id, string title) { + TreeViewColumn col; + col = new TreeViewColumn.with_attributes(title, new CellRendererText(), "text", column_id); + col.set_sort_column_id(column_id); + view.insert_column(col, -1); +} + public class LeftLabel : Label { public LeftLabel(string? text = null) { if (text != null) @@ -171,22 +178,24 @@ public class MainWindow : Window { unit_model_filter = new TreeModelFilter(unit_model, null); unit_model_filter.set_visible_func(unit_filter); - unit_view = new TreeView.with_model(unit_model_filter); + TreeModelSort unit_model_sort = new TreeModelSort.with_model(unit_model_filter); + + unit_view = new TreeView.with_model(unit_model_sort); job_view = new TreeView.with_model(job_model); unit_view.cursor_changed.connect(unit_changed); job_view.cursor_changed.connect(job_changed); - unit_view.insert_column_with_attributes(-1, "Load State", new CellRendererText(), "text", 2); - unit_view.insert_column_with_attributes(-1, "Active State", new CellRendererText(), "text", 3); - unit_view.insert_column_with_attributes(-1, "Unit State", new CellRendererText(), "text", 4); - unit_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 0); - unit_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 5); + new_column(unit_view, 2, "Load State"); + new_column(unit_view, 3, "Active State"); + new_column(unit_view, 4, "Unit State"); + new_column(unit_view, 0, "Unit"); + new_column(unit_view, 5, "Job"); - job_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 0); - job_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 1); - job_view.insert_column_with_attributes(-1, "Type", new CellRendererText(), "text", 2); - job_view.insert_column_with_attributes(-1, "State", new CellRendererText(), "text", 3); + new_column(job_view, 0, "Job"); + new_column(job_view, 1, "Unit"); + new_column(job_view, 2, "Type"); + new_column(job_view, 3, "State"); ScrolledWindow scroll = new ScrolledWindow(null, null); scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); @@ -897,7 +906,7 @@ public class MainWindow : Window { } public void unit_type_changed() { - TreeModelFilter model = (TreeModelFilter) unit_view.get_model(); + TreeModelFilter model = (TreeModelFilter) ((TreeModelSort) unit_view.get_model()).get_model(); model.refilter(); } From a3c159a23c7cae889f89ed69bbe82c272bf163ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 25 Feb 2011 18:20:16 +0100 Subject: [PATCH 03/36] systemadm: split the type+status combo box into type combo & status checkbox --- src/systemadm.vala | 62 ++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index 21177bf396..e78fd7c4d4 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -113,6 +113,7 @@ public class MainWindow : Window { private RightLabel job_type_label; private ComboBox unit_type_combo_box; + private CheckButton inactive_checkbox; public MainWindow() throws IOError { title = user ? "systemd User Service Manager" : "systemd System Manager"; @@ -137,8 +138,7 @@ public class MainWindow : Window { type_hbox.pack_start(unit_type_combo_box, false, false, 0); unit_vbox.pack_start(type_hbox, false, false, 0); - unit_type_combo_box.append_text("Show All Units"); - unit_type_combo_box.append_text("Show Only Live Units"); + unit_type_combo_box.append_text("Show All"); unit_type_combo_box.append_text("Services"); unit_type_combo_box.append_text("Sockets"); unit_type_combo_box.append_text("Devices"); @@ -146,9 +146,13 @@ public class MainWindow : Window { unit_type_combo_box.append_text("Automounts"); unit_type_combo_box.append_text("Targets"); unit_type_combo_box.append_text("Snapshots"); - unit_type_combo_box.set_active(1); + unit_type_combo_box.set_active(0); // Show All unit_type_combo_box.changed.connect(unit_type_changed); + inactive_checkbox = new CheckButton.with_label("inactive too"); + inactive_checkbox.toggled.connect(unit_type_changed); + type_hbox.pack_start(inactive_checkbox, false, false, 0); + unit_load_entry = new Entry(); unit_load_button = new Button.with_mnemonic("_Load"); unit_load_button.set_sensitive(false); @@ -872,37 +876,31 @@ public class MainWindow : Window { if (id == null) return false; + if (!inactive_checkbox.get_active() + && active_state == "inactive" && job == "") + return false; + switch (unit_type_combo_box.get_active()) { - - case 0: - return true; - - case 1: - return active_state != "inactive" || job != ""; - - case 2: - return id.has_suffix(".service"); - - case 3: - return id.has_suffix(".socket"); - - case 4: - return id.has_suffix(".device"); - - case 5: - return id.has_suffix(".mount"); - - case 6: - return id.has_suffix(".automount"); - - case 7: - return id.has_suffix(".target"); - - case 8: - return id.has_suffix(".snapshot"); + case 0: + return true; + case 1: + return id.has_suffix(".service"); + case 2: + return id.has_suffix(".socket"); + case 3: + return id.has_suffix(".device"); + case 4: + return id.has_suffix(".mount"); + case 5: + return id.has_suffix(".automount"); + case 6: + return id.has_suffix(".target"); + case 7: + return id.has_suffix(".snapshot"); + default: + assert(false); + return false; } - - return false; } public void unit_type_changed() { From e377ad0d11e1bd9954c6084956494ebbf41b4486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 28 Feb 2011 10:35:23 +0100 Subject: [PATCH 04/36] systemadm: filter on swaps, paths, and timers too. --- src/systemadm.vala | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index e78fd7c4d4..6126eca221 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -138,13 +138,16 @@ public class MainWindow : Window { type_hbox.pack_start(unit_type_combo_box, false, false, 0); unit_vbox.pack_start(type_hbox, false, false, 0); - unit_type_combo_box.append_text("Show All"); + unit_type_combo_box.append_text("All unit types"); + unit_type_combo_box.append_text("Targets"); unit_type_combo_box.append_text("Services"); - unit_type_combo_box.append_text("Sockets"); unit_type_combo_box.append_text("Devices"); unit_type_combo_box.append_text("Mounts"); unit_type_combo_box.append_text("Automounts"); - unit_type_combo_box.append_text("Targets"); + unit_type_combo_box.append_text("Swaps"); + unit_type_combo_box.append_text("Sockets"); + unit_type_combo_box.append_text("Paths"); + unit_type_combo_box.append_text("Timers"); unit_type_combo_box.append_text("Snapshots"); unit_type_combo_box.set_active(0); // Show All unit_type_combo_box.changed.connect(unit_type_changed); @@ -884,9 +887,9 @@ public class MainWindow : Window { case 0: return true; case 1: - return id.has_suffix(".service"); + return id.has_suffix(".target"); case 2: - return id.has_suffix(".socket"); + return id.has_suffix(".service"); case 3: return id.has_suffix(".device"); case 4: @@ -894,8 +897,14 @@ public class MainWindow : Window { case 5: return id.has_suffix(".automount"); case 6: - return id.has_suffix(".target"); + return id.has_suffix(".swap"); case 7: + return id.has_suffix(".socket"); + case 8: + return id.has_suffix(".path"); + case 9: + return id.has_suffix(".timer"); + case 10: return id.has_suffix(".snapshot"); default: assert(false); From 0dd27daff4ba4bdad99b12b85b630ab21c84fa9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 1 Mar 2011 11:18:13 +0100 Subject: [PATCH 05/36] systemadm: add a wrappable label and use it for status lines The new WrapLabel is there to work around a deficiency in GTK, namely the fact that it is hard to make labels which are both resizable and wrappable. The code is a port from libview. --- Makefile.am | 3 +- src/.gitignore | 1 + src/systemadm.vala | 7 ++--- src/wraplabel.vala | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 src/wraplabel.vala diff --git a/Makefile.am b/Makefile.am index e1d1186887..ec0f7b5d13 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1418,7 +1418,8 @@ systemd_stdio_bridge_LDADD = \ systemadm_SOURCES = \ src/systemadm.vala \ - src/systemd-interfaces.vala + src/systemd-interfaces.vala \ + src/wraplabel.vala systemadm_CFLAGS = \ $(AM_CFLAGS) \ diff --git a/src/.gitignore b/src/.gitignore index cafff82a75..a3fd20b404 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -12,4 +12,5 @@ org.freedesktop.systemd1.policy gnome-ask-password-agent.c systemd-interfaces.c systemadm.c +wraplabel.c 73-seat-late.rules diff --git a/src/systemadm.vala b/src/systemadm.vala index 6126eca221..68652d0064 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -46,12 +46,11 @@ public class LeftLabel : Label { } } -public class RightLabel : Label { +public class RightLabel : WrapLabel { + public RightLabel(string? text = null) { - set_text_or_na(text); - set_alignment(0, 0); - set_ellipsize(EllipsizeMode.START); set_selectable(true); + set_text_or_na(text); } public void set_text_or_na(string? text = null) { diff --git a/src/wraplabel.vala b/src/wraplabel.vala new file mode 100644 index 0000000000..49858c3222 --- /dev/null +++ b/src/wraplabel.vala @@ -0,0 +1,73 @@ +// Copyright (c) 2005 VMware, Inc. + +// This is a translation of http://git.gnome.org/browse/meld/tree/meld/ui/wraplabel.py, +// which in turn is a translation of WrapLabel from libview. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// Python translation from wrapLabel.{cc|h} by Gian Mario Tagliaretti +// Vala translation from wraplabel.py by Zbigniew Jędrzejewski-Szmek + +public class WrapLabel : Gtk.Label { + private int _wrap_width; + + public WrapLabel(string? text = null) { + this._wrap_width = 0; + var layout = get_layout(); + layout.set_wrap(Pango.WrapMode.WORD_CHAR); + if (text != null) + this.set_text(text); + this.set_alignment(0, 0); + } + + public override void size_request(out Gtk.Requisition requisition) { + int width, height; + var layout = get_layout(); + layout.get_pixel_size(out width, out height); + requisition.width = 0; + requisition.height = height; + } + + public override void size_allocate(Gdk.Rectangle allocation) { + base.size_allocate (allocation); + this._set_wrap_width(allocation.width); + } + + public new void set_text(string str) { + base.set_text(str); + this._set_wrap_width(this._wrap_width); + } + + public new void set_markup(string str) { + base.set_markup(str); + this._set_wrap_width(this._wrap_width); + } + + private void _set_wrap_width(int width) { + if (width == 0) + return; + + var layout = get_layout(); + layout.set_width(width * Pango.SCALE); + if (_wrap_width != width) { + this._wrap_width = width; + this.queue_resize(); + } + } +} From 11216eb0bd5aab6b14af004fd2f24d423e3d356d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 3 Mar 2011 20:54:01 +0100 Subject: [PATCH 06/36] systemadm: add libgee as dependency and use it for a unit map --- Makefile.am | 1 + configure.ac | 2 +- src/systemadm.vala | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index ec0f7b5d13..0712945532 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1432,6 +1432,7 @@ systemadm_CFLAGS = \ systemadm_VALAFLAGS = \ --pkg=posix \ --pkg=gtk+-2.0 \ + --pkg=gee-1.0 \ -g systemadm_LDADD = \ diff --git a/configure.ac b/configure.ac index ca07456be6..b2411c937b 100644 --- a/configure.ac +++ b/configure.ac @@ -327,7 +327,7 @@ AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"]) have_gtk=no AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools])) if test "x$enable_gtk" != "xno"; then - PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 ], + PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0], [AC_DEFINE(HAVE_GTK, 1, [Define if GTK is available]) have_gtk=yes], have_gtk=no) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) diff --git a/src/systemadm.vala b/src/systemadm.vala index 68652d0064..c893da01da 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -79,6 +79,8 @@ public class MainWindow : Window { private ListStore unit_model; private ListStore job_model; + private Gee.HashMap unit_map; + private Button start_button; private Button stop_button; private Button restart_button; @@ -180,6 +182,8 @@ public class MainWindow : Window { unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit)); job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32)); + unit_map = new Gee.HashMap(); + TreeModelFilter unit_model_filter; unit_model_filter = new TreeModelFilter(unit_model, null); unit_model_filter.set_visible_func(unit_filter); @@ -355,6 +359,8 @@ public class MainWindow : Window { "org.freedesktop.systemd1", i.unit_path); + unit_map[i.id] = u; + unit_model.append(out iter); unit_model.set(iter, 0, i.id, @@ -415,6 +421,10 @@ public class MainWindow : Window { return u; } + public Unit? get_unit(string id) { + return this.unit_map[id]; + } + public void unit_changed() { Unit u = get_current_unit(); @@ -712,6 +722,8 @@ public class MainWindow : Window { "org.freedesktop.systemd1", path); + unit_map[id] = u; + update_unit_iter(iter, id, u); } catch (IOError e) { show_error(e.message); @@ -773,6 +785,8 @@ public class MainWindow : Window { } } while (unit_model.iter_next(ref iter)); + + unit_map.unset(id); } public void on_job_removed(uint32 id, ObjectPath path, string res) { From 8278f06953f5339646e5ff98900321f1525c0a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 3 Mar 2011 01:30:08 +0100 Subject: [PATCH 07/36] systemadm: display dependencies sorted --- src/systemadm.vala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index c893da01da..088ba26be9 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -458,6 +458,10 @@ public class MainWindow : Window { } public string make_dependency_string(string? prefix, string word, string[] dependencies) { + Gee.Collection sorted = new Gee.TreeSet(); + foreach (string i in dependencies) + sorted.add(i); + bool first = true; string r; @@ -466,7 +470,7 @@ public class MainWindow : Window { else r = prefix; - foreach (string i in dependencies) { + foreach (string i in sorted) { if (r != "") r += first ? "\n" : ","; From 23b51f17b1cf473bff3ae5332477e2028a5c5f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 3 Mar 2011 22:20:19 +0100 Subject: [PATCH 08/36] systemadm: use color for dependency links --- src/systemadm.vala | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index 088ba26be9..eed46b57e9 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -457,6 +457,25 @@ public class MainWindow : Window { unit_cgroup_label.set_text_or_na(); } + public string format_unit_link(string i) { + Unit? u = get_unit(i); + if(u == null) + return "" + i + "" + + i + "(" + + u.sub_state + ")" + ""; + return " " + span + ""; + } + + public string make_dependency_string(string? prefix, string word, string[] dependencies) { Gee.Collection sorted = new Gee.TreeSet(); foreach (string i in dependencies) @@ -479,7 +498,7 @@ public class MainWindow : Window { first = false; } - r += " " + i + ""; + r += format_unit_link(i); } return r; From 8b1451ade7794c21d29141dc363d0f626e2070ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 17 Sep 2011 14:57:19 +0100 Subject: [PATCH 09/36] systemadm: use bold for "requires", etc. --- src/systemadm.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index eed46b57e9..a3068f157d 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -494,7 +494,7 @@ public class MainWindow : Window { r += first ? "\n" : ","; if (first) { - r += word; + r += "" + word + ":"; first = false; } From 37d3b881f1cc7c18d23013ff29429ab67ab5b61d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 18 Sep 2011 11:06:07 +0200 Subject: [PATCH 10/36] systemadm: make the dependency listing selectable There's no reason to forbid selecting the text. --- src/systemadm.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index a3068f157d..e7fa35402d 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -238,7 +238,7 @@ public class MainWindow : Window { job_type_label = new RightLabel(); unit_dependency_label.set_track_visited_links(false); - unit_dependency_label.set_selectable(false); + unit_dependency_label.set_selectable(true); unit_dependency_label.activate_link.connect(on_activate_link); unit_fragment_path_label.set_track_visited_links(false); From 734b60d7961a28adab45ef141807a0f3e0ba11e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 24 Feb 2011 16:30:55 +0100 Subject: [PATCH 11/36] systemadm: catch exceptions generated by dbus Otherwise, access-denied dbus errors were not caught, and only caused a message to be printed out on the console. After this change a proper popup window pops up :). --- src/systemadm.vala | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index e7fa35402d..d4208008fe 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -642,7 +642,7 @@ public class MainWindow : Window { try { u.start("replace"); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -655,7 +655,7 @@ public class MainWindow : Window { try { u.stop("replace"); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -668,7 +668,7 @@ public class MainWindow : Window { try { u.reload("replace"); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -681,7 +681,7 @@ public class MainWindow : Window { try { u.restart("replace"); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -694,7 +694,7 @@ public class MainWindow : Window { try { j.cancel(); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -722,7 +722,7 @@ public class MainWindow : Window { 4, u.sub_state, 5, t != "" ? "→ %s".printf(t) : "", 6, u); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -748,7 +748,7 @@ public class MainWindow : Window { unit_map[id] = u; update_unit_iter(iter, id, u); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -784,7 +784,7 @@ public class MainWindow : Window { update_job_iter(iter, id, j); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -866,7 +866,7 @@ public class MainWindow : Window { } while (unit_model.iter_next(ref iter)); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -902,7 +902,7 @@ public class MainWindow : Window { } while (job_model.iter_next(ref iter)); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -957,7 +957,7 @@ public class MainWindow : Window { public void on_server_reload() { try { manager.reload(); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -969,7 +969,7 @@ public class MainWindow : Window { if (unit_type_combo_box.get_active() != 0) unit_type_combo_box.set_active(8); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -998,7 +998,7 @@ public class MainWindow : Window { m.destroy(); show_unit(u); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } } @@ -1018,7 +1018,7 @@ public class MainWindow : Window { path); show_unit(u); - } catch (IOError e) { + } catch (Error e) { show_error(e.message); } From 8f38d5a4c6e627180809db739b2bdaa5ca0c645a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 18 Sep 2011 17:00:12 +0200 Subject: [PATCH 12/36] systemadm: coalesce id and decription fields This is just in interest of saving space (e.g. 5 lines for multi-user.target). --- src/systemadm.vala | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index d4208008fe..4cb5c55ef3 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -96,7 +96,6 @@ public class MainWindow : Window { private Manager manager; private RightLabel unit_id_label; - private RightLabel unit_aliases_label; private RightLabel unit_dependency_label; private RightLabel unit_description_label; private RightLabel unit_load_state_label; @@ -220,7 +219,6 @@ public class MainWindow : Window { job_vbox.pack_start(scroll, true, true, 0); unit_id_label = new RightLabel(); - unit_aliases_label = new RightLabel(); unit_dependency_label = new RightLabel(); unit_description_label = new RightLabel(); unit_load_state_label = new RightLabel(); @@ -255,8 +253,6 @@ public class MainWindow : Window { unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0); unit_table.attach(unit_id_label, 1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Aliases:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_aliases_label, 1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); unit_table.attach(new LeftLabel("Description:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); unit_table.attach(unit_description_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0); @@ -443,7 +439,6 @@ public class MainWindow : Window { restart_button.set_sensitive(false); unit_id_label.set_text_or_na(); - unit_aliases_label.set_text_or_na(); unit_description_label.set_text_or_na(); unit_description_label.set_text_or_na(); unit_load_state_label.set_text_or_na(); @@ -507,20 +502,23 @@ public class MainWindow : Window { public void show_unit(Unit unit) { current_unit_id = unit.id; - unit_id_label.set_text_or_na(current_unit_id); - - string a = ""; + string id_display = current_unit_id; + bool has_alias = false; foreach (string i in unit.names) { if (i == current_unit_id) continue; - if (a == "") - a = i; - else - a += "\n" + i; - } + if (!has_alias) { + id_display += " (aliases:"; + has_alias = true; + } - unit_aliases_label.set_text_or_na(a); + id_display += " " + i; + } + if(has_alias) + id_display += ")"; + + unit_id_label.set_text_or_na(id_display); string[] requires = unit.requires, From fe7e28146f30ec442c0dd7f71002a1b482d910a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Sep 2011 08:14:02 +0200 Subject: [PATCH 13/36] systemadm: adjust row numbers after removing 'aliases' --- src/systemadm.vala | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index 4cb5c55ef3..11189995c8 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -253,31 +253,31 @@ public class MainWindow : Window { unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0); unit_table.attach(unit_id_label, 1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Description:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_description_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_dependency_label, 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Fragment Path:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_fragment_path_label, 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Control Group:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_cgroup_label, 1, 6, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Description:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_description_label, 1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_dependency_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Fragment Path:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_fragment_path_label, 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Control Group:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_cgroup_label, 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Load State:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_load_state_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Active State:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_active_state_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Unit State:"), 0, 1, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_sub_state_label, 1, 2, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Load State:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_load_state_label, 1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Active State:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_state_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Unit State:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_sub_state_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_active_enter_timestamp_label, 3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Active Exit Timestamp:"), 2, 3, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_active_exit_timestamp_label, 3, 4, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Activated:"), 2, 3, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_enter_timestamp_label, 3, 4, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Deactivated:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_exit_timestamp_label, 3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Can Start/Stop:"), 4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_can_start_label, 5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(new LeftLabel("Can Reload:"), 4, 5, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0); - unit_table.attach(unit_can_reload_label, 5, 6, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Can Start/Stop:"), 4, 5, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_can_start_label, 5, 6, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Can Reload:"), 4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_can_reload_label, 5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); job_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0); job_table.attach(job_id_label, 1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); From 79b1e6cb8080e5c88754484f5af591ce74714ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 19 Sep 2011 08:20:17 +0200 Subject: [PATCH 14/36] systemadm: use colors for id too, remove color from fragment link --- src/systemadm.vala | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/systemadm.vala b/src/systemadm.vala index 11189995c8..5971ac07e5 100644 --- a/src/systemadm.vala +++ b/src/systemadm.vala @@ -452,7 +452,7 @@ public class MainWindow : Window { unit_cgroup_label.set_text_or_na(); } - public string format_unit_link(string i) { + public string format_unit_link(string i, bool link) { Unit? u = get_unit(i); if(u == null) return "" + i + "" + i + "(" + u.sub_state + ")" + ""; - return " " + span + ""; + if(link) + return " " + span + ""; + else + return span; } @@ -493,7 +496,7 @@ public class MainWindow : Window { first = false; } - r += format_unit_link(i); + r += format_unit_link(i, true); } return r; @@ -502,7 +505,7 @@ public class MainWindow : Window { public void show_unit(Unit unit) { current_unit_id = unit.id; - string id_display = current_unit_id; + string id_display = format_unit_link(current_unit_id, false); bool has_alias = false; foreach (string i in unit.names) { if (i == current_unit_id) @@ -518,7 +521,7 @@ public class MainWindow : Window { if(has_alias) id_display += ")"; - unit_id_label.set_text_or_na(id_display); + unit_id_label.set_markup_or_na(id_display); string[] requires = unit.requires, @@ -564,7 +567,9 @@ public class MainWindow : Window { string fp = unit.fragment_path; if (fp != "") - unit_fragment_path_label.set_markup_or_na("" + fp + "" ); + unit_fragment_path_label.set_markup_or_na( + "" + + "" + fp + ""); else unit_fragment_path_label.set_text_or_na(); From 563ba9ea6e60774086555998b957edf923e24b46 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Mon, 17 Oct 2011 11:12:12 +0200 Subject: [PATCH 15/36] manager: fix a crash in isolating HASHMAP_FOREACH is safe against the removal of the current entry, but not against the removal of other entries. job_finish_and_invalidate() can recursively remove other entries. It triggered an assertion failure: Assertion 'j->installed' failed at src/manager.c:1218, function transaction_apply(). Aborting. Fix the crash by iterating from the beginning when there is a possibility that the iterator could be invalid. It is O(n^2) in the worst case, but that's better than a crash. https://bugzilla.redhat.com/show_bug.cgi?id=717325 --- src/job.c | 19 ++++++++++++++----- src/manager.c | 7 ++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/job.c b/src/job.c index 5c0913b7d8..20971da852 100644 --- a/src/job.c +++ b/src/job.c @@ -527,6 +527,7 @@ int job_finish_and_invalidate(Job *j, JobResult result) { Unit *other; JobType t; Iterator i; + bool recursed = false; assert(j); assert(j->installed); @@ -573,23 +574,29 @@ int job_finish_and_invalidate(Job *j, JobResult result) { if (other->meta.job && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || - other->meta.job->type == JOB_RELOAD_OR_START)) + other->meta.job->type == JOB_RELOAD_OR_START)) { job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY); + recursed = true; + } SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i) if (other->meta.job && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || - other->meta.job->type == JOB_RELOAD_OR_START)) + other->meta.job->type == JOB_RELOAD_OR_START)) { job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY); + recursed = true; + } SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) if (other->meta.job && !other->meta.job->override && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || - other->meta.job->type == JOB_RELOAD_OR_START)) + other->meta.job->type == JOB_RELOAD_OR_START)) { job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY); + recursed = true; + } } else if (t == JOB_STOP) { @@ -597,8 +604,10 @@ int job_finish_and_invalidate(Job *j, JobResult result) { if (other->meta.job && (other->meta.job->type == JOB_START || other->meta.job->type == JOB_VERIFY_ACTIVE || - other->meta.job->type == JOB_RELOAD_OR_START)) + other->meta.job->type == JOB_RELOAD_OR_START)) { job_finish_and_invalidate(other->meta.job, JOB_DEPENDENCY); + recursed = true; + } } } @@ -626,7 +635,7 @@ finish: manager_check_finished(u->meta.manager); - return 0; + return recursed; } int job_start_timer(Job *j) { diff --git a/src/manager.c b/src/manager.c index e626347dec..6d20258893 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1214,13 +1214,18 @@ static int transaction_apply(Manager *m, JobMode mode) { /* When isolating first kill all installed jobs which * aren't part of the new transaction */ + rescan: HASHMAP_FOREACH(j, m->jobs, i) { assert(j->installed); if (hashmap_get(m->transaction_jobs, j->unit)) continue; - job_finish_and_invalidate(j, JOB_CANCELED); + /* 'j' itself is safe to remove, but if other jobs + are invalidated recursively, our iterator may become + invalid and we need to start over. */ + if (job_finish_and_invalidate(j, JOB_CANCELED) > 0) + goto rescan; } } From e51db373c242b7541794affb2b5e411bcce26d0f Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Mon, 17 Oct 2011 21:00:42 +0200 Subject: [PATCH 16/36] service: Drop rcN.d runlevels from SysV services that also exist in rcS.d Services which claim to start in both rcN.d and rcS.d generate loops which for some reason seems to usually end up with dbus not starting and the whole machine being quite unhappy. We now rather assume that if a service can be started in rcS, it should not also start in rcN.d. Fixes Debian bug #637037 --- src/service.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index e64d289fed..6184390659 100644 --- a/src/service.c +++ b/src/service.c @@ -83,7 +83,7 @@ static const struct { #define RUNLEVELS_UP "12345" /* #define RUNLEVELS_DOWN "06" */ -/* #define RUNLEVELS_BOOT "bBsS" */ +#define RUNLEVELS_BOOT "bBsS" #endif static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { @@ -811,6 +811,13 @@ static int service_load_sysv_path(Service *s, const char *path) { if ((r = sysv_exec_commands(s)) < 0) goto finish; + if (s->sysv_runlevels && + chars_intersect(RUNLEVELS_BOOT, s->sysv_runlevels) && + chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { + /* Service has both boot and "up" runlevels + configured. Kill the "up" ones. */ + delete_chars(s->sysv_runlevels, RUNLEVELS_UP); + } if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { /* If there a runlevels configured for this service From 5a8d081c58f7b83172ad5031a8fdac0c33072b2a Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Mon, 17 Oct 2011 21:01:40 +0200 Subject: [PATCH 17/36] audit: do not complain if kernel lacks audit When running on a kernel without audit support, systemd currently writes a mysterious-sounding error to its log: systemd[1]: Failed to connect to audit log: Protocol not supported Better to suppress the audit_open() failure message when (and only when) it is due to running on a kernel without audit support, since in this case the admin probably does not mind systemd not writing to the audit log. This way, more serious errors like ENOMEM and EACCES will stand out more. --- src/manager.c | 5 ++++- src/update-utmp.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/manager.c b/src/manager.c index 6d20258893..111167a8c2 100644 --- a/src/manager.c +++ b/src/manager.c @@ -286,7 +286,10 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { goto fail; #ifdef HAVE_AUDIT - if ((m->audit_fd = audit_open()) < 0) + if ((m->audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error("Failed to connect to audit log: %m"); #endif diff --git a/src/update-utmp.c b/src/update-utmp.c index f81e7f495f..12e4d11042 100644 --- a/src/update-utmp.c +++ b/src/update-utmp.c @@ -376,7 +376,10 @@ int main(int argc, char *argv[]) { umask(0022); #ifdef HAVE_AUDIT - if ((c.audit_fd = audit_open()) < 0) + if ((c.audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error("Failed to connect to audit log: %m"); #endif From 74eeab044e506a39786f484b160d9f64d48ad243 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 11 Oct 2011 20:56:53 -0400 Subject: [PATCH 18/36] systemctl-completion: always invoke with --no-legend In the case of completion for the 'restart' verb, passing the invalid unit name (the colums header) causes completion to cease functioning entirely, with the error: Failed to issue method call: Unit name UNIT is not valid. This adds a small wrapper function for systemctl which can have common options added to it. --- src/systemctl-bash-completion.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh index 6369a6ca39..6ebb792c00 100644 --- a/src/systemctl-bash-completion.sh +++ b/src/systemctl-bash-completion.sh @@ -15,6 +15,10 @@ # You should have received a copy of the GNU General Public License # along with systemd; If not, see . +__systemctl() { + systemctl --no-legend "$@" +} + __contains_word () { local word=$1; shift for w in $*; do [[ $w = $word ]] && return 0; done @@ -24,7 +28,7 @@ __contains_word () { __filter_units_by_property () { local property=$1 value=$2 ; shift ; shift local -a units=( $* ) - local -a props=( $(systemctl show --property "$property" -- ${units[*]} | grep -v ^$) ) + local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) ) for ((i=0; $i < ${#units[*]}; i++)); do if [[ "${props[i]}" = "$property=$value" ]]; then echo "${units[i]}" @@ -32,10 +36,10 @@ __filter_units_by_property () { done } -__get_all_units () { systemctl list-units --full --all | awk ' {print $1}' ; } -__get_active_units () { systemctl list-units --full | awk ' {print $1}' ; } -__get_inactive_units () { systemctl list-units --full --all | awk '$3 == "inactive" {print $1}' ; } -__get_failed_units () { systemctl list-units --full | awk '$3 == "failed" {print $1}' ; } +__get_all_units () { __systemctl list-units --full --all | awk ' {print $1}' ; } +__get_active_units () { __systemctl list-units --full | awk ' {print $1}' ; } +__get_inactive_units () { __systemctl list-units --full --all | awk '$3 == "inactive" {print $1}' ; } +__get_failed_units () { __systemctl list-units --full | awk '$3 == "failed" {print $1}' ; } _systemctl () { local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} @@ -134,13 +138,13 @@ _systemctl () { comps='' elif __contains_word "$verb" ${VERBS[JOBS]}; then - comps=$( systemctl list-jobs | awk '{print $1}' ) + comps=$( __systemctl list-jobs | awk '{print $1}' ) elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then - comps=$( systemctl list-units --type snapshot --full --all | awk '{print $1}' ) + comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' ) elif __contains_word "$verb" ${VERBS[ENVS]}; then - comps=$( systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) + comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) compopt -o nospace fi From 1c0a113fd3fe3344b2c947ca9948760057052716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 Oct 2011 11:49:59 +0200 Subject: [PATCH 19/36] systemctl: make list-unit-files output more economical The first column is given the width of the widest entry, if possible, otherwise all entries are ellipsized to fit in ($COLUMNS - (width of second column)). [ Added a few fixes, calculate state_cols too, respect '--no-legend', better handling of '--full' -- michich ] --- src/systemctl.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/systemctl.c b/src/systemctl.c index 0de2444d43..b0baf8dc5f 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -551,11 +551,30 @@ static bool output_show_unit_file(const UnitFileList *u) { } static void output_unit_file_list(const UnitFileList *units, unsigned c) { - unsigned n_shown = 0; + unsigned max_id_len, id_cols, state_cols, n_shown = 0; const UnitFileList *u; - if (on_tty()) - printf("%-25s %-6s\n", "UNIT FILE", "STATE"); + max_id_len = sizeof("UNIT FILE")-1; + state_cols = sizeof("STATE")-1; + for (u = units; u < units + c; u++) { + if (!output_show_unit_file(u)) + continue; + + max_id_len = MAX(max_id_len, strlen(file_name_from_path(u->path))); + state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state))); + } + + if (!arg_full) { + unsigned basic_cols; + id_cols = MIN(max_id_len, 25); + basic_cols = 1 + id_cols + state_cols; + if (basic_cols < (unsigned) columns()) + id_cols += MIN(columns() - basic_cols, max_id_len - id_cols); + } else + id_cols = max_id_len; + + if (!arg_no_legend) + printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE"); for (u = units; u < units + c; u++) { char *e; @@ -580,16 +599,16 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { id = file_name_from_path(u->path); - e = arg_full ? NULL : ellipsize(id, 25, 33); + e = arg_full ? NULL : ellipsize(id, id_cols, 33); - printf("%-25s %s%-6s%s\n", - e ? e : id, - on, unit_file_state_to_string(u->state), off); + printf("%-*s %s%-*s%s\n", + id_cols, e ? e : id, + on, state_cols, unit_file_state_to_string(u->state), off); free(e); } - if (on_tty()) + if (!arg_no_legend) printf("\n%u unit files listed.\n", n_shown); } From a6eb9147a820d1c08b315867373a21bd0ece2f05 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 13:48:30 +0100 Subject: [PATCH 20/36] update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 9149018134..16cfd215f0 100644 --- a/TODO +++ b/TODO @@ -21,6 +21,8 @@ Features: * unset container= in PID1? +* automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service@serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary. + * if we can not get user quota for tmpfs, mount a separate tmpfs instance for every user in /run/user/$USER with a configured maximum size From b7f44df59a7f76d2bd5302df2f5ec9be9b7fa2fa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 13:52:28 +0100 Subject: [PATCH 21/36] README: explain dependency on cgroups --- README | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index 15afb2cf95..a4cbeaebd3 100644 --- a/README +++ b/README @@ -30,7 +30,10 @@ LICENSE: GPLv2+ for all code, except sd-daemon.[ch] which is MIT REQUIREMENTS: - Linux kernel >= 2.6.39 (with devtmpfs, cgroups; optional but strongly recommended: autofs4, ipv6) + Linux kernel >= 2.6.39 + with devtmpfs + with cgroups (but it's OK to disable all controllers) + optional but strongly recommended: autofs4, ipv6 libudev >= 172 dbus >= 1.4.0 libcap From bb53abeb8c3407ea250be69bc43510b03c0df3da Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 14:20:31 +0100 Subject: [PATCH 22/36] plymouth: fix ply proto endianess issues Plymouth enforces LE even for the local Ply proto, hence we should do the conversion properly for BE arch compat. Tracked down by Harald Hoyer. https://bugzilla.redhat.com/show_bug.cgi?id=744415 --- src/tty-ask-password-agent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c index 43d008fc70..13481b29e9 100644 --- a/src/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent.c @@ -206,6 +206,7 @@ static int ask_password_plymouth( continue; memcpy(&size, buffer+1, sizeof(size)); + size = le32toh(size); if (size+5 > sizeof(buffer)) { r = -EIO; goto finish; From 7c2ec00930ce1f4aabfbb405d84b67eb9d065ef0 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sat, 22 Oct 2011 18:47:08 +0200 Subject: [PATCH 23/36] random-seed: convert poolsize from bits to bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem was first noted in a bug report against Arch's initscripts. Reported-by: Taylan Ulrich Bayırlı Reported-by: Gerardo Exequiel Pozzi --- src/random-seed.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/random-seed.c b/src/random-seed.c index ee5cae315c..0c63794b66 100644 --- a/src/random-seed.c +++ b/src/random-seed.c @@ -51,7 +51,11 @@ int main(int argc, char *argv[]) { /* Read pool size, if possible */ if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) { - fscanf(f, "%zu", &buf_size); + if (fscanf(f, "%zu", &buf_size) > 0) { + /* poolsize is in bits on 2.6, but we want bytes */ + buf_size /= 8; + } + fclose(f); } From 7670e5a2aab543bc6b442ab0683411770e06fe26 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Wed, 26 Oct 2011 09:38:39 +0200 Subject: [PATCH 24/36] condition: Fix file descriptor leak in test_capability() Detected by cppcheck. --- src/condition.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/condition.c b/src/condition.c index f18c45421a..2b51a16f17 100644 --- a/src/condition.c +++ b/src/condition.c @@ -187,6 +187,8 @@ static bool test_capability(const char *parameter) { } } + fclose(f); + return !!(capabilities & (1ULL << value)); } From f632a6634dd4eff041425aa9b3fb48ccfa98c014 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 18:18:17 +0100 Subject: [PATCH 25/36] initctl: don't use dbus connection after PID 1 got respawned After reexec PID 1 our bus connection is invalidated. Hence don't try to reuse it, just terminate so that when we are spawned the next time we just get a new one. Spotted by Marti Raudsepp. --- src/initctl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/initctl.c b/src/initctl.c index eaa717ad91..097c85fdd4 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -56,6 +56,8 @@ typedef struct Server { unsigned n_fifos; DBusConnection *bus; + + bool quit; } Server; struct Fifo { @@ -174,6 +176,13 @@ static void request_process(Server *s, const struct init_request *req) { case 'U': if (kill(1, SIGTERM) < 0) log_error("kill() failed: %m"); + + /* The bus connection will be + * terminated if PID 1 is reexecuted, + * hence let's just exit here, and + * rely on that we'll be restarted on + * the next request */ + s->quit = true; break; case 'q': @@ -404,7 +413,7 @@ int main(int argc, char *argv[]) { "READY=1\n" "STATUS=Processing requests..."); - for (;;) { + while (!server.quit) { struct epoll_event event; int k; From 6ddaf1ca4ab0e6a094f6d37fa1e0c604c6d867ba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 22:02:36 +0100 Subject: [PATCH 26/36] cgroup: always recreate cgroup before we try to apply attributes We might have trimmed the cgroup tree previously, hence don't trust our own "realized" flag, always recreate cgroup tree before applying our attributes to make sure this actually works out. https://bugzilla.redhat.com/show_bug.cgi?id=749687 --- src/cgroup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cgroup.c b/src/cgroup.c index dcf2c2feb7..be837c3d0f 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -38,9 +38,6 @@ int cgroup_bonding_realize(CGroupBonding *b) { assert(b->path); assert(b->controller); - if (b->realized) - return 0; - r = cg_create(b->controller, b->path); if (r < 0) { log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r)); From 7fc2a89a7387db1e5daa4892393c9e9536920c25 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 22:27:48 +0100 Subject: [PATCH 27/36] mount: order remote mounts after both network.target and remote-fs-pre.target Since remote-fs-pre.target is optional we cannot count on it to order remote mounts after network.target, so let's add that order explicitly in addition to remote-fs-pre.target. https://bugzilla.redhat.com/show_bug.cgi?id=749940 --- src/mount.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mount.c b/src/mount.c index ef953f0d0a..f9cfe910a0 100644 --- a/src/mount.c +++ b/src/mount.c @@ -327,7 +327,7 @@ static bool needs_quota(MountParameters *p) { } static int mount_add_fstab_links(Mount *m) { - const char *target, *after = NULL; + const char *target, *after = NULL, *after2 = NULL; MountParameters *p; Unit *tu; int r; @@ -358,6 +358,7 @@ static int mount_add_fstab_links(Mount *m) { if (mount_is_network(p)) { target = SPECIAL_REMOTE_FS_TARGET; after = SPECIAL_REMOTE_FS_PRE_TARGET; + after2 = SPECIAL_NETWORK_TARGET; } else { target = SPECIAL_LOCAL_FS_TARGET; after = SPECIAL_LOCAL_FS_PRE_TARGET; @@ -374,6 +375,10 @@ static int mount_add_fstab_links(Mount *m) { if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true)) < 0) return r; + if (after2) + if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true)) < 0) + return r; + if (automount) { Unit *am; From fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 22:29:48 +0100 Subject: [PATCH 28/36] units: drop [Install] section from remote-fs-pre.target remote-fs-pre.target is not a unit a user should ever explicitly enable. Instead services which need to hook before network mounts should pull it in. --- units/remote-fs-pre.target | 3 --- 1 file changed, 3 deletions(-) diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target index 5406aa22d3..8aceb08b9d 100644 --- a/units/remote-fs-pre.target +++ b/units/remote-fs-pre.target @@ -10,6 +10,3 @@ [Unit] Description=Remote File Systems (Pre) After=network.target - -[Install] -WantedBy=multi-user.target From 87e75fddbb3701fd5f4e0d62dc1d661e8d94b071 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 17 Oct 2011 13:01:08 +0200 Subject: [PATCH 29/36] cryptsetup-generator: avoid ordering cycle on swap Devices with random keys (swap), should not be ordered before local-fs.target, as this creates a cycle with systemd-load-random-seed.service (and also it does not make sense, a swap device is not a local-fs). --- src/cryptsetup-generator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c index 6f3aa786bc..a48b7a4562 100644 --- a/src/cryptsetup-generator.c +++ b/src/cryptsetup-generator.c @@ -112,8 +112,7 @@ static int create_disk( "DefaultDependencies=no\n" "BindTo=%s dev-mapper-%%i.device\n" "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n" - "Before=umount.target\n" - "Before=local-fs.target\n", + "Before=umount.target\n", d, d); if (!nofail) @@ -125,6 +124,9 @@ static int create_disk( streq(password, "/dev/hw_random"))) fprintf(f, "After=systemd-random-seed-load.service\n"); + else + fprintf(f, + "Before=local-fs.target\n"); fprintf(f, "\n[Service]\n" From 25d6283acfeb87730c2c0c4c2ef76a66fa397e87 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Nov 2011 23:53:15 +0100 Subject: [PATCH 30/36] update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 16cfd215f0..fe73283cfe 100644 --- a/TODO +++ b/TODO @@ -19,6 +19,8 @@ Bugfixes: Features: +* as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys + * unset container= in PID1? * automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service@serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary. From 6fdae8a6a40d6a3b5f77516abaee23b3eab002f6 Mon Sep 17 00:00:00 2001 From: Dexter Morgan Date: Fri, 28 Oct 2011 19:16:33 +0200 Subject: [PATCH 31/36] Add Mageia support This patch adds support for the Mageia Linux distribution: http://www.mageia.org/ Mageia is a fork of Mandriva although some divergence has already occured and thus inclusion of these changes upstream allow us to (hopefully) migrate more rapidly to the new standard approaches systemd offers. Indeed, we already use the preferred mechanism of OS identification via the /etc/os-release file rather than a distro specific variation. This patch mostly mirrors the patch added previously for Mandriva support. In addition to those original authors, this patch was mostly written by Dexter Morgan with help from Colin Guthrie and Eugeni Dodonov. --- Makefile.am | 31 +++++++++++++++++++++++++++++++ configure.ac | 8 ++++++++ src/fsck.c | 2 +- src/hostname-setup.c | 4 ++-- src/locale-setup.c | 2 +- src/quotacheck.c | 6 +++--- src/service.c | 3 ++- src/systemctl.c | 2 +- src/vconsole-setup.c | 4 ++-- units/console-shell.service.m4 | 3 +++ units/getty@.service.m4 | 3 +++ units/mageia/prefdm.service | 21 +++++++++++++++++++++ units/rescue.service.m4 | 5 ++++- units/serial-getty@.service.m4 | 3 +++ 14 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 units/mageia/prefdm.service diff --git a/Makefile.am b/Makefile.am index dabe32ac46..f701a45c87 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,6 +119,13 @@ AM_CPPFLAGS += \ -DKBD_LOADKEYS=\"/bin/loadkeys\" \ -DKBD_SETFONT=\"/bin/setfont\" \ -DDEFAULT_FONT=\"latarcyrheb-sun16\" +else +if TARGET_MAGEIA +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/bin/loadkeys\" \ + -DKBD_SETFONT=\"/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +endif endif endif endif @@ -542,6 +549,13 @@ dist_systemunit_DATA += \ units/suse/halt-local.service endif +if TARGET_MAGEIA +dist_systemunit_DATA += \ + units/mageia/prefdm.service \ + units/fedora/rc-local.service \ + units/fedora/halt-local.service +endif + if HAVE_PLYMOUTH dist_systemunit_DATA += \ units/plymouth-start.service \ @@ -1999,6 +2013,23 @@ if TARGET_SUSE $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) endif +if TARGET_MAGEIA + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f rc-local.service && \ + $(LN_S) $(systemunitdir)/rc-local.service rc-local.service ) + ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ + rm -f halt-local.service && \ + $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f display-manager.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) prefdm.service dm.service ) + ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ + rm -f display-manager.service && \ + $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) +endif + if HAVE_SYSV_COMPAT ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ rm -f var-lock.mount && \ diff --git a/configure.ac b/configure.ac index 0ec6f69bc8..0bc98603d3 100644 --- a/configure.ac +++ b/configure.ac @@ -371,6 +371,7 @@ if test "z$with_distro" = "z"; then test -f "/etc/mandriva-release" && with_distro="mandriva" test -f "/etc/meego-release" && with_distro="meego" test -f "/etc/angstrom-version" && with_distro="angstrom" + test -f "/etc/mageia-release" && with_distro="mageia" if test "x`lsb_release -is 2>/dev/null`" = "xUbuntu"; then with_distro="ubuntu" fi @@ -458,6 +459,12 @@ case $with_distro in AC_DEFINE(TARGET_ANGSTROM, [], [Target is Ångström]) M4_DEFINES=-DTARGET_ANGSTROM=1 ;; + mageia) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_MAGEIA, [], [Target is Mageia]) + M4_DISTRO_FLAG=-DTARGET_MAGEIA=1 + have_plymouth=yes + ;; other) ;; *) @@ -515,6 +522,7 @@ AM_CONDITIONAL(TARGET_ALTLINUX, test x"$with_distro" = xaltlinux) AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva) AM_CONDITIONAL(TARGET_MEEGO, test x"$with_distro" = xmeego) AM_CONDITIONAL(TARGET_ANGSTROM, test x"$with_distro" = xangstrom) +AM_CONDITIONAL(TARGET_MAGEIA, test x"$with_distro" = xmageia) AM_CONDITIONAL(HAVE_PLYMOUTH, test "$have_plymouth" = "yes") AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes") diff --git a/src/fsck.c b/src/fsck.c index c5088ad71c..3477ba16ad 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -127,7 +127,7 @@ static int parse_proc_cmdline(void) { arg_skip = true; else if (startswith(w, "fsck.mode")) log_warning("Invalid fsck.mode= parameter. Ignoring."); -#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) else if (strneq(w, "fastboot", l)) arg_skip = true; else if (strneq(w, "forcefsck", l)) diff --git a/src/hostname-setup.c b/src/hostname-setup.c index 7216b75c8a..2c2f10cfd1 100644 --- a/src/hostname-setup.c +++ b/src/hostname-setup.c @@ -30,7 +30,7 @@ #include "util.h" #include "log.h" -#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) +#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA) #define FILENAME "/etc/sysconfig/network" #elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) #define FILENAME "/etc/HOSTNAME" @@ -64,7 +64,7 @@ static int read_and_strip_hostname(const char *path, char **hn) { static int read_distro_hostname(char **hn) { -#if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) +#if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA) int r; FILE *f; diff --git a/src/locale-setup.c b/src/locale-setup.c index 340293619f..7f692e9c5d 100644 --- a/src/locale-setup.c +++ b/src/locale-setup.c @@ -199,7 +199,7 @@ int locale_setup(void) { if (r != -ENOENT) log_warning("Failed to read /etc/profile.env: %s", strerror(-r)); } -#elif defined(TARGET_MANDRIVA) +#elif defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA ) if (r <= 0 && (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, "LANG", &variables[VARIABLE_LANG], diff --git a/src/quotacheck.c b/src/quotacheck.c index 98b59a090a..60033a8eb2 100644 --- a/src/quotacheck.c +++ b/src/quotacheck.c @@ -54,7 +54,7 @@ static int parse_proc_cmdline(void) { arg_skip = true; else if (startswith(w, "quotacheck.mode")) log_warning("Invalid quotacheck.mode= parameter. Ignoring."); -#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) else if (strneq(w, "forcequotacheck", l)) arg_force = true; #endif @@ -65,8 +65,8 @@ static int parse_proc_cmdline(void) { } static void test_files(void) { -#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) - /* This exists only on Fedora or Mandriva */ +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) + /* This exists only on Fedora, Mandriva or Mageia */ if (access("/forcequotacheck", F_OK) >= 0) arg_force = true; #endif diff --git a/src/service.c b/src/service.c index 6184390659..eb475d9cc9 100644 --- a/src/service.c +++ b/src/service.c @@ -277,7 +277,8 @@ static int sysv_translate_facility(const char *name, const char *filename, char static const char * const table[] = { /* LSB defined facilities */ "local_fs", SPECIAL_LOCAL_FS_TARGET, -#ifndef TARGET_MANDRIVA +#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) +#else /* Due to unfortunate name selection in Mandriva, * $network is provided by network-up which is ordered * after network which actually starts interfaces. diff --git a/src/systemctl.c b/src/systemctl.c index b0baf8dc5f..175159d68f 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -3462,7 +3462,7 @@ finish: static int enable_sysv_units(char **args) { int r = 0; -#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX)) +#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA)) const char *verb = args[0]; unsigned f = 1, t = 1; LookupPaths paths; diff --git a/src/vconsole-setup.c b/src/vconsole-setup.c index c5f3628c9b..91967891f1 100644 --- a/src/vconsole-setup.c +++ b/src/vconsole-setup.c @@ -160,7 +160,7 @@ int main(int argc, char **argv) { #ifdef TARGET_GENTOO char *vc_unicode = NULL; #endif -#ifdef TARGET_MANDRIVA +#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) char *vc_keytable = NULL; #endif int fd = -1; @@ -371,7 +371,7 @@ int main(int argc, char **argv) { log_warning("Failed to read /etc/conf.d/keymaps: %s", strerror(-r)); } -#elif defined(TARGET_MANDRIVA) +#elif defined(TARGET_MANDRIVA) || defined (TARGET_MAGEIA) if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, "SYSFONT", &vc_font, diff --git a/units/console-shell.service.m4 b/units/console-shell.service.m4 index a4a9108b32..02adc8403b 100644 --- a/units/console-shell.service.m4 +++ b/units/console-shell.service.m4 @@ -23,6 +23,9 @@ After=rc-local.service m4_ifdef(`TARGET_MANDRIVA', After=rc-local.service )m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl Before=getty.target [Service] diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index 14d8187269..d2a145dacd 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -24,6 +24,9 @@ After=rc-local.service m4_ifdef(`TARGET_MANDRIVA', After=rc-local.service )m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl # If additional gettys are spawned during boot then we should make # sure that this is synchronized before getty.target, even though diff --git a/units/mageia/prefdm.service b/units/mageia/prefdm.service new file mode 100644 index 0000000000..4a896bf582 --- /dev/null +++ b/units/mageia/prefdm.service @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +[Unit] +Description=Display Manager +After=livesys-late.service rc-local.service systemd-user-sessions.service +After=network.target acpid.service fs.service haldaemon.service + +# Do not stop plymouth, it is done in prefdm if required +Conflicts=plymouth-quit.service +After=plymouth-quit.service + +[Service] +ExecStart=/etc/X11/prefdm +Type=forking +Restart=always +RestartSec=0 diff --git a/units/rescue.service.m4 b/units/rescue.service.m4 index 19b30d89f9..7dd8a220b8 100644 --- a/units/rescue.service.m4 +++ b/units/rescue.service.m4 @@ -25,10 +25,13 @@ ExecStart=-/bin/bash -c "exec ${SINGLE}"', m4_ifdef(`TARGET_MANDRIVA', `EnvironmentFile=/etc/sysconfig/init ExecStart=-/bin/bash -c "exec ${SINGLE}"', +m4_ifdef(`TARGET_MAGEIA', +`EnvironmentFile=/etc/sysconfig/init +ExecStart=-/bin/bash -c "exec ${SINGLE}"', m4_ifdef(`TARGET_MEEGO', `EnvironmentFile=/etc/sysconfig/init ExecStart=-/bin/bash -c "exec ${SINGLE}"', -`ExecStart=-/sbin/sulogin'))) +`ExecStart=-/sbin/sulogin')))) ExecStopPost=-/bin/systemctl --fail --no-block default StandardInput=tty-force StandardOutput=inherit diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 index 082290cb8b..e5f0ca6c6c 100644 --- a/units/serial-getty@.service.m4 +++ b/units/serial-getty@.service.m4 @@ -24,6 +24,9 @@ After=rc-local.service m4_ifdef(`TARGET_MANDRIVA', After=rc-local.service )m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl # If additional gettys are spawned during boot then we should make # sure that this is synchronized before getty.target, even though From 8aea83c718af18e6436e6bdce9437238de052dbb Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 2 Nov 2011 10:48:49 +0200 Subject: [PATCH 32/36] bash-completion: update with new verbs and arguments Adds arguments --root= --runtime --no-legend. Adds verbs link mask unmask reenable list-unit-files. Also uses list-unit-files to make nicer enable and disable completions. Rebased due to changes in systemctl. --- src/systemctl-bash-completion.sh | 61 +++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh index 6ebb792c00..0aa87af0bd 100644 --- a/src/systemctl-bash-completion.sh +++ b/src/systemctl-bash-completion.sh @@ -16,7 +16,7 @@ # along with systemd; If not, see . __systemctl() { - systemctl --no-legend "$@" + systemctl --full --no-legend "$@" } __contains_word () { @@ -36,10 +36,13 @@ __filter_units_by_property () { done } -__get_all_units () { __systemctl list-units --full --all | awk ' {print $1}' ; } -__get_active_units () { __systemctl list-units --full | awk ' {print $1}' ; } -__get_inactive_units () { __systemctl list-units --full --all | awk '$3 == "inactive" {print $1}' ; } -__get_failed_units () { __systemctl list-units --full | awk '$3 == "failed" {print $1}' ; } +__get_all_units () { __systemctl list-units --all | awk ' {print $1}' ; } +__get_active_units () { __systemctl list-units | awk ' {print $1}' ; } +__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; } +__get_failed_units () { __systemctl list-units | awk '$3 == "failed" {print $1}' ; } +__get_enabled_units () { __systemctl list-unit-files | awk '$2 == "enabled" {print $1}' ; } +__get_disabled_units () { __systemctl list-unit-files | awk '$2 == "disabled" {print $1}' ; } +__get_masked_units () { __systemctl list-unit-files | awk '$2 == "masked" {print $1}' ; } _systemctl () { local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} @@ -47,15 +50,15 @@ _systemctl () { local -A OPTS=( [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global - --help -h --no-ask-password --no-block --no-pager --no-reload --no-wall - --order --require --quiet -q --privileged -P --system --user --version' - [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t' + --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall + --order --require --quiet -q --privileged -P --system --user --version --runtime' + [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root' ) if __contains_word "$prev" ${OPTS[ARG]}; then case $prev in --signal|-s) - comps=$(compgen -A signal | grep '^SIG' | grep -Ev 'RTMIN|RTMAX|JUNK') + comps=$(compgen -A signal) ;; --type|-t) comps='automount device mount path service snapshot socket swap target timer' @@ -66,7 +69,14 @@ _systemctl () { --kill-mode) comps='control-group process' ;; - --property|-p|--host|-H) + --root) + comps=$(compgen -A directory -- "$cur" ) + compopt -o filenames + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) comps='' ;; esac @@ -81,22 +91,26 @@ _systemctl () { fi local -A VERBS=( - [ALL_UNITS]='enable disable is-active is-enabled status show' + [ALL_UNITS]='is-active is-enabled status show mask preset' + [ENABLED_UNITS]='disable reenable' + [DISABLED_UNITS]='enable' [FAILED_UNITS]='reset-failed' [STARTABLE_UNITS]='start' - [STOPPABLE_UNITS]='stop kill try-restart condrestart' + [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart' [ISOLATABLE_UNITS]='isolate' - [RELOADABLE_UNITS]='reload reload-or-try-restart force-reload' - [RESTARTABLE_UNITS]='restart reload-or-restart' + [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload' + [RESTARTABLE_UNITS]='restart reload-or-restart' + [MASKED_UNITS]='unmask' [JOBS]='cancel' [SNAPSHOTS]='delete' [ENVS]='set-environment unset-environment' - [STANDALONE]='daemon-reexec daemon-reload default dot dump emergency exit halt kexec - list-jobs list-units poweroff reboot rescue show-environment' + [STANDALONE]='daemon-reexec daemon-reload default dot dump + emergency exit halt kexec list-jobs list-units + list-unit-files poweroff reboot rescue show-environment' [NAME]='snapshot load' + [FILE]='link' ) - local verb for ((i=0; $i <= $COMP_CWORD; i++)); do if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then @@ -111,6 +125,12 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then comps=$( __get_all_units ) + elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then + comps=$( __get_enabled_units ) + + elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then + comps=$( __get_disabled_units ) + elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then comps=$( __filter_units_by_property CanStart yes \ $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' )) @@ -134,6 +154,9 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then comps=$( __get_failed_units ) + elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then + comps=$( __get_masked_units ) + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then comps='' @@ -146,6 +169,10 @@ _systemctl () { elif __contains_word "$verb" ${VERBS[ENVS]}; then comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) compopt -o nospace + + elif __contains_word "$verb" ${VERBS[FILE]}; then + comps=$( compgen -A file -- "$cur" ) + compopt -o filenames fi COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) From 3cdbf916d3629733fa9998d5802bf4c20d98c50e Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 2 Nov 2011 10:48:50 +0200 Subject: [PATCH 33/36] bash-completion: add completions for systemd-loginctl This script is straightforward and should give proper completions for all of systemd-loginctl's verbs. --- src/systemctl-bash-completion.sh | 83 ++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh index 0aa87af0bd..176591f281 100644 --- a/src/systemctl-bash-completion.sh +++ b/src/systemctl-bash-completion.sh @@ -179,3 +179,86 @@ _systemctl () { return 0 } complete -F _systemctl systemctl + +__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; } +__get_all_users () { systemd-loginctl list-users | awk '{print $2}' ; } +__get_all_seats () { systemd-loginctl list-seats | awk '{print $1}' ; } + +_systemd_loginctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version' + [ARG]='--host -H --kill-who --property -p --signal -s' + ) + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --kill-who) + comps='all leader' + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 + fi + + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session' + [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user' + [SEATS]='seat-status show-seat terminate-seat' + [STANDALONE]='list-sessions list-users list-seats flush-devices' + [ATTACH]='attach' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps="${VERBS[*]}" + + elif __contains_word "$verb" ${VERBS[SESSIONS]}; then + comps=$( __get_all_sessions ) + + elif __contains_word "$verb" ${VERBS[USERS]}; then + comps=$( __get_all_users ) + + elif __contains_word "$verb" ${VERBS[SEATS]}; then + comps=$( __get_all_seats ) + + elif __contains_word "$verb" ${VERBS[STANDALONE]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[ATTACH]}; then + if [[ $prev = $verb ]]; then + comps=$( __get_all_seats ) + else + comps=$(compgen -A file -- "$cur" ) + compopt -o filenames + fi + fi + + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 +} +complete -F _systemd_loginctl systemd-loginctl From f5a613c03c54cc82e92c38af0b3e1c130003a68b Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 2 Nov 2011 10:48:51 +0200 Subject: [PATCH 34/36] bash-completion: rename file since it is no longer for systemctl only --- Makefile.am | 2 +- ...{systemctl-bash-completion.sh => systemd-bash-completion.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{systemctl-bash-completion.sh => systemd-bash-completion.sh} (100%) diff --git a/Makefile.am b/Makefile.am index f701a45c87..0ce2356d78 100644 --- a/Makefile.am +++ b/Makefile.am @@ -321,7 +321,7 @@ dbusinterface_DATA += \ endif dist_bashcompletion_DATA = \ - src/systemctl-bash-completion.sh + src/systemd-bash-completion.sh dist_tmpfiles_DATA = \ tmpfiles.d/systemd.conf \ diff --git a/src/systemctl-bash-completion.sh b/src/systemd-bash-completion.sh similarity index 100% rename from src/systemctl-bash-completion.sh rename to src/systemd-bash-completion.sh From 353fa6a21aab96b0b82ab40cc22b08b1fb0bf652 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 3 Nov 2011 19:42:53 +0100 Subject: [PATCH 35/36] cgroup: immediately remove all cgroups which run empty Some controllers have scaling problems when many empty cgroups exist. Hence, as soon as we get a notification that a cgroup is empty, delete it. This is also nice to keep the systemd-cgls output short. --- src/cgroup.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cgroup.c b/src/cgroup.c index be837c3d0f..4bbb54fd7e 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -363,7 +363,8 @@ int cgroup_notify_empty(Manager *m, const char *group) { assert(m); assert(group); - if (!(l = hashmap_get(m->cgroup_bondings, group))) + l = hashmap_get(m->cgroup_bondings, group); + if (!l) return 0; LIST_FOREACH(by_path, b, l) { @@ -372,7 +373,8 @@ int cgroup_notify_empty(Manager *m, const char *group) { if (!b->unit) continue; - if ((t = cgroup_bonding_is_empty_list(b)) < 0) { + t = cgroup_bonding_is_empty_list(b); + if (t < 0) { /* If we don't know, we don't know */ if (t != -EAGAIN) @@ -381,9 +383,13 @@ int cgroup_notify_empty(Manager *m, const char *group) { continue; } - if (t > 0) + if (t > 0) { + /* If it is empty, let's delete it */ + cgroup_bonding_trim_list(b->unit->meta.cgroup_bondings, true); + if (UNIT_VTABLE(b->unit)->cgroup_notify_empty) UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit); + } } return 0; From 4cbd9ecf45f64c3a9acc99d473fbf3be3687ae24 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 3 Nov 2011 19:55:36 +0100 Subject: [PATCH 36/36] update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index fe73283cfe..5303497164 100644 --- a/TODO +++ b/TODO @@ -19,6 +19,8 @@ Bugfixes: Features: +* when an instanced service exits, remove its parent cgroup too if possible. + * as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys * unset container= in PID1?