[systemd-commits] 10 commits - TODO src/core src/cryptsetup src/debug-generator src/fsck src/fstab-generator src/gpt-auto-generator src/hibernate-resume src/journal src/modules-load src/quotacheck src/shared src/systemctl src/test src/udev
Lennart Poettering
lennart at kemper.freedesktop.org
Thu Nov 6 16:21:25 PST 2014
TODO | 4
src/core/kmod-setup.c | 2
src/core/main.c | 8 -
src/core/timer.c | 6
src/cryptsetup/cryptsetup-generator.c | 7 -
src/debug-generator/debug-generator.c | 5
src/fsck/fsck.c | 5
src/fstab-generator/fstab-generator.c | 5
src/gpt-auto-generator/gpt-auto-generator.c | 5
src/hibernate-resume/hibernate-resume-generator.c | 12 +
src/journal/coredump.c | 2
src/journal/journald-server.c | 4
src/modules-load/modules-load.c | 5
src/quotacheck/quotacheck.c | 10 +
src/shared/condition.c | 4
src/shared/copy.c | 87 ++++++++----
src/shared/copy.h | 1
src/shared/fileio.c | 91 -------------
src/shared/fileio.h | 1
src/shared/util.c | 148 ++++++++++------------
src/shared/util.h | 4
src/systemctl/systemctl.c | 5
src/test/test-copy.c | 26 +++
src/test/test-fileio.c | 25 ---
src/test/test-util.c | 41 ++++--
src/udev/net/link-config.c | 7 -
src/udev/udevd.c | 4
27 files changed, 253 insertions(+), 271 deletions(-)
New commits:
commit f4934dfaaac70c6d0d49463af62cbd089bfa64c8
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Nov 7 01:19:48 2014 +0100
util: simplify normalize_env_assignment() a bit
diff --git a/src/shared/util.c b/src/shared/util.c
index 3eb8a0f..3411cea 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2783,7 +2783,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
if (k < 0)
return k;
- snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
+ sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
k = readlink_malloc(fn, &s);
if (k < 0) {
@@ -3591,41 +3591,33 @@ char *unquote(const char *s, const char* quotes) {
}
char *normalize_env_assignment(const char *s) {
- _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
- char *eq, *r;
+ _cleanup_free_ char *value = NULL;
+ const char *eq;
+ char *p, *name;
eq = strchr(s, '=');
if (!eq) {
- char *t;
+ char *r, *t;
r = strdup(s);
if (!r)
return NULL;
t = strstrip(r);
- if (t == r)
- return r;
+ if (t != r)
+ memmove(r, t, strlen(t) + 1);
- memmove(r, t, strlen(t) + 1);
return r;
}
- name = strndup(s, eq - s);
- if (!name)
- return NULL;
-
- p = strdup(eq + 1);
- if (!p)
- return NULL;
+ name = strndupa(s, eq - s);
+ p = strdupa(eq + 1);
value = unquote(strstrip(p), QUOTES);
if (!value)
return NULL;
- if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
- r = NULL;
-
- return r;
+ return strjoin(strstrip(name), "=", value, NULL);
}
int wait_for_terminate(pid_t pid, siginfo_t *status) {
commit b5e1fad5b1b9d29694e8c51245821a732fc22f93
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Nov 7 01:19:14 2014 +0100
util: file_is_priv_sticky() is used internally in util.c only nowadays, make it static
diff --git a/src/shared/util.c b/src/shared/util.c
index ba86d20..3eb8a0f 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2941,6 +2941,19 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root
return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
}
+static int file_is_priv_sticky(const char *p) {
+ struct stat st;
+
+ assert(p);
+
+ if (lstat(p, &st) < 0)
+ return -errno;
+
+ return
+ (st.st_uid == 0 || st.st_uid == getuid()) &&
+ (st.st_mode & S_ISVTX);
+}
+
static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
int fd, r;
struct statfs s;
@@ -4829,19 +4842,6 @@ int block_get_whole_disk(dev_t d, dev_t *ret) {
return -ENOENT;
}
-int file_is_priv_sticky(const char *p) {
- struct stat st;
-
- assert(p);
-
- if (lstat(p, &st) < 0)
- return -errno;
-
- return
- (st.st_uid == 0 || st.st_uid == getuid()) &&
- (st.st_mode & S_ISVTX);
-}
-
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/shared/util.h b/src/shared/util.h
index 4997225..24480be 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -582,8 +582,6 @@ static inline bool _pure_ in_charset(const char *s, const char* charset) {
int block_get_whole_disk(dev_t d, dev_t *ret);
-int file_is_priv_sticky(const char *p);
-
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
commit 25e14499c4c5b02229d05a5bc26c3693ade5f987
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Nov 7 01:10:57 2014 +0100
update TODO
diff --git a/TODO b/TODO
index 8a1241f..f26aae8 100644
--- a/TODO
+++ b/TODO
@@ -37,6 +37,8 @@ External:
Features:
+* code cleanup: retire FOREACH_WORD_QUOTED, port to unquote_first_word() loops instead
+
* logind: when the power button is pressed short, just popup a logout dialog. If it is pressed for 1s, do the usual shutdown. Inspiration are Macs here.
* optionally support running journald from the command line for testing purposes in external projects
@@ -60,8 +62,6 @@ Features:
* maybe provide an API to allow migration of foreign PIDs into existing scopes.
-* kdbus: maybe rename "connection name" concept to something that doesn't reuse the word "name"?
-
* PID 1 doesn't apply nspawns devices cgroup policy
* maybe support a new very "soft" reboot mode, that simply kills all processes, disassembles everything, flushes /run and sysvipc, and then reexecs systemd again
commit 779042e772d2459f7649b34a164902dc456f1bab
Author: Michael Chapman <mike at very.puzzling.org>
Date: Thu Nov 6 19:47:02 2014 +1100
timer: reenable TIMER_ACTIVE timers when restarted
A timer configured with OnActiveSec will start its associated unit again
if the timer is stopped, then started. However, if the timer unit is
restarted -- with "systemctl restart", say -- this does not occur.
This commit ensures that TIMER_ACTIVE timers are re-enabled whenever the
timer is started, even if that's within a restart job.
diff --git a/src/core/timer.c b/src/core/timer.c
index a3713e2..5c4e9f9 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -521,6 +521,7 @@ fail:
static int timer_start(Unit *u) {
Timer *t = TIMER(u);
+ TimerValue *v;
assert(t);
assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
@@ -530,6 +531,11 @@ static int timer_start(Unit *u) {
t->last_trigger = DUAL_TIMESTAMP_NULL;
+ /* Reenable all timers that depend on unit activation time */
+ LIST_FOREACH(value, v, t->values)
+ if (v->base == TIMER_ACTIVE)
+ v->disabled = false;
+
if (t->stamp_path) {
struct stat st;
commit f32d2db140150b9d38684a699c9875b6e24ca27c
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Nov 7 00:10:24 2014 +0100
util: rework /proc/cmdline parser to use unquote_first_word()
diff --git a/src/shared/condition.c b/src/shared/condition.c
index ae23599..c5a3caa 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -101,7 +101,7 @@ static int condition_test_kernel_command_line(Condition *c) {
_cleanup_free_ char *word = NULL;
bool found;
- r = unquote_first_word(&p, &word);
+ r = unquote_first_word(&p, &word, true);
if (r < 0)
return r;
if (r == 0)
diff --git a/src/shared/util.c b/src/shared/util.c
index 6401aaf..ba86d20 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6146,8 +6146,7 @@ int split_pair(const char *s, const char *sep, char **l, char **r) {
int shall_restore_state(void) {
_cleanup_free_ char *line = NULL;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
r = proc_cmdline(&line);
@@ -6155,15 +6154,20 @@ int shall_restore_state(void) {
return r;
r = 1;
- FOREACH_WORD_QUOTED(word, l, line, state) {
+ p = line;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
const char *e;
- char n[l+1];
int k;
- memcpy(n, word, l);
- n[l] = 0;
+ k = unquote_first_word(&p, &word, true);
+ if (k < 0)
+ return k;
+ if (k == 0)
+ break;
- e = startswith(n, "systemd.restore_state=");
+ e = startswith(word, "systemd.restore_state=");
if (!e)
continue;
@@ -6186,8 +6190,7 @@ int proc_cmdline(char **ret) {
int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
_cleanup_free_ char *line = NULL;
- const char *w, *state;
- size_t l;
+ const char *p;
int r;
assert(parse_item);
@@ -6196,11 +6199,16 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
if (r < 0)
return r;
- FOREACH_WORD_QUOTED(w, l, line, state) {
- char word[l+1], *value;
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ char *value = NULL;
- memcpy(word, w, l);
- word[l] = 0;
+ r = unquote_first_word(&p, &word, true);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
/* Filter out arguments that are intended only for the
* initrd */
@@ -6976,7 +6984,7 @@ int is_dir(const char* path, bool follow) {
return !!S_ISDIR(st.st_mode);
}
-int unquote_first_word(const char **p, char **ret) {
+int unquote_first_word(const char **p, char **ret, bool relax) {
_cleanup_free_ char *s = NULL;
size_t allocated = 0, sz = 0;
@@ -7035,8 +7043,11 @@ int unquote_first_word(const char **p, char **ret) {
break;
case VALUE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
@@ -7047,9 +7058,11 @@ int unquote_first_word(const char **p, char **ret) {
break;
case SINGLE_QUOTE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
- else if (c == '\'')
+ } else if (c == '\'')
state = VALUE;
else if (c == '\\')
state = SINGLE_QUOTE_ESCAPE;
@@ -7063,8 +7076,11 @@ int unquote_first_word(const char **p, char **ret) {
break;
case SINGLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
@@ -7090,8 +7106,11 @@ int unquote_first_word(const char **p, char **ret) {
break;
case DOUBLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
@@ -7151,7 +7170,7 @@ int unquote_many_words(const char **p, ...) {
l = newa0(char*, n);
for (c = 0; c < n; c++) {
- r = unquote_first_word(p, &l[c]);
+ r = unquote_first_word(p, &l[c], false);
if (r < 0) {
int j;
diff --git a/src/shared/util.h b/src/shared/util.h
index af589b6..4997225 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1018,7 +1018,7 @@ int take_password_lock(const char *root);
int is_symlink(const char *path);
int is_dir(const char *path, bool follow);
-int unquote_first_word(const char **p, char **ret);
+int unquote_first_word(const char **p, char **ret, bool relax);
int unquote_many_words(const char **p, ...) _sentinel_;
int free_and_strdup(char **p, const char *s);
diff --git a/src/test/test-util.c b/src/test/test-util.c
index de6a2a0..01b0192 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -1173,51 +1173,60 @@ static void test_unquote_first_word(void) {
char *t;
p = original = "foobar waldo";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 7);
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "waldo"));
free(t);
assert_se(p == original + 12);
- assert_se(unquote_first_word(&p, &t) == 0);
+ assert_se(unquote_first_word(&p, &t, false) == 0);
assert_se(!t);
assert_se(p == original + 12);
p = original = "\"foobar\" \'waldo\'";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 9);
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "waldo"));
free(t);
assert_se(p == original + 16);
- assert_se(unquote_first_word(&p, &t) == 0);
+ assert_se(unquote_first_word(&p, &t, false) == 0);
assert_se(!t);
assert_se(p == original + 16);
p = original = "\"";
- assert_se(unquote_first_word(&p, &t) == -EINVAL);
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
assert_se(p == original + 1);
p = original = "\'";
- assert_se(unquote_first_word(&p, &t) == -EINVAL);
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
assert_se(p == original + 1);
+ p = original = "\'fooo";
+ assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
+ assert_se(p == original + 5);
+
+ p = original = "\'fooo";
+ assert_se(unquote_first_word(&p, &t, true) > 0);
+ assert_se(streq(t, "fooo"));
+ assert_se(p == original + 5);
+
p = original = "yay\'foo\'bar";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "yayfoobar"));
free(t);
assert_se(p == original + 11);
p = original = " foobar ";
- assert_se(unquote_first_word(&p, &t) > 0);
+ assert_se(unquote_first_word(&p, &t, false) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(p == original + 12);
@@ -1277,6 +1286,17 @@ static void test_unquote_many_words(void) {
free(a);
}
+static int parse_item(const char *key, const char *value) {
+ assert_se(key);
+
+ log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
+ return 0;
+}
+
+static void test_parse_proc_cmdline(void) {
+ assert_se(parse_proc_cmdline(parse_item) >= 0);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -1348,6 +1368,7 @@ int main(int argc, char *argv[]) {
test_execute_directory();
test_unquote_first_word();
test_unquote_many_words();
+ test_parse_proc_cmdline();
return 0;
}
commit b5884878a2874447b2a9f07f324a7cd909d96d48
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Nov 6 21:53:34 2014 +0100
util: simplify proc_cmdline() to reuse get_process_cmdline()
Also, make all parsing of the kernel cmdline non-fatal.
diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c
index 2f3f608..38e1726 100644
--- a/src/core/kmod-setup.c
+++ b/src/core/kmod-setup.c
@@ -47,7 +47,7 @@ static void systemd_kmod_log(
static bool cmdline_check_kdbus(void) {
_cleanup_free_ char *line = NULL;
- if (proc_cmdline(&line) <= 0)
+ if (proc_cmdline(&line) < 0)
return false;
return strstr(line, "kdbus") != NULL;
diff --git a/src/core/main.c b/src/core/main.c
index d48604e..56a1f61 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1402,9 +1402,11 @@ int main(int argc, char *argv[]) {
if (parse_config_file() < 0)
goto finish;
- if (arg_running_as == SYSTEMD_SYSTEM)
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- goto finish;
+ if (arg_running_as == SYSTEMD_SYSTEM) {
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
+ }
/* Note that this also parses bits from the kernel command
* line, including "debug". */
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 20dca84..7c79ca3 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -308,7 +308,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **disks_done = NULL;
_cleanup_fclose_ FILE *f = NULL;
unsigned n = 0;
- int r = EXIT_FAILURE, r2 = EXIT_FAILURE;
+ int r = EXIT_FAILURE, r2 = EXIT_FAILURE, z;
char **i;
if (argc > 1 && argc != 4) {
@@ -325,8 +325,9 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- goto cleanup;
+ z = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (z < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-z));
if (!arg_enabled) {
r = r2 = EXIT_SUCCESS;
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
index fd7c29d..5bbcd8f 100644
--- a/src/debug-generator/debug-generator.c
+++ b/src/debug-generator/debug-generator.c
@@ -150,8 +150,9 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- return EXIT_FAILURE;
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
if (arg_debug_shell) {
r = strv_extend(&arg_wants, "debug-shell.service");
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 70a5918..5562217 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -236,7 +236,10 @@ int main(int argc, char *argv[]) {
umask(0022);
- parse_proc_cmdline(parse_proc_cmdline_item);
+ q = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (q < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-q));
+
test_files();
if (!arg_force && arg_skip)
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 94cbc3a..af45c25 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -593,8 +593,9 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- return EXIT_FAILURE;
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 539e2e6..d4cfe37 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -772,8 +772,9 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- return EXIT_FAILURE;
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
if (!arg_enabled) {
log_debug("Disabled, exiting.");
diff --git a/src/hibernate-resume/hibernate-resume-generator.c b/src/hibernate-resume/hibernate-resume-generator.c
index f407216..41f65d9 100644
--- a/src/hibernate-resume/hibernate-resume-generator.c
+++ b/src/hibernate-resume/hibernate-resume-generator.c
@@ -45,6 +45,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
static int process_resume(void) {
_cleanup_free_ char *name = NULL, *lnk = NULL;
+ if (!arg_resume_dev)
+ return 0;
+
name = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_dev, ".service");
if (!name)
return log_oom();
@@ -83,12 +86,11 @@ int main(int argc, char *argv[]) {
if (!in_initrd())
return EXIT_SUCCESS;
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- return EXIT_FAILURE;
-
- if (arg_resume_dev != NULL)
- r = process_resume();
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
+ r = process_resume();
free(arg_resume_dev);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 2f782f2..62ae79a 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1310,10 +1310,10 @@ static int server_parse_proc_cmdline(Server *s) {
int r;
r = proc_cmdline(&line);
- if (r < 0)
+ if (r < 0) {
log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- if (r <= 0)
return 0;
+ }
FOREACH_WORD_QUOTED(w, l, line, state) {
_cleanup_free_ char *word;
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
index c77b092..08de5e0 100644
--- a/src/modules-load/modules-load.c
+++ b/src/modules-load/modules-load.c
@@ -243,8 +243,9 @@ int main(int argc, char *argv[]) {
umask(0022);
- if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
- return EXIT_FAILURE;
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
ctx = kmod_new(NULL, NULL);
if (!ctx) {
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
index ed95b48..6f39dae 100644
--- a/src/quotacheck/quotacheck.c
+++ b/src/quotacheck/quotacheck.c
@@ -74,6 +74,7 @@ int main(int argc, char *argv[]) {
};
pid_t pid;
+ int r;
if (argc > 1) {
log_error("This program takes no arguments.");
@@ -86,7 +87,10 @@ int main(int argc, char *argv[]) {
umask(0022);
- parse_proc_cmdline(parse_proc_cmdline_item);
+ r = parse_proc_cmdline(parse_proc_cmdline_item);
+ if (r < 0)
+ log_warning("Failed to parse kernel command line, ignoring: %s", strerror(-r));
+
test_files();
if (!arg_force) {
@@ -107,5 +111,7 @@ int main(int argc, char *argv[]) {
_exit(1); /* Operational error */
}
- return wait_for_terminate_and_warn("quotacheck", pid) >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ r = wait_for_terminate_and_warn("quotacheck", pid);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 08bebee..ae23599 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -93,8 +93,6 @@ static int condition_test_kernel_command_line(Condition *c) {
r = proc_cmdline(&line);
if (r < 0)
return r;
- if (r == 0)
- return false;
equal = !!strchr(c->parameter, '=');
p = line;
diff --git a/src/shared/util.c b/src/shared/util.c
index dc1bc39..6401aaf 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6153,11 +6153,8 @@ int shall_restore_state(void) {
r = proc_cmdline(&line);
if (r < 0)
return r;
- if (r == 0) /* Container ... */
- return 1;
r = 1;
-
FOREACH_WORD_QUOTED(word, l, line, state) {
const char *e;
char n[l+1];
@@ -6179,30 +6176,12 @@ int shall_restore_state(void) {
}
int proc_cmdline(char **ret) {
- int r;
-
- if (detect_container(NULL) > 0) {
- char *buf = NULL, *p;
- size_t sz = 0;
-
- r = read_full_file("/proc/1/cmdline", &buf, &sz);
- if (r < 0)
- return r;
-
- for (p = buf; p + 1 < buf + sz; p++)
- if (*p == 0)
- *p = ' ';
-
- *p = 0;
- *ret = buf;
- return 1;
- }
-
- r = read_one_line_file("/proc/cmdline", ret);
- if (r < 0)
- return r;
+ assert(ret);
- return 1;
+ if (detect_container(NULL) > 0)
+ return get_process_cmdline(1, 0, false, ret);
+ else
+ return read_one_line_file("/proc/cmdline", ret);
}
int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
@@ -6215,9 +6194,7 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
r = proc_cmdline(&line);
if (r < 0)
- log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- if (r <= 0)
- return 0;
+ return r;
FOREACH_WORD_QUOTED(w, l, line, state) {
char word[l+1], *value;
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 428a71d..5aefb7d 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -174,11 +174,10 @@ static bool enable_name_policy(void) {
size_t l;
r = proc_cmdline(&line);
- if (r < 0)
- log_warning("Failed to read /proc/cmdline, ignoring: %s",
- strerror(-r));
- if (r <= 0)
+ if (r < 0) {
+ log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
return true;
+ }
FOREACH_WORD_QUOTED(word, l, line, state)
if (strneq(word, "net.ifnames=0", l))
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 305ce86..a040529 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -961,10 +961,10 @@ static void kernel_cmdline_options(struct udev *udev) {
int r;
r = proc_cmdline(&line);
- if (r < 0)
+ if (r < 0) {
log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- if (r <= 0)
return;
+ }
FOREACH_WORD_QUOTED(word, l, line, state) {
char *s, *opt, *value;
commit f2997962ff8aeea577bed878d3bc4e4f64784e45
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Nov 6 21:21:39 2014 +0100
fileio: simplify write_string_file_atomic() by reusing write_string_stream()
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index f4efc4c..ff6b1a7 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -66,7 +66,7 @@ int write_string_file_no_create(const char *fn, const char *line) {
assert(line);
/* We manually build our own version of fopen(..., "we") that
- * without O_CREAT */
+ * works without O_CREAT */
fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return -errno;
@@ -94,20 +94,10 @@ int write_string_file_atomic(const char *fn, const char *line) {
fchmod_umask(fileno(f), 0644);
- errno = 0;
- fputs(line, f);
- if (!endswith(line, "\n"))
- fputc('\n', f);
-
- fflush(f);
-
- if (ferror(f))
- r = errno ? -errno : -EIO;
- else {
+ r = write_string_stream(f, line);
+ if (r >= 0) {
if (rename(p, fn) < 0)
r = -errno;
- else
- r = 0;
}
if (r < 0)
commit 84ee0960443b795936026239f8c0ff8429aed699
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Nov 6 21:20:32 2014 +0100
copy: change error code when hitting copy limit to EFBIG
After all, this is about files, not arguments, hence EFBIG is more
appropriate than E2BIG
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index f423fa2..26a2010 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -329,7 +329,7 @@ static int save_external_coredump(
}
r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
- if (r == -E2BIG) {
+ if (r == -EFBIG) {
log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", info[INFO_PID], info[INFO_COMM]);
goto fail;
} else if (IN_SET(r, -EDQUOT, -ENOSPC)) {
diff --git a/src/shared/copy.c b/src/shared/copy.c
index a863246..abb7fbc 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -37,7 +37,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
if (max_bytes != (off_t) -1) {
if (max_bytes <= 0)
- return -E2BIG;
+ return -EFBIG;
if ((off_t) m > max_bytes)
m = (size_t) max_bytes;
commit cda134ab1eac84f874aacf8e885a07112a7fd5ce
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Nov 6 21:19:20 2014 +0100
copy: teach copy_bytes() sendfile() support, and then replace sendfile_full() by it
diff --git a/src/shared/copy.c b/src/shared/copy.c
index 3744797..a863246 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -19,17 +19,20 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/sendfile.h>
+
#include "util.h"
#include "copy.h"
int copy_bytes(int fdf, int fdt, off_t max_bytes) {
+ bool try_sendfile = true;
+
assert(fdf >= 0);
assert(fdt >= 0);
for (;;) {
- char buf[PIPE_BUF];
- ssize_t n, k;
- size_t m = sizeof(buf);
+ size_t m = PIPE_BUF;
+ ssize_t n;
if (max_bytes != (off_t) -1) {
@@ -40,19 +43,44 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
m = (size_t) max_bytes;
}
- n = read(fdf, buf, m);
- if (n < 0)
- return -errno;
- if (n == 0)
- break;
+ /* First try sendfile(), unless we already tried */
+ if (try_sendfile) {
+
+ n = sendfile(fdt, fdf, NULL, m);
+ if (n < 0) {
+ if (errno != EINVAL && errno != ENOSYS)
+ return -errno;
+
+ try_sendfile = false;
+ /* use fallback below */
+ } else if (n == 0) /* EOF */
+ break;
+ else if (n > 0)
+ /* Succcess! */
+ goto next;
+ }
+
+ /* As a fallback just copy bits by hand */
+ {
+ char buf[m];
+ ssize_t k;
- errno = 0;
- k = loop_write(fdt, buf, n, false);
- if (k < 0)
- return k;
- if (k != n)
- return errno ? -errno : -EIO;
+ n = read(fdf, buf, m);
+ if (n < 0)
+ return -errno;
+ if (n == 0) /* EOF */
+ break;
+
+ errno = 0;
+ k = loop_write(fdt, buf, n, false);
+ if (k < 0)
+ return k;
+ if (k != n)
+ return errno ? -errno : -EIO;
+
+ }
+ next:
if (max_bytes != (off_t) -1) {
assert(max_bytes >= n);
max_bytes -= n;
@@ -262,34 +290,39 @@ int copy_tree(const char *from, const char *to, bool merge) {
return -ENOTSUP;
}
-int copy_file(const char *from, const char *to, int flags, mode_t mode) {
- _cleanup_close_ int fdf = -1, fdt = -1;
- int r;
+int copy_file_fd(const char *from, int fdt) {
+ _cleanup_close_ int fdf = -1;
assert(from);
- assert(to);
+ assert(fdt >= 0);
fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fdf < 0)
return -errno;
+ return copy_bytes(fdf, fdt, (off_t) -1);
+}
+
+int copy_file(const char *from, const char *to, int flags, mode_t mode) {
+ int fdt, r;
+
+ assert(from);
+ assert(to);
+
fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
if (fdt < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (off_t) -1);
+ r = copy_file_fd(from, fdt);
if (r < 0) {
+ close(fdt);
unlink(to);
return r;
}
- r = close(fdt);
- fdt = -1;
-
- if (r < 0) {
- r = -errno;
- unlink(to);
- return r;
+ if (close(fdt) < 0) {
+ unlink_noerrno(to);
+ return -errno;
}
return 0;
diff --git a/src/shared/copy.h b/src/shared/copy.h
index 6b93107..6293211 100644
--- a/src/shared/copy.h
+++ b/src/shared/copy.h
@@ -24,6 +24,7 @@
#include <stdbool.h>
#include <sys/types.h>
+int copy_file_fd(const char *from, int to);
int copy_file(const char *from, const char *to, int flags, mode_t mode);
int copy_tree(const char *from, const char *to, bool merge);
int copy_bytes(int fdf, int fdt, off_t max_bytes);
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index 38028b9..f4efc4c 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -20,12 +20,12 @@
***/
#include <unistd.h>
-#include <sys/sendfile.h>
-#include "fileio.h"
+
#include "util.h"
#include "strv.h"
#include "utf8.h"
#include "ctype.h"
+#include "fileio.h"
int write_string_stream(FILE *f, const char *line) {
assert(f);
@@ -144,77 +144,6 @@ int read_one_line_file(const char *fn, char **line) {
return 0;
}
-ssize_t sendfile_full(int out_fd, const char *fn) {
- _cleanup_fclose_ FILE *f;
- struct stat st;
- int r;
- ssize_t s;
-
- size_t n, l;
- _cleanup_free_ char *buf = NULL;
-
- assert(out_fd > 0);
- assert(fn);
-
- f = fopen(fn, "re");
- if (!f)
- return -errno;
-
- r = fstat(fileno(f), &st);
- if (r < 0)
- return -errno;
-
- s = sendfile(out_fd, fileno(f), NULL, st.st_size);
- if (s < 0)
- if (errno == EINVAL || errno == ENOSYS) {
- /* continue below */
- } else
- return -errno;
- else
- return s;
-
- /* sendfile() failed, fall back to read/write */
-
- /* Safety check */
- if (st.st_size > 4*1024*1024)
- return -E2BIG;
-
- n = st.st_size > 0 ? st.st_size : LINE_MAX;
- l = 0;
-
- while (true) {
- char *t;
- size_t k;
-
- t = realloc(buf, n);
- if (!t)
- return -ENOMEM;
-
- buf = t;
- k = fread(buf + l, 1, n - l, f);
-
- if (k <= 0) {
- if (ferror(f))
- return -errno;
-
- break;
- }
-
- l += k;
- n *= 2;
-
- /* Safety check */
- if (n > 4*1024*1024)
- return -E2BIG;
- }
-
- r = write(out_fd, buf, l);
- if (r < 0)
- return -errno;
-
- return (ssize_t) l;
-}
-
int read_full_stream(FILE *f, char **contents, size_t *size) {
size_t n, l;
_cleanup_free_ char *buf = NULL;
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
index c256915..5ae51c1 100644
--- a/src/shared/fileio.h
+++ b/src/shared/fileio.h
@@ -33,7 +33,6 @@ int write_string_file_atomic(const char *fn, const char *line);
int read_one_line_file(const char *fn, char **line);
int read_full_file(const char *fn, char **contents, size_t *size);
int read_full_stream(FILE *f, char **contents, size_t *size);
-ssize_t sendfile_full(int out_fd, const char *fn);
int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index d9e9c2a..c903c54 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -67,6 +67,7 @@
#include "logs-show.h"
#include "socket-util.h"
#include "fileio.h"
+#include "copy.h"
#include "env-util.h"
#include "bus-util.h"
#include "bus-message.h"
@@ -4647,7 +4648,7 @@ static int cat(sd_bus *bus, char **args) {
ansi_highlight_off());
fflush(stdout);
- r = sendfile_full(STDOUT_FILENO, fragment_path);
+ r = copy_file_fd(fragment_path, STDOUT_FILENO);
if (r < 0) {
log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
continue;
@@ -4662,7 +4663,7 @@ static int cat(sd_bus *bus, char **args) {
ansi_highlight_off());
fflush(stdout);
- r = sendfile_full(STDOUT_FILENO, *path);
+ r = copy_file_fd(*path, STDOUT_FILENO);
if (r < 0) {
log_warning("Failed to cat %s: %s", *path, strerror(-r));
continue;
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index 6aa86a0..d2cad08 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -48,11 +48,36 @@ static void test_copy_file(void) {
assert_se(read_full_file(fn_copy, &buf, &sz) == 0);
assert_se(streq(buf, "foo bar bar bar foo\n"));
+ assert_se(sz == 20);
unlink(fn);
unlink(fn_copy);
}
+static void test_copy_file_fd(void) {
+ char in_fn[] = "/tmp/test-copy-file-fd-XXXXXX";
+ char out_fn[] = "/tmp/test-copy-file-fd-XXXXXX";
+ _cleanup_close_ int in_fd = -1, out_fd = -1;
+ char text[] = "boohoo\nfoo\n\tbar\n";
+ char buf[64] = {0};
+
+ in_fd = mkostemp_safe(in_fn, O_RDWR);
+ assert_se(in_fd >= 0);
+ out_fd = mkostemp_safe(out_fn, O_RDWR);
+ assert_se(out_fd >= 0);
+
+ assert_se(write_string_file(in_fn, text) == 0);
+ assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd) < 0);
+ assert_se(copy_file_fd(in_fn, out_fd) >= 0);
+ assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
+
+ assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
+ assert_se(streq(buf, text));
+
+ unlink(in_fn);
+ unlink(out_fn);
+}
+
static void test_copy_tree(void) {
char original_dir[] = "/tmp/test-copy_tree/";
char copy_dir[] = "/tmp/test-copy_tree-copy/";
@@ -109,6 +134,7 @@ static void test_copy_tree(void) {
int main(int argc, char *argv[]) {
test_copy_file();
+ test_copy_file_fd();
test_copy_tree();
return 0;
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index c26a6fa..cdf1973 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -348,30 +348,6 @@ static void test_write_string_file_no_create(void) {
unlink(fn);
}
-static void test_sendfile_full(void) {
- char in_fn[] = "/tmp/test-sendfile_full-XXXXXX";
- char out_fn[] = "/tmp/test-sendfile_full-XXXXXX";
- _cleanup_close_ int in_fd, out_fd;
- char text[] = "boohoo\nfoo\n\tbar\n";
- char buf[64] = {0};
-
- in_fd = mkostemp_safe(in_fn, O_RDWR);
- assert_se(in_fd >= 0);
- out_fd = mkostemp_safe(out_fn, O_RDWR);
- assert_se(out_fd >= 0);
-
- assert_se(write_string_file(in_fn, text) == 0);
- assert_se(sendfile_full(out_fd, "/a/file/which/does/not/exist/i/guess") < 0);
- assert_se(sendfile_full(out_fd, in_fn) == sizeof(text) - 1);
- assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
-
- assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
- assert_se(streq(buf, text));
-
- unlink(in_fn);
- unlink(out_fn);
-}
-
static void test_load_env_file_pairs(void) {
char fn[] = "/tmp/test-load_env_file_pairs-XXXXXX";
int fd;
@@ -428,7 +404,6 @@ int main(int argc, char *argv[]) {
test_write_string_stream();
test_write_string_file();
test_write_string_file_no_create();
- test_sendfile_full();
test_load_env_file_pairs();
return 0;
commit 0c2576ef74a9f9b96519cdcb7f9c01742d8255e2
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Nov 6 21:11:10 2014 +0100
util: make use of isempty() where appropriate
diff --git a/src/shared/util.c b/src/shared/util.c
index 39ce46a..dc1bc39 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -695,7 +695,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
}
/* Kernel threads have no argv[] */
- if (r == NULL || r[0] == 0) {
+ if (isempty(r)) {
_cleanup_free_ char *t = NULL;
int h;
More information about the systemd-commits
mailing list