summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/util.c2
-rw-r--r--src/bootchart/store.c58
-rw-r--r--src/bootchart/svg.c4
-rw-r--r--src/core/main.c4
-rw-r--r--src/login/logind-dbus.c28
-rw-r--r--src/login/logind.c6
-rw-r--r--src/login/logind.h2
-rw-r--r--src/shared/install.c2
-rw-r--r--src/sysv-generator/sysv-generator.c32
l---------src/udev/accelerometer/Makefile1
-rw-r--r--src/udev/accelerometer/accelerometer.c303
11 files changed, 115 insertions, 327 deletions
diff --git a/src/basic/util.c b/src/basic/util.c
index 727be56f58..906e4abad6 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -3627,7 +3627,7 @@ bool string_is_safe(const char *p) {
if (*t > 0 && *t < ' ')
return false;
- if (strchr("\\\"\'\0x7f", *t))
+ if (strchr("\\\"\'\x7f", *t))
return false;
}
diff --git a/src/bootchart/store.c b/src/bootchart/store.c
index f159cbafe2..00439f0409 100644
--- a/src/bootchart/store.c
+++ b/src/bootchart/store.c
@@ -115,6 +115,7 @@ int log_sample(DIR *proc,
struct list_sample_data *sampledata;
struct ps_sched_struct *ps_prev = NULL;
int procfd;
+ int taskfd = -1;
sampledata = *ptr;
@@ -409,6 +410,63 @@ schedstat_next:
ps->total = (ps->last->runtime - ps->first->runtime)
/ 1000000000.0;
+ /* Take into account CPU runtime/waittime spent in non-main threads of the process
+ * by parsing "/proc/[pid]/task/[tid]/schedstat" for all [tid] != [pid]
+ * See https://github.com/systemd/systemd/issues/139
+ */
+
+ /* Browse directory "/proc/[pid]/task" to know the thread ids of process [pid] */
+ snprintf(filename, sizeof(filename), PID_FMT "/task", pid);
+ taskfd = openat(procfd, filename, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+ if (taskfd >= 0) {
+ _cleanup_closedir_ DIR *taskdir = NULL;
+
+ taskdir = fdopendir(taskfd);
+ if (!taskdir) {
+ safe_close(taskfd);
+ return -errno;
+ }
+ FOREACH_DIRENT(ent, taskdir, break) {
+ int r;
+ int tid = -1;
+ _cleanup_close_ int tid_schedstat = -1;
+ long long delta_rt;
+ long long delta_wt;
+
+ if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9'))
+ continue;
+
+ /* Skip main thread as it was already accounted */
+ r = safe_atoi(ent->d_name, &tid);
+ if (r < 0 || tid == pid)
+ continue;
+
+ /* Parse "/proc/[pid]/task/[tid]/schedstat" */
+ snprintf(filename, sizeof(filename), PID_FMT "/schedstat", tid);
+ tid_schedstat = openat(taskfd, filename, O_RDONLY|O_CLOEXEC);
+
+ if (tid_schedstat == -1)
+ continue;
+
+ s = pread(tid_schedstat, buf, sizeof(buf) - 1, 0);
+ if (s <= 0)
+ continue;
+ buf[s] = '\0';
+
+ if (!sscanf(buf, "%s %s %*s", rt, wt))
+ continue;
+
+ r = safe_atolli(rt, &delta_rt);
+ if (r < 0)
+ continue;
+ r = safe_atolli(rt, &delta_wt);
+ if (r < 0)
+ continue;
+ ps->sample->runtime += delta_rt;
+ ps->sample->waittime += delta_wt;
+ }
+ }
+
if (!arg_pss)
goto catch_rename;
diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c
index f442200b66..0ac1f55a91 100644
--- a/src/bootchart/svg.c
+++ b/src/bootchart/svg.c
@@ -76,8 +76,6 @@ static void svg_header(FILE *of, struct list_sample_data *head, double graph_sta
assert(head);
- sampledata = head;
- LIST_FIND_TAIL(link, sampledata, head);
sampledata_last = head;
LIST_FOREACH_BEFORE(link, sampledata, head) {
sampledata_last = sampledata;
@@ -1296,6 +1294,8 @@ int svg_do(FILE *of,
double offset = 7;
int r, c;
+ sampledata = head;
+ LIST_FIND_TAIL(link, sampledata, head);
ps = ps_first;
/* count initcall thread count first */
diff --git a/src/core/main.c b/src/core/main.c
index 332453a0ea..523f0ce020 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1995,6 +1995,10 @@ finish:
command_line[pos++] = "kmsg";
break;
+ case LOG_TARGET_NULL:
+ command_line[pos++] = "null";
+ break;
+
case LOG_TARGET_CONSOLE:
default:
command_line[pos++] = "console";
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 8ebcd3f5ca..640ae92f7f 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1486,18 +1486,13 @@ static int execute_shutdown_or_sleep(
return 0;
}
-static int manager_inhibit_timeout_handler(
- sd_event_source *s,
- uint64_t usec,
- void *userdata) {
+int manager_dispatch_delayed(Manager *manager, bool timeout) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
Inhibitor *offending = NULL;
- Manager *manager = userdata;
int r;
assert(manager);
- assert(manager->inhibit_timeout_source == s);
if (manager->action_what == 0 || manager->action_job)
return 0;
@@ -1505,6 +1500,9 @@ static int manager_inhibit_timeout_handler(
if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
_cleanup_free_ char *comm = NULL, *u = NULL;
+ if (!timeout)
+ return 0;
+
(void) get_process_comm(offending->pid, &comm);
u = uid_to_name(offending->uid);
@@ -1520,9 +1518,25 @@ static int manager_inhibit_timeout_handler(
manager->action_unit = NULL;
manager->action_what = 0;
+ return r;
}
- return 0;
+ return 1;
+}
+
+static int manager_inhibit_timeout_handler(
+ sd_event_source *s,
+ uint64_t usec,
+ void *userdata) {
+
+ Manager *manager = userdata;
+ int r;
+
+ assert(manager);
+ assert(manager->inhibit_timeout_source == s);
+
+ r = manager_dispatch_delayed(manager, true);
+ return (r < 0) ? r : 0;
}
static int delay_shutdown_or_sleep(
diff --git a/src/login/logind.c b/src/login/logind.c
index 01f7cd9ee0..e2fb496289 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1109,6 +1109,12 @@ static int manager_run(Manager *m) {
manager_gc(m, true);
+ r = manager_dispatch_delayed(m, false);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ continue;
+
r = sd_event_run(m->event, (uint64_t) -1);
if (r < 0)
return r;
diff --git a/src/login/logind.h b/src/login/logind.h
index feb381d0b1..ad437b72cb 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -194,3 +194,5 @@ int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char
int manager_setup_wall_message_timer(Manager *m);
bool logind_wall_tty_filter(const char *tty, void *userdata);
+
+int manager_dispatch_delayed(Manager *manager, bool timeout);
diff --git a/src/shared/install.c b/src/shared/install.c
index 559fda211d..c37cf1948a 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -2263,7 +2263,7 @@ int unit_file_get_list(
}
}
- return r;
+ return 0;
}
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 9ae518ac4a..0d246b1835 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -241,19 +241,21 @@ static bool usage_contains_reload(const char *line) {
static char *sysv_translate_name(const char *name) {
char *r;
+ _cleanup_free_ char *c;
- r = new(char, strlen(name) + strlen(".service") + 1);
- if (!r)
- return NULL;
+ c = strdup(name);
+ if (!c)
+ return NULL;
- if (endswith(name, ".sh"))
- /* Drop .sh suffix */
- strcpy(stpcpy(r, name) - 3, ".service");
- else
- /* Normal init script name */
- strcpy(stpcpy(r, name), ".service");
+ r = endswith(c, ".sh");
+ if (r) {
+ *r = '\0';
+ }
- return r;
+ if (unit_name_mangle(c, UNIT_NAME_NOGLOB, &r) >= 0)
+ return r;
+ else
+ return NULL;
}
static int sysv_translate_facility(const char *name, const char *filename, char **_r) {
@@ -340,6 +342,7 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co
FOREACH_WORD_QUOTED(word, z, text, state_) {
_cleanup_free_ char *n = NULL, *m = NULL;
+ UnitType t;
n = strndup(word, z);
if (!n)
@@ -351,12 +354,13 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co
if (r == 0)
continue;
- if (unit_name_to_type(m) == UNIT_SERVICE) {
+ t = unit_name_to_type(m);
+ if (t == UNIT_SERVICE) {
log_debug("Adding Provides: alias '%s' for '%s'", m, s->name);
r = add_alias(s->name, m);
if (r < 0)
log_warning_errno(r, "[%s:%u] Failed to add LSB Provides name %s, ignoring: %m", s->path, line, m);
- } else {
+ } else if (t == UNIT_TARGET) {
/* NB: SysV targets which are provided by a
* service are pulled in by the services, as
* an indication that the generic service is
@@ -374,6 +378,10 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co
return log_oom();
}
}
+ else if (t == _UNIT_TYPE_INVALID)
+ log_warning("Unit name '%s' is invalid", m);
+ else
+ log_warning("Unknown unit type for unit '%s'", m);
}
if (!isempty(state_))
log_error("[%s:%u] Trailing garbage in Provides, ignoring.", s->path, line);
diff --git a/src/udev/accelerometer/Makefile b/src/udev/accelerometer/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/udev/accelerometer/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c
deleted file mode 100644
index 9e2c590c15..0000000000
--- a/src/udev/accelerometer/accelerometer.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * accelerometer - exports device orientation through property
- *
- * When an "change" event is received on an accelerometer,
- * open its device node, and from the value, as well as the previous
- * value of the property, calculate the device's new orientation,
- * and export it as ID_INPUT_ACCELEROMETER_ORIENTATION.
- *
- * Possible values are:
- * undefined
- * * normal
- * * bottom-up
- * * left-up
- * * right-up
- *
- * The property will be persistent across sessions, and the new
- * orientations can be deducted from the previous one (it allows
- * for a threshold for switching between opposite ends of the
- * orientation).
- *
- * Copyright (C) 2011 Red Hat, Inc.
- * Author:
- * Bastien Nocera <hadess@hadess.net>
- *
- * orientation_calc() from the sensorfw package
- * Copyright (C) 2009-2010 Nokia Corporation
- * Authors:
- * Üstün Ergenoglu <ext-ustun.ergenoglu@nokia.com>
- * Timo Rongas <ext-timo.2.rongas@nokia.com>
- * Lihan Guo <lihan.guo@digia.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <limits.h>
-#include <linux/input.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-
-/* we must use this kernel-compatible implementation */
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x) ((x)%BITS_PER_LONG)
-#define BIT(x) (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
-
-typedef enum {
- ORIENTATION_UNDEFINED,
- ORIENTATION_NORMAL,
- ORIENTATION_BOTTOM_UP,
- ORIENTATION_LEFT_UP,
- ORIENTATION_RIGHT_UP
-} OrientationUp;
-
-static const char *orientations[] = {
- "undefined",
- "normal",
- "bottom-up",
- "left-up",
- "right-up",
- NULL
-};
-
-#define ORIENTATION_UP_UP ORIENTATION_NORMAL
-
-#define DEFAULT_THRESHOLD 250
-#define RADIANS_TO_DEGREES 180.0/M_PI
-#define SAME_AXIS_LIMIT 5
-
-#define THRESHOLD_LANDSCAPE 25
-#define THRESHOLD_PORTRAIT 20
-
-static const char *
-orientation_to_string (OrientationUp o)
-{
- return orientations[o];
-}
-
-static OrientationUp
-string_to_orientation (const char *orientation)
-{
- int i;
-
- if (orientation == NULL)
- return ORIENTATION_UNDEFINED;
- for (i = 0; orientations[i] != NULL; i++) {
- if (streq (orientation, orientations[i]))
- return i;
- }
- return ORIENTATION_UNDEFINED;
-}
-
-static OrientationUp
-orientation_calc (OrientationUp prev,
- int x, int y, int z)
-{
- int rotation;
- OrientationUp ret = prev;
-
- /* Portrait check */
- rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
-
- if (abs(rotation) > THRESHOLD_PORTRAIT) {
- ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
-
- /* Some threshold to switching between portrait modes */
- if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
- if (abs(rotation) < SAME_AXIS_LIMIT) {
- ret = prev;
- }
- }
-
- } else {
- /* Landscape check */
- rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
-
- if (abs(rotation) > THRESHOLD_LANDSCAPE) {
- ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
-
- /* Some threshold to switching between landscape modes */
- if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
- if (abs(rotation) < SAME_AXIS_LIMIT) {
- ret = prev;
- }
- }
- }
- }
-
- return ret;
-}
-
-static OrientationUp
-get_prev_orientation(struct udev_device *dev)
-{
- const char *value;
-
- value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION");
- if (value == NULL)
- return ORIENTATION_UNDEFINED;
- return string_to_orientation(value);
-}
-
-#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; }
-
-/* accelerometers */
-static void test_orientation(struct udev *udev,
- struct udev_device *dev,
- const char *devpath)
-{
- OrientationUp old, new;
- _cleanup_close_ int fd = -1;
- struct input_absinfo abs_info;
- int x = 0, y = 0, z = 0;
- int r;
- char text[64];
-
- old = get_prev_orientation(dev);
-
- fd = open(devpath, O_RDONLY|O_CLOEXEC);
- if (fd < 0)
- return;
-
- READ_AXIS(ABS_X, x);
- READ_AXIS(ABS_Y, y);
- READ_AXIS(ABS_Z, z);
-
- new = orientation_calc(old, x, y, z);
- snprintf(text, sizeof(text),
- "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new));
- puts(text);
-}
-
-static void help(void) {
-
- printf("%s [options] <device path>\n\n"
- "Accelerometer device identification.\n\n"
- " -h --help Print this message\n"
- " -d --debug Debug to stderr\n"
- , program_invocation_short_name);
-}
-
-int main (int argc, char** argv)
-{
- struct udev *udev;
- struct udev_device *dev;
-
- static const struct option options[] = {
- { "debug", no_argument, NULL, 'd' },
- { "help", no_argument, NULL, 'h' },
- {}
- };
-
- char devpath[PATH_MAX];
- char *devnode;
- struct udev_enumerate *enumerate;
- struct udev_list_entry *list_entry;
-
- log_parse_environment();
- log_open();
-
- udev = udev_new();
- if (udev == NULL)
- return 1;
-
- /* CLI argument parsing */
- while (1) {
- int option;
-
- option = getopt_long(argc, argv, "dh", options, NULL);
- if (option == -1)
- break;
-
- switch (option) {
- case 'd':
- log_set_target(LOG_TARGET_CONSOLE);
- log_set_max_level(LOG_DEBUG);
- log_open();
- break;
- case 'h':
- help();
- exit(0);
- default:
- exit(1);
- }
- }
-
- if (argv[optind] == NULL) {
- help();
- exit(1);
- }
-
- /* get the device */
- snprintf(devpath, sizeof(devpath), "/sys/%s", argv[optind]);
- dev = udev_device_new_from_syspath(udev, devpath);
- if (dev == NULL) {
- fprintf(stderr, "unable to access '%s'\n", devpath);
- return 1;
- }
-
- /* Get the children devices and find the devnode */
- devnode = NULL;
- enumerate = udev_enumerate_new(udev);
- udev_enumerate_add_match_parent(enumerate, dev);
- udev_enumerate_scan_devices(enumerate);
- udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
- struct udev_device *device;
- const char *node;
-
- device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
- udev_list_entry_get_name(list_entry));
- if (device == NULL)
- continue;
- /* Already found it */
- if (devnode != NULL) {
- udev_device_unref(device);
- continue;
- }
-
- node = udev_device_get_devnode(device);
- if (node == NULL) {
- udev_device_unref(device);
- continue;
- }
- /* Use the event sub-device */
- if (strstr(node, "/event") == NULL) {
- udev_device_unref(device);
- continue;
- }
-
- devnode = strdup(node);
- udev_device_unref(device);
- }
-
- if (devnode == NULL) {
- fprintf(stderr, "unable to get device node for '%s'\n", devpath);
- return 0;
- }
-
- log_debug("opening accelerometer device %s", devnode);
- test_orientation(udev, dev, devnode);
- free(devnode);
- log_close();
- return 0;
-}