summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-01-14 02:11:57 +0100
committerLennart Poettering <lennart@poettering.net>2013-01-14 21:24:58 +0100
commit1dcf60656cc68cf0182703d77e31f24f05b0c8cc (patch)
tree32f46201784103ae013c03dd5b9b0b0ffa7293ad
parentf84190d8cad66f36eef1d851213711244ca297be (diff)
systemctl: be smarter when mangling snapshot names
For "systemctl snapshot" it makes no sense to complete an incomplete name with ".service" as we previously did, use ".snapshot" instead. Also, don't bother with mount units or suchlike, we know that this must be a snapshot and hence is the only sane way for completion.
-rw-r--r--src/shared/unit-name.c30
-rw-r--r--src/shared/unit-name.h1
-rw-r--r--src/systemctl/systemctl.c46
3 files changed, 54 insertions, 23 deletions
diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
index 88ca0b8f2c..06bbfacb00 100644
--- a/src/shared/unit-name.c
+++ b/src/shared/unit-name.c
@@ -506,6 +506,36 @@ char *unit_name_mangle(const char *name) {
return r;
}
+char *snapshot_name_mangle(const char *name) {
+ char *r, *t;
+ const char *f;
+
+ assert(name);
+
+ /* Similar to unit_name_mangle(), but is called when we know
+ * that this is about snapshot units. */
+
+ r = new(char, strlen(name) * 4 + 1 + sizeof(".snapshot")-1);
+ if (!r)
+ return NULL;
+
+ for (f = name, t = r; *f; f++) {
+ if (*f == '/')
+ *(t++) = '-';
+ else if (!strchr(VALID_CHARS, *f))
+ t = do_escape_char(*f, t);
+ else
+ *(t++) = *f;
+ }
+
+ if (!endswith(name, ".snapshot"))
+ strcpy(t, ".snapshot");
+ else
+ *t = 0;
+
+ return r;
+}
+
UnitType unit_name_to_type(const char *n) {
const char *e;
diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h
index d7528a3ac7..9150dd0b3f 100644
--- a/src/shared/unit-name.h
+++ b/src/shared/unit-name.h
@@ -94,3 +94,4 @@ char *unit_name_to_path(const char *name);
char *unit_dbus_path_from_name(const char *name);
char *unit_name_mangle(const char *name);
+char *snapshot_name_mangle(const char *name);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index b22010dcac..76c67f20c8 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3173,17 +3173,19 @@ static int snapshot(DBusConnection *bus, char **args) {
dbus_bool_t cleanup = FALSE;
DBusMessageIter iter, sub;
const char
- *name = "", *path, *id,
+ *path, *id,
*interface = "org.freedesktop.systemd1.Unit",
*property = "Id";
_cleanup_free_ char *n = NULL;
dbus_error_init(&error);
- if (strv_length(args) > 1) {
- name = args[1];
- n = unit_name_mangle(name);
- }
+ if (strv_length(args) > 1)
+ n = snapshot_name_mangle(args[1]);
+ else
+ n = strdup("");
+ if (!n)
+ return log_oom();
r = bus_method_call_with_reply (
bus,
@@ -3193,18 +3195,18 @@ static int snapshot(DBusConnection *bus, char **args) {
"CreateSnapshot",
&reply,
NULL,
- DBUS_TYPE_STRING, n ? (const char**) &n : &name,
+ DBUS_TYPE_STRING, &n,
DBUS_TYPE_BOOLEAN, &cleanup,
DBUS_TYPE_INVALID);
if (r < 0)
- goto finish;
+ return r;
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID)) {
log_error("Failed to parse reply: %s", bus_error_message(&error));
- r = -EIO;
- goto finish;
+ dbus_error_free(&error);
+ return -EIO;
}
dbus_message_unref(reply);
@@ -3222,21 +3224,19 @@ static int snapshot(DBusConnection *bus, char **args) {
DBUS_TYPE_STRING, &property,
DBUS_TYPE_INVALID);
if (r < 0)
- goto finish;
+ return r;
if (!dbus_message_iter_init(reply, &iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
log_error("Failed to parse reply.");
- r = -EIO;
- goto finish;
+ return -EIO;
}
dbus_message_iter_recurse(&iter, &sub);
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
log_error("Failed to parse reply.");
- r = -EIO;
- goto finish;
+ return -EIO;
}
dbus_message_iter_get_basic(&sub, &id);
@@ -3244,10 +3244,7 @@ static int snapshot(DBusConnection *bus, char **args) {
if (!arg_quiet)
puts(id);
-finish:
- dbus_error_free(&error);
-
- return r;
+ return 0;
}
static int delete_snapshot(DBusConnection *bus, char **args) {
@@ -3259,7 +3256,10 @@ static int delete_snapshot(DBusConnection *bus, char **args) {
_cleanup_free_ char *n = NULL;
int r;
- n = unit_name_mangle(*name);
+ n = snapshot_name_mangle(*name);
+ if (!n)
+ return log_oom();
+
r = bus_method_call_with_reply(
bus,
"org.freedesktop.systemd1",
@@ -3268,7 +3268,7 @@ static int delete_snapshot(DBusConnection *bus, char **args) {
"RemoveSnapshot",
NULL,
NULL,
- DBUS_TYPE_STRING, n ? &n : name,
+ DBUS_TYPE_STRING, &n,
DBUS_TYPE_INVALID);
if (r < 0)
return r;
@@ -3302,7 +3302,7 @@ static int daemon_reload(DBusConnection *bus, char **args) {
/* "daemon-reload" */ "Reload";
}
- r = bus_method_call_with_reply (
+ r = bus_method_call_with_reply(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
@@ -3320,10 +3320,10 @@ static int daemon_reload(DBusConnection *bus, char **args) {
/* On reexecution, we expect a disconnect, not
* a reply */
r = 0;
- else if (r)
+ else if (r < 0)
log_error("Failed to issue method call: %s", bus_error_message(&error));
- dbus_error_free(&error);
+ dbus_error_free(&error);
return r;
}