[systemd-commits] 13 commits - Makefile.am configure.ac man/sd_pid_get_session.xml src/cryptsetup src/cryptsetup-generator.c src/cryptsetup.c src/generate-kbd-model-map src/journal src/kbd-model-map src/locale src/localed.c src/login src/logs-show.c src/logs-show.h src/nspawn.c src/readahead src/sd-id128.c src/socket.c src/systemctl.c
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Jan 3 12:09:06 PST 2012
Makefile.am | 203 +++++++------
configure.ac | 16 +
man/sd_pid_get_session.xml | 40 +-
src/cryptsetup-generator.c | 298 -------------------
src/cryptsetup.c | 529 ----------------------------------
src/cryptsetup/cryptsetup-generator.c | 298 +++++++++++++++++++
src/cryptsetup/cryptsetup.c | 529 ++++++++++++++++++++++++++++++++++
src/generate-kbd-model-map | 33 --
src/journal/journal-send.c | 16 -
src/journal/journalctl.c | 311 -------------------
src/journal/journald.c | 85 +++--
src/journal/sd-journal.c | 161 ++++++----
src/journal/sd-journal.h | 2
src/kbd-model-map | 72 ----
src/locale/generate-kbd-model-map | 33 ++
src/locale/kbd-model-map | 72 ++++
src/login/libsystemd-login.sym | 5
src/login/sd-login.c | 27 +
src/login/sd-login.h | 4
src/logs-show.c | 404 +++++++++++++++++++++++++
src/logs-show.h | 49 +++
src/nspawn.c | 12
src/readahead/sd-readahead.c | 14
src/readahead/sd-readahead.h | 10
src/sd-id128.c | 30 +
src/socket.c | 16 -
src/systemctl.c | 4
27 files changed, 1814 insertions(+), 1459 deletions(-)
New commits:
commit 86aa7ba4f9969bbfc75ebd51f944313695f1a0a1
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 21:08:28 2012 +0100
systemctl: hook up systemctl with the journal
diff --git a/Makefile.am b/Makefile.am
index 8bb5b9d..6c0fd05 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -98,7 +98,8 @@ AM_CPPFLAGS = \
-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
-I $(top_srcdir)/src \
-I $(top_srcdir)/src/readahead \
- -I $(top_srcdir)/src/login
+ -I $(top_srcdir)/src/login \
+ -I $(top_srcdir)/src/journal
if TARGET_GENTOO
AM_CPPFLAGS += \
@@ -923,7 +924,8 @@ systemctl_SOURCES = \
src/unit-name.c \
src/pager.c \
src/install.c \
- src/spawn-agent.c
+ src/spawn-agent.c \
+ src/logs-show.c
systemctl_CFLAGS = \
$(AM_CFLAGS) \
@@ -932,6 +934,7 @@ systemctl_CFLAGS = \
systemctl_LDADD = \
libsystemd-basic.la \
libsystemd-daemon.la \
+ libsystemd-journal.la \
$(DBUS_LIBS)
systemd_notify_SOURCES = \
@@ -1189,14 +1192,12 @@ endif
systemd_journalctl_SOURCES = \
src/journal/journalctl.c \
- src/journal/sd-journal.c \
- src/journal/journal-file.c \
- src/journal/lookup3.c \
- src/sd-id128.c \
- src/pager.c
+ src/pager.c \
+ src/logs-show.c
systemd_journalctl_LDADD = \
- libsystemd-basic.la
+ libsystemd-basic.la \
+ libsystemd-journal.la
if HAVE_XZ
systemd_journalctl_SOURCES += \
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 7015182..4c20ff6 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -35,319 +35,14 @@
#include "util.h"
#include "build.h"
#include "pager.h"
+#include "logs-show.h"
-#define PRINT_THRESHOLD 128
-
-static enum {
- OUTPUT_SHORT,
- OUTPUT_VERBOSE,
- OUTPUT_EXPORT,
- OUTPUT_JSON,
- _OUTPUT_MAX
-} arg_output = OUTPUT_SHORT;
+static output_mode arg_output = OUTPUT_SHORT;
static bool arg_follow = false;
static bool arg_show_all = false;
static bool arg_no_pager = false;
-static bool contains_unprintable(const void *p, size_t l) {
- const char *j;
-
- for (j = p; j < (const char *) p + l; j++)
- if (*j < ' ' || *j >= 127)
- return true;
-
- return false;
-}
-
-static int output_short(sd_journal *j, unsigned line) {
- int r;
- uint64_t realtime;
- time_t t;
- struct tm tm;
- char buf[64];
- const void *data;
- size_t length;
- size_t n = 0;
-
- assert(j);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0) {
- log_error("Failed to get realtime: %s", strerror(-r));
- return r;
- }
-
- t = (time_t) (realtime / USEC_PER_SEC);
- if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) {
- log_error("Failed to format time.");
- return -EINVAL;
- }
-
- fputs(buf, stdout);
- n += strlen(buf);
-
- if (sd_journal_get_data(j, "_HOSTNAME", &data, &length) >= 0 &&
- (arg_show_all || (!contains_unprintable(data, length) &&
- length < PRINT_THRESHOLD))) {
- printf(" %.*s", (int) length - 10, ((const char*) data) + 10);
- n += length - 10 + 1;
- }
-
- if (sd_journal_get_data(j, "MESSAGE", &data, &length) >= 0) {
- if (arg_show_all)
- printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
- else if (contains_unprintable(data, length))
- fputs(" [blob data]", stdout);
- else if (length - 8 + n < columns())
- printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
- else if (n < columns()) {
- char *e;
-
- e = ellipsize_mem((const char *) data + 8, length - 8, columns() - n - 2, 90);
-
- if (!e)
- printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
- else
- printf(" %s", e);
-
- free(e);
- }
- }
-
- fputc('\n', stdout);
-
- return 0;
-}
-
-static int output_verbose(sd_journal *j, unsigned line) {
- const void *data;
- size_t length;
- char *cursor;
- uint64_t realtime;
- char ts[FORMAT_TIMESTAMP_MAX];
- int r;
-
- assert(j);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0) {
- log_error("Failed to get realtime timestamp: %s", strerror(-r));
- return r;
- }
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0) {
- log_error("Failed to get cursor: %s", strerror(-r));
- return r;
- }
-
- printf("%s [%s]\n",
- format_timestamp(ts, sizeof(ts), realtime),
- cursor);
-
- free(cursor);
-
- SD_JOURNAL_FOREACH_DATA(j, data, length) {
- if (!arg_show_all && (length > PRINT_THRESHOLD ||
- contains_unprintable(data, length))) {
- const char *c;
-
- c = memchr(data, '=', length);
- if (!c) {
- log_error("Invalid field.");
- return -EINVAL;
- }
-
- printf("\t%.*s=[blob data]\n",
- (int) (c - (const char*) data),
- (const char*) data);
- } else
- printf("\t%.*s\n", (int) length, (const char*) data);
- }
-
- return 0;
-}
-
-static int output_export(sd_journal *j, unsigned line) {
- sd_id128_t boot_id;
- char sid[33];
- int r;
- usec_t realtime, monotonic;
- char *cursor;
- const void *data;
- size_t length;
-
- assert(j);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0) {
- log_error("Failed to get realtime timestamp: %s", strerror(-r));
- return r;
- }
-
- r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
- if (r < 0) {
- log_error("Failed to get monotonic timestamp: %s", strerror(-r));
- return r;
- }
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0) {
- log_error("Failed to get cursor: %s", strerror(-r));
- return r;
- }
-
- printf(".cursor=%s\n"
- ".realtime=%llu\n"
- ".monotonic=%llu\n"
- ".boot_id=%s\n",
- cursor,
- (unsigned long long) realtime,
- (unsigned long long) monotonic,
- sd_id128_to_string(boot_id, sid));
-
- free(cursor);
-
- SD_JOURNAL_FOREACH_DATA(j, data, length) {
-
- if (contains_unprintable(data, length)) {
- const char *c;
- uint64_t le64;
-
- c = memchr(data, '=', length);
- if (!c) {
- log_error("Invalid field.");
- return -EINVAL;
- }
-
- fwrite(data, c - (const char*) data, 1, stdout);
- fputc('\n', stdout);
- le64 = htole64(length - (c - (const char*) data) - 1);
- fwrite(&le64, sizeof(le64), 1, stdout);
- fwrite(c + 1, length - (c - (const char*) data) - 1, 1, stdout);
- } else
- fwrite(data, length, 1, stdout);
-
- fputc('\n', stdout);
- }
-
- fputc('\n', stdout);
-
- return 0;
-}
-
-static void json_escape(const char* p, size_t l) {
-
- if (contains_unprintable(p, l)) {
- bool not_first = false;
-
- fputs("[ ", stdout);
-
- while (l > 0) {
- if (not_first)
- printf(", %u", (uint8_t) *p);
- else {
- not_first = true;
- printf("%u", (uint8_t) *p);
- }
-
- p++;
- l--;
- }
-
- fputs(" ]", stdout);
- } else {
- fputc('\"', stdout);
-
- while (l > 0) {
- if (*p == '"' || *p == '\\') {
- fputc('\\', stdout);
- fputc(*p, stdout);
- } else
- fputc(*p, stdout);
-
- p++;
- l--;
- }
-
- fputc('\"', stdout);
- }
-}
-
-static int output_json(sd_journal *j, unsigned line) {
- uint64_t realtime, monotonic;
- char *cursor;
- const void *data;
- size_t length;
- sd_id128_t boot_id;
- char sid[33];
- int r;
-
- assert(j);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0) {
- log_error("Failed to get realtime timestamp: %s", strerror(-r));
- return r;
- }
-
- r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
- if (r < 0) {
- log_error("Failed to get monotonic timestamp: %s", strerror(-r));
- return r;
- }
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0) {
- log_error("Failed to get cursor: %s", strerror(-r));
- return r;
- }
-
- if (line == 1)
- fputc('\n', stdout);
- else
- fputs(",\n", stdout);
-
- printf("{\n"
- "\t\".cursor\" : \"%s\",\n"
- "\t\".realtime\" : %llu,\n"
- "\t\".monotonic\" : %llu,\n"
- "\t\".boot_id\" : \"%s\"",
- cursor,
- (unsigned long long) realtime,
- (unsigned long long) monotonic,
- sd_id128_to_string(boot_id, sid));
-
- free(cursor);
-
- SD_JOURNAL_FOREACH_DATA(j, data, length) {
- const char *c;
-
- c = memchr(data, '=', length);
- if (!c) {
- log_error("Invalid field.");
- return -EINVAL;
- }
-
- fputs(",\n\t", stdout);
- json_escape(data, c - (const char*) data);
- fputs(" : ", stdout);
- json_escape(c + 1, length - (c - (const char*) data) - 1);
- }
-
- fputs("\n}", stdout);
- fflush(stdout);
-
- return 0;
-}
-
-static int (*output_funcs[_OUTPUT_MAX])(sd_journal*j, unsigned line) = {
- [OUTPUT_SHORT] = output_short,
- [OUTPUT_VERBOSE] = output_verbose,
- [OUTPUT_EXPORT] = output_export,
- [OUTPUT_JSON] = output_json
-};
static int help(void) {
@@ -503,7 +198,7 @@ int main(int argc, char *argv[]) {
line ++;
- r = output_funcs[arg_output](j, line);
+ r = output_journal(j, arg_output, line, arg_show_all);
if (r < 0)
goto finish;
}
diff --git a/src/logs-show.c b/src/logs-show.c
new file mode 100644
index 0000000..d178f95
--- /dev/null
+++ b/src/logs-show.c
@@ -0,0 +1,404 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <time.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "logs-show.h"
+#include "log.h"
+#include "util.h"
+
+#define PRINT_THRESHOLD 128
+
+static bool contains_unprintable(const void *p, size_t l) {
+ const char *j;
+
+ for (j = p; j < (const char *) p + l; j++)
+ if (*j < ' ' || *j >= 127)
+ return true;
+
+ return false;
+}
+
+static int output_short(sd_journal *j, unsigned line, bool show_all) {
+ int r;
+ uint64_t realtime;
+ time_t t;
+ struct tm tm;
+ char buf[64];
+ const void *data;
+ size_t length;
+ size_t n = 0;
+
+ assert(j);
+
+ r = sd_journal_get_realtime_usec(j, &realtime);
+ if (r < 0) {
+ log_error("Failed to get realtime: %s", strerror(-r));
+ return r;
+ }
+
+ t = (time_t) (realtime / USEC_PER_SEC);
+ if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) {
+ log_error("Failed to format time.");
+ return -EINVAL;
+ }
+
+ fputs(buf, stdout);
+ n += strlen(buf);
+
+ if (sd_journal_get_data(j, "_HOSTNAME", &data, &length) >= 0 &&
+ (show_all || (!contains_unprintable(data, length) &&
+ length < PRINT_THRESHOLD))) {
+ printf(" %.*s", (int) length - 10, ((const char*) data) + 10);
+ n += length - 10 + 1;
+ }
+
+ if (sd_journal_get_data(j, "MESSAGE", &data, &length) >= 0) {
+ if (show_all)
+ printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
+ else if (contains_unprintable(data, length))
+ fputs(" [blob data]", stdout);
+ else if (length - 8 + n < columns())
+ printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
+ else if (n < columns()) {
+ char *e;
+
+ e = ellipsize_mem((const char *) data + 8, length - 8, columns() - n - 2, 90);
+
+ if (!e)
+ printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
+ else
+ printf(" %s", e);
+
+ free(e);
+ }
+ }
+
+ fputc('\n', stdout);
+
+ return 0;
+}
+
+static int output_verbose(sd_journal *j, unsigned line, bool show_all) {
+ const void *data;
+ size_t length;
+ char *cursor;
+ uint64_t realtime;
+ char ts[FORMAT_TIMESTAMP_MAX];
+ int r;
+
+ assert(j);
+
+ r = sd_journal_get_realtime_usec(j, &realtime);
+ if (r < 0) {
+ log_error("Failed to get realtime timestamp: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_get_cursor(j, &cursor);
+ if (r < 0) {
+ log_error("Failed to get cursor: %s", strerror(-r));
+ return r;
+ }
+
+ printf("%s [%s]\n",
+ format_timestamp(ts, sizeof(ts), realtime),
+ cursor);
+
+ free(cursor);
+
+ SD_JOURNAL_FOREACH_DATA(j, data, length) {
+ if (!show_all && (length > PRINT_THRESHOLD ||
+ contains_unprintable(data, length))) {
+ const char *c;
+
+ c = memchr(data, '=', length);
+ if (!c) {
+ log_error("Invalid field.");
+ return -EINVAL;
+ }
+
+ printf("\t%.*s=[blob data]\n",
+ (int) (c - (const char*) data),
+ (const char*) data);
+ } else
+ printf("\t%.*s\n", (int) length, (const char*) data);
+ }
+
+ return 0;
+}
+
+static int output_export(sd_journal *j, unsigned line, bool show_all) {
+ sd_id128_t boot_id;
+ char sid[33];
+ int r;
+ usec_t realtime, monotonic;
+ char *cursor;
+ const void *data;
+ size_t length;
+
+ assert(j);
+
+ r = sd_journal_get_realtime_usec(j, &realtime);
+ if (r < 0) {
+ log_error("Failed to get realtime timestamp: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
+ if (r < 0) {
+ log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_get_cursor(j, &cursor);
+ if (r < 0) {
+ log_error("Failed to get cursor: %s", strerror(-r));
+ return r;
+ }
+
+ printf(".cursor=%s\n"
+ ".realtime=%llu\n"
+ ".monotonic=%llu\n"
+ ".boot_id=%s\n",
+ cursor,
+ (unsigned long long) realtime,
+ (unsigned long long) monotonic,
+ sd_id128_to_string(boot_id, sid));
+
+ free(cursor);
+
+ SD_JOURNAL_FOREACH_DATA(j, data, length) {
+
+ if (contains_unprintable(data, length)) {
+ const char *c;
+ uint64_t le64;
+
+ c = memchr(data, '=', length);
+ if (!c) {
+ log_error("Invalid field.");
+ return -EINVAL;
+ }
+
+ fwrite(data, c - (const char*) data, 1, stdout);
+ fputc('\n', stdout);
+ le64 = htole64(length - (c - (const char*) data) - 1);
+ fwrite(&le64, sizeof(le64), 1, stdout);
+ fwrite(c + 1, length - (c - (const char*) data) - 1, 1, stdout);
+ } else
+ fwrite(data, length, 1, stdout);
+
+ fputc('\n', stdout);
+ }
+
+ fputc('\n', stdout);
+
+ return 0;
+}
+
+static void json_escape(const char* p, size_t l) {
+
+ if (contains_unprintable(p, l)) {
+ bool not_first = false;
+
+ fputs("[ ", stdout);
+
+ while (l > 0) {
+ if (not_first)
+ printf(", %u", (uint8_t) *p);
+ else {
+ not_first = true;
+ printf("%u", (uint8_t) *p);
+ }
+
+ p++;
+ l--;
+ }
+
+ fputs(" ]", stdout);
+ } else {
+ fputc('\"', stdout);
+
+ while (l > 0) {
+ if (*p == '"' || *p == '\\') {
+ fputc('\\', stdout);
+ fputc(*p, stdout);
+ } else
+ fputc(*p, stdout);
+
+ p++;
+ l--;
+ }
+
+ fputc('\"', stdout);
+ }
+}
+
+static int output_json(sd_journal *j, unsigned line, bool show_all) {
+ uint64_t realtime, monotonic;
+ char *cursor;
+ const void *data;
+ size_t length;
+ sd_id128_t boot_id;
+ char sid[33];
+ int r;
+
+ assert(j);
+
+ r = sd_journal_get_realtime_usec(j, &realtime);
+ if (r < 0) {
+ log_error("Failed to get realtime timestamp: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
+ if (r < 0) {
+ log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_get_cursor(j, &cursor);
+ if (r < 0) {
+ log_error("Failed to get cursor: %s", strerror(-r));
+ return r;
+ }
+
+ if (line == 1)
+ fputc('\n', stdout);
+ else
+ fputs(",\n", stdout);
+
+ printf("{\n"
+ "\t\".cursor\" : \"%s\",\n"
+ "\t\".realtime\" : %llu,\n"
+ "\t\".monotonic\" : %llu,\n"
+ "\t\".boot_id\" : \"%s\"",
+ cursor,
+ (unsigned long long) realtime,
+ (unsigned long long) monotonic,
+ sd_id128_to_string(boot_id, sid));
+
+ free(cursor);
+
+ SD_JOURNAL_FOREACH_DATA(j, data, length) {
+ const char *c;
+
+ c = memchr(data, '=', length);
+ if (!c) {
+ log_error("Invalid field.");
+ return -EINVAL;
+ }
+
+ fputs(",\n\t", stdout);
+ json_escape(data, c - (const char*) data);
+ fputs(" : ", stdout);
+ json_escape(c + 1, length - (c - (const char*) data) - 1);
+ }
+
+ fputs("\n}", stdout);
+ fflush(stdout);
+
+ return 0;
+}
+
+static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, bool show_all) = {
+ [OUTPUT_SHORT] = output_short,
+ [OUTPUT_VERBOSE] = output_verbose,
+ [OUTPUT_EXPORT] = output_export,
+ [OUTPUT_JSON] = output_json
+};
+
+int output_journal(sd_journal *j, output_mode mode, unsigned line, bool show_all) {
+ assert(mode < _OUTPUT_MODE_MAX);
+
+ return output_funcs[mode](j, line, show_all);
+}
+
+int show_journal_by_service(
+ const char *service,
+ output_mode mode,
+ const char *prefix,
+ unsigned n_columns,
+ usec_t not_before,
+ unsigned how_many,
+ bool show_all) {
+
+ char *m = NULL;
+ sd_journal *j;
+ int r;
+ unsigned i;
+
+ assert(service);
+
+ if (n_columns <= 0)
+ n_columns = columns();
+
+ if (how_many <= 0)
+ how_many = 10;
+
+ if (!prefix)
+ prefix = "";
+
+ if (asprintf(&m, "_SYSTEMD_SERVICE=%s", service) < 0) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY);
+ if (r < 0)
+ goto finish;
+
+ r = sd_journal_add_match(j, m, strlen(m));
+ if (r < 0)
+ goto finish;
+
+ r = sd_journal_seek_tail(j);
+ if (r < 0)
+ goto finish;
+
+ for (i = 0; i < how_many; i++)
+ sd_journal_previous(j);
+
+ for (i = 0; i < how_many; i++) {
+
+ r = sd_journal_next(j);
+ if (r < 0)
+ goto finish;
+
+ if (r == 0)
+ break;
+
+ r = output_journal(j, mode, i+1, show_all);
+ if (r < 0)
+ goto finish;
+ }
+
+finish:
+ if (m)
+ free(m);
+
+ if (j)
+ sd_journal_close(j);
+
+ return r;
+}
diff --git a/src/logs-show.h b/src/logs-show.h
new file mode 100644
index 0000000..f83df06
--- /dev/null
+++ b/src/logs-show.h
@@ -0,0 +1,49 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foologsshowhfoo
+#define foologsshowhfoo
+
+/***
+ This file is part of systemd.
+
+ Copyright 2012 Lennart Poettering
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "sd-journal.h"
+#include "util.h"
+
+typedef enum output_mode {
+ OUTPUT_SHORT,
+ OUTPUT_VERBOSE,
+ OUTPUT_EXPORT,
+ OUTPUT_JSON,
+ _OUTPUT_MODE_MAX
+} output_mode;
+
+int output_journal(sd_journal *j, output_mode mode, unsigned line, bool show_all);
+
+int show_journal_by_service(
+ const char *service,
+ output_mode mode,
+ const char *prefix,
+ unsigned n_columns,
+ usec_t not_before,
+ unsigned how_many,
+ bool show_all);
+
+#endif
diff --git a/src/systemctl.c b/src/systemctl.c
index 1142200..10e3991 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -58,6 +58,7 @@
#include "pager.h"
#include "spawn-agent.h"
#include "install.h"
+#include "logs-show.h"
static const char *arg_type = NULL;
static char **arg_property = NULL;
@@ -2261,6 +2262,9 @@ static void print_status_info(UnitStatusInfo *i) {
}
}
+ if (i->id && arg_transport != TRANSPORT_SSH)
+ show_journal_by_service(i->id, OUTPUT_SHORT, NULL, 0, 0, 0, arg_all);
+
if (i->need_daemon_reload)
printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n",
ansi_highlight(true),
commit adf7d506b50af9ba398a9925c8cd47ba328e720c
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 21:07:12 2012 +0100
journal: never fail if we cannot access /var, just print a warning
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 5c8e713..1faf570 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -1196,12 +1196,10 @@ static int system_journal_open(Server *s) {
fix_perms(s->system_journal, 0);
} else if (r < 0) {
- if (r == -ENOENT || r == -EROFS)
- r = 0;
- else {
- log_error("Failed to open system journal: %s", strerror(-r));
- return r;
- }
+ if (r != -ENOENT && r != -EROFS)
+ log_warning("Failed to open system journal: %s", strerror(-r));
+
+ r = 0;
}
}
@@ -1221,13 +1219,10 @@ static int system_journal_open(Server *s) {
free(fn);
if (r < 0) {
+ if (r != -ENOENT)
+ log_warning("Failed to open runtime journal: %s", strerror(-r));
- if (r == -ENOENT)
- r = 0;
- else {
- log_error("Failed to open runtime journal: %s", strerror(-r));
- return r;
- }
+ r = 0;
}
} else {
commit 52f4f45bf48cfb757024f9abf49f1533b661397a
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 21:02:13 2012 +0100
journald: treat a read-only /var identical to an unmounted one
diff --git a/Makefile.am b/Makefile.am
index 1af9cbc..8bb5b9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1175,6 +1175,7 @@ systemd_journald_CFLAGS = \
systemd_journald_LDADD = \
libsystemd-basic.la \
libsystemd-daemon.la \
+ libsystemd-login.la \
$(ACL_LIBS)
if HAVE_XZ
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 44c2aa4..5c8e713 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -1196,7 +1196,7 @@ static int system_journal_open(Server *s) {
fix_perms(s->system_journal, 0);
} else if (r < 0) {
- if (r == -ENOENT)
+ if (r == -ENOENT || r == -EROFS)
r = 0;
else {
log_error("Failed to open system journal: %s", strerror(-r));
commit 85d83bf41c8bdf55c10b7f845d81e5787ef6c295
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 21:01:11 2012 +0100
journald: add _SYSTEMD_SESSION, _SYSTEMD_OWNER_UID, _SYSTEMD_SERVICE to all entries
diff --git a/src/journal/journald.c b/src/journal/journald.c
index f637d94..44c2aa4 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -41,6 +41,7 @@
#include "list.h"
#include "journal-rate-limit.h"
#include "sd-journal.h"
+#include "sd-login.h"
#include "journal-internal.h"
#define USER_JOURNALS_MAX 1024
@@ -423,7 +424,8 @@ static void dispatch_message_real(Server *s,
*source_time = NULL, *boot_id = NULL, *machine_id = NULL,
*comm = NULL, *cmdline = NULL, *hostname = NULL,
*audit_session = NULL, *audit_loginuid = NULL,
- *exe = NULL, *cgroup = NULL;
+ *exe = NULL, *cgroup = NULL, *session = NULL,
+ *owner_uid = NULL, *service = NULL;
char idbuf[33];
sd_id128_t id;
@@ -436,11 +438,11 @@ static void dispatch_message_real(Server *s,
assert(s);
assert(iovec);
assert(n > 0);
- assert(n + 13 <= m);
+ assert(n + 16 <= m);
if (ucred) {
- uint32_t session;
- char *path;
+ uint32_t audit;
+ uid_t owner;
realuid = ucred->uid;
@@ -456,30 +458,33 @@ static void dispatch_message_real(Server *s,
r = get_process_comm(ucred->pid, &t);
if (r >= 0) {
comm = strappend("_COMM=", t);
+ free(t);
+
if (comm)
IOVEC_SET_STRING(iovec[n++], comm);
- free(t);
}
r = get_process_exe(ucred->pid, &t);
if (r >= 0) {
exe = strappend("_EXE=", t);
+ free(t);
+
if (comm)
IOVEC_SET_STRING(iovec[n++], exe);
- free(t);
}
r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t);
if (r >= 0) {
cmdline = strappend("_CMDLINE=", t);
+ free(t);
+
if (cmdline)
IOVEC_SET_STRING(iovec[n++], cmdline);
- free(t);
}
- r = audit_session_from_pid(ucred->pid, &session);
+ r = audit_session_from_pid(ucred->pid, &audit);
if (r >= 0)
- if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) session) >= 0)
+ if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0)
IOVEC_SET_STRING(iovec[n++], audit_session);
r = audit_loginuid_from_pid(ucred->pid, &loginuid);
@@ -487,14 +492,34 @@ static void dispatch_message_real(Server *s,
if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
IOVEC_SET_STRING(iovec[n++], audit_loginuid);
- path = shortened_cgroup_path(ucred->pid);
- if (path) {
- cgroup = strappend("_SYSTEMD_CGROUP=", path);
+ t = shortened_cgroup_path(ucred->pid);
+ if (t) {
+ cgroup = strappend("_SYSTEMD_CGROUP=", t);
+ free(t);
+
if (cgroup)
IOVEC_SET_STRING(iovec[n++], cgroup);
+ }
+
+ if (sd_pid_get_session(ucred->pid, &t) >= 0) {
+ session = strappend("_SYSTEMD_SESSION=", t);
+ free(t);
+
+ if (session)
+ IOVEC_SET_STRING(iovec[n++], session);
+ }
- free(path);
+ if (sd_pid_get_service(ucred->pid, &t) >= 0) {
+ service = strappend("_SYSTEMD_SERVICE=", t);
+ free(t);
+
+ if (service)
+ IOVEC_SET_STRING(iovec[n++], service);
}
+
+ if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0)
+ if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
+ IOVEC_SET_STRING(iovec[n++], owner_uid);
}
if (tv) {
@@ -519,9 +544,9 @@ static void dispatch_message_real(Server *s,
t = gethostname_malloc();
if (t) {
hostname = strappend("_HOSTNAME=", t);
+ free(t);
if (hostname)
IOVEC_SET_STRING(iovec[n++], hostname);
- free(t);
}
assert(n <= m);
@@ -562,6 +587,9 @@ retry:
free(audit_session);
free(audit_loginuid);
free(cgroup);
+ free(session);
+ free(owner_uid);
+ free(service);
}
static void dispatch_message(Server *s,
@@ -611,7 +639,7 @@ static void dispatch_message(Server *s,
if (rl > 1) {
int j = 0;
char suppress_message[LINE_MAX];
- struct iovec suppress_iovec[15];
+ struct iovec suppress_iovec[18];
/* Write a suppression message if we suppressed something */
@@ -632,7 +660,7 @@ finish:
static void process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv) {
char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL;
- struct iovec iovec[16];
+ struct iovec iovec[19];
unsigned n = 0;
int priority = LOG_USER | LOG_INFO;
@@ -739,11 +767,11 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_
/* A property follows */
- if (n+13 >= m) {
+ if (n+16 >= m) {
struct iovec *c;
unsigned u;
- u = MAX((n+13U) * 2U, 4U);
+ u = MAX((n+16U) * 2U, 4U);
c = realloc(iovec, u * sizeof(struct iovec));
if (!c) {
log_error("Out of memory");
@@ -827,7 +855,7 @@ static void process_native_message(Server *s, const void *buffer, size_t buffer_
}
static int stdout_stream_log(StdoutStream *s, const char *p, size_t l) {
- struct iovec iovec[15];
+ struct iovec iovec[18];
char *message = NULL, *syslog_priority = NULL;
unsigned n = 0;
size_t tag_len;
commit 000a2c98860e4c1de7e1477bedf6ad216f8c5854
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:58:07 2012 +0100
sd-id128: add _public_ to all exports, and add validity checks for all parameters
diff --git a/Makefile.am b/Makefile.am
index 651b37d..1af9cbc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1925,7 +1925,7 @@ man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
man/sd_session_get_uid.3: man/sd_session_is_active.3
man/sd_session_get_seat.3: man/sd_session_is_active.3
man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
-man/sd_pid_get_session.3: man/sd_pid_get_session.3
+man/sd_pid_get_service.3: man/sd_pid_get_session.3
man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
man/sd_uid_get_seats.3: man/sd_uid_get_state.3
diff --git a/src/sd-id128.c b/src/sd-id128.c
index f5e0432..387cf91 100644
--- a/src/sd-id128.c
+++ b/src/sd-id128.c
@@ -27,10 +27,11 @@
#include "util.h"
#include "macro.h"
-char *sd_id128_to_string(sd_id128_t id, char s[33]) {
+_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) {
unsigned n;
- assert(s);
+ if (!s)
+ return NULL;
for (n = 0; n < 16; n++) {
s[n*2] = hexchar(id.bytes[n] >> 4);
@@ -42,12 +43,14 @@ char *sd_id128_to_string(sd_id128_t id, char s[33]) {
return s;
}
-int sd_id128_from_string(const char s[33], sd_id128_t *ret) {
+_public_ int sd_id128_from_string(const char s[33], sd_id128_t *ret) {
unsigned n;
sd_id128_t t;
- assert(s);
- assert(ret);
+ if (!s)
+ return -EINVAL;
+ if (!ret)
+ return -EINVAL;
for (n = 0; n < 16; n++) {
int a, b;
@@ -70,7 +73,7 @@ int sd_id128_from_string(const char s[33], sd_id128_t *ret) {
return 0;
}
-sd_id128_t sd_id128_make_v4_uuid(sd_id128_t id) {
+_public_ sd_id128_t sd_id128_make_v4_uuid(sd_id128_t id) {
/* Stolen from generate_random_uuid() of drivers/char/random.c
* in the kernel sources */
@@ -83,7 +86,7 @@ sd_id128_t sd_id128_make_v4_uuid(sd_id128_t id) {
return id;
}
-int sd_id128_get_machine(sd_id128_t *ret) {
+_public_ int sd_id128_get_machine(sd_id128_t *ret) {
static __thread sd_id128_t saved_machine_id;
static __thread bool saved_machine_id_valid = false;
int fd;
@@ -92,6 +95,9 @@ int sd_id128_get_machine(sd_id128_t *ret) {
unsigned j;
sd_id128_t t;
+ if (!ret)
+ return -EINVAL;
+
if (saved_machine_id_valid) {
*ret = saved_machine_id;
return 0;
@@ -129,7 +135,7 @@ int sd_id128_get_machine(sd_id128_t *ret) {
return 0;
}
-int sd_id128_get_boot(sd_id128_t *ret) {
+_public_ int sd_id128_get_boot(sd_id128_t *ret) {
static __thread sd_id128_t saved_boot_id;
static __thread bool saved_boot_id_valid = false;
int fd;
@@ -139,6 +145,9 @@ int sd_id128_get_boot(sd_id128_t *ret) {
sd_id128_t t;
char *p;
+ if (!ret)
+ return -EINVAL;
+
if (saved_boot_id_valid) {
*ret = saved_boot_id;
return 0;
@@ -181,12 +190,13 @@ int sd_id128_get_boot(sd_id128_t *ret) {
return 0;
}
-int sd_id128_randomize(sd_id128_t *ret) {
+_public_ int sd_id128_randomize(sd_id128_t *ret) {
int fd;
ssize_t k;
sd_id128_t t;
- assert(ret);
+ if (!ret)
+ return -EINVAL;
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
commit a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0a
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:54:15 2012 +0100
journal: add _public_ to all sd-journal calls, and add parameter checks
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index cc3cd8c..db5dbc0 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -53,7 +53,7 @@ retry:
return fd;
}
-int sd_journal_print(int priority, const char *format, ...) {
+_public_ int sd_journal_print(int priority, const char *format, ...) {
int r;
va_list ap;
@@ -64,7 +64,7 @@ int sd_journal_print(int priority, const char *format, ...) {
return r;
}
-int sd_journal_printv(int priority, const char *format, va_list ap) {
+_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
char buffer[8 + LINE_MAX], p[11];
struct iovec iov[2];
@@ -88,7 +88,7 @@ int sd_journal_printv(int priority, const char *format, va_list ap) {
return sd_journal_sendv(iov, 2);
}
-int sd_journal_send(const char *format, ...) {
+_public_ int sd_journal_send(const char *format, ...) {
int r, n = 0, i = 0, j;
va_list ap;
struct iovec *iov = NULL;
@@ -131,7 +131,7 @@ fail:
return r;
}
-int sd_journal_sendv(const struct iovec *iov, int n) {
+_public_ int sd_journal_sendv(const struct iovec *iov, int n) {
int fd;
struct iovec *w;
uint64_t *l;
@@ -148,8 +148,12 @@ int sd_journal_sendv(const struct iovec *iov, int n) {
for (i = 0; i < n; i++) {
char *c, *nl;
+ if (!iov[i].iov_base ||
+ iov[i].iov_len <= 1)
+ return -EINVAL;
+
c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
- if (!c)
+ if (!c || c == iov[i].iov_base)
return -EINVAL;
nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
@@ -205,7 +209,7 @@ int sd_journal_sendv(const struct iovec *iov, int n) {
return 0;
}
-int sd_journal_stream_fd(const char *tag, int priority, int priority_prefix) {
+_public_ int sd_journal_stream_fd(const char *tag, int priority, int priority_prefix) {
union sockaddr_union sa;
int fd;
char *header;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 38e58f5..bb3b0ae 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -106,17 +106,17 @@ static int same_field(const void *_a, size_t s, const void *_b, size_t t) {
return -EINVAL;
}
-int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
+_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
Match *m, *after = NULL;
uint64_t le_hash;
- assert(j);
-
+ if (!j)
+ return -EINVAL;
+ if (!data)
+ return -EINVAL;
if (size <= 0)
return -EINVAL;
- assert(data);
-
le_hash = htole64(hash64(data, size));
LIST_FOREACH(matches, m, j->matches) {
@@ -159,8 +159,9 @@ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
return 0;
}
-void sd_journal_flush_matches(sd_journal *j) {
- assert(j);
+_public_ void sd_journal_flush_matches(sd_journal *j) {
+ if (!j)
+ return;
while (j->matches) {
Match *m = j->matches;
@@ -626,7 +627,8 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
uint64_t new_offset = 0;
Object *new_entry = NULL;
- assert(j);
+ if (!j)
+ return -EINVAL;
HASHMAP_FOREACH(f, j->files, i) {
Object *o;
@@ -667,18 +669,19 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
return 1;
}
-int sd_journal_next(sd_journal *j) {
+_public_ int sd_journal_next(sd_journal *j) {
return real_journal_next(j, DIRECTION_DOWN);
}
-int sd_journal_previous(sd_journal *j) {
+_public_ int sd_journal_previous(sd_journal *j) {
return real_journal_next(j, DIRECTION_UP);
}
-int sd_journal_next_skip(sd_journal *j, uint64_t skip) {
+_public_ int sd_journal_next_skip(sd_journal *j, uint64_t skip) {
int c = 0, r;
- assert(j);
+ if (!j)
+ return -EINVAL;
while (skip > 0) {
r = sd_journal_next(j);
@@ -695,10 +698,11 @@ int sd_journal_next_skip(sd_journal *j, uint64_t skip) {
return c;
}
-int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
+_public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
int c = 0, r;
- assert(j);
+ if (!j)
+ return -EINVAL;
while (skip > 0) {
r = sd_journal_previous(j);
@@ -715,13 +719,15 @@ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
return 1;
}
-int sd_journal_get_cursor(sd_journal *j, char **cursor) {
+_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
Object *o;
int r;
char bid[33], sid[33];
- assert(j);
- assert(cursor);
+ if (!j)
+ return -EINVAL;
+ if (!cursor)
+ return -EINVAL;
if (!j->current_file || j->current_file->current_offset <= 0)
return -EADDRNOTAVAIL;
@@ -745,7 +751,7 @@ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
return 1;
}
-int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
+_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
char *w;
size_t l;
char *state;
@@ -759,8 +765,10 @@ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
xor_hash_set = false;
sd_id128_t seqnum_id, boot_id;
- assert(j);
- assert(cursor);
+ if (!j)
+ return -EINVAL;
+ if (!cursor)
+ return -EINVAL;
FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
char *item;
@@ -850,8 +858,9 @@ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
return 0;
}
-int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
- assert(j);
+_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
+ if (!j)
+ return -EINVAL;
reset_location(j);
j->current_location.type = LOCATION_DISCRETE;
@@ -862,8 +871,9 @@ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t u
return 0;
}
-int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
- assert(j);
+_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
+ if (!j)
+ return -EINVAL;
reset_location(j);
j->current_location.type = LOCATION_DISCRETE;
@@ -873,8 +883,9 @@ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
return 0;
}
-int sd_journal_seek_head(sd_journal *j) {
- assert(j);
+_public_ int sd_journal_seek_head(sd_journal *j) {
+ if (!j)
+ return -EINVAL;
reset_location(j);
j->current_location.type = LOCATION_HEAD;
@@ -882,8 +893,9 @@ int sd_journal_seek_head(sd_journal *j) {
return 0;
}
-int sd_journal_seek_tail(sd_journal *j) {
- assert(j);
+_public_ int sd_journal_seek_tail(sd_journal *j) {
+ if (!j)
+ return -EINVAL;
reset_location(j);
j->current_location.type = LOCATION_TAIL;
@@ -1095,7 +1107,7 @@ static void remove_root_wd(sd_journal *j, int wd) {
}
}
-int sd_journal_open(sd_journal **ret, int flags) {
+_public_ int sd_journal_open(sd_journal **ret, int flags) {
sd_journal *j;
const char *p;
const char search_paths[] =
@@ -1103,7 +1115,13 @@ int sd_journal_open(sd_journal **ret, int flags) {
"/var/log/journal\0";
int r;
- assert(ret);
+ if (!ret)
+ return -EINVAL;
+
+ if (flags & ~(SD_JOURNAL_LOCAL_ONLY|
+ SD_JOURNAL_RUNTIME_ONLY|
+ SD_JOURNAL_SYSTEM_ONLY))
+ return -EINVAL;
j = new0(sd_journal, 1);
if (!j)
@@ -1184,8 +1202,9 @@ fail:
return r;
};
-void sd_journal_close(sd_journal *j) {
- assert(j);
+_public_ void sd_journal_close(sd_journal *j) {
+ if (!j)
+ return;
if (j->inotify_wd_dirs) {
void *k;
@@ -1222,13 +1241,15 @@ void sd_journal_close(sd_journal *j) {
free(j);
}
-int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
+_public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
Object *o;
JournalFile *f;
int r;
- assert(j);
- assert(ret);
+ if (!j)
+ return -EINVAL;
+ if (!ret)
+ return -EINVAL;
f = j->current_file;
if (!f)
@@ -1245,14 +1266,16 @@ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
return 0;
}
-int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) {
+_public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) {
Object *o;
JournalFile *f;
int r;
sd_id128_t id;
- assert(j);
- assert(ret);
+ if (!j)
+ return -EINVAL;
+ if (!ret)
+ return -EINVAL;
f = j->current_file;
if (!f)
@@ -1280,17 +1303,21 @@ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_
return 0;
}
-int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
+_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
JournalFile *f;
uint64_t i, n;
size_t field_length;
int r;
Object *o;
- assert(j);
- assert(field);
- assert(data);
- assert(size);
+ if (!j)
+ return -EINVAL;
+ if (!field)
+ return -EINVAL;
+ if (!data)
+ return -EINVAL;
+ if (!size)
+ return -EINVAL;
if (isempty(field) || strchr(field, '='))
return -EINVAL;
@@ -1369,16 +1396,19 @@ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, siz
return -ENOENT;
}
-int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
+_public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
JournalFile *f;
uint64_t p, l, n, le_hash;
int r;
Object *o;
size_t t;
- assert(j);
- assert(data);
- assert(size);
+ if (!j)
+ return -EINVAL;
+ if (!data)
+ return -EINVAL;
+ if (!size)
+ return -EINVAL;
f = j->current_file;
if (!f)
@@ -1433,14 +1463,16 @@ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
return 1;
}
-void sd_journal_restart_data(sd_journal *j) {
- assert(j);
+_public_ void sd_journal_restart_data(sd_journal *j) {
+ if (!j)
+ return;
j->current_field = 0;
}
-int sd_journal_get_fd(sd_journal *j) {
- assert(j);
+_public_ int sd_journal_get_fd(sd_journal *j) {
+ if (!j)
+ return -EINVAL;
return j->inotify_fd;
}
@@ -1523,10 +1555,11 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
log_warning("Unknown inotify event.");
}
-int sd_journal_process(sd_journal *j) {
+_public_ int sd_journal_process(sd_journal *j) {
uint8_t buffer[sizeof(struct inotify_event) + FILENAME_MAX];
- assert(j);
+ if (!j)
+ return -EINVAL;
for (;;) {
struct inotify_event *e;
@@ -1555,19 +1588,27 @@ int sd_journal_process(sd_journal *j) {
}
}
-int sd_journal_query_unique(sd_journal *j, const char *field) {
- assert(j);
- assert(field);
+_public_ int sd_journal_query_unique(sd_journal *j, const char *field) {
+ if (!j)
+ return -EINVAL;
+ if (!field)
+ return -EINVAL;
return -ENOTSUP;
}
-int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) {
- assert(j);
+_public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) {
+ if (!j)
+ return -EINVAL;
+ if (!data)
+ return -EINVAL;
+ if (!l)
+ return -EINVAL;
return -ENOTSUP;
}
-void sd_journal_restart_unique(sd_journal *j) {
- assert(j);
+_public_ void sd_journal_restart_unique(sd_journal *j) {
+ if (!j)
+ return;
}
diff --git a/src/journal/sd-journal.h b/src/journal/sd-journal.h
index 97f9f0f..d7e2528 100644
--- a/src/journal/sd-journal.h
+++ b/src/journal/sd-journal.h
@@ -31,12 +31,12 @@
/* TODO:
*
+ * - add options for copy-to-console, copy-to-kmsg
* - OR of matches is borked...
* - extend hash tables table as we go
* - accelerate looking for "all hostnames" and suchlike.
* - hookup with systemctl
* - handle incomplete header
- * - write unit files
*
* - local deserializer
* - http server
commit 9847946e12479b27d3ebfd024f00a6ac33ce73d3
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:51:38 2012 +0100
login: introduce sd_pid_get_service()
diff --git a/Makefile.am b/Makefile.am
index 225c6fc..651b37d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,9 +20,9 @@ ACLOCAL_AMFLAGS = -I m4
SUBDIRS = po
-LIBSYSTEMD_LOGIN_CURRENT=0
-LIBSYSTEMD_LOGIN_REVISION=6
-LIBSYSTEMD_LOGIN_AGE=0
+LIBSYSTEMD_LOGIN_CURRENT=1
+LIBSYSTEMD_LOGIN_REVISION=0
+LIBSYSTEMD_LOGIN_AGE=1
LIBSYSTEMD_DAEMON_CURRENT=0
LIBSYSTEMD_DAEMON_REVISION=0
@@ -1910,6 +1910,7 @@ MANPAGES_ALIAS += \
man/sd_session_get_uid.3 \
man/sd_session_get_seat.3 \
man/sd_pid_get_owner_uid.3 \
+ man/sd_pid_get_service.3 \
man/sd_uid_is_on_seat.3 \
man/sd_uid_get_sessions.3 \
man/sd_uid_get_seats.3 \
@@ -1924,6 +1925,7 @@ man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
man/sd_session_get_uid.3: man/sd_session_is_active.3
man/sd_session_get_seat.3: man/sd_session_is_active.3
man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
+man/sd_pid_get_session.3: man/sd_pid_get_session.3
man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
man/sd_uid_get_seats.3: man/sd_uid_get_state.3
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
index 24e4680..4086c5a 100644
--- a/man/sd_pid_get_session.xml
+++ b/man/sd_pid_get_session.xml
@@ -44,8 +44,9 @@
<refnamediv>
<refname>sd_pid_get_session</refname>
+ <refname>sd_pid_get_service</refname>
<refname>sd_pid_get_owner_uid</refname>
- <refpurpose>Determine session or owner of a session of a specific PID</refpurpose>
+ <refpurpose>Determine session, service or owner of a session of a specific PID</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -59,6 +60,12 @@
</funcprototype>
<funcprototype>
+ <funcdef>int <function>sd_pid_get_service</function></funcdef>
+ <paramdef>pid_t <parameter>pid</parameter></paramdef>
+ <paramdef>char** <parameter>service</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
<funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
<paramdef>pid_t <parameter>pid</parameter></paramdef>
<paramdef>uid_t* <parameter>uid</parameter></paramdef>
@@ -75,11 +82,23 @@
identifier. The session identifier is a short string,
suitable for usage in file system paths. Note that not
all processes are part of a login session (e.g. system
- service processes and user processes that are shared
- between multiple sessions of the same user). For
- processes not being part of a login session this
- function will fail. The returned string needs to be
- freed with the libc
+ service processes, user processes that are shared
+ between multiple sessions of the same user, or kernel
+ threads). For processes not being part of a login
+ session this function will fail. The returned string
+ needs to be freed with the libc
+ <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call after use.</para>
+
+ <para><function>sd_pid_get_service()</function> may be
+ used to determine the system service identifier of a
+ process identified by the specified process
+ identifier. The service name is a short string,
+ suitable for usage in file system paths. Note that not
+ all processes are part of a service (e.g. user
+ processes, or kernel threads). For processes not being
+ part of a system service this function will fail. The
+ returned string needs to be freed with the libc
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
@@ -106,10 +125,11 @@
<refsect1>
<title>Notes</title>
- <para>The <function>sd_pid_get_session()</function>
- and <function>sd_pid_get_owner_uid()</function>
- interfaces are available as shared library, which can
- be compiled and linked to with the
+ <para>The <function>sd_pid_get_session()</function>,
+ <function>sd_pid_get_service()</function>, and
+ <function>sd_pid_get_owner_uid()</function> interfaces
+ are available as shared library, which can be compiled
+ and linked to with the
<literal>libsystemd-login</literal>
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
file.</para>
diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
index 0d51fa7..bac46f4 100644
--- a/src/login/libsystemd-login.sym
+++ b/src/login/libsystemd-login.sym
@@ -33,3 +33,8 @@ global:
local:
*;
};
+
+LIBSYSTEMD_LOGIN_38 {
+global:
+ sd_pid_get_service;
+} LIBSYSTEMD_LOGIN_31;
diff --git a/src/login/sd-login.c b/src/login/sd-login.c
index a0a56c4..1d43681 100644
--- a/src/login/sd-login.c
+++ b/src/login/sd-login.c
@@ -121,6 +121,33 @@ _public_ int sd_pid_get_session(pid_t pid, char **session) {
return 0;
}
+_public_ int sd_pid_get_service(pid_t pid, char **service) {
+ int r;
+ char *cgroup, *p;
+
+ if (!service)
+ return -EINVAL;
+
+ r = pid_get_cgroup(pid, NULL, &cgroup);
+ if (r < 0)
+ return r;
+
+ if (!startswith(cgroup, "/system/")) {
+ free(cgroup);
+ return -ENOENT;
+ }
+
+ p = cgroup + 8;
+ p = strndup(p, strcspn(p, "/"));
+ free(cgroup);
+
+ if (!p)
+ return -ENOMEM;
+
+ *service = p;
+ return 0;
+}
+
_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
int r;
char *root, *cgroup, *p, *cc;
diff --git a/src/login/sd-login.h b/src/login/sd-login.h
index 0cb0bf0..1d8a55e 100644
--- a/src/login/sd-login.h
+++ b/src/login/sd-login.h
@@ -53,6 +53,10 @@ int sd_pid_get_session(pid_t pid, char **session);
* return an error for system processes. */
int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
+/* Get service name from PID. This will return an error for
+ * non-service processes. */
+int sd_pid_get_service(pid_t, char **service);
+
/* Get state from uid. Possible states: offline, lingering, online, active */
int sd_uid_get_state(uid_t uid, char**state);
commit b72491a2fd8c237299055c636d4f748bca2b4b1f
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:41:20 2012 +0100
nspawn: get rid of BUFFER_SIZE, use LINE_MAX instead
diff --git a/src/nspawn.c b/src/nspawn.c
index 653d7db..3ea603f 100644
--- a/src/nspawn.c
+++ b/src/nspawn.c
@@ -394,11 +394,9 @@ static int is_os_tree(const char *path) {
return r < 0 ? 0 : 1;
}
-#define BUFFER_SIZE 1024
-
static int process_pty(int master, sigset_t *mask) {
- char in_buffer[BUFFER_SIZE], out_buffer[BUFFER_SIZE];
+ char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
size_t in_buffer_full = 0, out_buffer_full = 0;
struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev;
bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false;
@@ -519,9 +517,9 @@ static int process_pty(int master, sigset_t *mask) {
(master_readable && out_buffer_full <= 0) ||
(stdout_writable && out_buffer_full > 0)) {
- if (stdin_readable && in_buffer_full < BUFFER_SIZE) {
+ if (stdin_readable && in_buffer_full < LINE_MAX) {
- if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) {
+ if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) {
if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
stdin_readable = false;
@@ -553,9 +551,9 @@ static int process_pty(int master, sigset_t *mask) {
}
}
- if (master_readable && out_buffer_full < BUFFER_SIZE) {
+ if (master_readable && out_buffer_full < LINE_MAX) {
- if ((k = read(master, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) {
+ if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) {
if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
master_readable = false;
commit 4f3656e1cec7fe3d7d3537e23a406cb88d734502
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:34:09 2012 +0100
readahead: bring export definition of sd-readahead in line with sd-daemon
diff --git a/src/readahead/sd-readahead.c b/src/readahead/sd-readahead.c
index c5cfe67..a334066 100644
--- a/src/readahead/sd-readahead.c
+++ b/src/readahead/sd-readahead.c
@@ -37,6 +37,18 @@
#include "sd-readahead.h"
+#if (__GNUC__ >= 4)
+#ifdef SD_EXPORT_SYMBOLS
+/* Export symbols */
+#define _sd_export_ __attribute__ ((visibility("default")))
+#else
+/* Don't export the symbols */
+#define _sd_export_ __attribute__ ((visibility("hidden")))
+#endif
+#else
+#define _sd_export_
+#endif
+
static int touch(const char *path) {
#if !defined(DISABLE_SYSTEMD) && defined(__linux__)
@@ -60,7 +72,7 @@ static int touch(const char *path) {
return 0;
}
-int sd_readahead(const char *action) {
+_sd_export_ int sd_readahead(const char *action) {
if (!action)
return -EINVAL;
diff --git a/src/readahead/sd-readahead.h b/src/readahead/sd-readahead.h
index 5bf975a..ee7e306 100644
--- a/src/readahead/sd-readahead.h
+++ b/src/readahead/sd-readahead.h
@@ -56,14 +56,6 @@ extern "C" {
See sd-readahead(7) for more information.
*/
-#ifndef _sd_hidden_
-#if (__GNUC__ >= 4) && !defined(SD_EXPORT_SYMBOLS)
-#define _sd_hidden_ __attribute__ ((visibility("hidden")))
-#else
-#define _sd_hidden_
-#endif
-#endif
-
/*
Controls ongoing disk read-ahead operations during boot-up. The argument
must be a string, and either "cancel", "done" or "noreplay".
@@ -72,7 +64,7 @@ extern "C" {
done = terminate read-ahead data collection, keep collected information
noreplay = terminate read-ahead replay
*/
-int sd_readahead(const char *action) _sd_hidden_;
+int sd_readahead(const char *action);
#ifdef __cplusplus
}
commit 4cfc6dbe52e4ff867750ce0d64f09d42c0ea6c27
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Jan 3 20:33:28 2012 +0100
socket: only add dependency on kmsg socket to socket units which have any kind of exec program specified
diff --git a/src/socket.c b/src/socket.c
index bbfc842..1f5e067 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -323,6 +323,17 @@ static int socket_add_default_dependencies(Socket *s) {
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
}
+static bool socket_has_exec(Socket *s) {
+ unsigned i;
+ assert(s);
+
+ for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
+ if (s->exec_command[i])
+ return true;
+
+ return false;
+}
+
static int socket_load(Unit *u) {
Socket *s = SOCKET(u);
int r;
@@ -352,8 +363,9 @@ static int socket_load(Unit *u) {
if ((r = socket_add_device_link(s)) < 0)
return r;
- if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
- return r;
+ if (socket_has_exec(s))
+ if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
+ return r;
if ((r = unit_add_default_cgroups(u)) < 0)
return r;
commit 4de856120f252e7aa19c923c10fbf23310d623aa
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jan 2 17:07:00 2012 +0100
build-sys: make quotacheck and randomseed optional
diff --git a/Makefile.am b/Makefile.am
index b55e0b9..225c6fc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -182,7 +182,6 @@ rootlibexec_PROGRAMS = \
systemd-cgroups-agent \
systemd-initctl \
systemd-update-utmp \
- systemd-random-seed \
systemd-shutdownd \
systemd-shutdown \
systemd-modules-load \
@@ -190,7 +189,6 @@ rootlibexec_PROGRAMS = \
systemd-kmsg-syslogd \
systemd-reply-password \
systemd-fsck \
- systemd-quotacheck \
systemd-timestamp \
systemd-ac-power \
systemd-detect-virt \
@@ -325,8 +323,6 @@ nodist_systemunit_DATA = \
units/systemd-remount-api-vfs.service \
units/systemd-update-utmp-runlevel.service \
units/systemd-update-utmp-shutdown.service \
- units/systemd-random-seed-save.service \
- units/systemd-random-seed-load.service \
units/systemd-tmpfiles-setup.service \
units/systemd-tmpfiles-clean.service \
units/systemd-ask-password-wall.service \
@@ -338,7 +334,6 @@ nodist_systemunit_DATA = \
units/kexec.service \
units/fsck at .service \
units/fsck-root.service \
- units/quotacheck.service \
units/rescue.service \
units/user at .service
@@ -362,8 +357,6 @@ EXTRA_DIST += \
units/systemd-remount-api-vfs.service.in \
units/systemd-update-utmp-runlevel.service.in \
units/systemd-update-utmp-shutdown.service.in \
- units/systemd-random-seed-save.service.in \
- units/systemd-random-seed-load.service.in \
units/systemd-tmpfiles-setup.service.in \
units/systemd-tmpfiles-clean.service.in \
units/systemd-ask-password-wall.service.in \
@@ -376,7 +369,6 @@ EXTRA_DIST += \
units/user/exit.service.in \
units/fsck at .service.in \
units/fsck-root.service.in \
- units/quotacheck.service.in \
units/user at .service.in \
systemd.pc.in \
introspect.awk \
@@ -792,12 +784,6 @@ systemd_update_utmp_LDADD = \
$(DBUS_LIBS) \
$(AUDIT_LIBS)
-systemd_random_seed_SOURCES = \
- src/random-seed.c
-
-systemd_random_seed_LDADD = \
- libsystemd-basic.la
-
systemd_shutdownd_SOURCES = \
src/utmp-wtmp.c \
src/shutdownd.c
@@ -862,12 +848,6 @@ systemd_fsck_LDADD = \
$(UDEV_LIBS) \
$(DBUS_LIBS)
-systemd_quotacheck_SOURCES = \
- src/quotacheck.c
-
-systemd_quotacheck_LDADD = \
- libsystemd-basic.la
-
systemd_timestamp_SOURCES = \
src/timestamp.c
@@ -1452,6 +1432,55 @@ MANPAGES += \
endif
# ------------------------------------------------------------------------------
+if ENABLE_QUOTACHECK
+rootlibexec_PROGRAMS += \
+ systemd-quotacheck
+
+nodist_systemunit_DATA += \
+ units/quotacheck.service
+
+EXTRA_DIST += \
+ units/quotacheck.service.in
+
+systemd_quotacheck_SOURCES = \
+ src/quotacheck.c
+
+systemd_quotacheck_LDADD = \
+ libsystemd-basic.la
+endif
+
+# ------------------------------------------------------------------------------
+if ENABLE_RANDOMSEED
+rootlibexec_PROGRAMS += \
+ systemd-random-seed
+
+nodist_systemunit_DATA += \
+ units/systemd-random-seed-save.service \
+ units/systemd-random-seed-load.service
+
+EXTRA_DIST += \
+ units/systemd-random-seed-save.service.in \
+ units/systemd-random-seed-load.service.in
+
+systemd_random_seed_SOURCES = \
+ src/random-seed.c
+
+systemd_random_seed_LDADD = \
+ libsystemd-basic.la
+
+randomseed-install-data-hook:
+ ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \
+ rm -f systemd-random-seed-save.service && \
+ $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service )
+ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+ rm -f systemd-random-seed-load.service && \
+ $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service )
+
+INSTALL_DATA_HOOKS += \
+ randomseed-install-data-hook
+endif
+
+# ------------------------------------------------------------------------------
if HAVE_LIBCRYPTSETUP
rootlibexec_PROGRAMS += \
systemd-cryptsetup
@@ -2137,10 +2166,8 @@ systemd-install-data-hook:
rm -f systemd-update-utmp-runlevel.service && \
$(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \
- rm -f systemd-update-utmp-shutdown.service \
- systemd-random-seed-save.service && \
- $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service && \
- $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service )
+ rm -f systemd-update-utmp-shutdown.service && \
+ $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service )
( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \
rm -f systemd-remount-api-vfs.service \
fsck-root.service \
@@ -2191,7 +2218,6 @@ systemd-install-data-hook:
sys-kernel-security.mount \
sys-fs-fuse-connections.mount \
systemd-modules-load.service \
- systemd-random-seed-load.service \
systemd-tmpfiles-setup.service \
systemd-sysctl.service \
systemd-ask-password-console.path \
@@ -2203,7 +2229,6 @@ systemd-install-data-hook:
$(LN_S) ../sys-kernel-security.mount sys-kernel-security.mount && \
$(LN_S) ../sys-fs-fuse-connections.mount sys-fs-fuse-connections.mount && \
$(LN_S) ../systemd-modules-load.service systemd-modules-load.service && \
- $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service && \
$(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \
$(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \
$(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path && \
diff --git a/configure.ac b/configure.ac
index 9f03f63..0316ad1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -330,6 +330,20 @@ if test "x$enable_readahead" != "xno"; then
fi
AM_CONDITIONAL(ENABLE_READAHEAD, [test "$have_readahead" = "yes"])
+have_quotacheck=no
+AC_ARG_ENABLE(quotacheck, AS_HELP_STRING([--disable-quotacheck], [disable quotacheck tools]))
+if test "x$enable_quotacheck" != "xno"; then
+ have_quotacheck=yes
+fi
+AM_CONDITIONAL(ENABLE_QUOTACHECK, [test "$have_quotacheck" = "yes"])
+
+have_randomseed=no
+AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools]))
+if test "x$enable_randomseed" != "xno"; then
+ have_randomseed=yes
+fi
+AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"])
+
have_logind=no
AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon]))
if test "x$enable_logind" != "xno"; then
@@ -627,6 +641,8 @@ AC_MSG_RESULT([
binfmt: ${have_binfmt}
vconsole: ${have_vconsole}
readahead: ${have_readahead}
+ quotacheck: ${have_quotacheck}
+ randomseed: ${have_randomseed}
logind: ${have_logind}
hostnamed: ${have_hostnamed}
timedated: ${have_timedated}
commit 776a564f54dd54c7c4e2b2d865e8f9e7ee5404f3
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Jan 2 16:50:03 2012 +0100
build-sys: move kbd-model-map to locale/
diff --git a/Makefile.am b/Makefile.am
index 0c3e970..b55e0b9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -809,12 +809,6 @@ systemd_shutdownd_LDADD = \
libsystemd-basic.la \
libsystemd-daemon.la
-dist_pkgdata_DATA = \
- src/kbd-model-map
-
-dist_noinst_SCRIPT = \
- src/generate-kbd-model-map
-
systemd_shutdown_SOURCES = \
src/mount-setup.c \
src/umount.c \
@@ -1598,6 +1592,16 @@ INSTALL_DATA_HOOKS += \
EXTRA_DIST += \
units/systemd-localed.service.in
+
+dist_pkgdata_DATA = \
+ src/locale/kbd-model-map
+
+dist_noinst_SCRIPT = \
+ src/locale/generate-kbd-model-map
+
+update-kbd-model-map:
+ src/locale/generate-kbd-model-map > src/locale/kbd-model-map
+
endif
# ------------------------------------------------------------------------------
@@ -2340,6 +2344,3 @@ upload: all distcheck
git-tag:
git tag "v$(VERSION)" -m "systemd $(VERSION)"
-
-update-kbd-model-map:
- src/generate-kbd-model-map > src/kbd-model-map
diff --git a/src/generate-kbd-model-map b/src/generate-kbd-model-map
deleted file mode 100755
index 624c517..0000000
--- a/src/generate-kbd-model-map
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import system_config_keyboard.keyboard_models
-
-def strdash(s):
- return s.strip() or '-'
-
-def tab_extend(s, n=1):
- s = strdash(s)
- k = len(s) // 8
-
- if k >= n:
- f = 1
- else:
- f = n - k
-
- return s + '\t'*f
-
-
-models = system_config_keyboard.keyboard_models.KeyboardModels().get_models()
-
-print "# Generated from system-config-keyboard's model list"
-print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions"
-
-for key, value in reversed(models.items()):
- options = "terminate:ctrl_alt_bksp"
- if value[4]:
- options += ',' + value[4]
-
- print ''.join((tab_extend(key, 3), tab_extend(value[1]),
- tab_extend(value[2], 2), tab_extend(value[3], 2),
- options))
diff --git a/src/kbd-model-map b/src/kbd-model-map
deleted file mode 100644
index a895880..0000000
--- a/src/kbd-model-map
+++ /dev/null
@@ -1,72 +0,0 @@
-# Generated from system-config-keyboard's model list
-# consolelayout xlayout xmodel xvariant xoptions
-sg ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp
-nl nl pc105 - terminate:ctrl_alt_bksp
-mk-utf mkd,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-trq tr pc105 - terminate:ctrl_alt_bksp
-guj in,us pc105 guj terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-uk gb pc105 - terminate:ctrl_alt_bksp
-is-latin1 is pc105 - terminate:ctrl_alt_bksp
-de de pc105 - terminate:ctrl_alt_bksp
-gur gur,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-la-latin1 latam pc105 - terminate:ctrl_alt_bksp
-us us pc105+inet - terminate:ctrl_alt_bksp
-ko kr pc105 - terminate:ctrl_alt_bksp
-ro-std ro pc105 std terminate:ctrl_alt_bksp
-de-latin1 de pc105 - terminate:ctrl_alt_bksp
-tml-inscript in,us pc105 tam terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-slovene si pc105 - terminate:ctrl_alt_bksp
-hu101 hu pc105 qwerty terminate:ctrl_alt_bksp
-jp106 jp jp106 - terminate:ctrl_alt_bksp
-croat hr pc105 - terminate:ctrl_alt_bksp
-ben-probhat in,us pc105 ben_probhat terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-fi-latin1 fi pc105 - terminate:ctrl_alt_bksp
-it2 it pc105 - terminate:ctrl_alt_bksp
-hu hu pc105 - terminate:ctrl_alt_bksp
-sr-latin rs pc105 latin terminate:ctrl_alt_bksp
-fi fi pc105 - terminate:ctrl_alt_bksp
-fr_CH ch pc105 fr terminate:ctrl_alt_bksp
-dk-latin1 dk pc105 - terminate:ctrl_alt_bksp
-fr fr pc105 - terminate:ctrl_alt_bksp
-it it pc105 - terminate:ctrl_alt_bksp
-tml-uni in,us pc105 tam_TAB terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-ua-utf ua,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-fr-latin1 fr pc105 - terminate:ctrl_alt_bksp
-sg-latin1 ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp
-be-latin1 be pc105 - terminate:ctrl_alt_bksp
-dk dk pc105 - terminate:ctrl_alt_bksp
-fr-pc fr pc105 - terminate:ctrl_alt_bksp
-bg_pho-utf8 bg,us pc105 ,phonetic terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-it-ibm it pc105 - terminate:ctrl_alt_bksp
-cz-us-qwertz cz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-ar-digits ara,us pc105 digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-br-abnt2 br abnt2 - terminate:ctrl_alt_bksp
-ro ro pc105 - terminate:ctrl_alt_bksp
-us-acentos us pc105 intl terminate:ctrl_alt_bksp
-pt-latin1 pt pc105 - terminate:ctrl_alt_bksp
-ro-std-cedilla ro pc105 std_cedilla terminate:ctrl_alt_bksp
-tj tj pc105 - terminate:ctrl_alt_bksp
-ar-qwerty ara,us pc105 qwerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-ar-azerty-digits ara,us pc105 azerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-ben in,us pc105 ben terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-de-latin1-nodeadkeys de pc105 nodeadkeys terminate:ctrl_alt_bksp
-no no pc105 - terminate:ctrl_alt_bksp
-bg_bds-utf8 bg,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-dvorak us pc105 dvorak terminate:ctrl_alt_bksp
-ru ru,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-cz-lat2 cz pc105 qwerty terminate:ctrl_alt_bksp
-pl2 pl pc105 - terminate:ctrl_alt_bksp
-es es pc105 - terminate:ctrl_alt_bksp
-ro-cedilla ro pc105 cedilla terminate:ctrl_alt_bksp
-ie ie pc105 - terminate:ctrl_alt_bksp
-ar-azerty ara,us pc105 azerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-ar-qwerty-digits ara,us pc105 qwerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-et ee pc105 - terminate:ctrl_alt_bksp
-sk-qwerty sk pc105 - terminate:ctrl_alt_bksp,qwerty
-dev dev,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
-fr-latin9 fr pc105 latin9 terminate:ctrl_alt_bksp
-fr_CH-latin1 ch pc105 fr terminate:ctrl_alt_bksp
-cf ca(fr) pc105 - terminate:ctrl_alt_bksp
-sv-latin1 se pc105 - terminate:ctrl_alt_bksp
-sr-cy rs pc105 - terminate:ctrl_alt_bksp
-gr gr,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
diff --git a/src/locale/generate-kbd-model-map b/src/locale/generate-kbd-model-map
new file mode 100755
index 0000000..624c517
--- /dev/null
+++ b/src/locale/generate-kbd-model-map
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+import sys
+import system_config_keyboard.keyboard_models
+
+def strdash(s):
+ return s.strip() or '-'
+
+def tab_extend(s, n=1):
+ s = strdash(s)
+ k = len(s) // 8
+
+ if k >= n:
+ f = 1
+ else:
+ f = n - k
+
+ return s + '\t'*f
+
+
+models = system_config_keyboard.keyboard_models.KeyboardModels().get_models()
+
+print "# Generated from system-config-keyboard's model list"
+print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions"
+
+for key, value in reversed(models.items()):
+ options = "terminate:ctrl_alt_bksp"
+ if value[4]:
+ options += ',' + value[4]
+
+ print ''.join((tab_extend(key, 3), tab_extend(value[1]),
+ tab_extend(value[2], 2), tab_extend(value[3], 2),
+ options))
diff --git a/src/locale/kbd-model-map b/src/locale/kbd-model-map
new file mode 100644
index 0000000..a895880
--- /dev/null
+++ b/src/locale/kbd-model-map
@@ -0,0 +1,72 @@
+# Generated from system-config-keyboard's model list
+# consolelayout xlayout xmodel xvariant xoptions
+sg ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp
+nl nl pc105 - terminate:ctrl_alt_bksp
+mk-utf mkd,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+trq tr pc105 - terminate:ctrl_alt_bksp
+guj in,us pc105 guj terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+uk gb pc105 - terminate:ctrl_alt_bksp
+is-latin1 is pc105 - terminate:ctrl_alt_bksp
+de de pc105 - terminate:ctrl_alt_bksp
+gur gur,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+la-latin1 latam pc105 - terminate:ctrl_alt_bksp
+us us pc105+inet - terminate:ctrl_alt_bksp
+ko kr pc105 - terminate:ctrl_alt_bksp
+ro-std ro pc105 std terminate:ctrl_alt_bksp
+de-latin1 de pc105 - terminate:ctrl_alt_bksp
+tml-inscript in,us pc105 tam terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+slovene si pc105 - terminate:ctrl_alt_bksp
+hu101 hu pc105 qwerty terminate:ctrl_alt_bksp
+jp106 jp jp106 - terminate:ctrl_alt_bksp
+croat hr pc105 - terminate:ctrl_alt_bksp
+ben-probhat in,us pc105 ben_probhat terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fi-latin1 fi pc105 - terminate:ctrl_alt_bksp
+it2 it pc105 - terminate:ctrl_alt_bksp
+hu hu pc105 - terminate:ctrl_alt_bksp
+sr-latin rs pc105 latin terminate:ctrl_alt_bksp
+fi fi pc105 - terminate:ctrl_alt_bksp
+fr_CH ch pc105 fr terminate:ctrl_alt_bksp
+dk-latin1 dk pc105 - terminate:ctrl_alt_bksp
+fr fr pc105 - terminate:ctrl_alt_bksp
+it it pc105 - terminate:ctrl_alt_bksp
+tml-uni in,us pc105 tam_TAB terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ua-utf ua,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fr-latin1 fr pc105 - terminate:ctrl_alt_bksp
+sg-latin1 ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp
+be-latin1 be pc105 - terminate:ctrl_alt_bksp
+dk dk pc105 - terminate:ctrl_alt_bksp
+fr-pc fr pc105 - terminate:ctrl_alt_bksp
+bg_pho-utf8 bg,us pc105 ,phonetic terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+it-ibm it pc105 - terminate:ctrl_alt_bksp
+cz-us-qwertz cz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-digits ara,us pc105 digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+br-abnt2 br abnt2 - terminate:ctrl_alt_bksp
+ro ro pc105 - terminate:ctrl_alt_bksp
+us-acentos us pc105 intl terminate:ctrl_alt_bksp
+pt-latin1 pt pc105 - terminate:ctrl_alt_bksp
+ro-std-cedilla ro pc105 std_cedilla terminate:ctrl_alt_bksp
+tj tj pc105 - terminate:ctrl_alt_bksp
+ar-qwerty ara,us pc105 qwerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-azerty-digits ara,us pc105 azerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ben in,us pc105 ben terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+de-latin1-nodeadkeys de pc105 nodeadkeys terminate:ctrl_alt_bksp
+no no pc105 - terminate:ctrl_alt_bksp
+bg_bds-utf8 bg,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+dvorak us pc105 dvorak terminate:ctrl_alt_bksp
+ru ru,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+cz-lat2 cz pc105 qwerty terminate:ctrl_alt_bksp
+pl2 pl pc105 - terminate:ctrl_alt_bksp
+es es pc105 - terminate:ctrl_alt_bksp
+ro-cedilla ro pc105 cedilla terminate:ctrl_alt_bksp
+ie ie pc105 - terminate:ctrl_alt_bksp
+ar-azerty ara,us pc105 azerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+ar-qwerty-digits ara,us pc105 qwerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+et ee pc105 - terminate:ctrl_alt_bksp
+sk-qwerty sk pc105 - terminate:ctrl_alt_bksp,qwerty
+dev dev,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
+fr-latin9 fr pc105 latin9 terminate:ctrl_alt_bksp
+fr_CH-latin1 ch pc105 fr terminate:ctrl_alt_bksp
+cf ca(fr) pc105 - terminate:ctrl_alt_bksp
+sv-latin1 se pc105 - terminate:ctrl_alt_bksp
+sr-cy rs pc105 - terminate:ctrl_alt_bksp
+gr gr,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll
diff --git a/src/localed.c b/src/localed.c
deleted file mode 100644
index e69de29..0000000
commit b4d0195b0598df76d30f006507fa8466f5a5d330
Author: Lennart Poettering <lennart at poettering.net>
Date: Sat Dec 31 19:59:09 2011 +0100
cryptsetup: split off cryptsetup into its own subdir
diff --git a/Makefile.am b/Makefile.am
index 4c2d165..0c3e970 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -199,14 +199,6 @@ rootlibexec_PROGRAMS = \
systemgenerator_PROGRAMS = \
systemd-getty-generator
-if HAVE_LIBCRYPTSETUP
-rootlibexec_PROGRAMS += \
- systemd-cryptsetup
-
-systemgenerator_PROGRAMS += \
- systemd-cryptsetup-generator
-endif
-
noinst_PROGRAMS = \
test-engine \
test-job-type \
@@ -278,7 +270,6 @@ dist_systemunit_DATA = \
units/local-fs-pre.target \
units/remote-fs.target \
units/remote-fs-pre.target \
- units/cryptsetup.target \
units/network.target \
units/nss-lookup.target \
units/mail-transfer-agent.target \
@@ -579,7 +570,7 @@ libsystemd_core_la_LIBADD = \
$(CAP_LIBS)
# This is needed because automake is buggy in how it generates the
-# rules for C programs, but not Vala programs. We therefore can't
+# rules for C programs, but not Vala programs. We therefore can't
# list the .h files as dependencies if we want make dist to work.
EXTRA_DIST += \
@@ -906,27 +897,6 @@ systemd_detect_virt_SOURCES = \
systemd_detect_virt_LDADD = \
libsystemd-basic.la
-systemd_cryptsetup_SOURCES = \
- src/cryptsetup.c \
- src/ask-password-api.c
-
-systemd_cryptsetup_CFLAGS = \
- $(AM_CFLAGS) \
- $(LIBCRYPTSETUP_CFLAGS) \
- $(UDEV_CFLAGS)
-
-systemd_cryptsetup_LDADD = \
- $(LIBCRYPTSETUP_LIBS) \
- $(UDEV_LIBS) \
- libsystemd-basic.la
-
-systemd_cryptsetup_generator_SOURCES = \
- src/cryptsetup-generator.c \
- src/unit-name.c
-
-systemd_cryptsetup_generator_LDADD = \
- libsystemd-basic.la
-
systemd_getty_generator_SOURCES = \
src/getty-generator.c \
src/unit-name.c
@@ -1488,6 +1458,47 @@ MANPAGES += \
endif
# ------------------------------------------------------------------------------
+if HAVE_LIBCRYPTSETUP
+rootlibexec_PROGRAMS += \
+ systemd-cryptsetup
+
+systemgenerator_PROGRAMS += \
+ systemd-cryptsetup-generator
+
+dist_systemunit_DATA += \
+ units/cryptsetup.target
+
+systemd_cryptsetup_SOURCES = \
+ src/cryptsetup/cryptsetup.c \
+ src/ask-password-api.c
+
+systemd_cryptsetup_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(LIBCRYPTSETUP_CFLAGS) \
+ $(UDEV_CFLAGS)
+
+systemd_cryptsetup_LDADD = \
+ $(LIBCRYPTSETUP_LIBS) \
+ $(UDEV_LIBS) \
+ libsystemd-basic.la
+
+systemd_cryptsetup_generator_SOURCES = \
+ src/cryptsetup/cryptsetup-generator.c \
+ src/unit-name.c
+
+systemd_cryptsetup_generator_LDADD = \
+ libsystemd-basic.la
+
+cryptsetup-install-data-hook:
+ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
+ rm -f cryptsetup.target && \
+ $(LN_S) ../cryptsetup.target cryptsetup.target )
+
+INSTALL_DATA_HOOKS += \
+ cryptsetup-install-data-hook
+endif
+
+# ------------------------------------------------------------------------------
if ENABLE_HOSTNAMED
systemd_hostnamed_SOURCES = \
src/hostname/hostnamed.c \
@@ -1908,7 +1919,7 @@ endif
SED_PROCESS = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(SED) -e 's, at rootlibexecdir\@,$(rootlibexecdir),g' \
+ $(SED) -e 's, at rootlibexecdir\@,$(rootlibexecdir),g' \
-e 's, at rootbindir\@,$(rootbindir),g' \
-e 's, at bindir\@,$(bindir),g' \
-e 's, at SYSTEMCTL\@,$(rootbindir)/systemctl,g' \
@@ -2180,8 +2191,7 @@ systemd-install-data-hook:
systemd-tmpfiles-setup.service \
systemd-sysctl.service \
systemd-ask-password-console.path \
- systemd-kmsg-syslogd.service \
- cryptsetup.target && \
+ systemd-kmsg-syslogd.service && \
$(LN_S) ../dev-hugepages.mount dev-hugepages.mount && \
$(LN_S) ../dev-mqueue.mount dev-mqueue.mount && \
$(LN_S) ../sys-kernel-config.mount sys-kernel-config.mount && \
@@ -2193,8 +2203,7 @@ systemd-install-data-hook:
$(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \
$(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \
$(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path && \
- $(LN_S) ../systemd-kmsg-syslogd.service && \
- $(LN_S) ../cryptsetup.target cryptsetup.target )
+ $(LN_S) ../systemd-kmsg-syslogd.service )
( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \
rm -f systemd-tmpfiles-clean.timer && \
$(LN_S) ../systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer )
diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c
deleted file mode 100644
index a48b7a4..0000000
--- a/src/cryptsetup-generator.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- 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.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "log.h"
-#include "util.h"
-#include "unit-name.h"
-
-const char *arg_dest = "/tmp";
-
-static bool has_option(const char *haystack, const char *needle) {
- const char *f = haystack;
- size_t l;
-
- assert(needle);
-
- if (!haystack)
- return false;
-
- l = strlen(needle);
-
- while ((f = strstr(f, needle))) {
-
- if (f > haystack && f[-1] != ',') {
- f++;
- continue;
- }
-
- if (f[l] != 0 && f[l] != ',') {
- f++;
- continue;
- }
-
- return true;
- }
-
- return false;
-}
-
-static int create_disk(
- const char *name,
- const char *device,
- const char *password,
- const char *options) {
-
- char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
- int r;
- FILE *f = NULL;
- bool noauto, nofail;
-
- assert(name);
- assert(device);
-
- noauto = has_option(options, "noauto");
- nofail = has_option(options, "nofail");
-
- if (!(n = unit_name_build_escape("cryptsetup", name, ".service"))) {
- r = -ENOMEM;
- log_error("Failed to allocate unit name.");
- goto fail;
- }
-
- if (asprintf(&p, "%s/%s", arg_dest, n) < 0) {
- r = -ENOMEM;
- log_error("Failed to allocate unit file name.");
- goto fail;
- }
-
- if (!(u = fstab_node_to_udev_node(device))) {
- r = -ENOMEM;
- log_error("Failed to allocate device node.");
- goto fail;
- }
-
- if (!(d = unit_name_from_path(u, ".device"))) {
- r = -ENOMEM;
- log_error("Failed to allocate device name.");
- goto fail;
- }
-
- if (!(f = fopen(p, "wxe"))) {
- r = -errno;
- log_error("Failed to create unit file: %m");
- goto fail;
- }
-
- fprintf(f,
- "[Unit]\n"
- "Description=Cryptography Setup for %%I\n"
- "Conflicts=umount.target\n"
- "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",
- d, d);
-
- if (!nofail)
- fprintf(f,
- "Before=cryptsetup.target\n");
-
- if (password && (streq(password, "/dev/urandom") ||
- streq(password, "/dev/random") ||
- 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"
- "Type=oneshot\n"
- "RemainAfterExit=yes\n"
- "TimeoutSec=0\n" /* the binary handles timeouts anyway */
- "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
- "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
- name, u, strempty(password), strempty(options),
- name);
-
- if (has_option(options, "tmp"))
- fprintf(f,
- "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
- name);
-
- if (has_option(options, "swap"))
- fprintf(f,
- "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
- name);
-
- fflush(f);
-
- if (ferror(f)) {
- r = -errno;
- log_error("Failed to write file: %m");
- goto fail;
- }
-
- if (asprintf(&from, "../%s", n) < 0) {
- r = -ENOMEM;
- goto fail;
- }
-
- if (!noauto) {
-
- if (asprintf(&to, "%s/%s.wants/%s", arg_dest, d, n) < 0) {
- r = -ENOMEM;
- goto fail;
- }
-
- mkdir_parents(to, 0755);
-
- if (symlink(from, to) < 0) {
- log_error("Failed to create symlink '%s' to '%s': %m", from, to);
- r = -errno;
- goto fail;
- }
-
- free(to);
- to = NULL;
-
- if (!nofail)
- asprintf(&to, "%s/cryptsetup.target.requires/%s", arg_dest, n);
- else
- asprintf(&to, "%s/cryptsetup.target.wants/%s", arg_dest, n);
-
- if (!to) {
- r = -ENOMEM;
- goto fail;
- }
-
- mkdir_parents(to, 0755);
-
- if (symlink(from, to) < 0) {
- log_error("Failed to create symlink '%s' to '%s': %m", from, to);
- r = -errno;
- goto fail;
- }
- }
-
- free(to);
- to = NULL;
-
- e = unit_name_escape(name);
- if (asprintf(&to, "%s/dev-mapper-%s.device.requires/%s", arg_dest, e, n) < 0) {
- r = -ENOMEM;
- goto fail;
- }
-
- mkdir_parents(to, 0755);
-
- if (symlink(from, to) < 0) {
- log_error("Failed to create symlink '%s' to '%s': %m", from, to);
- r = -errno;
- goto fail;
- }
-
- r = 0;
-
-fail:
- free(p);
- free(n);
- free(d);
- free(e);
-
- free(from);
- free(to);
-
- if (f)
- fclose(f);
-
- return r;
-}
-
-int main(int argc, char *argv[]) {
- FILE *f;
- int r = EXIT_SUCCESS;
- unsigned n = 0;
-
- if (argc > 2) {
- log_error("This program takes one or no arguments.");
- return EXIT_FAILURE;
- }
-
- if (argc > 1)
- arg_dest = argv[1];
-
- log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
- log_parse_environment();
- log_open();
-
- umask(0022);
-
- if (!(f = fopen("/etc/crypttab", "re"))) {
-
- if (errno == ENOENT)
- r = EXIT_SUCCESS;
- else {
- r = EXIT_FAILURE;
- log_error("Failed to open /etc/crypttab: %m");
- }
-
- goto finish;
- }
-
- for (;;) {
- char line[LINE_MAX], *l;
- char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
- int k;
-
- if (!(fgets(line, sizeof(line), f)))
- break;
-
- n++;
-
- l = strstrip(line);
- if (*l == '#' || *l == 0)
- continue;
-
- if ((k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options)) < 2 || k > 4) {
- log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
- r = EXIT_FAILURE;
- goto next;
- }
-
- if (create_disk(name, device, password, options) < 0)
- r = EXIT_FAILURE;
-
- next:
- free(name);
- free(device);
- free(password);
- free(options);
- }
-
-finish:
- return r;
-}
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
deleted file mode 100644
index ac7b6d6..0000000
--- a/src/cryptsetup.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- 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.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <string.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <mntent.h>
-
-#include <libcryptsetup.h>
-#include <libudev.h>
-
-#include "log.h"
-#include "util.h"
-#include "strv.h"
-#include "ask-password-api.h"
-#include "def.h"
-
-static const char *opt_type = NULL; /* LUKS1 or PLAIN */
-static char *opt_cipher = NULL;
-static unsigned opt_key_size = 0;
-static char *opt_hash = NULL;
-static unsigned opt_tries = 0;
-static bool opt_readonly = false;
-static bool opt_verify = false;
-static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC;
-
-/* Options Debian's crypttab knows we don't:
-
- offset=
- skip=
- precheck=
- check=
- checkargs=
- noearly=
- loud=
- keyscript=
-*/
-
-static int parse_one_option(const char *option) {
- assert(option);
-
- /* Handled outside of this tool */
- if (streq(option, "noauto"))
- return 0;
-
- if (startswith(option, "cipher=")) {
- char *t;
-
- if (!(t = strdup(option+7)))
- return -ENOMEM;
-
- free(opt_cipher);
- opt_cipher = t;
-
- } else if (startswith(option, "size=")) {
-
- if (safe_atou(option+5, &opt_key_size) < 0) {
- log_error("size= parse failure, ignoring.");
- return 0;
- }
-
- } else if (startswith(option, "hash=")) {
- char *t;
-
- if (!(t = strdup(option+5)))
- return -ENOMEM;
-
- free(opt_hash);
- opt_hash = t;
-
- } else if (startswith(option, "tries=")) {
-
- if (safe_atou(option+6, &opt_tries) < 0) {
- log_error("tries= parse failure, ignoring.");
- return 0;
- }
-
- } else if (streq(option, "readonly"))
- opt_readonly = true;
- else if (streq(option, "verify"))
- opt_verify = true;
- else if (streq(option, "luks"))
- opt_type = CRYPT_LUKS1;
- else if (streq(option, "plain") ||
- streq(option, "swap") ||
- streq(option, "tmp"))
- opt_type = CRYPT_PLAIN;
- else if (startswith(option, "timeout=")) {
-
- if (parse_usec(option+8, &opt_timeout) < 0) {
- log_error("timeout= parse failure, ignoring.");
- return 0;
- }
-
- } else if (!streq(option, "none"))
- log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
-
- return 0;
-}
-
-static int parse_options(const char *options) {
- char *state;
- char *w;
- size_t l;
-
- assert(options);
-
- FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
- char *o;
- int r;
-
- if (!(o = strndup(w, l)))
- return -ENOMEM;
-
- r = parse_one_option(o);
- free(o);
-
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-static void log_glue(int level, const char *msg, void *usrptr) {
- log_debug("%s", msg);
-}
-
-static char *disk_description(const char *path) {
- struct udev *udev = NULL;
- struct udev_device *device = NULL;
- struct stat st;
- char *description = NULL;
- const char *model;
-
- assert(path);
-
- if (stat(path, &st) < 0)
- return NULL;
-
- if (!S_ISBLK(st.st_mode))
- return NULL;
-
- if (!(udev = udev_new()))
- return NULL;
-
- if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev)))
- goto finish;
-
- if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) ||
- (model = udev_device_get_property_value(device, "ID_MODEL")) ||
- (model = udev_device_get_property_value(device, "DM_NAME")))
- description = strdup(model);
-
-finish:
- if (device)
- udev_device_unref(device);
-
- if (udev)
- udev_unref(udev);
-
- return description;
-}
-
-static char *disk_mount_point(const char *label) {
- char *mp = NULL, *device = NULL;
- FILE *f = NULL;
- struct mntent *m;
-
- /* Yeah, we don't support native systemd unit files here for now */
-
- if (asprintf(&device, "/dev/mapper/%s", label) < 0)
- goto finish;
-
- if (!(f = setmntent("/etc/fstab", "r")))
- goto finish;
-
- while ((m = getmntent(f)))
- if (path_equal(m->mnt_fsname, device)) {
- mp = strdup(m->mnt_dir);
- break;
- }
-
-finish:
- if (f)
- endmntent(f);
-
- free(device);
-
- return mp;
-}
-
-static int help(void) {
-
- printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n"
- "%s detach VOLUME\n\n"
- "Attaches or detaches an encrypted block device.\n",
- program_invocation_short_name,
- program_invocation_short_name);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- int r = EXIT_FAILURE;
- struct crypt_device *cd = NULL;
- char **passwords = NULL, *truncated_cipher = NULL;
- const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL;
- char *description = NULL, *name_buffer = NULL, *mount_point = NULL;
- unsigned keyfile_size = 0;
-
- if (argc <= 1) {
- help();
- return EXIT_SUCCESS;
- }
-
- if (argc < 3) {
- log_error("This program requires at least two arguments.");
- return EXIT_FAILURE;
- }
-
- log_set_target(LOG_TARGET_AUTO);
- log_parse_environment();
- log_open();
-
- umask(0022);
-
- if (streq(argv[1], "attach")) {
- uint32_t flags = 0;
- int k;
- unsigned try;
- const char *key_file = NULL;
- usec_t until;
- crypt_status_info status;
-
- /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
-
- if (argc < 4) {
- log_error("attach requires at least two arguments.");
- goto finish;
- }
-
- if (argc >= 5 &&
- argv[4][0] &&
- !streq(argv[4], "-") &&
- !streq(argv[4], "none")) {
-
- if (!path_is_absolute(argv[4]))
- log_error("Password file path %s is not absolute. Ignoring.", argv[4]);
- else
- key_file = argv[4];
- }
-
- if (argc >= 6 && argv[5][0] && !streq(argv[5], "-"))
- parse_options(argv[5]);
-
- /* A delicious drop of snake oil */
- mlockall(MCL_FUTURE);
-
- description = disk_description(argv[3]);
- mount_point = disk_mount_point(argv[2]);
-
- if (description && streq(argv[2], description)) {
- /* If the description string is simply the
- * volume name, then let's not show this
- * twice */
- free(description);
- description = NULL;
- }
-
- if (mount_point && description)
- asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
- else if (mount_point)
- asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
- else if (description)
- asprintf(&name_buffer, "%s (%s)", description, argv[2]);
-
- name = name_buffer ? name_buffer : argv[2];
-
- if ((k = crypt_init(&cd, argv[3]))) {
- log_error("crypt_init() failed: %s", strerror(-k));
- goto finish;
- }
-
- crypt_set_log_callback(cd, log_glue, NULL);
-
- status = crypt_status(cd, argv[2]);
- if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) {
- log_info("Volume %s already active.", argv[2]);
- r = EXIT_SUCCESS;
- goto finish;
- }
-
- if (opt_readonly)
- flags |= CRYPT_ACTIVATE_READONLY;
-
- if (opt_timeout > 0)
- until = now(CLOCK_MONOTONIC) + opt_timeout;
- else
- until = 0;
-
- opt_tries = opt_tries > 0 ? opt_tries : 3;
- opt_key_size = (opt_key_size > 0 ? opt_key_size : 256);
- hash = opt_hash ? opt_hash : "ripemd160";
-
- if (opt_cipher) {
- size_t l;
-
- l = strcspn(opt_cipher, "-");
-
- if (!(truncated_cipher = strndup(opt_cipher, l))) {
- log_error("Out of memory");
- goto finish;
- }
-
- cipher = truncated_cipher;
- cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain";
- } else {
- cipher = "aes";
- cipher_mode = "cbc-essiv:sha256";
- }
-
- for (try = 0; try < opt_tries; try++) {
- bool pass_volume_key = false;
-
- strv_free(passwords);
- passwords = NULL;
-
- if (!key_file) {
- char *text;
- char **p;
-
- if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) {
- log_error("Out of memory");
- goto finish;
- }
-
- k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords);
- free(text);
-
- if (k < 0) {
- log_error("Failed to query password: %s", strerror(-k));
- goto finish;
- }
-
- if (opt_verify) {
- char **passwords2 = NULL;
-
- assert(strv_length(passwords) == 1);
-
- if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) {
- log_error("Out of memory");
- goto finish;
- }
-
- k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2);
- free(text);
-
- if (k < 0) {
- log_error("Failed to query verification password: %s", strerror(-k));
- goto finish;
- }
-
- assert(strv_length(passwords2) == 1);
-
- if (!streq(passwords[0], passwords2[0])) {
- log_warning("Passwords did not match, retrying.");
- strv_free(passwords2);
- continue;
- }
-
- strv_free(passwords2);
- }
-
- strv_uniq(passwords);
-
- STRV_FOREACH(p, passwords) {
- char *c;
-
- if (strlen(*p)+1 >= opt_key_size)
- continue;
-
- /* Pad password if necessary */
- if (!(c = new(char, opt_key_size))) {
- log_error("Out of memory.");
- goto finish;
- }
-
- strncpy(c, *p, opt_key_size);
- free(*p);
- *p = c;
- }
- }
-
- k = 0;
-
- if (!opt_type || streq(opt_type, CRYPT_LUKS1))
- k = crypt_load(cd, CRYPT_LUKS1, NULL);
-
- if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) {
- struct crypt_params_plain params;
-
- zero(params);
- params.hash = hash;
-
- /* In contrast to what the name
- * crypt_setup() might suggest this
- * doesn't actually format anything,
- * it just configures encryption
- * parameters when used for plain
- * mode. */
- k = crypt_format(cd, CRYPT_PLAIN,
- cipher,
- cipher_mode,
- NULL,
- NULL,
- opt_key_size / 8,
- ¶ms);
-
- pass_volume_key = streq(hash, "plain");
-
- /* for CRYPT_PLAIN limit reads
- * from keyfile to key length */
- keyfile_size = opt_key_size / 8;
- }
-
- if (k < 0) {
- log_error("Loading of cryptographic parameters failed: %s", strerror(-k));
- goto finish;
- }
-
- log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
- crypt_get_cipher(cd),
- crypt_get_cipher_mode(cd),
- crypt_get_volume_key_size(cd)*8,
- argv[3]);
-
- if (key_file)
- k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, keyfile_size, flags);
- else {
- char **p;
-
- STRV_FOREACH(p, passwords) {
-
- if (pass_volume_key)
- k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags);
- else
- k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags);
-
- if (k >= 0)
- break;
- }
- }
-
- if (k >= 0)
- break;
-
- if (k != -EPERM) {
- log_error("Failed to activate: %s", strerror(-k));
- goto finish;
- }
-
- log_warning("Invalid passphrase.");
- }
-
- if (try >= opt_tries) {
- log_error("Too many attempts.");
- r = EXIT_FAILURE;
- goto finish;
- }
-
- } else if (streq(argv[1], "detach")) {
- int k;
-
- if ((k = crypt_init_by_name(&cd, argv[2]))) {
- log_error("crypt_init() failed: %s", strerror(-k));
- goto finish;
- }
-
- crypt_set_log_callback(cd, log_glue, NULL);
-
- if ((k = crypt_deactivate(cd, argv[2])) < 0) {
- log_error("Failed to deactivate: %s", strerror(-k));
- goto finish;
- }
-
- } else {
- log_error("Unknown verb %s.", argv[1]);
- goto finish;
- }
-
- r = EXIT_SUCCESS;
-
-finish:
-
- if (cd)
- crypt_free(cd);
-
- free(opt_cipher);
- free(opt_hash);
-
- free(truncated_cipher);
-
- strv_free(passwords);
-
- free(description);
- free(mount_point);
- free(name_buffer);
-
- return r;
-}
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
new file mode 100644
index 0000000..a48b7a4
--- /dev/null
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -0,0 +1,298 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "util.h"
+#include "unit-name.h"
+
+const char *arg_dest = "/tmp";
+
+static bool has_option(const char *haystack, const char *needle) {
+ const char *f = haystack;
+ size_t l;
+
+ assert(needle);
+
+ if (!haystack)
+ return false;
+
+ l = strlen(needle);
+
+ while ((f = strstr(f, needle))) {
+
+ if (f > haystack && f[-1] != ',') {
+ f++;
+ continue;
+ }
+
+ if (f[l] != 0 && f[l] != ',') {
+ f++;
+ continue;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+static int create_disk(
+ const char *name,
+ const char *device,
+ const char *password,
+ const char *options) {
+
+ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
+ int r;
+ FILE *f = NULL;
+ bool noauto, nofail;
+
+ assert(name);
+ assert(device);
+
+ noauto = has_option(options, "noauto");
+ nofail = has_option(options, "nofail");
+
+ if (!(n = unit_name_build_escape("cryptsetup", name, ".service"))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit name.");
+ goto fail;
+ }
+
+ if (asprintf(&p, "%s/%s", arg_dest, n) < 0) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit file name.");
+ goto fail;
+ }
+
+ if (!(u = fstab_node_to_udev_node(device))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device node.");
+ goto fail;
+ }
+
+ if (!(d = unit_name_from_path(u, ".device"))) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device name.");
+ goto fail;
+ }
+
+ if (!(f = fopen(p, "wxe"))) {
+ r = -errno;
+ log_error("Failed to create unit file: %m");
+ goto fail;
+ }
+
+ fprintf(f,
+ "[Unit]\n"
+ "Description=Cryptography Setup for %%I\n"
+ "Conflicts=umount.target\n"
+ "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",
+ d, d);
+
+ if (!nofail)
+ fprintf(f,
+ "Before=cryptsetup.target\n");
+
+ if (password && (streq(password, "/dev/urandom") ||
+ streq(password, "/dev/random") ||
+ 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"
+ "Type=oneshot\n"
+ "RemainAfterExit=yes\n"
+ "TimeoutSec=0\n" /* the binary handles timeouts anyway */
+ "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
+ "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
+ name, u, strempty(password), strempty(options),
+ name);
+
+ if (has_option(options, "tmp"))
+ fprintf(f,
+ "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
+ name);
+
+ if (has_option(options, "swap"))
+ fprintf(f,
+ "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
+ name);
+
+ fflush(f);
+
+ if (ferror(f)) {
+ r = -errno;
+ log_error("Failed to write file: %m");
+ goto fail;
+ }
+
+ if (asprintf(&from, "../%s", n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ if (!noauto) {
+
+ if (asprintf(&to, "%s/%s.wants/%s", arg_dest, d, n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+ goto fail;
+ }
+
+ free(to);
+ to = NULL;
+
+ if (!nofail)
+ asprintf(&to, "%s/cryptsetup.target.requires/%s", arg_dest, n);
+ else
+ asprintf(&to, "%s/cryptsetup.target.wants/%s", arg_dest, n);
+
+ if (!to) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+ goto fail;
+ }
+ }
+
+ free(to);
+ to = NULL;
+
+ e = unit_name_escape(name);
+ if (asprintf(&to, "%s/dev-mapper-%s.device.requires/%s", arg_dest, e, n) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+ goto fail;
+ }
+
+ r = 0;
+
+fail:
+ free(p);
+ free(n);
+ free(d);
+ free(e);
+
+ free(from);
+ free(to);
+
+ if (f)
+ fclose(f);
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ FILE *f;
+ int r = EXIT_SUCCESS;
+ unsigned n = 0;
+
+ if (argc > 2) {
+ log_error("This program takes one or no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 1)
+ arg_dest = argv[1];
+
+ log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+ log_parse_environment();
+ log_open();
+
+ umask(0022);
+
+ if (!(f = fopen("/etc/crypttab", "re"))) {
+
+ if (errno == ENOENT)
+ r = EXIT_SUCCESS;
+ else {
+ r = EXIT_FAILURE;
+ log_error("Failed to open /etc/crypttab: %m");
+ }
+
+ goto finish;
+ }
+
+ for (;;) {
+ char line[LINE_MAX], *l;
+ char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
+ int k;
+
+ if (!(fgets(line, sizeof(line), f)))
+ break;
+
+ n++;
+
+ l = strstrip(line);
+ if (*l == '#' || *l == 0)
+ continue;
+
+ if ((k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options)) < 2 || k > 4) {
+ log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
+ r = EXIT_FAILURE;
+ goto next;
+ }
+
+ if (create_disk(name, device, password, options) < 0)
+ r = EXIT_FAILURE;
+
+ next:
+ free(name);
+ free(device);
+ free(password);
+ free(options);
+ }
+
+finish:
+ return r;
+}
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
new file mode 100644
index 0000000..ac7b6d6
--- /dev/null
+++ b/src/cryptsetup/cryptsetup.c
@@ -0,0 +1,529 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <mntent.h>
+
+#include <libcryptsetup.h>
+#include <libudev.h>
+
+#include "log.h"
+#include "util.h"
+#include "strv.h"
+#include "ask-password-api.h"
+#include "def.h"
+
+static const char *opt_type = NULL; /* LUKS1 or PLAIN */
+static char *opt_cipher = NULL;
+static unsigned opt_key_size = 0;
+static char *opt_hash = NULL;
+static unsigned opt_tries = 0;
+static bool opt_readonly = false;
+static bool opt_verify = false;
+static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC;
+
+/* Options Debian's crypttab knows we don't:
+
+ offset=
+ skip=
+ precheck=
+ check=
+ checkargs=
+ noearly=
+ loud=
+ keyscript=
+*/
+
+static int parse_one_option(const char *option) {
+ assert(option);
+
+ /* Handled outside of this tool */
+ if (streq(option, "noauto"))
+ return 0;
+
+ if (startswith(option, "cipher=")) {
+ char *t;
+
+ if (!(t = strdup(option+7)))
+ return -ENOMEM;
+
+ free(opt_cipher);
+ opt_cipher = t;
+
+ } else if (startswith(option, "size=")) {
+
+ if (safe_atou(option+5, &opt_key_size) < 0) {
+ log_error("size= parse failure, ignoring.");
+ return 0;
+ }
+
+ } else if (startswith(option, "hash=")) {
+ char *t;
+
+ if (!(t = strdup(option+5)))
+ return -ENOMEM;
+
+ free(opt_hash);
+ opt_hash = t;
+
+ } else if (startswith(option, "tries=")) {
+
+ if (safe_atou(option+6, &opt_tries) < 0) {
+ log_error("tries= parse failure, ignoring.");
+ return 0;
+ }
+
+ } else if (streq(option, "readonly"))
+ opt_readonly = true;
+ else if (streq(option, "verify"))
+ opt_verify = true;
+ else if (streq(option, "luks"))
+ opt_type = CRYPT_LUKS1;
+ else if (streq(option, "plain") ||
+ streq(option, "swap") ||
+ streq(option, "tmp"))
+ opt_type = CRYPT_PLAIN;
+ else if (startswith(option, "timeout=")) {
+
+ if (parse_usec(option+8, &opt_timeout) < 0) {
+ log_error("timeout= parse failure, ignoring.");
+ return 0;
+ }
+
+ } else if (!streq(option, "none"))
+ log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
+
+ return 0;
+}
+
+static int parse_options(const char *options) {
+ char *state;
+ char *w;
+ size_t l;
+
+ assert(options);
+
+ FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
+ char *o;
+ int r;
+
+ if (!(o = strndup(w, l)))
+ return -ENOMEM;
+
+ r = parse_one_option(o);
+ free(o);
+
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static void log_glue(int level, const char *msg, void *usrptr) {
+ log_debug("%s", msg);
+}
+
+static char *disk_description(const char *path) {
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL;
+ struct stat st;
+ char *description = NULL;
+ const char *model;
+
+ assert(path);
+
+ if (stat(path, &st) < 0)
+ return NULL;
+
+ if (!S_ISBLK(st.st_mode))
+ return NULL;
+
+ if (!(udev = udev_new()))
+ return NULL;
+
+ if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev)))
+ goto finish;
+
+ if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) ||
+ (model = udev_device_get_property_value(device, "ID_MODEL")) ||
+ (model = udev_device_get_property_value(device, "DM_NAME")))
+ description = strdup(model);
+
+finish:
+ if (device)
+ udev_device_unref(device);
+
+ if (udev)
+ udev_unref(udev);
+
+ return description;
+}
+
+static char *disk_mount_point(const char *label) {
+ char *mp = NULL, *device = NULL;
+ FILE *f = NULL;
+ struct mntent *m;
+
+ /* Yeah, we don't support native systemd unit files here for now */
+
+ if (asprintf(&device, "/dev/mapper/%s", label) < 0)
+ goto finish;
+
+ if (!(f = setmntent("/etc/fstab", "r")))
+ goto finish;
+
+ while ((m = getmntent(f)))
+ if (path_equal(m->mnt_fsname, device)) {
+ mp = strdup(m->mnt_dir);
+ break;
+ }
+
+finish:
+ if (f)
+ endmntent(f);
+
+ free(device);
+
+ return mp;
+}
+
+static int help(void) {
+
+ printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n"
+ "%s detach VOLUME\n\n"
+ "Attaches or detaches an encrypted block device.\n",
+ program_invocation_short_name,
+ program_invocation_short_name);
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int r = EXIT_FAILURE;
+ struct crypt_device *cd = NULL;
+ char **passwords = NULL, *truncated_cipher = NULL;
+ const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL;
+ char *description = NULL, *name_buffer = NULL, *mount_point = NULL;
+ unsigned keyfile_size = 0;
+
+ if (argc <= 1) {
+ help();
+ return EXIT_SUCCESS;
+ }
+
+ if (argc < 3) {
+ log_error("This program requires at least two arguments.");
+ return EXIT_FAILURE;
+ }
+
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+
+ umask(0022);
+
+ if (streq(argv[1], "attach")) {
+ uint32_t flags = 0;
+ int k;
+ unsigned try;
+ const char *key_file = NULL;
+ usec_t until;
+ crypt_status_info status;
+
+ /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
+
+ if (argc < 4) {
+ log_error("attach requires at least two arguments.");
+ goto finish;
+ }
+
+ if (argc >= 5 &&
+ argv[4][0] &&
+ !streq(argv[4], "-") &&
+ !streq(argv[4], "none")) {
+
+ if (!path_is_absolute(argv[4]))
+ log_error("Password file path %s is not absolute. Ignoring.", argv[4]);
+ else
+ key_file = argv[4];
+ }
+
+ if (argc >= 6 && argv[5][0] && !streq(argv[5], "-"))
+ parse_options(argv[5]);
+
+ /* A delicious drop of snake oil */
+ mlockall(MCL_FUTURE);
+
+ description = disk_description(argv[3]);
+ mount_point = disk_mount_point(argv[2]);
+
+ if (description && streq(argv[2], description)) {
+ /* If the description string is simply the
+ * volume name, then let's not show this
+ * twice */
+ free(description);
+ description = NULL;
+ }
+
+ if (mount_point && description)
+ asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
+ else if (mount_point)
+ asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
+ else if (description)
+ asprintf(&name_buffer, "%s (%s)", description, argv[2]);
+
+ name = name_buffer ? name_buffer : argv[2];
+
+ if ((k = crypt_init(&cd, argv[3]))) {
+ log_error("crypt_init() failed: %s", strerror(-k));
+ goto finish;
+ }
+
+ crypt_set_log_callback(cd, log_glue, NULL);
+
+ status = crypt_status(cd, argv[2]);
+ if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) {
+ log_info("Volume %s already active.", argv[2]);
+ r = EXIT_SUCCESS;
+ goto finish;
+ }
+
+ if (opt_readonly)
+ flags |= CRYPT_ACTIVATE_READONLY;
+
+ if (opt_timeout > 0)
+ until = now(CLOCK_MONOTONIC) + opt_timeout;
+ else
+ until = 0;
+
+ opt_tries = opt_tries > 0 ? opt_tries : 3;
+ opt_key_size = (opt_key_size > 0 ? opt_key_size : 256);
+ hash = opt_hash ? opt_hash : "ripemd160";
+
+ if (opt_cipher) {
+ size_t l;
+
+ l = strcspn(opt_cipher, "-");
+
+ if (!(truncated_cipher = strndup(opt_cipher, l))) {
+ log_error("Out of memory");
+ goto finish;
+ }
+
+ cipher = truncated_cipher;
+ cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain";
+ } else {
+ cipher = "aes";
+ cipher_mode = "cbc-essiv:sha256";
+ }
+
+ for (try = 0; try < opt_tries; try++) {
+ bool pass_volume_key = false;
+
+ strv_free(passwords);
+ passwords = NULL;
+
+ if (!key_file) {
+ char *text;
+ char **p;
+
+ if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) {
+ log_error("Out of memory");
+ goto finish;
+ }
+
+ k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords);
+ free(text);
+
+ if (k < 0) {
+ log_error("Failed to query password: %s", strerror(-k));
+ goto finish;
+ }
+
+ if (opt_verify) {
+ char **passwords2 = NULL;
+
+ assert(strv_length(passwords) == 1);
+
+ if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) {
+ log_error("Out of memory");
+ goto finish;
+ }
+
+ k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2);
+ free(text);
+
+ if (k < 0) {
+ log_error("Failed to query verification password: %s", strerror(-k));
+ goto finish;
+ }
+
+ assert(strv_length(passwords2) == 1);
+
+ if (!streq(passwords[0], passwords2[0])) {
+ log_warning("Passwords did not match, retrying.");
+ strv_free(passwords2);
+ continue;
+ }
+
+ strv_free(passwords2);
+ }
+
+ strv_uniq(passwords);
+
+ STRV_FOREACH(p, passwords) {
+ char *c;
+
+ if (strlen(*p)+1 >= opt_key_size)
+ continue;
+
+ /* Pad password if necessary */
+ if (!(c = new(char, opt_key_size))) {
+ log_error("Out of memory.");
+ goto finish;
+ }
+
+ strncpy(c, *p, opt_key_size);
+ free(*p);
+ *p = c;
+ }
+ }
+
+ k = 0;
+
+ if (!opt_type || streq(opt_type, CRYPT_LUKS1))
+ k = crypt_load(cd, CRYPT_LUKS1, NULL);
+
+ if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) {
+ struct crypt_params_plain params;
+
+ zero(params);
+ params.hash = hash;
+
+ /* In contrast to what the name
+ * crypt_setup() might suggest this
+ * doesn't actually format anything,
+ * it just configures encryption
+ * parameters when used for plain
+ * mode. */
+ k = crypt_format(cd, CRYPT_PLAIN,
+ cipher,
+ cipher_mode,
+ NULL,
+ NULL,
+ opt_key_size / 8,
+ ¶ms);
+
+ pass_volume_key = streq(hash, "plain");
+
+ /* for CRYPT_PLAIN limit reads
+ * from keyfile to key length */
+ keyfile_size = opt_key_size / 8;
+ }
+
+ if (k < 0) {
+ log_error("Loading of cryptographic parameters failed: %s", strerror(-k));
+ goto finish;
+ }
+
+ log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
+ crypt_get_cipher(cd),
+ crypt_get_cipher_mode(cd),
+ crypt_get_volume_key_size(cd)*8,
+ argv[3]);
+
+ if (key_file)
+ k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, keyfile_size, flags);
+ else {
+ char **p;
+
+ STRV_FOREACH(p, passwords) {
+
+ if (pass_volume_key)
+ k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags);
+ else
+ k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags);
+
+ if (k >= 0)
+ break;
+ }
+ }
+
+ if (k >= 0)
+ break;
+
+ if (k != -EPERM) {
+ log_error("Failed to activate: %s", strerror(-k));
+ goto finish;
+ }
+
+ log_warning("Invalid passphrase.");
+ }
+
+ if (try >= opt_tries) {
+ log_error("Too many attempts.");
+ r = EXIT_FAILURE;
+ goto finish;
+ }
+
+ } else if (streq(argv[1], "detach")) {
+ int k;
+
+ if ((k = crypt_init_by_name(&cd, argv[2]))) {
+ log_error("crypt_init() failed: %s", strerror(-k));
+ goto finish;
+ }
+
+ crypt_set_log_callback(cd, log_glue, NULL);
+
+ if ((k = crypt_deactivate(cd, argv[2])) < 0) {
+ log_error("Failed to deactivate: %s", strerror(-k));
+ goto finish;
+ }
+
+ } else {
+ log_error("Unknown verb %s.", argv[1]);
+ goto finish;
+ }
+
+ r = EXIT_SUCCESS;
+
+finish:
+
+ if (cd)
+ crypt_free(cd);
+
+ free(opt_cipher);
+ free(opt_hash);
+
+ free(truncated_cipher);
+
+ strv_free(passwords);
+
+ free(description);
+ free(mount_point);
+ free(name_buffer);
+
+ return r;
+}
More information about the systemd-commits
mailing list